From 336cc6c77d29fec9ffba632153830554539eb01f Mon Sep 17 00:00:00 2001 From: Gerkiz <fs@nvfs.se> Date: Thu, 11 Nov 2021 01:56:03 +0100 Subject: [PATCH 1/5] wave defense - minor changes Fixed a bug that made so spawners did not spawn. Modified so biters have the ability to spawn within a radius. --- modules/wave_defense/main.lua | 123 +++++++++++++++++++------ modules/wave_defense/table.lua | 5 + modules/wave_defense/threat_events.lua | 22 +++-- 3 files changed, 115 insertions(+), 35 deletions(-) diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index 941e712b..22fc0cd8 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -57,20 +57,39 @@ local function valid(userdata) return true end +local function shuffle(tbl) + local size = #tbl + for i = size, 1, -1 do + local rand = math.random(size) + tbl[i], tbl[rand] = tbl[rand], tbl[i] + end + return tbl +end + local function find_initial_spot(surface, position) local spot = WD.get('spot') if not spot then - local pos = surface.find_non_colliding_position('rocket-silo', position, 128, 1) + local pos = surface.find_non_colliding_position('stone-furnace', position, 128, 1) if not pos then - pos = surface.find_non_colliding_position('rocket-silo', position, 148, 1) + pos = surface.find_non_colliding_position('stone-furnace', position, 148, 1) end if not pos then - pos = surface.find_non_colliding_position('rocket-silo', position, 164, 1) + pos = surface.find_non_colliding_position('stone-furnace', position, 164, 1) end if not pos then pos = position end + if math_random(1, 2) == 1 then + local random_pos = {{x = pos.x - 10, y = pos.y - 5}, {x = pos.x + 10, y = pos.y + 5}, {x = pos.x - 10, y = pos.y + 5}, {x = pos.x + 10, y = pos.y - 5}} + local actual_pos = shuffle(random_pos) + pos = {x = actual_pos[1].x, y = actual_pos[1].y} + end + + if not pos then + pos = position + end + WD.set('spot', pos) return pos else @@ -181,7 +200,7 @@ local function get_spawn_pos() local initial_position = WD.get('spawn_position') local located_position = find_initial_spot(surface, initial_position) - local valid_position = surface.find_non_colliding_position('behemoth-biter', located_position, 32, 1) + local valid_position = surface.find_non_colliding_position('steel-chest', located_position, 32, 1) local debug = WD.get('debug') if debug then if valid_position then @@ -338,6 +357,12 @@ local function set_main_target() end end + local unit_groups_size = WD.get('unit_groups_size') + if unit_groups_size < 0 then + unit_groups_size = 0 + end + WD.set('unit_groups_size', unit_groups_size) + local sec_target = SideTargets.get_side_target() if not sec_target then sec_target = get_random_character() @@ -429,9 +454,14 @@ local function get_active_unit_groups_count() count = count + 1 else g.destroy() + unit_groups[k] = nil + local unit_groups_size = WD.get('unit_groups_size') + WD.set('unit_groups_size', unit_groups_size - 1) end else unit_groups[k] = nil + local unit_groups_size = WD.get('unit_groups_size') + WD.set('unit_groups_size', unit_groups_size - 1) local unit_group_last_command = WD.get('unit_group_last_command') if unit_group_last_command[k] then unit_group_last_command[k] = nil @@ -447,10 +477,12 @@ local function get_active_unit_groups_count() return count end -local function spawn_biter(surface, is_boss_biter) - if not is_boss_biter then - if not can_units_spawn() then - return +local function spawn_biter(surface, position, forceSpawn, is_boss_biter) + if not forceSpawn then + if not is_boss_biter then + if not can_units_spawn() then + return + end end end @@ -462,11 +494,17 @@ local function spawn_biter(surface, is_boss_biter) else name = BiterRolls.wave_defense_roll_biter_name() end - local position = get_spawn_pos() + + local old_position = position + + position = surface.find_non_colliding_position('steel-chest', position, 10, 1) + if not position then + position = old_position + end local biter = surface.create_entity({name = name, position = position, force = 'enemy'}) biter.ai_settings.allow_destroy_when_commands_fail = true - biter.ai_settings.allow_try_return_to_spawner = true + biter.ai_settings.allow_try_return_to_spawner = false biter.ai_settings.do_separation = true local increase_health_per_wave = WD.get('increase_health_per_wave') @@ -615,6 +653,8 @@ local function reform_group(group) debug_print('Creating new unit group, because old one was stuck.') local unit_groups = WD.get('unit_groups') unit_groups[new_group.group_number] = new_group + local unit_groups_size = WD.get('unit_groups_size') + WD.set('unit_groups_size', unit_groups_size + 1) return new_group else @@ -631,6 +671,8 @@ local function reform_group(group) positions[group.group_number] = nil end table.remove(unit_groups, group.group_number) + local unit_groups_size = WD.get('unit_groups_size') + WD.set('unit_groups_size', unit_groups_size - 1) end group.destroy() end @@ -883,10 +925,14 @@ local function give_main_command_to_group() end end -local function spawn_unit_group() - if not can_units_spawn() then - debug_print('spawn_unit_group - Cant spawn units?') - return +local function spawn_unit_group(fs) + if fs then + debug_print('spawn_unit_group - forcing new biters') + else + if not can_units_spawn() then + debug_print('spawn_unit_group - Cant spawn units?') + return + end end local target = WD.get('target') if not valid(target) then @@ -895,9 +941,13 @@ local function spawn_unit_group() end local max_active_unit_groups = WD.get('max_active_unit_groups') - if get_active_unit_groups_count() >= max_active_unit_groups then - debug_print('spawn_unit_group - unit_groups at max') - return + if fs then + debug_print('spawn_unit_group - forcing new biters') + else + if get_active_unit_groups_count() >= max_active_unit_groups then + debug_print('spawn_unit_group - unit_groups at max') + return + end end local surface_index = WD.get('surface_index') local remove_entities = WD.get('remove_entities') @@ -932,15 +982,14 @@ local function spawn_unit_group() BiterRolls.wave_defense_set_unit_raffle(wave_number) debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y) - local position = spawn_position local unit_group_pos = WD.get('unit_group_pos') - local unit_group = surface.create_unit_group({position = position, force = 'enemy'}) + local unit_group = surface.create_unit_group({position = spawn_position, force = 'enemy'}) unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0} local average_unit_group_size = WD.get('average_unit_group_size') local group_size = math_floor(average_unit_group_size * group_size_modifier_raffle[math_random(1, group_size_modifier_raffle_size)]) for _ = 1, group_size, 1 do - local biter = spawn_biter(surface) + local biter = spawn_biter(surface, spawn_position, fs) if not biter then debug_print('spawn_unit_group - No biters were found?') break @@ -951,7 +1000,7 @@ local function spawn_unit_group() end local boss_wave = WD.get('boss_wave') - if boss_wave then + if not boss_wave then local count = math_random(1, math_floor(wave_number * 0.01) + 2) if count > 16 then count = 16 @@ -960,7 +1009,7 @@ local function spawn_unit_group() count = 4 end for _ = 1, count, 1 do - local biter = spawn_biter(surface, true) + local biter = spawn_biter(surface, spawn_position, fs, true) if not biter then debug_print('spawn_unit_group - No biters were found?') break @@ -972,8 +1021,10 @@ local function spawn_unit_group() local unit_groups = WD.get('unit_groups') unit_groups[unit_group.group_number] = unit_group + local unit_groups_size = WD.get('unit_groups_size') + WD.set('unit_groups_size', unit_groups_size + 1) if math_random(1, 2) == 1 then - WD.set('random_group', unit_group.group_number) + WD.set('random_group', unit_group) end WD.set('spot', 'nil') return true @@ -1028,7 +1079,6 @@ end local tick_tasks = { [30] = set_main_target, [60] = set_enemy_evolution, - [90] = spawn_unit_group, [120] = give_main_command_to_group, [150] = ThreatEvent.build_nest, [180] = ThreatEvent.build_worm, @@ -1037,7 +1087,7 @@ local tick_tasks = { [7200] = refresh_active_unit_threat } -local function on_tick() +local function t1() local tick = game.tick local game_lost = WD.get('game_lost') if game_lost then @@ -1058,10 +1108,10 @@ local function on_tick() local t2 = tick % 18000 if tick_tasks[t] then - tick_tasks[t]() + tick_tasks[t](true) end if tick_tasks[t2] then - tick_tasks[t2]() + tick_tasks[t2](true) end local resolve_pathing = WD.get('resolve_pathing') @@ -1083,6 +1133,23 @@ local function on_tick() end end -Event.on_nth_tick(30, on_tick) +local function t2() + local game_lost = WD.get('game_lost') + if game_lost then + return + end + + local paused = WD.get('paused') + if paused then + return + end + + spawn_unit_group() +end + +Public.spawn_unit_group = spawn_unit_group + +Event.on_nth_tick(30, t1) +Event.on_nth_tick(130, t2) return Public diff --git a/modules/wave_defense/table.lua b/modules/wave_defense/table.lua index 28a32868..4db7b16a 100644 --- a/modules/wave_defense/table.lua +++ b/modules/wave_defense/table.lua @@ -18,6 +18,10 @@ function Public.debug_module() this.debug = true end +function Public.enable_debug() + this.debug = true +end + function Public.reset_wave_defense() this.boss_wave = false this.boss_wave_warning = false @@ -50,6 +54,7 @@ function Public.reset_wave_defense() this.threat_log = {} this.threat_log_index = 0 this.unit_groups = {} + this.unit_groups_size = 0 this.unit_group_pos = { positions = {} } diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua index 2ded88cc..20476ea2 100644 --- a/modules/wave_defense/threat_events.lua +++ b/modules/wave_defense/threat_events.lua @@ -36,7 +36,10 @@ end local function place_nest_near_unit_group() local unit_groups = WD.get('unit_groups') local random_group = WD.get('random_group') - local group = unit_groups[random_group] + if not (random_group and random_group.valid) then + return + end + local group = unit_groups[random_group.group_number] if not group then return end @@ -74,6 +77,7 @@ local function place_nest_near_unit_group() return end local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force}) + BiterHealthBooster.add_boss_unit(spawner, 4) local nests = WD.get('nests') nests[#nests + 1] = spawner unit.surface.create_entity({name = 'blood-explosion-huge', position = position}) @@ -90,8 +94,8 @@ function Public.build_nest() if threat < 1024 then return end - local index = WD.get('index') - if index == 0 then + local unit_groups_size = WD.get('unit_groups_size') + if unit_groups_size == 0 then return end for _ = 1, 2, 1 do @@ -111,14 +115,17 @@ function Public.build_worm() return end - local index = WD.get('index') - if index == 0 then + local unit_groups_size = WD.get('unit_groups_size') + if unit_groups_size == 0 then return end local random_group = WD.get('random_group') + if not (random_group and random_group.valid) then + return + end local unit_groups = WD.get('unit_groups') - local group = unit_groups[random_group] + local group = unit_groups[random_group.group_number] if not group then return end @@ -157,7 +164,8 @@ function Public.build_worm() then return end - unit.surface.create_entity({name = worm, position = position, force = unit.force}) + local u = unit.surface.create_entity({name = worm, position = position, force = unit.force}) + BiterHealthBooster.add_boss_unit(u, 4) unit.surface.create_entity({name = 'blood-explosion-huge', position = position}) unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position}) remove_unit(unit) From 2e277143f6cf1a3294291cc0de4648af81dc2a2a Mon Sep 17 00:00:00 2001 From: Gerkiz <fs@nvfs.se> Date: Thu, 11 Nov 2021 01:56:14 +0100 Subject: [PATCH 2/5] rpg - use local values --- modules/rpg/gui.lua | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/modules/rpg/gui.lua b/modules/rpg/gui.lua index f3a0a270..e3098b17 100644 --- a/modules/rpg/gui.lua +++ b/modules/rpg/gui.lua @@ -26,6 +26,8 @@ local spell2_button_name = Public.spell2_button_name local spell3_button_name = Public.spell3_button_name local sub = string.sub +local round = math.round +local floor = math.floor function Public.draw_gui_char_button(player) if player.gui.top[draw_main_frame_name] then @@ -236,7 +238,7 @@ local function draw_main_frame(player, location) end add_gui_description(scroll_table, ({'rpg_gui.experience_name'}), 100) - local exp_gui = add_gui_stat(scroll_table, math.floor(rpg_t.xp), 125, ({'rpg_gui.gain_info_tooltip'})) + local exp_gui = add_gui_stat(scroll_table, floor(rpg_t.xp), 125, ({'rpg_gui.gain_info_tooltip'})) data.exp_gui = exp_gui add_gui_description(scroll_table, ' ', 75) @@ -281,11 +283,11 @@ local function draw_main_frame(player, location) add_gui_description(left_bottom_table, ' ', 40) add_gui_description(left_bottom_table, ({'rpg_gui.life_name'}), w1, ({'rpg_gui.life_tooltip'})) - local health_gui = add_gui_stat(left_bottom_table, math.floor(player.character.health), w2, ({'rpg_gui.life_increase'})) + local health_gui = add_gui_stat(left_bottom_table, floor(player.character.health), w2, ({'rpg_gui.life_increase'})) data.health = health_gui add_gui_stat( left_bottom_table, - math.floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus), + floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus), w2, ({'rpg_gui.life_maximum'}) ) @@ -299,8 +301,8 @@ local function draw_main_frame(player, location) local i = player.character.get_inventory(defines.inventory.character_armor) if not i.is_empty() then if i[1].grid then - shield = math.floor(i[1].grid.shield) - shield_max = math.floor(i[1].grid.max_shield) + shield = floor(i[1].grid.shield) + shield_max = floor(i[1].grid.max_shield) shield_desc_tip = ({'rpg_gui.shield_tooltip'}) shield_tip = ({'rpg_gui.shield_current'}) shield_max_tip = ({'rpg_gui.shield_max'}) @@ -341,17 +343,17 @@ local function draw_main_frame(player, location) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.mining_name'}), w1) - local mining_speed_value = math.round((player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100) .. '%' + local mining_speed_value = round((player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100) .. '%' add_gui_stat(right_bottom_table, mining_speed_value, w2) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.slot_name'}), w1) - local slot_bonus_value = '+ ' .. math.round(player.force.character_inventory_slots_bonus + player.character_inventory_slots_bonus) + local slot_bonus_value = '+ ' .. round(player.force.character_inventory_slots_bonus + player.character_inventory_slots_bonus) add_gui_stat(right_bottom_table, slot_bonus_value, w2) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.melee_name'}), w1) - local melee_damage_value = math.round(100 * (1 + Public.get_melee_modifier(player))) .. '%' + local melee_damage_value = round(100 * (1 + Public.get_melee_modifier(player))) .. '%' local melee_damage_tooltip if rpg_extra.enable_one_punch then melee_damage_tooltip = ({ @@ -391,17 +393,17 @@ local function draw_main_frame(player, location) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.crafting_speed'}), w1) - local crafting_speed_value = math.round((player.force.manual_crafting_speed_modifier + player.character_crafting_speed_modifier + 1) * 100) .. '%' + local crafting_speed_value = round((player.force.manual_crafting_speed_modifier + player.character_crafting_speed_modifier + 1) * 100) .. '%' add_gui_stat(right_bottom_table, crafting_speed_value, w2) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.running_speed'}), w1) - local running_speed_value = math.round((player.force.character_running_speed_modifier + player.character_running_speed_modifier + 1) * 100) .. '%' + local running_speed_value = round((player.force.character_running_speed_modifier + player.character_running_speed_modifier + 1) * 100) .. '%' add_gui_stat(right_bottom_table, running_speed_value, w2) add_gui_description(right_bottom_table, ' ', w0) add_gui_description(right_bottom_table, ({'rpg_gui.health_bonus_name'}), w1) - local health_bonus_value = '+ ' .. math.round((player.force.character_health_bonus + player.character_health_bonus)) + local health_bonus_value = '+ ' .. round((player.force.character_health_bonus + player.character_health_bonus)) local health_tooltip = ({'rpg_gui.health_tooltip', Public.get_heal_modifier(player)}) add_gui_stat(right_bottom_table, health_bonus_value, w2, health_tooltip) @@ -409,10 +411,10 @@ local function draw_main_frame(player, location) if rpg_extra.enable_mana then add_gui_description(right_bottom_table, ({'rpg_gui.mana_bonus'}), w1) - local mana_bonus_value = '+ ' .. (math.floor(Public.get_mana_modifier(player) * 10) / 10) + local mana_bonus_value = '+ ' .. (floor(Public.get_mana_modifier(player) * 10) / 10) local mana_bonus_tooltip = ({ 'rpg_gui.mana_regen_bonus', - (math.floor(Public.get_mana_modifier(player) * 10) / 10) + (floor(Public.get_mana_modifier(player) * 10) / 10) }) add_gui_stat(right_bottom_table, mana_bonus_value, w2, mana_bonus_tooltip) end @@ -475,28 +477,28 @@ function Public.update_player_stats(player) local rpg_extra = Public.get('rpg_extra') local rpg_t = Public.get_value_from_player(player.index) local strength = rpg_t.strength - 10 - P.update_single_modifier(player, 'character_inventory_slots_bonus', 'rpg', math.round(strength * 0.2, 3)) - P.update_single_modifier(player, 'character_mining_speed_modifier', 'rpg', math.round(strength * 0.007, 3)) - P.update_single_modifier(player, 'character_maximum_following_robot_count_bonus', 'rpg', math.round(strength / 2 * 0.03, 3)) + P.update_single_modifier(player, 'character_inventory_slots_bonus', 'rpg', round(strength * 0.2, 3)) + P.update_single_modifier(player, 'character_mining_speed_modifier', 'rpg', round(strength * 0.007, 3)) + P.update_single_modifier(player, 'character_maximum_following_robot_count_bonus', 'rpg', round(strength / 2 * 0.03, 3)) local magic = rpg_t.magicka - 10 local v = magic * 0.22 - P.update_single_modifier(player, 'character_build_distance_bonus', 'rpg', math.min(60, math.round(v * 0.12, 3))) - P.update_single_modifier(player, 'character_item_drop_distance_bonus', 'rpg', math.min(60, math.round(v * 0.05, 3))) - P.update_single_modifier(player, 'character_reach_distance_bonus', 'rpg', math.min(60, math.round(v * 0.12, 3))) - P.update_single_modifier(player, 'character_loot_pickup_distance_bonus', 'rpg', math.min(20, math.round(v * 0.12, 3))) - P.update_single_modifier(player, 'character_item_pickup_distance_bonus', 'rpg', math.min(20, math.round(v * 0.12, 3))) - P.update_single_modifier(player, 'character_resource_reach_distance_bonus', 'rpg', math.min(20, math.round(v * 0.05, 3))) + P.update_single_modifier(player, 'character_build_distance_bonus', 'rpg', math.min(60, round(v * 0.12, 3))) + P.update_single_modifier(player, 'character_item_drop_distance_bonus', 'rpg', math.min(60, round(v * 0.05, 3))) + P.update_single_modifier(player, 'character_reach_distance_bonus', 'rpg', math.min(60, round(v * 0.12, 3))) + P.update_single_modifier(player, 'character_loot_pickup_distance_bonus', 'rpg', math.min(20, round(v * 0.12, 3))) + P.update_single_modifier(player, 'character_item_pickup_distance_bonus', 'rpg', math.min(20, round(v * 0.12, 3))) + P.update_single_modifier(player, 'character_resource_reach_distance_bonus', 'rpg', math.min(20, round(v * 0.05, 3))) if rpg_t.mana_max >= rpg_extra.mana_limit then rpg_t.mana_max = rpg_extra.mana_limit else - rpg_t.mana_max = math.round((magic) * 2, 3) + rpg_t.mana_max = round((magic) * 2, 3) end local dexterity = rpg_t.dexterity - 10 - P.update_single_modifier(player, 'character_running_speed_modifier', 'rpg', math.round(dexterity * 0.0015, 3)) - P.update_single_modifier(player, 'character_crafting_speed_modifier', 'rpg', math.round(dexterity * 0.015, 3)) - P.update_single_modifier(player, 'character_health_bonus', 'rpg', math.round((rpg_t.vitality - 10) * 6, 3)) + P.update_single_modifier(player, 'character_running_speed_modifier', 'rpg', round(dexterity * 0.0010, 3)) -- reduced since too high speed kills UPS. + P.update_single_modifier(player, 'character_crafting_speed_modifier', 'rpg', round(dexterity * 0.015, 3)) + P.update_single_modifier(player, 'character_health_bonus', 'rpg', round((rpg_t.vitality - 10) * 6, 3)) P.update_player_modifiers(player) end From ac026d36c85c43ea34ed9d179edb1ca1fbc73052 Mon Sep 17 00:00:00 2001 From: Gerkiz <fs@nvfs.se> Date: Thu, 11 Nov 2021 01:56:30 +0100 Subject: [PATCH 3/5] event - minor changes Added support for filters. --- utils/event.lua | 5 +++-- utils/event_core.lua | 14 +++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/utils/event.lua b/utils/event.lua index a957090b..7a20999c 100644 --- a/utils/event.lua +++ b/utils/event.lua @@ -161,12 +161,13 @@ end -- See documentation at top of file for details on using events. -- @param event_name<number> -- @param handler<function> -function Event.add(event_name, handler) +-- @optional param filters<table> +function Event.add(event_name, handler, filters) if _LIFECYCLE == 8 then error('Calling Event.add after on_init() or on_load() has run is a desync risk.', 2) end - core_add(event_name, handler) + core_add(event_name, handler, filters) end --- Register a handler for the script.on_init event. diff --git a/utils/event_core.lua b/utils/event_core.lua index 328a9148..50655fe3 100644 --- a/utils/event_core.lua +++ b/utils/event_core.lua @@ -91,15 +91,23 @@ local function on_nth_tick_event(event) end --- Do not use this function, use Event.add instead as it has safety checks. -function Public.add(event_name, handler) +function Public.add(event_name, handler, filters) local handlers = event_handlers[event_name] if not handlers then event_handlers[event_name] = {handler} - script_on_event(event_name, on_event) + if filters then + script_on_event(event_name, on_event, filters) + else + script_on_event(event_name, on_event) + end else table.insert(handlers, handler) if #handlers == 1 then - script_on_event(event_name, on_event) + if filters then + script_on_event(event_name, on_event, filters) + else + script_on_event(event_name, on_event) + end end end end From a983d0bf78412a7e71fa624f145fa0616f82fb1a Mon Sep 17 00:00:00 2001 From: Gerkiz <fs@nvfs.se> Date: Thu, 11 Nov 2021 01:56:52 +0100 Subject: [PATCH 4/5] biter health booster - restored stun effect Biters now have a chance to recover from stun-effect and get slowed instead. --- modules/biter_health_booster_v2.lua | 68 +++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/modules/biter_health_booster_v2.lua b/modules/biter_health_booster_v2.lua index b109e2b1..a264f65b 100644 --- a/modules/biter_health_booster_v2.lua +++ b/modules/biter_health_booster_v2.lua @@ -30,7 +30,8 @@ local this = { acid_lines_delay = {}, acid_nova = false, boss_spawns_projectiles = false, - enable_boss_loot = false + enable_boss_loot = false, + randomize_discharge_stun = false } local radius = 6 @@ -40,6 +41,8 @@ local acid_splashes = { ['behemoth-biter'] = 'acid-stream-worm-big' } local acid_lines = { + ['small-spitter'] = 'acid-stream-spitter-small', + ['medium-spitter'] = 'acid-stream-spitter-medium', ['big-spitter'] = 'acid-stream-spitter-big', ['behemoth-spitter'] = 'acid-stream-spitter-big' } @@ -71,9 +74,19 @@ Global.register( end ) +local filters = { + {filter = 'name', name = 'unit'}, + {filter = 'name', name = 'turret'}, + {filter = 'name', name = 'ammo-turret'}, + {filter = 'name', name = 'electric-turret'}, + {filter = 'name', name = 'unit-spawner'} +} + local entity_types = { ['unit'] = true, ['turret'] = true, + ['ammo-turret'] = true, + ['electric-turret'] = true, ['unit-spawner'] = true } @@ -112,7 +125,7 @@ local function loaded_biters(event) { name = projectiles[random(1, 10)], position = entity.position, - force = 'neutral', + force = 'enemy', source = entity.position, target = position, max_range = 16, @@ -137,7 +150,8 @@ local function acid_nova(event) ) end end -local function acid_line(surface, name, source, target) + +local function create_entity_radius(surface, name, source, target) local distance = sqrt((source.x - target.x) ^ 2 + (source.y - target.y) ^ 2) local modifier = {(target.x - source.x) / distance, (target.y - source.y) / distance} @@ -228,7 +242,7 @@ local function set_boss_healthbar(health, max_health, healthbar_id) rendering.set_color(healthbar_id, {floor(255 - 255 * m), floor(200 * m), 0}) end -local function try_acid(cause, target) +local function extra_projectiles(cause, target) if not cause or not cause.valid then return end @@ -242,7 +256,7 @@ local function try_acid(cause, target) this.acid_lines_delay[cause_unit_number] = 0 end if this.acid_lines_delay[cause_unit_number] < game.tick then - acid_line(cause.surface, acid_lines[cause.name], cause.position, target.position) + create_entity_radius(cause.surface, acid_lines[cause.name], cause.position, target.position) this.acid_lines_delay[cause_unit_number] = game.tick + 180 end end @@ -255,28 +269,37 @@ local function on_entity_damaged(event) if not (biter and biter.valid) then return end + local surface = biter.surface local cause = event.cause local biter_health_boost_units = this.biter_health_boost_units local unit_number = biter.unit_number + local damage = event.final_damage_amount + --Create new health pool local health_pool = biter_health_boost_units[unit_number] - try_acid(cause, biter) + extra_projectiles(cause, biter) if not entity_types[biter.type] then return end - local damage_type = event.damage_type - if damage_type and damage_type.name == 'electric' then - local stickers = event.entity.stickers - if stickers and #stickers > 0 then - for i = 1, #stickers, 1 do - if stickers[i].sticked_to == event.entity and stickers[i].name == 'stun-sticker' then - stickers[i].destroy() - break + if this.randomize_discharge_stun then + local damage_type = event.damage_type + if damage_type and damage_type.name == 'electric' then + local stickers = biter.stickers + if stickers and #stickers > 0 then + for i = 1, #stickers, 1 do + if random(1, 4) == 1 then -- there's a % that biters can recover from stun and get slowed instead. + if stickers[i].sticked_to == biter and stickers[i].name == 'stun-sticker' then + stickers[i].destroy() + local slow = surface.create_entity {name = 'slowdown-sticker', position = biter.position, target = biter} + slow.time_to_live = 200 + break + end + end end end end @@ -305,7 +328,7 @@ local function on_entity_damaged(event) end --Reduce health pool - health_pool[1] = health_pool[1] - event.final_damage_amount + health_pool[1] = health_pool[1] - damage --Set entity health relative to health pool biter.health = health_pool[1] * health_pool[2] @@ -352,7 +375,7 @@ local function on_entity_died(event) end end if this.boss_spawns_projectiles then - if random(1, 96) == 1 then + if random(1, 32) == 1 then loaded_biters(event) end end @@ -513,13 +536,22 @@ function Public.enable_make_normal_unit_mini_bosses(boolean) return this.make_normal_unit_mini_bosses end +--- Enables that enemies can recover from stun randomly. +---@param boolean +function Public.enable_randomize_discharge_stun(boolean) + this.randomize_discharge_stun = boolean or false + + return this.randomize_discharge_stun +end + Event.on_init( function() Public.reset_table() end ) -Event.add(defines.events.on_entity_damaged, on_entity_damaged) + +Event.add(defines.events.on_entity_damaged, on_entity_damaged, filters) Event.on_nth_tick(7200, check_clear_table) -Event.add(defines.events.on_entity_died, on_entity_died) +Event.add(defines.events.on_entity_died, on_entity_died, filters) return Public From 3392526d702af9345064591c5b0ca090f61d8aa6 Mon Sep 17 00:00:00 2001 From: Gerkiz <fs@nvfs.se> Date: Thu, 11 Nov 2021 01:57:58 +0100 Subject: [PATCH 5/5] mtn v3 - minor changes Changed some functions to utilize local vars. Modified how we spawn biters. Instead of clumping them together, they're spawned near eachother. --- maps/mountain_fortress_v3/commands.lua | 56 +++++++++ maps/mountain_fortress_v3/functions.lua | 11 +- maps/mountain_fortress_v3/generate.lua | 131 +++++++++++--------- maps/mountain_fortress_v3/icw/functions.lua | 21 +++- maps/mountain_fortress_v3/main.lua | 1 + maps/mountain_fortress_v3/table.lua | 1 + maps/mountain_fortress_v3/terrain.lua | 57 +++++---- 7 files changed, 192 insertions(+), 86 deletions(-) diff --git a/maps/mountain_fortress_v3/commands.lua b/maps/mountain_fortress_v3/commands.lua index 3e524dd6..83e61b0f 100644 --- a/maps/mountain_fortress_v3/commands.lua +++ b/maps/mountain_fortress_v3/commands.lua @@ -2,7 +2,9 @@ local Color = require 'utils.color_presets' local Task = require 'utils.task' local Server = require 'utils.server' local WPT = require 'maps.mountain_fortress_v3.table' +local Collapse = require 'modules.collapse' local WD = require 'modules.wave_defense.table' +local WDM = require 'modules.wave_defense.main' local mapkeeper = '[color=blue]Mapkeeper:[/color]' @@ -175,3 +177,57 @@ commands.add_command( end end ) + +if _DEBUG then + commands.add_command( + 'start_collapse', + 'Enabled only on SP', + function() + local p + local player = game.player + + if game.is_multiplayer() then + return + end + + if player and player.valid then + p = player.print + if not player.admin then + p("[ERROR] You're not admin!", Color.fail) + return + end + if not Collapse.start_now() then + Collapse.start_now(true) + p('Collapse started!') + else + Collapse.start_now(false) + p('Collapse stopped!') + end + end + end + ) + + commands.add_command( + 'spawn_wave', + 'Enabled only on SP', + function() + local p + local player = game.player + + if game.is_multiplayer() then + return + end + + if player and player.valid then + p = player.print + if not player.admin then + p("[ERROR] You're not admin!", Color.fail) + return + end + WD.enable_debug() + WDM.spawn_unit_group(true) + p('Spawning wave!') + end + end + ) +end diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua index 28e8ed7e..8494b9fd 100644 --- a/maps/mountain_fortress_v3/functions.lua +++ b/maps/mountain_fortress_v3/functions.lua @@ -1189,6 +1189,7 @@ function Public.set_spawn_position() ::retry:: + local y_value_position = WPT.get('y_value_position') local locomotive_positions = WPT.get('locomotive_pos') local total_pos = #locomotive_positions.tbl @@ -1206,7 +1207,7 @@ function Public.set_spawn_position() collapse_position = surface.find_non_colliding_position('solar-panel', collapse_pos, 32, 2) end if not collapse_position then - collapse_position = surface.find_non_colliding_position('small-biter', collapse_pos, 32, 2) + collapse_position = surface.find_non_colliding_position('steel-chest', collapse_pos, 32, 2) end local sizeof = locomotive_positions.tbl[total_pos - total_pos + 1] if not sizeof then @@ -1221,7 +1222,7 @@ function Public.set_spawn_position() goto retry end - local locomotive_position = surface.find_non_colliding_position('small-biter', sizeof, 128, 1) + local locomotive_position = surface.find_non_colliding_position('steel-chest', sizeof, 128, 1) local distance_from = floor(math2d.position.distance(locomotive_position, locomotive.position)) local l_y = l.y local t_y = locomotive_position.y @@ -1248,20 +1249,22 @@ function Public.set_spawn_position() return end debug_str('distance_from was higher - spawning at locomotive_position') - WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - 20}) + WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - y_value_position}) else debug_str('distance_from was lower - spawning at locomotive_position') - WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - 20}) + WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - y_value_position}) end else if collapse_position then debug_str('total_pos was higher - spawning at collapse_position') + collapse_position = {x = collapse_position.x, y = collapse_position.y - y_value_position} WD.set_spawn_position(collapse_position) end end else if collapse_position then debug_str('total_pos was lower - spawning at collapse_position') + collapse_position = {x = collapse_position.x, y = collapse_position.y - y_value_position} WD.set_spawn_position(collapse_position) end end diff --git a/maps/mountain_fortress_v3/generate.lua b/maps/mountain_fortress_v3/generate.lua index dcf4f154..16b6ec20 100644 --- a/maps/mountain_fortress_v3/generate.lua +++ b/maps/mountain_fortress_v3/generate.lua @@ -5,6 +5,8 @@ local Task = require 'utils.task' local Token = require 'utils.token' local Event = require 'utils.event' local Terrain = require 'maps.mountain_fortress_v3.terrain' +local WD = require 'modules.wave_defense.table' +local BiterHealthBooster = require 'modules.biter_health_booster_v2' local Public = {} @@ -269,25 +271,27 @@ local function do_place_buildings(data) } == 0 then entity = surface.create_entity(e) - if entity and e.direction then - entity.direction = e.direction - end - if entity and e.force then - entity.force = e.force - end - if entity and e.callback then - local c = e.callback.callback - if not c then - return + if entity then + if e.direction then + entity.direction = e.direction end - local d = {callback_data = e.callback.data} - if not d then + if e.force then + entity.force = e.force + end + if e.callback then + local c = e.callback.callback + if not c then + return + end + local d = {callback_data = e.callback.data} + if not d then + callback = Token.get(c) + callback(entity) + return + end callback = Token.get(c) - callback(entity) - return + callback(entity, d) end - callback = Token.get(c) - callback(entity, d) end end end @@ -340,56 +344,67 @@ local function do_place_entities(data) if e.collision then if surface.can_place_entity(e) then entity = surface.create_entity(e) - wintery(entity) - if entity and e.direction then - entity.direction = e.direction - end - if entity and e.force then - entity.force = e.force - end - if entity and e.amount then - entity.amount = e.amount - end - if entity and e.callback then - local c = e.callback.callback - if not c then - return + if entity then + if e.note and e.note == 'wall' then + local wall_defenders_health_modifier = WD.get('modified_boss_unit_health') + BiterHealthBooster.add_unit(entity, wall_defenders_health_modifier) end - local d = {callback_data = e.callback.data} - if not d then - callback = Token.get(c) - callback(entity) - return + wintery(entity) + if e.direction then + entity.direction = e.direction + end + if e.force then + entity.force = e.force + end + if e.amount then + entity.amount = e.amount + end + if e.callback then + local c = e.callback.callback + if not c then + return + end + local d = {callback_data = e.callback.data} + if not d then + callback = Token.get(c) + callback(entity) + else + callback = Token.get(c) + callback(entity, d) + end end - callback = Token.get(c) - callback(entity, d) end end else entity = surface.create_entity(e) - wintery(entity) - if entity and e.direction then - entity.direction = e.direction - end - if entity and e.force then - entity.force = e.force - end - if entity and e.amount then - entity.amount = e.amount - end - if entity and e.callback then - local c = e.callback.callback - if not c then - return + if entity then + if e.note and e.note == 'wall' then + local wall_defenders_health_modifier = WD.get('modified_boss_unit_health') + BiterHealthBooster.add_unit(entity, wall_defenders_health_modifier) end - local d = {callback_data = e.callback.data} - if not d then - callback = Token.get(c) - callback(entity) - return + wintery(entity) + if e.direction then + entity.direction = e.direction + end + if e.force then + entity.force = e.force + end + if e.amount then + entity.amount = e.amount + end + if e.callback then + local c = e.callback.callback + if c then + local d = {callback_data = e.callback.data} + if not d then + callback = Token.get(c) + callback(entity) + else + callback = Token.get(c) + callback(entity, d) + end + end end - callback = Token.get(c) - callback(entity, d) end end end diff --git a/maps/mountain_fortress_v3/icw/functions.lua b/maps/mountain_fortress_v3/icw/functions.lua index 556705c0..a029d02f 100644 --- a/maps/mountain_fortress_v3/icw/functions.lua +++ b/maps/mountain_fortress_v3/icw/functions.lua @@ -268,7 +268,7 @@ function Public.hazardous_debris() end end - for _ = 1, 2 * speed, 1 do + for _ = 1, 6 * speed, 1 do local position = fallout_debris[random(1, size_of_debris)] local p = {x = position[1], y = position[2]} local get_tile = surface.get_tile(p) @@ -277,7 +277,24 @@ function Public.hazardous_debris() end end - for _ = 1, 1 * speed, 1 do + for _ = 1, 4 * speed, 1 do + local position = fallout_debris[random(1, size_of_debris)] + local p = {x = position[1], y = position[2]} + local get_tile = surface.get_tile(p) + if get_tile.valid and get_tile.name == 'out-of-map' then + create( + { + name = 'atomic-bomb-wave-spawns-nuke-shockwave-explosion', + position = position, + force = 'neutral', + target = {position[1], position[2] + fallout_width * 2}, + speed = speed + } + ) + end + end + + for _ = 1, 6 * speed, 1 do local position = fallout_debris[random(1, size_of_debris)] local p = {x = position[1], y = position[2]} local get_tile = surface.get_tile(p) diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index e175b788..7db48ed3 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -203,6 +203,7 @@ function Public.reset_map() BiterHealthBooster.check_on_entity_died(true) BiterHealthBooster.boss_spawns_projectiles(true) BiterHealthBooster.enable_boss_loot(false) + BiterHealthBooster.enable_randomize_discharge_stun(true) Balance.init_enemy_weapon_damage() diff --git a/maps/mountain_fortress_v3/table.lua b/maps/mountain_fortress_v3/table.lua index e0fb397f..0091b146 100644 --- a/maps/mountain_fortress_v3/table.lua +++ b/maps/mountain_fortress_v3/table.lua @@ -192,6 +192,7 @@ function Public.reset_table() this.offline_players = {} this.collapse_amount = false this.collapse_speed = false + this.y_value_position = 20 this.spawn_near_collapse = { active = true, total_pos = 35, diff --git a/maps/mountain_fortress_v3/terrain.lua b/maps/mountain_fortress_v3/terrain.lua index 0bb22779..7c295433 100644 --- a/maps/mountain_fortress_v3/terrain.lua +++ b/maps/mountain_fortress_v3/terrain.lua @@ -227,7 +227,8 @@ local function spawn_turret(entities, p, probability) force = 'enemy', callback = turret_list[probability].callback, direction = 4, - collision = true + collision = true, + note = 'wall' } end @@ -369,7 +370,8 @@ local function wall(p, data) entities[#entities + 1] = { name = Biters.wave_defense_roll_worm_name(), position = p, - force = 'enemy' + force = 'enemy', + note = 'wall' } end end @@ -2002,12 +2004,12 @@ local function process_level_1_position(x, y, data, void_or_lab) end --Chasms - if noise_cave_ponds < 0.111 and noise_cave_ponds > -0.112 then - if small_caves > 0.53 then + if noise_cave_ponds < 0.110 and noise_cave_ponds > -0.112 then + if small_caves > 0.5 then tiles[#tiles + 1] = {name = void_or_lab, position = p} return end - if small_caves < -0.53 then + if small_caves < -0.5 then tiles[#tiles + 1] = {name = void_or_lab, position = p} return end @@ -2144,10 +2146,10 @@ local function process_level_0_position(x, y, data, void_or_lab) local markets = data.markets local treasure = data.treasure - local small_caves = get_perlin('dungeons', p, seed) - local noise_cave_ponds = get_perlin('cave_ponds', p, seed) - local smol_areas = get_perlin('smol_areas', p, seed) - local no_rocks_2 = get_perlin('no_rocks_2', p, seed) + local small_caves = get_perlin('dungeons', p, seed + 34883) + local noise_cave_ponds = get_perlin('cave_ponds', p, seed + 28939) + local smol_areas = get_perlin('smol_areas', p, seed + 3992) + local no_rocks_2 = get_perlin('no_rocks_2', p, seed + 1922) local cave_rivers = get_perlin('cave_rivers', p, seed) local no_rocks = get_perlin('no_rocks', p, seed) @@ -2168,20 +2170,20 @@ local function process_level_0_position(x, y, data, void_or_lab) end --Chasms - if noise_cave_ponds < 0.111 and noise_cave_ponds > -0.112 then - if small_caves > 0.53 then + if noise_cave_ponds < 0.105 and noise_cave_ponds > -0.112 then + if small_caves > 0.52 then tiles[#tiles + 1] = {name = void_or_lab, position = p} return end - if small_caves < -0.53 then + if small_caves < -0.52 then tiles[#tiles + 1] = {name = void_or_lab, position = p} return end end --Water Ponds - if noise_cave_ponds > 0.670 then - if noise_cave_ponds > 0.750 then + if noise_cave_ponds > 0.64 then + if noise_cave_ponds > 0.74 then tiles[#tiles + 1] = {name = 'grass-' .. floor(noise_cave_ponds * 32) % 3 + 1, position = p} if random(1, 4) == 1 then markets[#markets + 1] = p @@ -2199,7 +2201,7 @@ local function process_level_0_position(x, y, data, void_or_lab) end --Rivers - if cave_rivers < 0.044 and cave_rivers > -0.062 then + if cave_rivers < 0.042 and cave_rivers > -0.062 then if noise_cave_ponds > 0.1 then tiles[#tiles + 1] = {name = 'water-shallow', position = p} if random(1, 64) == 1 then @@ -2209,7 +2211,7 @@ local function process_level_0_position(x, y, data, void_or_lab) end end - if noise_cave_ponds > 0.632 then + if noise_cave_ponds > 0.622 then if noise_cave_ponds > 0.542 then if cave_rivers > -0.302 then tiles[#tiles + 1] = {name = 'refined-hazard-concrete-right', position = p} @@ -2222,7 +2224,7 @@ local function process_level_0_position(x, y, data, void_or_lab) end --Worm oil Zones - if no_rocks < 0.031 and no_rocks > -0.141 then + if no_rocks < 0.035 and no_rocks > -0.145 then if small_caves > 0.081 then tiles[#tiles + 1] = {name = 'grass-' .. floor(noise_cave_ponds * 32) % 3 + 1, position = p} if random(1, 250) == 1 then @@ -2254,7 +2256,7 @@ local function process_level_0_position(x, y, data, void_or_lab) return end tiles[#tiles + 1] = {name = 'dirt-' .. floor(no_rocks_2 * 8) % 2 + 5, position = p} - if random(1, 32) == 1 then + if random(1, 18) == 1 then entities[#entities + 1] = {name = 'tree-0' .. random(1, 9), position = p} end @@ -2333,11 +2335,22 @@ local function border_chunk(p, data) entities[#entities + 1] = {name = trees[random(1, #trees)], position = pos} end - if random(1, 10) == 1 then - tiles[#tiles + 1] = {name = 'red-desert-' .. random(1, 3), position = pos} - else - tiles[#tiles + 1] = {name = 'dirt-' .. math.random(1, 6), position = pos} + local seed = data.seed + local small_caves = get_perlin('dungeons', p, seed + 34883) + local noise_cave_ponds = get_perlin('cave_ponds', p, seed + 28939) + local cave_rivers = get_perlin('cave_rivers', p, seed) + + if small_caves > 0.64 then + tiles[#tiles + 1] = {name = 'nuclear-ground', position = pos} end + if noise_cave_ponds > 0.33 then + tiles[#tiles + 1] = {name = 'red-desert-' .. random(1, 3), position = pos} + end + if cave_rivers > 0.54 then + tiles[#tiles + 1] = {name = 'grass-' .. random(1, 4), position = pos} + end + + -- tiles[#tiles + 1] = {name = 'dirt-' .. random(1, 6), position = pos} local scrap_mineable_entities, scrap_mineable_entities_index = get_scrap_mineable_entities()