1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/modules/wave_defense/threat_events.lua
MewMew 5a8fe50216 Update
Fixed that worms and spawners did not accurately reduce threat, scaling with their current health bonus.

Fixed that worms and spawners did not accurately give the correct amount of xp, scaling with their current health bonus.

Value tweaks.
2020-05-03 14:00:16 +02:00

196 lines
8.1 KiB
Lua

local WD = require "modules.wave_defense.table"
local threat_values = require "modules.wave_defense.threat_values"
local BiterRolls = require 'modules.wave_defense.biter_rolls'
local math_random = math.random
local Public = {}
local function remove_unit(entity)
local wave_defense_table = WD.get_table()
local unit_number = entity.unit_number
if not wave_defense_table.active_biters[unit_number] then return end
local m = 1
if global.biter_health_boost_units[unit_number] then
m = 1 / global.biter_health_boost_units[unit_number][2]
end
local active_threat_loss = math.round(threat_values[entity.name] * m, 2)
wave_defense_table.active_biter_threat = wave_defense_table.active_biter_threat - active_threat_loss
wave_defense_table.active_biter_count = wave_defense_table.active_biter_count - 1
wave_defense_table.active_biters[unit_number] = nil
end
local function place_nest_near_unit_group(wave_defense_table)
local group = wave_defense_table.unit_groups[math_random(1, #wave_defense_table.unit_groups)]
if not group then return end
if not group.valid then return end
if not group.members then return end
if not group.members[1] then return end
local unit = group.members[math_random(1, #group.members)]
if not unit.valid then return end
local name = "biter-spawner"
if math_random(1, 3) == 1 then name = "spitter-spawner" end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then return end
local r = wave_defense_table.nest_building_density
if unit.surface.count_entities_filtered({type = "unit-spawner", area = {{position.x - r, position.y - r},{position.x + r, position.y + r}}}) > 0 then return end
unit.surface.create_entity({name = name, position = position, force = unit.force})
unit.surface.create_entity({name = "blood-explosion-huge", position = position})
unit.surface.create_entity({name = "blood-explosion-huge", position = unit.position})
remove_unit(unit)
unit.destroy()
wave_defense_table.threat = wave_defense_table.threat - threat_values[name]
return true
end
function Public.build_nest()
local wave_defense_table = WD.get_table()
if wave_defense_table.threat < 1024 then return end
if #wave_defense_table.unit_groups == 0 then return end
for _ = 1, 2, 1 do
if place_nest_near_unit_group(wave_defense_table) then return end
end
end
function Public.build_worm()
local wave_defense_table = WD.get_table()
if wave_defense_table.threat < 512 then return end
if math_random(1, wave_defense_table.worm_building_chance) ~= 1 then return end
if #wave_defense_table.unit_groups == 0 then return end
local group = wave_defense_table.unit_groups[math_random(1, #wave_defense_table.unit_groups)]
if not group then return end
if not group.valid then return end
if not group.members then return end
if not group.members[1] then return end
local unit = group.members[math_random(1, #group.members)]
if not unit.valid then return end
local position = unit.surface.find_non_colliding_position("assembling-machine-1", unit.position, 8, 1)
BiterRolls.wave_defense_set_worm_raffle(wave_defense_table.wave_number)
local worm = BiterRolls.wave_defense_roll_worm_name()
if not position then return end
local r = wave_defense_table.worm_building_density
if unit.surface.count_entities_filtered({type = "turret", area = {{position.x - r, position.y - r},{position.x + r, position.y + r}}}) > 0 then return end
unit.surface.create_entity({name = worm, position = position, force = unit.force})
unit.surface.create_entity({name = "blood-explosion-huge", position = position})
unit.surface.create_entity({name = "blood-explosion-huge", position = unit.position})
remove_unit(unit)
unit.destroy()
wave_defense_table.threat = wave_defense_table.threat - threat_values[worm]
end
--[[
local function get_circle_vectors(radius)
local vectors = {}
for x = radius * -1, radius, 1 do
for y = radius * -1, radius, 1 do
if math.sqrt(x^2 + y^2) <= radius then
vectors[#vectors + 1] = {x, y}
end
end
end
return vectors
end
local acid_nova_entities = {
["small-biter"] = {projectile = "acid-stream-worm-small", vectors = get_circle_vectors(3), threat_cost = 32},
["medium-biter"] = {projectile = "acid-stream-worm-medium", vectors = get_circle_vectors(4), threat_cost = 64},
["big-biter"] = {projectile = "acid-stream-worm-big", vectors = get_circle_vectors(5), threat_cost = 96},
["behemoth-biter"] = {projectile = "acid-stream-worm-behemoth", vectors = get_circle_vectors(6), threat_cost = 128},
}
local function acid_nova(entity)
local wave_defense_table = WD.get_table()
if not acid_nova_entities[entity.name] then return end
if wave_defense_table.threat < 100000 then return end
if math.random(1, 32) ~= 1 then return end
for _ = 1, 8, 1 do
local i = math_random(1, #acid_nova_entities[entity.name].vectors)
entity.surface.create_entity({
name = acid_nova_entities[entity.name].projectile,
position = entity.position,
force = entity.force.name,
source = entity.position,
target = {x = entity.position.x + acid_nova_entities[entity.name].vectors[i][1], y = entity.position.y + acid_nova_entities[entity.name].vectors[i][2]},
max_range = 10,
speed = 0.001
})
end
wave_defense_table.threat = wave_defense_table.threat - acid_nova_entities[entity.name].threat_cost
return true
end
]]
local function shred_simple_entities(entity)
local wave_defense_table = WD.get_table()
if wave_defense_table.threat < 25000 then return end
local simple_entities = entity.surface.find_entities_filtered({type = "simple-entity", area = {{entity.position.x - 3, entity.position.y - 3},{entity.position.x + 3, entity.position.y + 3}}})
if #simple_entities == 0 then return end
if #simple_entities > 1 then table.shuffle_table(simple_entities) end
local r = math.floor(wave_defense_table.threat * 0.00004)
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
if simple_entities[i].valid then
if simple_entities[i].health then
damage_dealt = damage_dealt + simple_entities[i].health
simple_entities[i].die("neutral", simple_entities[i])
end
end
end
if damage_dealt == 0 then return end
local threat_cost = math.floor(damage_dealt * wave_defense_table.simple_entity_shredding_cost_modifier)
if threat_cost < 1 then threat_cost = 1 end
wave_defense_table.threat = wave_defense_table.threat - threat_cost
end
local function spawn_unit_spawner_inhabitants(wave_defense_table, entity)
if entity.type ~= "unit-spawner" then return end
local count = 8 + math.floor(wave_defense_table.wave_number * 0.02)
if count > 128 then count = 128 end
BiterRolls.wave_defense_set_unit_raffle(wave_defense_table.wave_number)
for _ = 1, count, 1 do
local position = {entity.position.x + (-4 + math.random(0, 8)), entity.position.y + (-4 + math.random(0, 8))}
if math.random(1,4) == 1 then
entity.surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position, force = "enemy"})
else
entity.surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position, force = "enemy"})
end
end
end
local function on_entity_died(event)
local wave_defense_table = WD.get_table()
local entity = event.entity
if not entity.valid then return end
if entity.type == "unit" then
if not threat_values[entity.name] then return end
wave_defense_table.threat = math.round(wave_defense_table.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
wave_defense_table.threat = math.round(wave_defense_table.threat - threat_values[entity.name] * global.biter_health_boost, 2)
end
spawn_unit_spawner_inhabitants(wave_defense_table, entity)
end
end
end
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(entity)
end
end
end
end
end
local event = require 'utils.event'
event.add(defines.events.on_entity_died, on_entity_died)
return Public