Skip to content

Commit

Permalink
Illusive worms, overrides, flight
Browse files Browse the repository at this point in the history
Signed-off-by: Kevadroz <kevinfdezdominguez@gmail.com>
  • Loading branch information
Kevadroz committed Jun 14, 2024
1 parent edd1dab commit 57fd58e
Show file tree
Hide file tree
Showing 2 changed files with 471 additions and 134 deletions.
184 changes: 155 additions & 29 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ local spawned_worm_var_name = modid .. ".spawned_worm"

local visited_cache = {}
local timeouts = {}
local worm_count = {}

local settings = {
factor_active = 0.0,
Expand All @@ -21,10 +22,7 @@ local settings = {
attraction_end_factor = 0.0,
attraction_start_radius = 0,
attraction_end_radius = 0,
spawned_eat_ground = false,
spawned_bleed = false,
spawned_loot = false,
spawned_pursue = false,
spawned_modifiers = {},
worms_sc = {}
}

Expand All @@ -50,6 +48,7 @@ local worm_to_xml = {

for _, worm in ipairs(spawnable_worms) do
timeouts[worm] = 0
worm_count[worm] = 0
end

local function inverse_lerp(min, max, number)
Expand All @@ -62,23 +61,75 @@ local function genWormXML(worm)
local xml_worm = nxml.parse(ModTextFileGetContent(worm_to_xml[worm]))

table.insert(xml_worm.children, nxml.new_element("VariableStorageComponent", {
name = spawned_worm_var_name
name = spawned_worm_var_name,
value_string = worm
}))

if settings.spawned_pursue then
local ws_table = settings.worms_sc[worm].overrides
if ws_table == nil then
ws_table = settings.spawned_modifiers
end

if ws_table == nil then
error("ws_table is nil for worm '" .. worm .. "'")
end

--local is_normal = ws_table.mode == "normal"
local is_illusion = ws_table.mode == "illusion"

if is_illusion then
local components_to_remove = {}
for component in xml_worm:each_of("WormComponent") do
local attr = component.attr
attr.ground_check_offset = (attr.ground_check_offset or 0) * 4
attr.hitbox_radius = 1
end
for component in xml_worm:each_of("DamageModelComponent") do
component.attr._enabled = false
end
for component in xml_worm:each_of("SpriteComponent") do
if component.attr._tags and string.find(component.attr._tags, "health_bar", nil, true) then
table.insert(components_to_remove, component)
elseif worm ~= "kalmamato" then
component.attr.alpha = component.attr.alpha * 0.5
end
end
for component in xml_worm:each_of("MusicEnergyAffectorComponent") do
table.insert(components_to_remove, component)
end
for component in xml_worm:each_of("BossHealthBarComponent") do
table.insert(components_to_remove, component)
end
for _, component in ipairs(components_to_remove) do
xml_worm:remove_child(component)
end

table.insert(xml_worm.children, nxml.new_element("AudioComponent", {
file = "data/audio/Desktop/animals.bank",
event_root = "animals/illusion"
}))

table.insert(xml_worm.children, nxml.new_element("LuaComponent", {
script_source_file = "data/scripts/animals/illusion_disappear.lua",
execute_every_n_frame = -1,
execute_on_removed = true
}))
end

if ws_table.pursue then
table.insert(xml_worm.children, nxml.new_element("LuaComponent", {
script_source_file = "mods/territorial_worms/files/spawned_worm_update.lua",
limit_to_every_n_frame = 3
}))
end

if not settings.spawned_eat_ground then
if (not ws_table.eat_ground) or is_illusion then
for component in xml_worm:each_of("CellEaterComponent") do
component.attr._enabled = false
end
end

if not settings.spawned_bleed then
if (not ws_table.bleed) or is_illusion then
for component in xml_worm:each_of("DamageModelComponent") do
local attr = component.attr
if attr.blood_material == "blood_worm" then
Expand All @@ -93,13 +144,16 @@ local function genWormXML(worm)
end
end

if not settings.spawned_loot then
if (not ws_table.loot) or is_illusion then
local components_to_remove = {}
for component in xml_worm:each_of("LuaComponent") do
if component.attr._tags and string.find(component.attr._tags, "death_reward", nil, true) ~= nil then
table.insert(components_to_remove, component)
end
end
for component in xml_worm:each_of("ItemChestComponent") do
table.insert(components_to_remove, component)
end
for _, component in ipairs(components_to_remove) do
xml_worm:remove_child(component)
end
Expand All @@ -108,18 +162,31 @@ local function genWormXML(worm)
}))
end

