mutators: comments
This commit is contained in:
parent
4d5a0e64e2
commit
ec95192907
1 changed files with 66 additions and 14 deletions
|
@ -1,14 +1,34 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
-- List of mods that are also mutators in order in which they should be enabled
|
||||
-- This is populated via VMFMod.register_as_mutator
|
||||
local mutators = {}
|
||||
local mutators_sequence = {}
|
||||
|
||||
-- This lists mutators and which ones should be enabled after them
|
||||
-- This is populated via VMFMod.register_as_mutator
|
||||
local mutators_sequence = {
|
||||
--[[
|
||||
this_mutator = {
|
||||
"will be enabled",
|
||||
"before these ones"
|
||||
}
|
||||
]]--
|
||||
}
|
||||
|
||||
-- So we don't sort after each one is added
|
||||
local mutators_sorted = false
|
||||
|
||||
local function update_mutators_sequence(mutator_name, load_these_after)
|
||||
|
||||
--[[
|
||||
PRIVATE METHODS
|
||||
]]--
|
||||
|
||||
-- Adds mutator names from enable_these_after to the list of mutators that should be enabled after the mutator_name
|
||||
local function update_mutators_sequence(mutator_name, enable_these_after)
|
||||
if not mutators_sequence[mutator_name] then
|
||||
mutators_sequence[mutator_name] = {}
|
||||
end
|
||||
for _, other_mutator_name in ipairs(load_these_after) do
|
||||
for _, other_mutator_name in ipairs(enable_these_after) do
|
||||
|
||||
if mutators_sequence[other_mutator_name] and table.has_item(mutators_sequence[other_mutator_name], mutator_name) then
|
||||
vmf:error("Mutators '" .. mutator_name .. "' and '" .. other_mutator_name .. "' are both set to load after the other one.")
|
||||
|
@ -17,36 +37,48 @@ local function update_mutators_sequence(mutator_name, load_these_after)
|
|||
end
|
||||
|
||||
end
|
||||
table.combine(mutators_sequence[mutator_name], load_these_after)
|
||||
table.combine(mutators_sequence[mutator_name], enable_these_after)
|
||||
end
|
||||
|
||||
-- This shouldn't happen
|
||||
local function error_endless_loop()
|
||||
vmf:error("Mutators: too many iterations. Check for loops in 'enable_before_these'/'enable_after_these'.")
|
||||
end
|
||||
|
||||
-- Sorts mutators in order they should be enabled
|
||||
local function sort_mutators()
|
||||
|
||||
-- LOG --
|
||||
vmf:dump(mutators_sequence, "seq", 5)
|
||||
for i, v in ipairs(mutators) do
|
||||
print(i, v:get_name())
|
||||
end
|
||||
print("-----------")
|
||||
-- /LOG --
|
||||
|
||||
local maxIter = #mutators * #mutators * #mutators
|
||||
-- Preventing endless loops (worst case is n*n*(n+1)/2 I believe)
|
||||
local maxIter = #mutators * #mutators * (#mutators + 1)/2
|
||||
local numIter = 0
|
||||
|
||||
-- The idea is that all mutators before the current one are already in the right order
|
||||
-- Starting from second mutator
|
||||
local i = 2
|
||||
while i <= #mutators do
|
||||
local mutator = mutators[i]
|
||||
local mutator_name = mutator:get_name()
|
||||
local load_these_after = mutators_sequence[mutator_name] or {}
|
||||
local enable_these_after = mutators_sequence[mutator_name] or {}
|
||||
|
||||
-- Going back from the previous mutator
|
||||
local j = i - 1
|
||||
while j > 0 do
|
||||
local other_mutator = mutators[j]
|
||||
if table.has_item(load_these_after, other_mutator:get_name()) then
|
||||
|
||||
-- Moving it after the current one if it is to be enabled after it
|
||||
if table.has_item(enable_these_after, other_mutator:get_name()) then
|
||||
table.remove(mutators, j)
|
||||
table.insert(mutators, i, other_mutator)
|
||||
|
||||
-- This will shift the current mutator back, so adjust the index
|
||||
i = i - 1
|
||||
end
|
||||
j = j - 1
|
||||
|
@ -62,29 +94,37 @@ local function sort_mutators()
|
|||
end
|
||||
mutators_sorted = true
|
||||
|
||||
-- LOG --
|
||||
for i, v in ipairs(mutators) do
|
||||
print(i, v:get_name())
|
||||
end
|
||||
print("-----------")
|
||||
-- /LOG --
|
||||
end
|
||||
|
||||
-- Enables/disables mutator while preserving the sequence in which they were enabled
|
||||
local function set_mutator_state(self, state)
|
||||
|
||||
local i = table.index_of(mutators, self)
|
||||
if i == nil then
|
||||
self:error("Mutator isn't in the list")
|
||||
return
|
||||
end
|
||||
|
||||
-- Sort mutators if this is the first call
|
||||
if not mutators_sorted then
|
||||
sort_mutators()
|
||||
end
|
||||
|
||||
local disabled_mutators = {}
|
||||
local load_these_after = mutators_sequence[self:get_name()]
|
||||
local enable_these_after = mutators_sequence[self:get_name()]
|
||||
|
||||
if load_these_after and #mutators > i then
|
||||
-- Disable mutators that were and are required to be enabled after the current one
|
||||
-- This will be recursive so that if mutator2 requires mutator3 to be enabled after it, mutator3 will be disabled before mutator2
|
||||
-- Yeah this is super confusing
|
||||
if enable_these_after and #mutators > i then
|
||||
for j = #mutators, i + 1, -1 do
|
||||
if mutators[j]:is_enabled() and table.has_item(load_these_after, mutators[j]:get_name()) then
|
||||
if mutators[j]:is_enabled() and table.has_item(enable_these_after, mutators[j]:get_name()) then
|
||||
print("Disabled ", mutators[j]:get_name())
|
||||
mutators[j]:disable()
|
||||
table.insert(disabled_mutators, 1, mutators[j])
|
||||
|
@ -92,6 +132,7 @@ local function set_mutator_state(self, state)
|
|||
end
|
||||
end
|
||||
|
||||
-- Enable/disable current mutator
|
||||
if state then
|
||||
print("Enabled ", self:get_name(), "!")
|
||||
VMFMod.enable(self)
|
||||
|
@ -100,6 +141,8 @@ local function set_mutator_state(self, state)
|
|||
VMFMod.disable(self)
|
||||
end
|
||||
|
||||
-- Re-enable disabled mutators
|
||||
-- This will be recursive
|
||||
if #disabled_mutators > 0 then
|
||||
for j = #disabled_mutators, 1, -1 do
|
||||
print("Enabled ", disabled_mutators[j]:get_name())
|
||||
|
@ -109,14 +152,23 @@ local function set_mutator_state(self, state)
|
|||
print("---------")
|
||||
end
|
||||
|
||||
-- Enables mutator (pcall for now)
|
||||
local function enable_mutator(self)
|
||||
vmf:pcall(function() set_mutator_state(self, true) end)
|
||||
end
|
||||
|
||||
-- Disables mutator (pcall for now)
|
||||
local function disable_mutator(self)
|
||||
vmf:pcall(function() set_mutator_state(self, false) end)
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
PUBLIC METHODS
|
||||
]]--
|
||||
|
||||
-- Turns a mod into a mutator
|
||||
-- For now all it does is creates a sequence in which they need to be enabled/disabled
|
||||
VMFMod.register_as_mutator = function(self, config)
|
||||
if not config then config = {} end
|
||||
|
||||
|
@ -148,7 +200,10 @@ VMFMod.register_as_mutator = function(self, config)
|
|||
self:init_state(false)
|
||||
end
|
||||
|
||||
-- Testing
|
||||
|
||||
--[[
|
||||
Testing
|
||||
--]]
|
||||
local mutation = new_mod("mutation")
|
||||
local deathwish = new_mod("deathwish")
|
||||
local mutator3 = new_mod("mutator3")
|
||||
|
@ -166,9 +221,6 @@ mutator555.on_disabled = function() end
|
|||
|
||||
|
||||
deathwish:register_as_mutator({
|
||||
enable_after_these = {
|
||||
"mutation"
|
||||
},
|
||||
enable_before_these = {
|
||||
"mutator555",
|
||||
"mutator3",
|
||||
|
|
Loading…
Add table
Reference in a new issue