-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmemspikefix.lua
More file actions
138 lines (99 loc) · 3.34 KB
/
memspikefix.lua
File metadata and controls
138 lines (99 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
local _G = GLOBAL
local assert, error = _G.assert, _G.error
local getmetatable, setmetatable = _G.getmetatable, _G.setmetatable
--[[
-- Receives a Prefab object, and tweaks its entity constructor ("fn") to
-- make the prefab be loaded before it is spawned.
--]]
local function MakeLazyLoader(prefab)
local fn = assert(prefab.fn)
local current_fn
local function new_fn(...)
_G.TheSim:UnloadPrefabs {prefab.name}
_G.TheSim:LoadPrefabs {prefab.name}
-- Ensures this only runs once, for efficiency.
current_fn = fn
return fn(...)
end
current_fn = new_fn
--[[
-- This extra layer of indirection ensures greater mod friendliness.
--
-- If we just set prefab.fn to new_fn, and later back to fn, we could
-- end up overriding an fn patch done by another mod. By switching between
-- the two internally, via the current_fn upvalue, we preserve any such
-- patching.
--]]
prefab.fn = function(...)
return current_fn(...)
end
end
------------------------------------------------------------------------
local memfix_modfilter
local function generic_modfilter(modwrangler_object, moddir)
return modwrangler_object:GetMod(moddir) ~= nil
end
local function selfish_modfilter(modwrangler_object, moddir)
return moddir == modname
end
memfix_modfilter = selfish_modfilter
function ApplyMemFixGlobally()
memfix_modfilter = generic_modfilter
end
------------------------------------------------------------------------
local function FixModRecipe(rec)
local placer_name = rec.placer or (rec.name.."_placer")
local placer_prefab = _G.Prefabs[placer_name]
if not placer_prefab then return end
placer_prefab.deps = placer_prefab.deps or {}
table.insert(placer_prefab.deps, rec.name)
end
------------------------------------------------------------------------
local ModWrangler = assert( _G.ModWrangler )
ModWrangler.RegisterPrefabs = (function()
local ModRegisterPrefabs = assert( ModWrangler.RegisterPrefabs )
return function(self, ...)
local ModWrangler_self = self
local MainRegisterPrefabs = assert( _G.RegisterPrefabs )
local Prefabs = assert(_G.Prefabs)
local Recipes = assert(_G.Recipes)
local mod_prefabnames = {}
_G.RegisterPrefabs = function(...)
for _, prefab in ipairs{...} do
local moddir = prefab.name:match("^MOD_(.+)$")
if moddir and memfix_modfilter(ModWrangler_self, moddir) then
local mod = ModWrangler_self:GetMod(moddir)
if mod then
if mod.modinfo then
mod.modinfo.memfixed = true
end
print("MEMFIXING "..moddir)
for _, name in ipairs(prefab.deps) do
table.insert(mod_prefabnames, name)
end
prefab.deps = {}
--print("Purged deps from "..prefab.name)
end
end
end
return MainRegisterPrefabs(...)
end
ModRegisterPrefabs(self, ...)
_G.RegisterPrefabs = MainRegisterPrefabs
-- First, do a pass over recipes to extend dependencies if need be.
for _, prefabname in ipairs(mod_prefabnames) do
local rec = Recipes[prefabname]
if rec then
FixModRecipe(rec)
end
end
for _, prefabname in ipairs(mod_prefabnames) do
--print("Registering "..prefabname)
local prefab = assert(Prefabs[prefabname])
MainRegisterPrefabs( prefab )
MakeLazyLoader(prefab)
-- This also takes care of the unloading, so there's no need to patch ModWrangler:UnloadPrefabs.
table.insert(self.loadedprefabs, prefabname)
end
end
end)()