if is_illusion and ws_table.despawn_time > 0 then
table.insert(xml_worm.children, nxml.new_element("LifetimeComponent", {
lifetime = ws_table.despawn_time * 60
}))
end

if is_illusion or ws_table.no_gravity then
for component in xml_worm:each_of("WormComponent") do
component.attr.gravity = 0
component.attr.tail_gravity = 0
end
end

local modded_xml = nxml.tostring(xml_worm, true)
ModTextFileSetContent(worm_xml_base_path .. worm .. ".xml", modded_xml)
-- if debug then
-- print(modded_xml)
-- print(worm, modded_xml)
-- end
end

local settings_prefix = modid .. "."
---@param id string
---@param container table
---@param prefix string?
local function setSetting(id, container, prefix)
local function SetSetting(id, container, prefix)
local this_prefix = settings_prefix
if prefix then
this_prefix = this_prefix .. prefix
Expand All @@ -133,49 +200,83 @@ local function setSetting(id, container, prefix)
---@diagnostic disable-next-line: assign-type-mismatch
container[id] = value
else
error("[" .. modid .. "] Settings type mismatch on setting \"" .. id .. "\":\n" ..
error("[" .. modid .. "] Settings type mismatch on setting \"" .. this_prefix .. id .. "\":\n" ..
"Expected '" .. setting_type .. "', got '" .. value_type .. "'.")
end
end

local after_post_init = false
---@param worm string?
---@return table?
local function GenSpawnModifierSettings(worm)
local prefix
if worm then
prefix = "sc_" .. worm .. "_overrides"
if ModSettingGet(settings_prefix .. prefix .. "_enabled") == true then
prefix = prefix .. "."
else
return nil
end
else
prefix = "spawned."
end

local sm_settings = {
pursue = false,
mode = "normal",
eat_ground = false,
bleed = false,
loot = false,
despawn_time = 0.0,
no_gravity = false
}

for id, _ in pairs(sm_settings) do
SetSetting(id, sm_settings, prefix)
end
return sm_settings
end

local function updateSettings()
for id, _ in pairs(settings) do
if id ~= "worms_sc" then
setSetting(id, settings)
for id, val in pairs(settings) do
if type(val) ~= "table" then
SetSetting(id, settings)
end
end
settings.factor_active = settings.factor_active / settings.section_count
settings.factor_passive = settings.factor_passive / 60

settings.attraction_enabled = settings.attraction_end_radius > 0

settings.spawned_modifiers = GenSpawnModifierSettings()

for _, worm in ipairs(spawnable_worms) do
if settings.worms_sc[worm] == nil then
settings.worms_sc[worm] = {
minimum_rage = 0.0,
top_rage = 0.0,
initial_chance = 0.0,
max_chance = 0.0,
timeout = 0.0
timeout = 0.0,
max_loaded = 0,
overrides = false
}
end
local prefix = "sc_" .. worm .. "_"
local worm_sc_container = settings.worms_sc[worm]
for id, _ in pairs(worm_sc_container) do
setSetting(id, worm_sc_container, prefix)
if id == "overrides" then
settings.worms_sc[worm].overrides = GenSpawnModifierSettings(worm)
else
SetSetting(id, worm_sc_container, prefix)
end
end
worm_sc_container.initial_chance = worm_sc_container.initial_chance / 100
worm_sc_container.max_chance = worm_sc_container.max_chance / 100
worm_sc_container.timeout = worm_sc_container.timeout / 60

worm_sc_container.enabled = worm_sc_container.max_chance > 0

if not after_post_init then
genWormXML(worm)
end
end
--print(smallfolk.dumps(settings))
end

---@param entity_id number
Expand All @@ -184,7 +285,7 @@ end
---@return number comp_id, boolean is_new
local function getAndCreateVariableComponent(entity_id, id, type)
local components = EntityGetComponent(entity_id, "VariableStorageComponent")
if (components ~= nil) then
if components ~= nil then
for _, comp_id in pairs(components) do
local var_name = ComponentGetValue2(comp_id, "name")
if (var_name == id) then
Expand Down Expand Up @@ -216,6 +317,7 @@ local function loadVisitedSections(entity_id, comp_id)
entity_cache[y][x] = true
end
visited_cache[entity_id] = entity_cache
return entity_cache
end

---@param x integer
Expand All @@ -228,14 +330,18 @@ local function markSectionVisited(entity_id, comp_id, x, y)
end
entity_cache[y][x] = true

local storage_string = ""
local storage_string_parts = {} --TODO: verify this works correctly with a print
for y2, column in pairs(entity_cache) do
for x2, visited in pairs(column) do
if visited then
storage_string = storage_string .. tostring(x2) .. "," .. tostring(y2) .. "|"
storage_string_parts[#storage_string_parts + 1] = ("%s,%s"):format(x2, y2)
end
end
end
local storage_string = table.concat(storage_string_parts, "|")
-- if debug then
-- print(storage_string)
-- end

ComponentSetValue2(comp_id, "value_string", storage_string)
end
Expand All @@ -251,7 +357,7 @@ local function isSectionVisited(entity_id, x, y)
if new then
return true
end
loadVisitedSections(entity_id, comp_id)
entity_cache = loadVisitedSections(entity_id, comp_id)
end
---@diagnostic disable-next-line: need-check-nil
local column = entity_cache[y]
Expand Down Expand Up @@ -304,7 +410,7 @@ end

local function doWormRageFactor(entity_id, runnable, value)
local components = EntityGetComponent(entity_id, "VariableStorageComponent")
if (components ~= nil) then
if components ~= nil then
for _, comp_id in pairs(components) do
local var_name = ComponentGetValue2(comp_id, "name")
if (var_name == worm_rage_var_name) then
Expand Down Expand Up @@ -355,7 +461,7 @@ local function doWormSpawnChance(entity_id, factor)
if (not worm_sc.enabled) or timeouts[worm] > 0 then
goto continue
end
if factor >= worm_sc.minimum_rage then
if factor >= worm_sc.minimum_rage and (worm_count[worm] < worm_sc.max_loaded or worm_sc.max_loaded == 0) then
local chance = lerp(worm_sc.max_chance, worm_sc.initial_chance,
clamp(inverse_lerp(worm_sc.minimum_rage, worm_sc.top_rage, factor), 0, 1))

Expand All @@ -373,6 +479,9 @@ local function doWormSpawnChance(entity_id, factor)
vec_x, vec_y = vec_mult(vec_x, vec_y, distance)

EntityLoad(worm_xml_base_path .. worm .. ".xml", x + vec_x, y + vec_y)
if debug then
print("Spawned " .. worm_xml_base_path .. worm .. ".xml" .. "!")
end

timeouts[worm] = settings.worms_sc[worm].timeout
end
Expand Down Expand Up @@ -559,12 +668,29 @@ function OnWorldPreUpdate()
for _, entity_id in ipairs(cache_to_clean) do
visited_cache[entity_id] = nil
end
for worm, _ in pairs(worm_count) do
worm_count[worm] = 0
end
for _, entity_id in ipairs(EntityGetWithTag("worm")) do
local components = EntityGetComponent(entity_id, "VariableStorageComponent")
if components ~= nil then
for _, comp_id in pairs(components) do
local var_name = ComponentGetValue2(comp_id, "name")
if (var_name == spawned_worm_var_name) then
local worm_name = ComponentGetValue2(comp_id, "value_string")
worm_count[worm_name] = worm_count[worm_name] + 1
end
end
end
end
end

function OnPlayerDied(player_entity)
setWormRageFactor(player_entity, 0.0)
end

function OnModPostInit()
after_post_init = true
for _, worm in ipairs(spawnable_worms) do
genWormXML(worm)
end
end
Loading

0 comments on commit 57fd58e

Please sign in to comment.