diff --git a/functions/basic_markets.lua b/functions/basic_markets.lua index 26880585..cd42244c 100644 --- a/functions/basic_markets.lua +++ b/functions/basic_markets.lua @@ -13,7 +13,7 @@ market.weapons = { market.ammo = { ["firearm-magazine"] = {value = 3, rarity = 1}, ["piercing-rounds-magazine"] = {value = 6, rarity = 4}, - ["uranium-rounds-magazine"] = {value = 16, rarity = 8}, + ["uranium-rounds-magazine"] = {value = 20, rarity = 8}, ["shotgun-shell"] = {value = 3, rarity = 1}, ["piercing-shotgun-shell"] = {value = 8, rarity = 5}, ["cannon-shell"] = {value = 8, rarity = 4}, @@ -58,8 +58,8 @@ market.equipment = { ["battery-mk2-equipment"] = {value = 2000, rarity = 8}, ["personal-laser-defense-equipment"] = {value = 2500, rarity = 7}, ["discharge-defense-equipment"] = {value = 2000, rarity = 5}, - ["belt-immunity-equipment"] = {value = 500, rarity = 1}, - ["exoskeleton-equipment"] = {value = 1000, rarity = 3}, + ["belt-immunity-equipment"] = {value = 200, rarity = 1}, + ["exoskeleton-equipment"] = {value = 800, rarity = 3}, ["personal-roboport-equipment"] = {value = 500, rarity = 3}, ["personal-roboport-mk2-equipment"] = {value = 5000, rarity = 8}, ["night-vision-equipment"] = {value = 250, rarity = 1}, diff --git a/maps/mountain_fortress_v2/main.lua b/maps/mountain_fortress_v2/main.lua index d8c1ced6..5b01eb31 100644 --- a/maps/mountain_fortress_v2/main.lua +++ b/maps/mountain_fortress_v2/main.lua @@ -3,13 +3,13 @@ --require "modules.flashlight_toggle_button" --require "modules.biter_noms_you" require "modules.rpg" -require "modules.biter_health_booster" require "modules.wave_defense.main" require "functions.soft_reset" require "functions.basic_markets" require "modules.biters_yield_coins" require "modules.biter_pets" require "modules.no_deconstruction_of_neutral_entities" +require "modules.shotgun_buff" require "modules.explosives" require "modules.rocks_broken_paint_tiles" require "modules.rocks_heal_over_time" @@ -147,8 +147,8 @@ local function biters_chew_rocks_faster(event) if not event.cause then return end if not event.cause.valid then return end if event.cause.force.index ~= 2 then return end --Enemy Force - local bonus_damage = event.final_damage_amount * math.abs(global.wave_defense.threat) * 0.0002 - event.entity.health = event.entity.health - bonus_damage + --local bonus_damage = event.final_damage_amount * math.abs(global.wave_defense.threat) * 0.0002 + event.entity.health = event.entity.health - event.final_damage_amount * 2.5 end local function hidden_biter(entity) @@ -247,10 +247,6 @@ local function on_player_joined_game(event) local surface = game.surfaces[global.active_surface_index] - global.wave_defense.surface_index = global.active_surface_index - global.wave_defense.target = global.locomotive_cargo - global.wave_defense.side_target_search_radius = 768 - if player.online_time == 0 then player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 3, 0.5), surface) for item, amount in pairs(starting_items) do diff --git a/maps/mountain_fortress_v2/terrain.lua b/maps/mountain_fortress_v2/terrain.lua index 1a5b5890..62a65712 100644 --- a/maps/mountain_fortress_v2/terrain.lua +++ b/maps/mountain_fortress_v2/terrain.lua @@ -1,6 +1,6 @@ local math_random = math.random local simplex_noise = require "utils.simplex_noise".d2 -local rock_raffle = {"sand-rock-big","sand-rock-big","sand-rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"} +local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"} local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"} local noises = { ["no_rocks"] = {{modifier = 0.0033, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}}, @@ -163,6 +163,7 @@ local function process_rock_chunk_position(p, seed, tiles, entities, markets, tr local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then tiles[#tiles + 1] = {name = "dirt-" .. math.floor(no_rocks_2 * 8) % 2 + 5, position = p} + if math_random(1,32) == 1 then entities[#entities + 1] = {name = "dead-tree-desert", position=p} end if math_random(1,512) == 1 then treasure[#treasure + 1] = p end return end @@ -184,7 +185,7 @@ local function process_rock_chunk_position(p, seed, tiles, entities, markets, tr end if math.abs(noise_large_caves) > m * 5 then tiles[#tiles + 1] = {name = "grass-2", position = p} - if math_random(1,512) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = math.abs(p.y) * 1000} end + if math_random(1,512) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = math.abs(p.y) * 500} end if math_random(1,512) == 1 then markets[#markets + 1] = p end if math_random(1,384) == 1 then wave_defense_set_worm_raffle(math.abs(p.y) * worm_level_modifier) @@ -299,7 +300,7 @@ local function biter_chunk(surface, left_top) tile_positions[#tile_positions + 1] = p end end - for i = 1, 2, 1 do + for i = 1, 1, 1 do local position = surface.find_non_colliding_position("biter-spawner", tile_positions[math_random(1, #tile_positions)], 16, 2) if position then local e = surface.create_entity({name = spawner_raffle[math_random(1, #spawner_raffle)], position = position}) @@ -307,7 +308,7 @@ local function biter_chunk(surface, left_top) e.active = false end end - for _, e in pairs(surface.find_entities_filtered({area = {{left_top.x, left_top.y},{left_top.x + 32, left_top.y + 32}}, type = "cliff"})) do e.destroy() end + --for _, e in pairs(surface.find_entities_filtered({area = {{left_top.x, left_top.y},{left_top.x + 32, left_top.y + 32}}, type = "cliff"})) do e.destroy() end end local function replace_water(surface, left_top) diff --git a/maps/mountain_fortress_v2/treasure.lua b/maps/mountain_fortress_v2/treasure.lua index 1ed2a53e..e87ecd75 100644 --- a/maps/mountain_fortress_v2/treasure.lua +++ b/maps/mountain_fortress_v2/treasure.lua @@ -59,8 +59,8 @@ function treasure_chest(surface, position) {{name = "engine-unit", count = math_random(16,32)}, weight = 2, evo_min = 0.1, evo_max = 0.5}, {{name = "electric-engine-unit", count = math_random(16,32)}, weight = 2, evo_min = 0.4, evo_max = 0.8}, {{name = "battery", count = math_random(50,150)}, weight = 2, evo_min = 0.3, evo_max = 0.8}, - {{name = "advanced-circuit", count = math_random(50,150)}, weight = 3, evo_min = 0.4, evo_max = 1}, - {{name = "electronic-circuit", count = math_random(50,150)}, weight = 3, evo_min = 0.0, evo_max = 0.4}, + {{name = "advanced-circuit", count = math_random(50,150)}, weight = 3, evo_min = 0.3, evo_max = 1}, + {{name = "electronic-circuit", count = math_random(50,150)}, weight = 4, evo_min = 0.0, evo_max = 0.4}, {{name = "processing-unit", count = math_random(50,150)}, weight = 3, evo_min = 0.7, evo_max = 1}, {{name = "explosives", count = math_random(40,100)}, weight = 20, evo_min = 0.0, evo_max = 1}, {{name = "lubricant-barrel", count = math_random(4,10)}, weight = 1, evo_min = 0.3, evo_max = 0.5}, @@ -87,7 +87,7 @@ function treasure_chest(surface, position) {{name = "rail", count = math_random(25,75)}, weight = 3, evo_min = 0.1, evo_max = 0.6}, {{name = "assembling-machine-1", count = math_random(2,4)}, weight = 3, evo_min = 0.0, evo_max = 0.3}, {{name = "assembling-machine-2", count = math_random(2,4)}, weight = 3, evo_min = 0.2, evo_max = 0.8}, - {{name = "assembling-machine-3", count = math_random(1,2)}, weight = 3, evo_min = 0.5, evo_max = 1}, + {{name = "assembling-machine-3", count = math_random(2,4)}, weight = 3, evo_min = 0.5, evo_max = 1}, {{name = "accumulator", count = math_random(4,8)}, weight = 3, evo_min = 0.4, evo_max = 1}, {{name = "offshore-pump", count = math_random(1,3)}, weight = 2, evo_min = 0.0, evo_max = 0.2}, {{name = "beacon", count = 1}, weight = 3, evo_min = 0.7, evo_max = 1}, @@ -129,9 +129,9 @@ function treasure_chest(surface, position) {{name = "radar", count = math_random(1,2)}, weight = 1, evo_min = 0.1, evo_max = 0.4}, {{name = "rail-signal", count = math_random(8,16)}, weight = 2, evo_min = 0.2, evo_max = 0.8}, {{name = "rail-chain-signal", count = math_random(8,16)}, weight = 2, evo_min = 0.2, evo_max = 0.8}, - {{name = "stone-wall", count = math_random(25,75)}, weight = 1, evo_min = 0.1, evo_max = 0.5}, - {{name = "gate", count = math_random(4,8)}, weight = 1, evo_min = 0.1, evo_max = 0.5}, - {{name = "storage-tank", count = math_random(1,4)}, weight = 3, evo_min = 0.3, evo_max = 0.6}, + {{name = "stone-wall", count = math_random(33,99)}, weight = 3, evo_min = 0.0, evo_max = 0.7}, + {{name = "gate", count = math_random(16,32)}, weight = 3, evo_min = 0.0, evo_max = 0.7}, + {{name = "storage-tank", count = math_random(2,6)}, weight = 3, evo_min = 0.3, evo_max = 0.6}, {{name = "train-stop", count = math_random(1,2)}, weight = 1, evo_min = 0.2, evo_max = 0.7}, {{name = "express-loader", count = math_random(1,2)}, weight = 1, evo_min = 0.5, evo_max = 1}, {{name = "fast-loader", count = math_random(1,2)}, weight = 1, evo_min = 0.2, evo_max = 0.7}, @@ -143,7 +143,7 @@ function treasure_chest(surface, position) {{name = "gun-turret", count = math_random(2,4)}, weight = 3, evo_min = 0.2, evo_max = 0.9}, } - local distance_to_center = (math.abs(position.y) + 1) * 0.00025 + local distance_to_center = (math.abs(position.y) + 1) * 0.0002 if distance_to_center > 1 then distance_to_center = 1 end for _, t in pairs (chest_loot) do diff --git a/modules/rpg.lua b/modules/rpg.lua index 54c85bc5..d684d91c 100644 --- a/modules/rpg.lua +++ b/modules/rpg.lua @@ -351,7 +351,7 @@ local function draw_gui(player, forced) end add_separator(frame, 400) - global.rpg[player.index].gui_refresh_delay = game.tick + 6 + global.rpg[player.index].gui_refresh_delay = game.tick + 60 update_char_button(player) end diff --git a/modules/shotgun_buff.lua b/modules/shotgun_buff.lua new file mode 100644 index 00000000..db36a1f7 --- /dev/null +++ b/modules/shotgun_buff.lua @@ -0,0 +1,16 @@ +local function on_research_finished(event) + local research = event.research + if string.sub(research.name, 0, 26) ~= "physical-projectile-damage" then return end + local multiplier = 4 + if global.shotgun_shell_damage_research_multiplier then multiplier = global.shotgun_shell_damage_research_multiplier end + + local modifier = game.forces[research.force.name].get_ammo_damage_modifier("shotgun-shell") + + modifier = modifier - research.effects[3].modifier + modifier = modifier + research.effects[3].modifier * multiplier + + game.forces[research.force.name].set_ammo_damage_modifier("shotgun-shell", modifier) +end + +local event = require 'utils.event' +event.add(defines.events.on_research_finished, on_research_finished) \ No newline at end of file diff --git a/modules/wave_defense/biter_rolls.lua b/modules/wave_defense/biter_rolls.lua index 73d0029a..0b4657c5 100644 --- a/modules/wave_defense/biter_rolls.lua +++ b/modules/wave_defense/biter_rolls.lua @@ -44,8 +44,8 @@ function wave_defense_set_unit_raffle(level) global.wave_defense.spitter_raffle["big-spitter"] = (level - 500) * 2 end if level > 800 then - global.wave_defense.biter_raffle["behemoth-biter"] = (level - 800) * 4 - global.wave_defense.spitter_raffle["behemoth-spitter"] = (level - 800) * 4 + global.wave_defense.biter_raffle["behemoth-biter"] = (level - 800) * 3 + global.wave_defense.spitter_raffle["behemoth-spitter"] = (level - 800) * 3 end for k, v in pairs(global.wave_defense.biter_raffle) do if global.wave_defense.biter_raffle[k] < 0 then global.wave_defense.biter_raffle[k] = 0 end @@ -80,7 +80,7 @@ function wave_defense_set_worm_raffle(level) global.wave_defense.worm_raffle["big-worm-turret"] = (level - 500) * 2 end if level > 800 then - global.wave_defense.worm_raffle["behemoth-worm-turret"] = (level - 800) * 4 + global.wave_defense.worm_raffle["behemoth-worm-turret"] = (level - 800) * 3 end for k, v in pairs(global.wave_defense.worm_raffle) do if global.wave_defense.worm_raffle[k] < 0 then global.wave_defense.worm_raffle[k] = 0 end diff --git a/modules/wave_defense/gui.lua b/modules/wave_defense/gui.lua index 78384b4f..6f2918a8 100644 --- a/modules/wave_defense/gui.lua +++ b/modules/wave_defense/gui.lua @@ -11,8 +11,8 @@ local function create_gui(player) label.style.font_color = {r=0.33, g=0.66, b=0.9} local progressbar = frame.add({ type = "progressbar", name = "progressbar", value = 0}) - progressbar.style.minimal_width = 128 - progressbar.style.maximal_width = 128 + progressbar.style.minimal_width = 96 + progressbar.style.maximal_width = 96 progressbar.style.top_padding = 10 local line = frame.add({type = "line", direction = "vertical"}) @@ -34,9 +34,7 @@ local function update_gui(player) if global.wave_defense.wave_number == 0 then player.gui.top.wave_defense.label.caption = "First wave in " .. math.floor((global.wave_defense.next_wave - game.tick) / 60) + 1 end local interval = global.wave_defense.next_wave - global.wave_defense.last_wave player.gui.top.wave_defense.progressbar.value = 1 - (global.wave_defense.next_wave - game.tick) / interval - local value = global.wave_defense.threat - if value < 0 then value = 0 end - player.gui.top.wave_defense.threat.caption = "Threat: " .. value + player.gui.top.wave_defense.threat.caption = "Threat: " .. math.floor(global.wave_defense.threat) end return update_gui \ No newline at end of file diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index e9db0171..929100f3 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -1,10 +1,11 @@ +require "modules.biter_health_booster" require "modules.wave_defense.biter_rolls" require "modules.wave_defense.threat_events" local update_gui = require "modules.wave_defense.gui" local threat_values = require "modules.wave_defense.threat_values" local math_random = math.random -local side_target_types = {"accumulator", "assembling-machine", "beacon", "boiler", "container", "electric-pole", "furnace", "lamp", "lab", - "logistic-container", "mining-drill", "container", "pump", "radar", "reactor", "roboport", "rocket-silo", "solar-panel", "storage-tank",} +local side_target_types = {"accumulator", "assembling-machine", "beacon", "boiler", "container", "furnace", "lamp", "lab", "logistic-container", "mining-drill", "container", "pump", "radar", "reactor", "roboport", "rocket-silo", "solar-panel", "storage-tank",} +--local side_target_types = {"assembling-machine", "electric-pole", "furnace", "mining-drill", "pump", "radar", "reactor", "roboport"} local function debug_print(msg) if not global.wave_defense.debug then return end @@ -19,14 +20,27 @@ local function is_unit_valid(biter) return true end +local function refresh_active_unit_threat() + debug_print("refresh_active_unit_threat - current value " .. global.wave_defense.active_biter_threat) + local active_biter_threat = 0 + for k, biter in pairs(global.wave_defense.active_biters) do + if biter.entity then + if biter.entity.valid then + active_biter_threat = active_biter_threat + threat_values[biter.entity.name] + end + end + end + global.wave_defense.active_biter_threat = math.round(active_biter_threat * global.biter_health_boost, 2) + debug_print("refresh_active_unit_threat - new value " .. global.wave_defense.active_biter_threat) +end + local function time_out_biters() - debug_print("time_out_biters") for k, biter in pairs(global.wave_defense.active_biters) do if not is_unit_valid(biter) then global.wave_defense.active_biter_count = global.wave_defense.active_biter_count - 1 if biter.entity then if biter.entity.valid then - global.wave_defense.threat = global.wave_defense.threat + threat_values[biter.entity.name] + global.wave_defense.active_biter_threat = global.wave_defense.active_biter_threat - math.round(threat_values[biter.entity.name] * global.biter_health_boost, 2) if biter.entity.force.index == 2 then biter.entity.destroy() end @@ -38,7 +52,6 @@ local function time_out_biters() end local function get_random_close_spawner(surface) - debug_print("get_random_close_spawner") local spawners = surface.find_entities_filtered({type = "unit-spawner"}) if not spawners[1] then return false end local center = global.wave_defense.target.position @@ -47,9 +60,61 @@ local function get_random_close_spawner(surface) local spawner_2 = spawners[math_random(1,#spawners)] if (center.x - spawner_2.position.x) ^ 2 + (center.y - spawner_2.position.y) ^ 2 < (center.x - spawner.position.x) ^ 2 + (center.y - spawner.position.y) ^ 2 then spawner = spawner_2 end end + debug_print("get_random_close_spawner - Found at x" .. spawner.position.x .. " y" .. spawner.position.y) return spawner end +local function set_side_target_list() + local surface = game.surfaces[global.wave_defense.surface_index] + local position = false + local force = false + + if global.wave_defense.target then + if global.wave_defense.target.valid then + position = global.wave_defense.target.position + force = global.wave_defense.target.force + end + end + + if not position then + local r = math_random(1, #game.connected_players) + position = {x = game.connected_players[r].position.x, y = game.connected_players[r].position.y} + force = game.connected_players[r].force + end + + global.wave_defense.side_targets = surface.find_entities_filtered({ + area = { + {position.x - global.wave_defense.side_target_search_radius, position.y - global.wave_defense.side_target_search_radius}, + {position.x + global.wave_defense.side_target_search_radius, position.y + global.wave_defense.side_target_search_radius} + }, + force = force, + type = side_target_types, + }) + + debug_print("set_side_target_list -- " .. #global.wave_defense.side_targets .. " targets around position x" .. position.x .. " y" .. position.y .. " saved.") +end + +local function get_side_target() + if not global.wave_defense.side_targets then return false end + if #global.wave_defense.side_targets < 2 then return false end + local side_target = global.wave_defense.side_targets[math_random(1,#global.wave_defense.side_targets)] + if not side_target then return false end + if not side_target.valid then return false end + for _ = 1, 4, 1 do + local new_target = global.wave_defense.side_targets[math_random(1,#global.wave_defense.side_targets)] + if new_target then + if new_target.valid then + local side_target_distance = (global.wave_defense.target.position.x - side_target.position.x) ^ 2 + (global.wave_defense.target.position.y - side_target.position.y) ^ 2 + local new_target_distance = (global.wave_defense.target.position.x - new_target.position.x) ^ 2 + (global.wave_defense.target.position.y - new_target.position.y) ^ 2 + if new_target_distance > side_target_distance then side_target = new_target end + end + end + end + debug_print("get_side_target -- " .. side_target.name .. " at position x" .. side_target.position.x .. " y" .. side_target.position.y .. " selected.") + return side_target +end + +--[[ local function set_main_target() if global.wave_defense.target then if global.wave_defense.target.valid then return end @@ -67,48 +132,27 @@ local function set_main_target() if #characters == 0 then return end global.wave_defense.target = characters[math_random(1, #characters)] end +]] -local function set_side_target_list() - debug_print("set_side_target_list") - if not global.wave_defense.target then return false end - if not global.wave_defense.target.valid then return false end - global.wave_defense.side_targets = global.wave_defense.target.surface.find_entities_filtered({ - area = { - {global.wave_defense.target.position.x - global.wave_defense.side_target_search_radius, global.wave_defense.target.position.y - global.wave_defense.side_target_search_radius}, - {global.wave_defense.target.position.x + global.wave_defense.side_target_search_radius, global.wave_defense.target.position.y + global.wave_defense.side_target_search_radius} - }, - force = global.wave_defense.target.force, - type = side_target_types - }) -end - -local function get_side_target() - debug_print("get_side_target") - if not global.wave_defense.side_targets then return false end - if #global.wave_defense.side_targets < 2 then return false end - local side_target = global.wave_defense.side_targets[math_random(1,#global.wave_defense.side_targets)] - if not side_target then return false end - if not side_target.valid then return false end - for _ = 1, 4, 1 do - local new_target = global.wave_defense.side_targets[math_random(1,#global.wave_defense.side_targets)] - if new_target then - if new_target.valid then - local side_target_distance = (global.wave_defense.target.position.x - side_target.position.x) ^ 2 + (global.wave_defense.target.position.y - side_target.position.y) ^ 2 - local new_target_distance = (global.wave_defense.target.position.x - new_target.position.x) ^ 2 + (global.wave_defense.target.position.y - new_target.position.y) ^ 2 - if new_target_distance > side_target_distance then side_target = new_target end - end - end - end - return side_target +local function set_main_target() + if global.wave_defense.target then + if global.wave_defense.target.valid then return end + end + if #global.wave_defense.side_targets == 0 then return end + local target = global.wave_defense.side_targets[math_random(1, #global.wave_defense.side_targets)] + if not target then return end + if not target.valid then return end + global.wave_defense.target = target + debug_print("set_main_target -- New main target " .. target.name .. " at position x" .. target.position.x .. " y" .. target.position.y .. " selected.") end local function set_group_spawn_position(surface) - debug_print("set_group_spawn_position") local spawner = get_random_close_spawner(surface) if not spawner then return end local position = surface.find_non_colliding_position("rocket-silo", spawner.position, 48, 1) if not position then return end global.wave_defense.spawn_position = {x = math.floor(position.x), y = math.floor(position.y)} + debug_print("set_group_spawn_position -- Changed position to x" .. global.wave_defense.spawn_position.x .. " y" .. global.wave_defense.spawn_position.y .. ".") end local function set_enemy_evolution() @@ -118,14 +162,13 @@ local function set_enemy_evolution() if evolution_factor > 1 then damage_increase = damage_increase + (evolution_factor - 1) - biter_health_boost = biter_health_boost + (evolution_factor - 1) + biter_health_boost = biter_health_boost + (evolution_factor - 1) * 2 evolution_factor = 1 end if global.wave_defense.threat > 0 then - local m = math.round(global.wave_defense.threat / 100000, 3) - biter_health_boost = biter_health_boost + m - damage_increase = damage_increase + m * 0.25 + biter_health_boost = math.round(biter_health_boost + global.wave_defense.threat * 0.00005, 3) + damage_increase = math.round(damage_increase + global.wave_defense.threat * 0.000005, 3) end global.biter_health_boost = biter_health_boost @@ -138,15 +181,38 @@ local function set_enemy_evolution() player.gui.top.wave_defense.threat.tooltip = "High threat may empower biters.\nBiter health " .. biter_health_boost * 100 .. "% | damage " .. (damage_increase + 1) * 100 .. "%" end end - - debug_print("evolution_factor: " .. evolution_factor) - debug_print("biter_health_boost: " .. global.biter_health_boost) - debug_print("damage_increase: " .. game.forces.enemy.get_ammo_damage_modifier("melee")) +end + +local function can_units_spawn() + if global.wave_defense.threat <= 0 then + debug_print("can_units_spawn - threat too low") + return false + end + if global.wave_defense.active_biter_count >= global.wave_defense.max_active_biters then + debug_print("can_units_spawn - active biter count too high") + return false + end + if global.wave_defense.active_biter_threat >= global.wave_defense.threat then + debug_print("can_units_spawn - active biter threat too high (" .. global.wave_defense.active_biter_threat .. ")") + return false + end + return true +end + +local function get_active_unit_groups_count() + local count = 0 + for _, g in pairs(global.wave_defense.unit_groups) do + if g.valid then + count = count + 1 + end + end + debug_print("Active unit group count: " .. count) + return count end local function spawn_biter(surface) - if global.wave_defense.threat <= 0 then return false end - if global.wave_defense.active_biter_count >= global.wave_defense.max_active_biters then return false end + if not can_units_spawn() then return end + local name if math.random(1,100) > 73 then name = wave_defense_roll_spitter_name() @@ -160,16 +226,21 @@ local function spawn_biter(surface) biter.ai_settings.allow_try_return_to_spawner = false global.wave_defense.active_biters[biter.unit_number] = {entity = biter, spawn_tick = game.tick} global.wave_defense.active_biter_count = global.wave_defense.active_biter_count + 1 - global.wave_defense.threat = global.wave_defense.threat - threat_values[name] + global.wave_defense.active_biter_threat = global.wave_defense.active_biter_threat + math.round(threat_values[name] * global.biter_health_boost, 2) return biter end local function spawn_unit_group() - if global.wave_defense.threat <= 0 then return false end - if global.wave_defense.active_biter_count >= global.wave_defense.max_active_biters then return false end + if not can_units_spawn() then return end + if not global.wave_defense.target then return end + if not global.wave_defense.target.valid then return end + if get_active_unit_groups_count() >= global.wave_defense.max_active_unit_groups then return end + + wave_defense_set_unit_raffle(global.wave_defense.wave_number) + local surface = game.surfaces[global.wave_defense.surface_index] set_group_spawn_position(surface) - debug_print("Spawning unit group at position:" .. global.wave_defense.spawn_position.x .." " .. global.wave_defense.spawn_position.y) + debug_print("Spawning unit group at x" .. global.wave_defense.spawn_position.x .." y" .. global.wave_defense.spawn_position.y) local unit_group = surface.create_unit_group({position = global.wave_defense.spawn_position, force = "enemy"}) for a = 1, global.wave_defense.group_size, 1 do local biter = spawn_biter(surface) @@ -186,33 +257,7 @@ local function spawn_unit_group() return true end -local function get_active_unit_groups_count() - local count = 0 - for _, g in pairs(global.wave_defense.unit_groups) do - if g.valid then - count = count + 1 - end - end - debug_print("Active unit groups count: " .. count) - return count -end - -local function spawn_attack_groups() - debug_print("spawn_attack_groups") - if not global.wave_defense.target then return end - if not global.wave_defense.target.valid then return end - if global.wave_defense.active_biter_count >= global.wave_defense.max_active_biters then return false end - if global.wave_defense.threat <= 0 then return false end - wave_defense_set_unit_raffle(global.wave_defense.wave_number) - - local count = get_active_unit_groups_count() - if count >= global.wave_defense.max_active_unit_groups then return end - - spawn_unit_group() -end - local function set_next_wave() - debug_print("set_next_wave") global.wave_defense.wave_number = global.wave_defense.wave_number + 1 global.wave_defense.group_size = global.wave_defense.wave_number * 2 if global.wave_defense.group_size > global.wave_defense.max_group_size then global.wave_defense.group_size = global.wave_defense.max_group_size end @@ -222,7 +267,6 @@ local function set_next_wave() end local function get_commmands(group) - debug_print("get_commmands") local commands = {} local group_position = {x = group.position.x, y = group.position.y} local step_length = global.wave_defense.unit_group_command_step_length @@ -240,10 +284,9 @@ local function get_commmands(group) local vector = {math.round((target_position.x - group_position.x) / steps, 3), math.round((target_position.y - group_position.y) / steps, 3)} if global.wave_defense.debug then - print("side_target x" .. side_target.position.x .. " y" .. side_target.position.y) - print("distance_to_target " .. distance_to_target) - print("steps " .. steps) - print("vector " .. vector[1] .. "_" .. vector[2]) + debug_print("get_commmands - to side_target x" .. side_target.position.x .. " y" .. side_target.position.y) + debug_print("get_commmands - distance_to_target:" .. distance_to_target .. " steps:" .. steps) + debug_print("get_commmands - vector " .. vector[1] .. "_" .. vector[2]) end for i = 1, steps, 1 do @@ -257,7 +300,6 @@ local function get_commmands(group) radius = 16, distraction = defines.distraction.by_anything } - --if global.wave_defense.debug then print(position) end end end @@ -275,10 +317,9 @@ local function get_commmands(group) local vector = {math.round((target_position.x - group_position.x) / steps, 3), math.round((target_position.y - group_position.y) / steps, 3)} if global.wave_defense.debug then - print("main_target") - print("distance_to_target " .. distance_to_target) - print("steps " .. steps) - print("vector " .. vector[1] .. "_" .. vector[2]) + debug_print("get_commmands - to main target x" .. target_position.x .. " y" .. target_position.y) + debug_print("get_commmands - distance_to_target:" .. distance_to_target .. " steps:" .. steps) + debug_print("get_commmands - vector " .. vector[1] .. "_" .. vector[2]) end for i = 1, steps, 1 do @@ -292,7 +333,6 @@ local function get_commmands(group) radius = 16, distraction = defines.distraction.by_anything } - --if global.wave_defense.debug then print(position) end end end @@ -330,7 +370,6 @@ local function give_commands_to_unit_groups() if #global.wave_defense.unit_groups == 0 then return end if not global.wave_defense.target then return end if not global.wave_defense.target.valid then return end - debug_print("give_commands_to_unit_groups") for k, group in pairs(global.wave_defense.unit_groups) do if group.valid then command_unit_group(group) @@ -343,10 +382,13 @@ end local tick_tasks = { [30] = set_main_target, [60] = set_enemy_evolution, - [90] = spawn_attack_groups, + [90] = spawn_unit_group, [120] = give_commands_to_unit_groups, [150] = build_nest, [180] = build_worm, + [1800] = set_side_target_list, + [3600] = time_out_biters, + [7200] = refresh_active_unit_threat, } local function on_tick() @@ -357,11 +399,10 @@ local function on_tick() if game.tick > global.wave_defense.next_wave then set_next_wave() end local t = game.tick % 300 - + local t2 = game.tick % 18000 + if tick_tasks[t] then tick_tasks[t]() end - - if game.tick % 1800 == 0 then time_out_biters() end - if game.tick % 7200 == 0 then set_side_target_list() end + if tick_tasks[t2] then tick_tasks[t2]() end end function reset_wave_defense() @@ -369,6 +410,7 @@ function reset_wave_defense() debug = false, surface_index = 1, active_biters = {}, + active_biter_threat = 0, unit_groups = {}, unit_group_last_command = {}, unit_group_command_delay = 3600 * 8, diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua index d4671f75..44fe2e71 100644 --- a/modules/wave_defense/threat_events.lua +++ b/modules/wave_defense/threat_events.lua @@ -3,8 +3,9 @@ local math_random = math.random local function remove_unit(entity) if not global.wave_defense.active_biters[entity.unit_number] then return end - global.wave_defense.active_biters[entity.unit_number] = nil + global.wave_defense.active_biter_threat = global.wave_defense.active_biter_threat - math.round(threat_values[entity.name] * global.biter_health_boost, 2) global.wave_defense.active_biter_count = global.wave_defense.active_biter_count - 1 + global.wave_defense.active_biters[entity.unit_number] = nil end function build_nest() @@ -95,13 +96,14 @@ local function acid_nova(entity) end local function shred_simple_entities(entity) - if global.wave_defense.threat < 5000 then return end + if global.wave_defense.threat < 10000 then return end local simple_entities = entity.surface.find_entities_filtered({type = "simple-entity", area = {{entity.position.x - 2, entity.position.y - 2},{entity.position.x + 2, entity.position.y + 2}}}) if #simple_entities == 0 then return end if #simple_entities > 1 then table.shuffle_table(simple_entities) end - local r = math.floor(global.wave_defense.threat * global.wave_defense.simple_entity_shredding_count_modifier) - if r < 1 then r = 1 end - local count = math.random(1, r) + --local r = math.floor(global.wave_defense.threat * global.wave_defense.simple_entity_shredding_count_modifier) + --if r < 1 then r = 1 end + --local count = math.random(1, r) + local count = 1 local damage_dealt = 0 for i = 1, count, 1 do if not simple_entities[i] then break end @@ -119,18 +121,28 @@ local function shred_simple_entities(entity) end local function on_entity_died(event) - if not event.entity.valid then return end + local entity = event.entity + if not entity.valid then return end - if event.entity.type == "unit" then - remove_unit(event.entity) - acid_nova(event.entity) + if entity.type == "unit" then + global.wave_defense.threat = math.round(global.wave_defense.threat - threat_values[entity.name] * global.biter_health_boost, 2) + remove_unit(entity) + acid_nova(entity) + else + if entity.force.index == 2 then + if entity.health then + if threat_values[entity.name] then + global.wave_defense.threat = global.wave_defense.threat - threat_values[entity.name] + end + end + end end - - if event.entity.force.index == 3 then + + if entity.force.index == 3 then if event.cause then if event.cause.valid then if event.cause.force.index == 2 then - shred_simple_entities(event.entity) + shred_simple_entities(entity) end end end diff --git a/modules/wave_defense/threat_values.lua b/modules/wave_defense/threat_values.lua index a34e3153..4169b124 100644 --- a/modules/wave_defense/threat_values.lua +++ b/modules/wave_defense/threat_values.lua @@ -1,15 +1,17 @@ local t = { - ["behemoth-biter"] = 24, - ["behemoth-spitter"] = 24, - ["big-biter"] = 8, - ["big-spitter"] = 8, + ["biter-spawner"] = 64, + ["spitter-spawner"] = 64, + ["behemoth-biter"] = 48, + ["behemoth-spitter"] = 48, + ["big-biter"] = 16, + ["big-spitter"] = 16, ["medium-biter"] = 4, ["medium-spitter"] = 4, ["small-biter"] = 1, ["small-spitter"] = 1, - ["small-worm-turret"] = 32, - ["medium-worm-turret"] = 48, - ["big-worm-turret"] = 64, - ["behemoth-worm-turret"] = 80, + ["small-worm-turret"] = 16, + ["medium-worm-turret"] = 32, + ["big-worm-turret"] = 48, + ["behemoth-worm-turret"] = 64, } return t \ No newline at end of file