mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-02-09 13:37:02 +02:00
wave defense table lookups
This commit is contained in:
parent
88f46983af
commit
dc3b62ed85
@ -1,105 +1,129 @@
|
||||
local WD = require "modules.wave_defense.table"
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
|
||||
local Public = {}
|
||||
|
||||
function Public.wave_defense_roll_biter_name()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local max_chance = 0
|
||||
for k, v in pairs(wave_defense_table.biter_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(wave_defense_table.biter_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then return k end
|
||||
end
|
||||
local biter_raffle = WD.get('biter_raffle')
|
||||
local max_chance = 0
|
||||
for k, v in pairs(biter_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(biter_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.wave_defense_roll_spitter_name()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local max_chance = 0
|
||||
for k, v in pairs(wave_defense_table.spitter_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(wave_defense_table.spitter_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then return k end
|
||||
end
|
||||
local spitter_raffle = WD.get('biter_raffle')
|
||||
local max_chance = 0
|
||||
for k, v in pairs(spitter_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(spitter_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.wave_defense_set_unit_raffle(level)
|
||||
local wave_defense_table = WD.get_table()
|
||||
wave_defense_table.biter_raffle = {
|
||||
["small-biter"] = 1000 - level * 1.75,
|
||||
["medium-biter"] = level,
|
||||
["big-biter"] = 0,
|
||||
["behemoth-biter"] = 0,
|
||||
}
|
||||
wave_defense_table.spitter_raffle = {
|
||||
["small-spitter"] = 1000 - level * 1.75,
|
||||
["medium-spitter"] = level,
|
||||
["big-spitter"] = 0,
|
||||
["behemoth-spitter"] = 0,
|
||||
}
|
||||
if level > 500 then
|
||||
wave_defense_table.biter_raffle["medium-biter"] = 500 - (level - 500)
|
||||
wave_defense_table.spitter_raffle["medium-spitter"] = 500 - (level - 500)
|
||||
wave_defense_table.biter_raffle["big-biter"] = (level - 500) * 2
|
||||
wave_defense_table.spitter_raffle["big-spitter"] = (level - 500) * 2
|
||||
end
|
||||
if level > 800 then
|
||||
wave_defense_table.biter_raffle["behemoth-biter"] = (level - 800) * 2.75
|
||||
wave_defense_table.spitter_raffle["behemoth-spitter"] = (level - 800) * 2.75
|
||||
end
|
||||
for k, v in pairs(wave_defense_table.biter_raffle) do
|
||||
if wave_defense_table.biter_raffle[k] < 0 then wave_defense_table.biter_raffle[k] = 0 end
|
||||
end
|
||||
for k, v in pairs(wave_defense_table.spitter_raffle) do
|
||||
if wave_defense_table.spitter_raffle[k] < 0 then wave_defense_table.spitter_raffle[k] = 0 end
|
||||
end
|
||||
WD.set(
|
||||
'biter_raffle',
|
||||
{
|
||||
['small-biter'] = 1000 - level * 1.75,
|
||||
['medium-biter'] = level,
|
||||
['big-biter'] = 0,
|
||||
['behemoth-biter'] = 0
|
||||
}
|
||||
)
|
||||
|
||||
WD.set(
|
||||
'spitter_raffle',
|
||||
{
|
||||
['small-spitter'] = 1000 - level * 1.75,
|
||||
['medium-spitter'] = level,
|
||||
['big-spitter'] = 0,
|
||||
['behemoth-spitter'] = 0
|
||||
}
|
||||
)
|
||||
local biter_raffle = WD.get('biter_raffle')
|
||||
local spitter_raffle = WD.get('spitter_raffle')
|
||||
if level > 500 then
|
||||
biter_raffle['medium-biter'] = 500 - (level - 500)
|
||||
spitter_raffle['medium-spitter'] = 500 - (level - 500)
|
||||
biter_raffle['big-biter'] = (level - 500) * 2
|
||||
spitter_raffle['big-spitter'] = (level - 500) * 2
|
||||
end
|
||||
if level > 800 then
|
||||
biter_raffle['behemoth-biter'] = (level - 800) * 2.75
|
||||
spitter_raffle['behemoth-spitter'] = (level - 800) * 2.75
|
||||
end
|
||||
for k, _ in pairs(biter_raffle) do
|
||||
if biter_raffle[k] < 0 then
|
||||
biter_raffle[k] = 0
|
||||
end
|
||||
end
|
||||
for k, _ in pairs(spitter_raffle) do
|
||||
if spitter_raffle[k] < 0 then
|
||||
spitter_raffle[k] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.wave_defense_roll_worm_name()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local max_chance = 0
|
||||
for k, v in pairs(wave_defense_table.worm_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(wave_defense_table.worm_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then return k end
|
||||
end
|
||||
local worm_raffle = WD.get('worm_raffle')
|
||||
local max_chance = 0
|
||||
for k, v in pairs(worm_raffle) do
|
||||
max_chance = max_chance + v
|
||||
end
|
||||
local r = math.random(0, math.floor(max_chance))
|
||||
local current_chance = 0
|
||||
for k, v in pairs(worm_raffle) do
|
||||
current_chance = current_chance + v
|
||||
if r <= current_chance then
|
||||
return k
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.wave_defense_set_worm_raffle(level)
|
||||
local wave_defense_table = WD.get_table()
|
||||
wave_defense_table.worm_raffle = {
|
||||
["small-worm-turret"] = 1000 - level * 1.75,
|
||||
["medium-worm-turret"] = level,
|
||||
["big-worm-turret"] = 0,
|
||||
["behemoth-worm-turret"] = 0,
|
||||
}
|
||||
if level > 500 then
|
||||
wave_defense_table.worm_raffle["medium-worm-turret"] = 500 - (level - 500)
|
||||
wave_defense_table.worm_raffle["big-worm-turret"] = (level - 500) * 2
|
||||
end
|
||||
if level > 800 then
|
||||
wave_defense_table.worm_raffle["behemoth-worm-turret"] = (level - 800) * 3
|
||||
end
|
||||
for k, v in pairs(wave_defense_table.worm_raffle) do
|
||||
if wave_defense_table.worm_raffle[k] < 0 then wave_defense_table.worm_raffle[k] = 0 end
|
||||
end
|
||||
WD.set(
|
||||
'worm_raffle',
|
||||
{
|
||||
['small-worm-turret'] = 1000 - level * 1.75,
|
||||
['medium-worm-turret'] = level,
|
||||
['big-worm-turret'] = 0,
|
||||
['behemoth-worm-turret'] = 0
|
||||
}
|
||||
)
|
||||
local worm_raffle = WD.get('worm_raffle')
|
||||
|
||||
if level > 500 then
|
||||
worm_raffle['medium-worm-turret'] = 500 - (level - 500)
|
||||
worm_raffle['big-worm-turret'] = (level - 500) * 2
|
||||
end
|
||||
if level > 800 then
|
||||
worm_raffle['behemoth-worm-turret'] = (level - 800) * 3
|
||||
end
|
||||
for k, _ in pairs(worm_raffle) do
|
||||
if worm_raffle[k] < 0 then
|
||||
worm_raffle[k] = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.wave_defense_print_chances(tbl)
|
||||
for k, v in pairs(tbl) do
|
||||
game.print(k .. " chance = " .. v)
|
||||
end
|
||||
for k, v in pairs(tbl) do
|
||||
game.print(k .. ' chance = ' .. v)
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
||||
return Public
|
||||
|
@ -96,7 +96,7 @@ local function spawn_biters(data)
|
||||
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position})
|
||||
end
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
if random(1, 64) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(unit, boosted_health, 0.38)
|
||||
end
|
||||
end
|
||||
|
@ -29,15 +29,13 @@ local function create_gui(player)
|
||||
label.style.left_padding = 4
|
||||
label.style.font_color = {r = 150, g = 0, b = 255}
|
||||
|
||||
local label =
|
||||
frame.add({type = 'label', caption = ' ', name = 'threat_value', tooltip = {'wave_defense.tooltip_1'}})
|
||||
local label = frame.add({type = 'label', caption = ' ', name = 'threat_value', tooltip = {'wave_defense.tooltip_1'}})
|
||||
label.style.font = 'default-bold'
|
||||
label.style.right_padding = 1
|
||||
label.style.minimal_width = 10
|
||||
label.style.font_color = {r = 150, g = 0, b = 255}
|
||||
|
||||
local label =
|
||||
frame.add({type = 'label', caption = ' ', name = 'threat_gains', tooltip = {'wave_defense.tooltip_2'}})
|
||||
local label = frame.add({type = 'label', caption = ' ', name = 'threat_gains', tooltip = {'wave_defense.tooltip_2'}})
|
||||
label.style.font = 'default'
|
||||
label.style.left_padding = 1
|
||||
label.style.right_padding = 1
|
||||
@ -45,21 +43,17 @@ end
|
||||
|
||||
--display threat gain/loss per minute during last 15 minutes
|
||||
local function get_threat_gain()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local past_index = wave_defense_table.threat_log_index - 900
|
||||
local threat_log_index = WD.get('threat_log_index')
|
||||
local threat_log = WD.get('threat_log')
|
||||
local past_index = threat_log_index - 900
|
||||
if past_index < 1 then
|
||||
past_index = 1
|
||||
end
|
||||
local gain =
|
||||
math.floor(
|
||||
(wave_defense_table.threat_log[wave_defense_table.threat_log_index] - wave_defense_table.threat_log[past_index]) /
|
||||
15
|
||||
)
|
||||
local gain = math.floor((threat_log[threat_log_index] - threat_log[past_index]) / 15)
|
||||
return gain
|
||||
end
|
||||
|
||||
local function update_gui(player)
|
||||
local wave_defense_table = WD.get_table()
|
||||
if not player.gui.top.wave_defense then
|
||||
create_gui(player)
|
||||
end
|
||||
@ -69,31 +63,38 @@ local function update_gui(player)
|
||||
biter_health_boost = global.biter_health_boost
|
||||
end
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
local next_wave = WD.get('next_wave')
|
||||
local last_wave = WD.get('last_wave')
|
||||
local max_active_biters = WD.get('max_active_biters')
|
||||
local threat = WD.get('threat')
|
||||
local enable_threat_log = WD.get('enable_threat_log')
|
||||
|
||||
gui.label.caption = {'wave_defense.gui_2'}
|
||||
gui.wave_number.caption = wave_defense_table.wave_number
|
||||
if wave_defense_table.wave_number == 0 then
|
||||
gui.wave_number.caption = wave_number
|
||||
if wave_number == 0 then
|
||||
gui.label.caption = {'wave_defense.gui_1'}
|
||||
gui.wave_number.caption = math.floor((wave_defense_table.next_wave - game.tick) / 60) + 1
|
||||
gui.wave_number.caption = math.floor((next_wave - game.tick) / 60) + 1
|
||||
end
|
||||
local interval = wave_defense_table.next_wave - wave_defense_table.last_wave
|
||||
gui.progressbar.value = 1 - (wave_defense_table.next_wave - game.tick) / interval
|
||||
local interval = next_wave - last_wave
|
||||
gui.progressbar.value = 1 - (next_wave - game.tick) / interval
|
||||
|
||||
gui.threat.caption = {'wave_defense.gui_3'}
|
||||
gui.threat.tooltip = {'wave_defense.tooltip_1', biter_health_boost * 100, wave_defense_table.max_active_biters}
|
||||
gui.threat_value.caption = math.floor(wave_defense_table.threat)
|
||||
gui.threat.tooltip = {'wave_defense.tooltip_1', biter_health_boost * 100, max_active_biters}
|
||||
gui.threat_value.caption = math.floor(threat)
|
||||
gui.threat_value.tooltip = {
|
||||
'wave_defense.tooltip_1',
|
||||
biter_health_boost * 100,
|
||||
wave_defense_table.max_active_biters
|
||||
max_active_biters
|
||||
}
|
||||
|
||||
if wave_defense_table.wave_number == 0 then
|
||||
if wave_number == 0 then
|
||||
gui.threat_gains.caption = ''
|
||||
return
|
||||
end
|
||||
if wave_defense_table.enable_threat_log then
|
||||
if enable_threat_log then
|
||||
local gain = get_threat_gain()
|
||||
local d = wave_defense_table.wave_number / 75
|
||||
local d = wave_number / 75
|
||||
|
||||
if gain >= 0 then
|
||||
gui.threat_gains.caption = ' (+' .. gain .. ')'
|
||||
|
@ -94,7 +94,7 @@ local function remove_rocks(entity)
|
||||
end
|
||||
|
||||
local function is_unit_valid(biter)
|
||||
local this = WD.get()
|
||||
local max_biter_age = WD.get('max_biter_age')
|
||||
if not biter.entity then
|
||||
debug_print('is_unit_valid - unit destroyed - does no longer exist')
|
||||
return false
|
||||
@ -107,7 +107,7 @@ local function is_unit_valid(biter)
|
||||
debug_print('is_unit_valid - unit destroyed - no unitgroup')
|
||||
return false
|
||||
end
|
||||
if biter.spawn_tick + this.max_biter_age < game.tick then
|
||||
if biter.spawn_tick + max_biter_age < game.tick then
|
||||
debug_print('is_unit_valid - unit destroyed - timed out')
|
||||
return false
|
||||
end
|
||||
@ -115,54 +115,59 @@ local function is_unit_valid(biter)
|
||||
end
|
||||
|
||||
local function refresh_active_unit_threat()
|
||||
local this = WD.get()
|
||||
debug_print('refresh_active_unit_threat - current value ' .. this.active_biter_threat)
|
||||
local active_biter_threat = 0
|
||||
for k, biter in pairs(this.active_biters) do
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
local active_biters = WD.get('active_biters')
|
||||
debug_print('refresh_active_unit_threat - current value ' .. active_biter_threat)
|
||||
local biter_threat = 0
|
||||
for k, biter in pairs(active_biters) do
|
||||
if biter.entity then
|
||||
if biter.entity.valid then
|
||||
active_biter_threat = active_biter_threat + threat_values[biter.entity.name]
|
||||
biter_threat = biter_threat + threat_values[biter.entity.name]
|
||||
end
|
||||
end
|
||||
end
|
||||
this.active_biter_threat = math_round(active_biter_threat * global.biter_health_boost, 2)
|
||||
debug_print('refresh_active_unit_threat - new value ' .. this.active_biter_threat)
|
||||
active_biter_threat = math_round(biter_threat * global.biter_health_boost, 2)
|
||||
debug_print('refresh_active_unit_threat - new value ' .. active_biter_threat)
|
||||
end
|
||||
|
||||
local function time_out_biters()
|
||||
local this = WD.get()
|
||||
for k, biter in pairs(this.active_biters) do
|
||||
local active_biters = WD.get('active_biters')
|
||||
local active_biter_count = WD.get('active_biter_count')
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
for k, biter in pairs(active_biters) do
|
||||
if not is_unit_valid(biter) then
|
||||
this.active_biter_count = this.active_biter_count - 1
|
||||
active_biter_count = active_biter_count - 1
|
||||
if biter.entity then
|
||||
if biter.entity.valid then
|
||||
this.active_biter_threat =
|
||||
this.active_biter_threat -
|
||||
math_round(threat_values[biter.entity.name] * global.biter_health_boost, 2)
|
||||
WD.set(
|
||||
'active_biter_threat',
|
||||
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
|
||||
end
|
||||
end
|
||||
this.active_biters[k] = nil
|
||||
active_biters[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_random_close_spawner()
|
||||
local this = WD.get()
|
||||
local spawners = this.nests
|
||||
local center = this.target.position
|
||||
local nests = WD.get('nests')
|
||||
local target = WD.get('target')
|
||||
local get_random_close_spawner_attempts = WD.get('get_random_close_spawner_attempts')
|
||||
local center = target.position
|
||||
local spawner
|
||||
for i = 1, this.get_random_close_spawner_attempts, 1 do
|
||||
for i = 1, get_random_close_spawner_attempts, 1 do
|
||||
::retry::
|
||||
if #spawners < 1 then
|
||||
if #nests < 1 then
|
||||
return false
|
||||
end
|
||||
local k = math_random(1, #spawners)
|
||||
local spawner_2 = spawners[k]
|
||||
local k = math_random(1, #nests)
|
||||
local spawner_2 = nests[k]
|
||||
if not spawner_2 or not spawner_2.valid then
|
||||
this.nests[k] = nil
|
||||
nests[k] = nil
|
||||
goto retry
|
||||
end
|
||||
if
|
||||
@ -177,13 +182,14 @@ local function get_random_close_spawner()
|
||||
return spawner
|
||||
end
|
||||
|
||||
local function get_random_character(this)
|
||||
local function get_random_character()
|
||||
local characters = {}
|
||||
local surface_index = WD.get('surface_index')
|
||||
local p = game.connected_players
|
||||
for _, player in pairs(p) do
|
||||
if player.character then
|
||||
if player.character.valid then
|
||||
if player.character.surface.index == this.surface_index then
|
||||
if player.character.surface.index == surface_index then
|
||||
characters[#characters + 1] = player.character
|
||||
end
|
||||
end
|
||||
@ -196,30 +202,29 @@ local function get_random_character(this)
|
||||
end
|
||||
|
||||
local function set_main_target()
|
||||
local this = WD.get()
|
||||
if this.target then
|
||||
if this.target.valid then
|
||||
local target = WD.get('target')
|
||||
if target then
|
||||
if target.valid then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local target = SideTargets.get_side_target()
|
||||
if not target then
|
||||
target = get_random_character(this)
|
||||
local sec_target = SideTargets.get_side_target()
|
||||
if not sec_target then
|
||||
sec_target = get_random_character()
|
||||
end
|
||||
if not target then
|
||||
if not sec_target then
|
||||
return
|
||||
end
|
||||
|
||||
this.target = target
|
||||
WD.set('target', sec_target)
|
||||
debug_print(
|
||||
'set_main_target -- New main target ' ..
|
||||
target.name .. ' at position x' .. target.position.x .. ' y' .. target.position.y .. ' selected.'
|
||||
sec_target.name .. ' at position x' .. sec_target.position.x .. ' y' .. sec_target.position.y .. ' selected.'
|
||||
)
|
||||
end
|
||||
|
||||
local function set_group_spawn_position(surface)
|
||||
local this = WD.get()
|
||||
local spawner = get_random_close_spawner()
|
||||
if not spawner then
|
||||
return
|
||||
@ -228,62 +233,66 @@ local function set_group_spawn_position(surface)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
this.spawn_position = {x = position.x, y = position.y}
|
||||
debug_print(
|
||||
'set_group_spawn_position -- Changed position to x' ..
|
||||
this.spawn_position.x .. ' y' .. this.spawn_position.y .. '.'
|
||||
)
|
||||
WD.set('spawn_position', {x = position.x, y = position.y})
|
||||
local spawn_position = WD.get('spawn_position')
|
||||
debug_print('set_group_spawn_position -- Changed position to x' .. spawn_position.x .. ' y' .. spawn_position.y .. '.')
|
||||
end
|
||||
|
||||
local function set_enemy_evolution()
|
||||
local this = WD.get()
|
||||
local evolution_factor = this.wave_number * 0.001
|
||||
local biter_health_boost = 1
|
||||
local wave_number = WD.get('wave_number')
|
||||
local biter_health_boost = WD.get('biter_health_boost')
|
||||
local threat = WD.get('threat')
|
||||
local evolution_factor = wave_number * 0.001
|
||||
local biter_h_boost = 1
|
||||
--local damage_increase = 0
|
||||
|
||||
if evolution_factor > 1 then
|
||||
--damage_increase = damage_increase + (evolution_factor - 1)
|
||||
--biter_health_boost = biter_health_boost + (evolution_factor - 1) * 2
|
||||
evolution_factor = 1
|
||||
end
|
||||
|
||||
if this.biter_health_boost then
|
||||
biter_health_boost = math_round(this.biter_health_boost + (this.threat - 5000) * 0.000033, 3)
|
||||
if biter_health_boost then
|
||||
biter_h_boost = math_round(biter_health_boost + (threat - 5000) * 0.000033, 3)
|
||||
else
|
||||
biter_health_boost = math_round(biter_health_boost + (this.threat - 5000) * 0.000033, 3)
|
||||
biter_h_boost = math_round(biter_h_boost + (threat - 5000) * 0.000033, 3)
|
||||
end
|
||||
if biter_health_boost <= 1 then
|
||||
biter_health_boost = 1
|
||||
if biter_h_boost <= 1 then
|
||||
biter_h_boost = 1
|
||||
end
|
||||
--damage_increase = math_round(damage_increase + this.threat * 0.0000025, 3)
|
||||
--damage_increase = math_round(damage_increase + threat * 0.0000025, 3)
|
||||
|
||||
global.biter_health_boost = biter_health_boost
|
||||
global.biter_health_boost = biter_h_boost
|
||||
--game.forces.enemy.set_ammo_damage_modifier("melee", damage_increase)
|
||||
--game.forces.enemy.set_ammo_damage_modifier("biological", damage_increase)
|
||||
game.forces.enemy.evolution_factor = evolution_factor
|
||||
end
|
||||
|
||||
local function can_units_spawn()
|
||||
local this = WD.get()
|
||||
if this.threat <= 0 then
|
||||
local threat = WD.get('threat')
|
||||
|
||||
if threat <= 0 then
|
||||
debug_print('can_units_spawn - threat too low')
|
||||
return false
|
||||
end
|
||||
if this.active_biter_count >= this.max_active_biters then
|
||||
|
||||
local active_biter_count = WD.get('active_biter_count')
|
||||
local max_active_biters = WD.get('max_active_biters')
|
||||
if active_biter_count >= max_active_biters then
|
||||
debug_print('can_units_spawn - active biter count too high')
|
||||
return false
|
||||
end
|
||||
if this.active_biter_threat >= this.threat then
|
||||
debug_print('can_units_spawn - active biter threat too high (' .. this.active_biter_threat .. ')')
|
||||
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
if active_biter_threat >= threat then
|
||||
debug_print('can_units_spawn - active biter threat too high (' .. active_biter_threat .. ')')
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function get_active_unit_groups_count()
|
||||
local this = WD.get()
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
local count = 0
|
||||
for _, g in pairs(this.unit_groups) do
|
||||
for _, g in pairs(unit_groups) do
|
||||
if g.valid then
|
||||
if #g.members > 0 then
|
||||
count = count + 1
|
||||
@ -297,70 +306,109 @@ local function get_active_unit_groups_count()
|
||||
end
|
||||
|
||||
local function spawn_biter(surface, is_boss_biter)
|
||||
local this = WD.get()
|
||||
if not is_boss_biter then
|
||||
if not can_units_spawn() then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local boosted_health = global.biter_health_boost
|
||||
|
||||
local name
|
||||
if math_random(1, 100) > 73 then
|
||||
name = BiterRolls.wave_defense_roll_spitter_name()
|
||||
else
|
||||
name = BiterRolls.wave_defense_roll_biter_name()
|
||||
end
|
||||
local position = this.spawn_position
|
||||
local spawn_position = WD.get('spawn_position')
|
||||
|
||||
local position = spawn_position
|
||||
|
||||
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 = false
|
||||
biter.ai_settings.do_separation = true
|
||||
if this.remove_entities then
|
||||
biter.ai_settings.path_resolution_modifier = -5
|
||||
|
||||
local remove_entities = WD.get('remove_entities')
|
||||
|
||||
if remove_entities then
|
||||
remove_trees(biter)
|
||||
remove_rocks(biter)
|
||||
end
|
||||
if is_boss_biter then
|
||||
BiterHealthBooster.add_boss_unit(biter, global.biter_health_boost * 5, 0.35)
|
||||
local modified_boss_health = WD.get('modified_boss_health')
|
||||
if modified_boss_health then
|
||||
local wave_number = WD.get('wave_number')
|
||||
if boosted_health == 1 then
|
||||
boosted_health = 1.25
|
||||
end
|
||||
boosted_health = boosted_health * (wave_number * 0.05)
|
||||
local sum = boosted_health * 5
|
||||
debug_print('Boss Health Boosted: ' .. sum)
|
||||
if sum >= 150 then
|
||||
sum = 150
|
||||
end
|
||||
BiterHealthBooster.add_boss_unit(biter, sum, 0.55)
|
||||
else
|
||||
local sum = boosted_health * 5
|
||||
debug_print('Boss Health Boosted: ' .. sum)
|
||||
BiterHealthBooster.add_boss_unit(biter, sum, 0.55)
|
||||
end
|
||||
end
|
||||
this.active_biters[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
|
||||
this.active_biter_count = this.active_biter_count + 1
|
||||
this.active_biter_threat = this.active_biter_threat + math_round(threat_values[name] * global.biter_health_boost, 2)
|
||||
WD.set('active_biters')[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
|
||||
local active_biter_count = WD.get('active_biter_count')
|
||||
WD.set('active_biter_count', active_biter_count + 1)
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
WD.set('active_biter_threat', active_biter_threat + math_round(threat_values[name] * boosted_health, 2))
|
||||
return biter
|
||||
end
|
||||
|
||||
local function set_next_wave()
|
||||
local this = WD.get()
|
||||
this.wave_number = this.wave_number + 1
|
||||
local wave_number = WD.get('wave_number')
|
||||
WD.set('wave_number', wave_number + 1)
|
||||
wave_number = WD.get('wave_number')
|
||||
|
||||
local threat_gain = this.wave_number * this.threat_gain_multiplier
|
||||
if this.wave_number > 1000 then
|
||||
threat_gain = threat_gain * (this.wave_number * 0.001)
|
||||
local threat_gain_multiplier = WD.get('threat_gain_multiplier')
|
||||
local threat_gain = wave_number * threat_gain_multiplier
|
||||
if wave_number > 1000 then
|
||||
threat_gain = threat_gain * (wave_number * 0.001)
|
||||
end
|
||||
if this.wave_number % 25 == 0 then
|
||||
this.boss_wave = true
|
||||
this.boss_wave_warning = true
|
||||
if this.alert_boss_wave then
|
||||
local msg = 'Boss Wave: ' .. this.wave_number
|
||||
if wave_number % 25 == 0 then
|
||||
WD.set('boss_wave', true)
|
||||
WD.set('boss_wave_warning', true)
|
||||
local alert_boss_wave = WD.get('alert_boss_wave')
|
||||
local spawn_position = WD.get('spawn_position')
|
||||
if alert_boss_wave then
|
||||
local msg = 'Boss Wave: ' .. wave_number
|
||||
local pos = {
|
||||
position = this.spawn_position
|
||||
position = spawn_position
|
||||
}
|
||||
Alert.alert_all_players_location(pos, msg, {r = 0.8, g = 0.1, b = 0.1})
|
||||
end
|
||||
threat_gain = threat_gain * 2
|
||||
else
|
||||
if this.boss_wave_warning then
|
||||
this.boss_wave_warning = false
|
||||
local boss_wave_warning = WD.get('boss_wave_warning')
|
||||
if boss_wave_warning then
|
||||
WD.set('boss_wave_warning', false)
|
||||
end
|
||||
end
|
||||
|
||||
this.threat = this.threat + math_floor(threat_gain)
|
||||
if not this.wave_enforced then
|
||||
this.last_wave = this.next_wave
|
||||
this.next_wave = game.tick + this.wave_interval
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', threat + math_floor(threat_gain))
|
||||
|
||||
local wave_enforced = WD.get('wave_enforced')
|
||||
local next_wave = WD.get('next_wave')
|
||||
local wave_interval = WD.get('wave_interval')
|
||||
if not wave_enforced then
|
||||
WD.set('last_wave', next_wave)
|
||||
WD.set('next_wave', game.tick + wave_interval)
|
||||
end
|
||||
if this.clear_corpses then
|
||||
local surface = game.surfaces[this.surface_index]
|
||||
|
||||
local clear_corpses = WD.get('clear_corpses')
|
||||
if clear_corpses then
|
||||
local surface_index = WD.get('surface_index')
|
||||
local surface = game.surfaces[surface_index]
|
||||
for _, entity in pairs(surface.find_entities_filtered {type = 'corpse'}) do
|
||||
if math_random(1, 2) == 1 then
|
||||
entity.destroy()
|
||||
@ -370,9 +418,9 @@ local function set_next_wave()
|
||||
end
|
||||
|
||||
local function reform_group(group)
|
||||
local this = WD.get()
|
||||
local unit_group_command_step_length = WD.get('unit_group_command_step_length')
|
||||
local group_position = {x = group.position.x, y = group.position.y}
|
||||
local step_length = this.unit_group_command_step_length
|
||||
local step_length = unit_group_command_step_length
|
||||
local position = group.surface.find_non_colliding_position('biter-spawner', group_position, step_length, 4)
|
||||
if position then
|
||||
local new_group = group.surface.create_unit_group {position = position, force = group.force}
|
||||
@ -380,17 +428,22 @@ local function reform_group(group)
|
||||
new_group.add_member(biter)
|
||||
end
|
||||
debug_print('Creating new unit group, because old one was stuck.')
|
||||
this.unit_groups[new_group.group_number] = new_group
|
||||
this.index = this.index + 1
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
unit_groups[new_group.group_number] = new_group
|
||||
local index = WD.get('index')
|
||||
WD.set('index', index + 1)
|
||||
|
||||
return new_group
|
||||
else
|
||||
debug_print('Destroying stuck group.')
|
||||
if this.unit_groups[group.group_number] then
|
||||
table.remove(this.unit_groups, group.group_number)
|
||||
this.index = this.index - 1
|
||||
if this.index <= 0 then
|
||||
this.index = 0
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
if unit_groups[group.group_number] then
|
||||
table.remove(unit_groups, group.group_number)
|
||||
local index = WD.get('index')
|
||||
WD.set('index', index - 1)
|
||||
index = WD.get('index')
|
||||
if index <= 0 then
|
||||
WD.set('index', 0)
|
||||
end
|
||||
end
|
||||
group.destroy()
|
||||
@ -399,29 +452,31 @@ local function reform_group(group)
|
||||
end
|
||||
|
||||
local function get_commmands(group)
|
||||
local this = WD.get()
|
||||
local unit_group_command_step_length = WD.get('unit_group_command_step_length')
|
||||
local enable_side_target = WD.get('enable_side_target')
|
||||
local commands = {}
|
||||
local group_position = {x = group.position.x, y = group.position.y}
|
||||
local step_length = this.unit_group_command_step_length
|
||||
local step_length = unit_group_command_step_length
|
||||
|
||||
if math_random(1, 2) == 1 then
|
||||
if not enable_side_target then
|
||||
goto continue
|
||||
end
|
||||
local side_target = SideTargets.get_side_target()
|
||||
if side_target then
|
||||
local target_position = side_target.position
|
||||
local distance_to_target =
|
||||
math_floor(
|
||||
math_sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2)
|
||||
)
|
||||
math_floor(math_sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2))
|
||||
local steps = math_floor(distance_to_target / step_length) + 1
|
||||
local vector = {
|
||||
math_round((target_position.x - group_position.x) / steps, 3),
|
||||
math_round((target_position.y - group_position.y) / steps, 3)
|
||||
}
|
||||
|
||||
if this.debug then
|
||||
debug_print(
|
||||
'get_commmands - to side_target x' .. side_target.position.x .. ' y' .. side_target.position.y
|
||||
)
|
||||
local d = WD.get('debug')
|
||||
|
||||
if d then
|
||||
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
|
||||
@ -449,8 +504,7 @@ local function get_commmands(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
local position =
|
||||
group.surface.find_non_colliding_position('behemoth-biter', group_position, step_length, 4)
|
||||
local position = group.surface.find_non_colliding_position('behemoth-biter', group_position, step_length, 4)
|
||||
if position then
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
@ -489,7 +543,14 @@ local function get_commmands(group)
|
||||
end
|
||||
end
|
||||
|
||||
local target_position = this.target.position
|
||||
::continue::
|
||||
|
||||
local target = WD.get('target')
|
||||
if not (target and target.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local target_position = target.position
|
||||
|
||||
for i = 1, 4, 1 do
|
||||
local obstacles =
|
||||
@ -531,7 +592,7 @@ local function get_commmands(group)
|
||||
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack,
|
||||
target = this.target,
|
||||
target = target,
|
||||
distraction = defines.distraction.by_enemy
|
||||
}
|
||||
|
||||
@ -539,13 +600,14 @@ local function get_commmands(group)
|
||||
end
|
||||
|
||||
local function command_unit_group(group)
|
||||
local this = WD.get()
|
||||
if not this.unit_group_last_command[group.group_number] then
|
||||
this.unit_group_last_command[group.group_number] = game.tick - (this.unit_group_command_delay + 1)
|
||||
local unit_group_last_command = WD.get('unit_group_last_command')
|
||||
local unit_group_command_delay = WD.get('unit_group_command_delay')
|
||||
if not unit_group_last_command[group.group_number] then
|
||||
unit_group_last_command[group.group_number] = game.tick - (unit_group_command_delay + 1)
|
||||
end
|
||||
|
||||
if this.unit_group_last_command[group.group_number] then
|
||||
if this.unit_group_last_command[group.group_number] + this.unit_group_command_delay > game.tick then
|
||||
if unit_group_last_command[group.group_number] then
|
||||
if unit_group_last_command[group.group_number] + unit_group_command_delay > game.tick then
|
||||
return
|
||||
end
|
||||
end
|
||||
@ -562,56 +624,60 @@ local function command_unit_group(group)
|
||||
}
|
||||
)
|
||||
|
||||
this.unit_group_last_command[group.group_number] = game.tick
|
||||
unit_group_last_command[group.group_number] = game.tick
|
||||
end
|
||||
|
||||
local function give_commands_to_unit_groups()
|
||||
local this = WD.get()
|
||||
if this.index == 0 then
|
||||
local index = WD.get('index')
|
||||
if index == 0 then
|
||||
return
|
||||
end
|
||||
if not this.target then
|
||||
local target = WD.get('target')
|
||||
if not (target and target.valid) then
|
||||
return
|
||||
end
|
||||
if not this.target.valid then
|
||||
return
|
||||
end
|
||||
for k, group in pairs(this.unit_groups) do
|
||||
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
for k, group in pairs(unit_groups) do
|
||||
if not group.valid then
|
||||
this.unit_groups[k] = nil
|
||||
this.index = this.index - 1
|
||||
if this.index <= 0 then
|
||||
this.index = 0
|
||||
unit_groups[k] = nil
|
||||
WD.set('index', index - 1)
|
||||
index = WD.get('index')
|
||||
if index <= 0 then
|
||||
WD.set('index', 0)
|
||||
end
|
||||
if this.unit_group_last_command[k] then
|
||||
this.unit_group_last_command[k] = nil
|
||||
local unit_group_last_command = WD.get('unit_group_last_command')
|
||||
if unit_group_last_command[k] then
|
||||
unit_group_last_command[k] = nil
|
||||
end
|
||||
end
|
||||
if type(group) ~= 'number' then
|
||||
if group.valid then
|
||||
command_unit_group(group, this)
|
||||
command_unit_group(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_unit_group()
|
||||
local this = WD.get()
|
||||
if not can_units_spawn() then
|
||||
return
|
||||
end
|
||||
if not this.target then
|
||||
local target = WD.get('target')
|
||||
if not (target and target.valid) then
|
||||
return
|
||||
end
|
||||
if not this.target.valid then
|
||||
|
||||
local max_active_unit_groups = WD.get('max_active_unit_groups')
|
||||
if get_active_unit_groups_count() >= max_active_unit_groups then
|
||||
return
|
||||
end
|
||||
if get_active_unit_groups_count() >= this.max_active_unit_groups then
|
||||
return
|
||||
end
|
||||
local surface = game.surfaces[this.surface_index]
|
||||
local surface_index = WD.get('surface_index')
|
||||
local surface = game.surfaces[surface_index]
|
||||
set_group_spawn_position(surface)
|
||||
local pos = this.spawn_position
|
||||
|
||||
local spawn_position = WD.get('spawn_position')
|
||||
local pos = spawn_position
|
||||
if not surface.can_place_entity({name = 'behemoth-biter', position = pos}) then
|
||||
return
|
||||
end
|
||||
@ -624,16 +690,15 @@ local function spawn_unit_group()
|
||||
end
|
||||
end
|
||||
|
||||
BiterRolls.wave_defense_set_unit_raffle(this.wave_number)
|
||||
local wave_number = WD.get('wave_number')
|
||||
BiterRolls.wave_defense_set_unit_raffle(wave_number)
|
||||
|
||||
debug_print('Spawning unit group at x' .. this.spawn_position.x .. ' y' .. this.spawn_position.y)
|
||||
local position = this.spawn_position
|
||||
debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y)
|
||||
local position = spawn_position
|
||||
|
||||
local unit_group = surface.create_unit_group({position = position, force = 'enemy'})
|
||||
local group_size =
|
||||
math_floor(
|
||||
this.average_unit_group_size * group_size_modifier_raffle[math_random(1, group_size_modifier_raffle_size)]
|
||||
)
|
||||
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)
|
||||
if not biter then
|
||||
@ -642,10 +707,14 @@ local function spawn_unit_group()
|
||||
unit_group.add_member(biter)
|
||||
end
|
||||
|
||||
if this.boss_wave then
|
||||
local count = math_random(1, math_floor(this.wave_number * 0.01) + 2)
|
||||
if count > 8 then
|
||||
count = 8
|
||||
local boss_wave = WD.get('boss_wave')
|
||||
if boss_wave then
|
||||
local count = math_random(1, math_floor(wave_number * 0.01) + 2)
|
||||
if count > 16 then
|
||||
count = 16
|
||||
end
|
||||
if count <= 1 then
|
||||
count = 4
|
||||
end
|
||||
for _ = 1, count, 1 do
|
||||
local biter = spawn_biter(surface, true)
|
||||
@ -654,22 +723,32 @@ local function spawn_unit_group()
|
||||
end
|
||||
unit_group.add_member(biter)
|
||||
end
|
||||
this.boss_wave = false
|
||||
WD.set('boss_wave', false)
|
||||
end
|
||||
this.unit_groups[unit_group.group_number] = unit_group
|
||||
|
||||
if unit_group then
|
||||
unit_group.start_moving()
|
||||
end
|
||||
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
unit_groups[unit_group.group_number] = unit_group
|
||||
if math_random(1, 2) == 1 then
|
||||
this.random_group = unit_group.group_number
|
||||
WD.set('random_group', unit_group.group_number)
|
||||
end
|
||||
this.index = this.index + 1
|
||||
local index = WD.get('index')
|
||||
WD.set('index', index + 1)
|
||||
return true
|
||||
end
|
||||
|
||||
local function log_threat()
|
||||
local this = WD.get()
|
||||
this.threat_log_index = this.threat_log_index + 1
|
||||
this.threat_log[this.threat_log_index] = this.threat
|
||||
if this.threat_log_index > 900 then
|
||||
this.threat_log[this.threat_log_index - 901] = nil
|
||||
local threat_log_index = WD.get('threat_log_index')
|
||||
WD.set('threat_log_index', threat_log_index + 1)
|
||||
local threat_log = WD.get('threat_log')
|
||||
local threat = WD.get('threat')
|
||||
threat_log_index = WD.get('threat_log_index')
|
||||
threat_log[threat_log_index] = threat
|
||||
if threat_log_index > 900 then
|
||||
threat_log[threat_log_index - 901] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -685,17 +764,19 @@ local tick_tasks = {
|
||||
}
|
||||
|
||||
local function on_tick()
|
||||
local this = WD.get()
|
||||
if this.game_lost then
|
||||
local tick = game.tick
|
||||
local game_lost = WD.get('game_lost')
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
|
||||
if game.tick > this.next_wave then
|
||||
local next_wave = WD.get('next_wave')
|
||||
if tick > next_wave then
|
||||
set_next_wave()
|
||||
end
|
||||
|
||||
local t = game.tick % 300
|
||||
local t2 = game.tick % 18000
|
||||
local t = tick % 300
|
||||
local t2 = tick % 18000
|
||||
|
||||
if tick_tasks[t] then
|
||||
tick_tasks[t]()
|
||||
@ -704,8 +785,9 @@ local function on_tick()
|
||||
tick_tasks[t2]()
|
||||
end
|
||||
|
||||
if this.enable_threat_log then
|
||||
if game.tick % 60 == 0 then
|
||||
local enable_threat_log = WD.get('enable_threat_log')
|
||||
if enable_threat_log then
|
||||
if tick % 60 == 0 then
|
||||
log_threat()
|
||||
end
|
||||
end
|
||||
|
@ -17,28 +17,35 @@ local side_target_types = {
|
||||
['solar-panel'] = true
|
||||
}
|
||||
|
||||
local function get_random_target(wave_defense_table)
|
||||
local r = math.random(1, wave_defense_table.side_target_count)
|
||||
if not wave_defense_table.side_targets[r] then
|
||||
table.remove(wave_defense_table.side_targets, r)
|
||||
wave_defense_table.side_target_count = wave_defense_table.side_target_count - 1
|
||||
local function get_random_target()
|
||||
local side_target_count = WD.get('side_target_count')
|
||||
local side_targets = WD.get('side_targets')
|
||||
local r = math.random(1, side_target_count)
|
||||
if not side_targets[r] then
|
||||
table.remove(side_targets, r)
|
||||
WD.set('side_target_count', side_target_count - 1)
|
||||
return
|
||||
end
|
||||
if not wave_defense_table.side_targets[r].valid then
|
||||
table.remove(wave_defense_table.side_targets, r)
|
||||
wave_defense_table.side_target_count = wave_defense_table.side_target_count - 1
|
||||
if not side_targets[r].valid then
|
||||
table.remove(side_targets, r)
|
||||
WD.set('side_target_count', side_target_count - 1)
|
||||
return
|
||||
end
|
||||
return wave_defense_table.side_targets[r]
|
||||
side_targets = WD.get('side_targets')
|
||||
return side_targets[r]
|
||||
end
|
||||
|
||||
function Public.get_side_target()
|
||||
local wave_defense_table = WD.get_table()
|
||||
local enable_side_target = WD.get('enable_side_target')
|
||||
if not enable_side_target then
|
||||
return
|
||||
end
|
||||
local side_target_count = WD.get('side_target_count')
|
||||
for _ = 1, 512, 1 do
|
||||
if wave_defense_table.side_target_count == 0 then
|
||||
if side_target_count == 0 then
|
||||
return
|
||||
end
|
||||
local target = get_random_target(wave_defense_table)
|
||||
local target = get_random_target()
|
||||
if target then
|
||||
return target
|
||||
end
|
||||
@ -46,19 +53,27 @@ function Public.get_side_target()
|
||||
end
|
||||
|
||||
local function add_entity(entity)
|
||||
local wave_defense_table = WD.get_table()
|
||||
local enable_side_target = WD.get('enable_side_target')
|
||||
|
||||
if not enable_side_target then
|
||||
return
|
||||
end
|
||||
|
||||
local surface_index = WD.get('surface_index')
|
||||
--skip entities that are on another surface
|
||||
if entity.surface.index ~= wave_defense_table.surface_index then
|
||||
return
|
||||
end
|
||||
if wave_defense_table.side_target_count >= 512 then
|
||||
if entity.surface.index ~= surface_index then
|
||||
return
|
||||
end
|
||||
|
||||
local side_target_count = WD.get('side_target_count')
|
||||
if side_target_count >= 512 then
|
||||
return
|
||||
end
|
||||
|
||||
local side_targets = WD.get('side_targets')
|
||||
--add entity to the side target list
|
||||
table.insert(wave_defense_table.side_targets, entity)
|
||||
wave_defense_table.side_target_count = wave_defense_table.side_target_count + 1
|
||||
table.insert(side_targets, entity)
|
||||
WD.set('side_target_count', side_target_count + 1)
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
|
@ -63,9 +63,11 @@ function Public.reset_wave_defense()
|
||||
this.biter_health_boost = 1
|
||||
this.alert_boss_wave = false
|
||||
this.remove_entities = false
|
||||
this.enable_side_target = false
|
||||
this.enable_threat_log = true
|
||||
this.disable_threat_below_zero = false
|
||||
this.check_collapse_position = true
|
||||
this.modified_boss_health = true
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
@ -77,11 +79,11 @@ function Public.get(key)
|
||||
end
|
||||
|
||||
function Public.set(key, value)
|
||||
if key then
|
||||
return this[key]
|
||||
elseif key and value then
|
||||
if key and (value or value == false) then
|
||||
this[key] = value
|
||||
return this[key]
|
||||
elseif key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
@ -90,10 +92,8 @@ end
|
||||
Public.get_table = Public.get
|
||||
|
||||
function Public.clear_corpses(value)
|
||||
if value then
|
||||
if (value or value == false) then
|
||||
this.clear_corpses = value
|
||||
else
|
||||
this.clear_corpses = false
|
||||
end
|
||||
return this.clear_corpses
|
||||
end
|
||||
@ -106,11 +106,9 @@ function Public.get_disable_threat_below_zero()
|
||||
return this.disable_threat_below_zero
|
||||
end
|
||||
|
||||
function Public.set_disable_threat_below_zero(value)
|
||||
if value then
|
||||
this.disable_threat_below_zero = value
|
||||
else
|
||||
this.disable_threat_below_zero = false
|
||||
function Public.set_disable_threat_below_zero(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.disable_threat_below_zero = boolean
|
||||
end
|
||||
return this.disable_threat_below_zero
|
||||
end
|
||||
@ -119,54 +117,60 @@ function Public.get_alert_boss_wave()
|
||||
return this.get_alert_boss_wave
|
||||
end
|
||||
|
||||
function Public.alert_boss_wave(value)
|
||||
if value then
|
||||
this.alert_boss_wave = value
|
||||
else
|
||||
this.alert_boss_wave = false
|
||||
function Public.alert_boss_wave(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.alert_boss_wave = boolean
|
||||
end
|
||||
return this.alert_boss_wave
|
||||
end
|
||||
|
||||
function Public.set_spawn_position(value)
|
||||
if type(value) == 'table' then
|
||||
this.spawn_position = value
|
||||
function Public.set_spawn_position(tbl)
|
||||
if type(tbl) == 'table' then
|
||||
this.spawn_position = tbl
|
||||
else
|
||||
error('Value must be of type table.')
|
||||
error('Tbl must be of type table.')
|
||||
end
|
||||
return this.spawn_position
|
||||
end
|
||||
|
||||
function Public.remove_entities(value)
|
||||
if value then
|
||||
this.remove_entities = value
|
||||
else
|
||||
this.remove_entities = false
|
||||
function Public.remove_entities(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.remove_entities = boolean
|
||||
end
|
||||
return this.remove_entities
|
||||
end
|
||||
|
||||
function Public.enable_threat_log(value)
|
||||
if value then
|
||||
this.enable_threat_log = value
|
||||
else
|
||||
this.enable_threat_log = false
|
||||
function Public.enable_threat_log(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.enable_threat_log = boolean
|
||||
end
|
||||
return this.enable_threat_log
|
||||
end
|
||||
|
||||
function Public.check_collapse_position(value)
|
||||
if value then
|
||||
this.check_collapse_position = value
|
||||
else
|
||||
this.check_collapse_position = false
|
||||
function Public.check_collapse_position(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.check_collapse_position = boolean
|
||||
end
|
||||
return this.check_collapse_position
|
||||
end
|
||||
|
||||
function Public.set_biter_health_boost(value)
|
||||
if value and type(value) == 'number' then
|
||||
this.biter_health_boost = value
|
||||
function Public.enable_side_target(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.enable_side_target = boolean
|
||||
end
|
||||
return this.enable_side_target
|
||||
end
|
||||
|
||||
function Public.modified_boss_health(boolean)
|
||||
if (boolean or boolean == false) then
|
||||
this.modified_boss_health = boolean
|
||||
end
|
||||
return this.modified_boss_health
|
||||
end
|
||||
|
||||
function Public.set_biter_health_boost(number)
|
||||
if number and type(number) == 'number' then
|
||||
this.biter_health_boost = number
|
||||
else
|
||||
this.biter_health_boost = 1
|
||||
end
|
||||
|
@ -1,14 +1,15 @@
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local threat_values = require 'modules.wave_defense.threat_values'
|
||||
local Event = require 'utils.event'
|
||||
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 active_biters = WD.get('active_biters')
|
||||
local unit_number = entity.unit_number
|
||||
if not wave_defense_table.active_biters[unit_number] then
|
||||
if not active_biters[unit_number] then
|
||||
return
|
||||
end
|
||||
local m = 1
|
||||
@ -16,13 +17,17 @@ local function remove_unit(entity)
|
||||
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
|
||||
local active_biter_threat = WD.get('active_biter_threat')
|
||||
WD.set('active_biter_threat', active_biter_threat - active_threat_loss)
|
||||
local active_biter_count = WD.get('active_biter_count')
|
||||
WD.set('active_biter_count', active_biter_count - 1)
|
||||
active_biters[unit_number] = nil
|
||||
end
|
||||
|
||||
local function place_nest_near_unit_group(wave_defense_table)
|
||||
local group = wave_defense_table.unit_groups[wave_defense_table.random_group]
|
||||
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 group then
|
||||
return
|
||||
end
|
||||
@ -47,7 +52,7 @@ local function place_nest_near_unit_group(wave_defense_table)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
local r = wave_defense_table.nest_building_density
|
||||
local r = WD.get('nest_building_density')
|
||||
if
|
||||
unit.surface.count_entities_filtered(
|
||||
{
|
||||
@ -60,42 +65,51 @@ local function place_nest_near_unit_group(wave_defense_table)
|
||||
return
|
||||
end
|
||||
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
|
||||
wave_defense_table.nests[#wave_defense_table.nests + 1] = spawner
|
||||
local nests = WD.get('nests')
|
||||
nests[#nests + 1] = spawner
|
||||
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]
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', 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
|
||||
local threat = WD.get('threat')
|
||||
if threat < 1024 then
|
||||
return
|
||||
end
|
||||
if wave_defense_table.index == 0 then
|
||||
local index = WD.get('index')
|
||||
if index == 0 then
|
||||
return
|
||||
end
|
||||
for _ = 1, 2, 1 do
|
||||
if place_nest_near_unit_group(wave_defense_table) then
|
||||
if place_nest_near_unit_group() then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.build_worm()
|
||||
local wave_defense_table = WD.get_table()
|
||||
if wave_defense_table.threat < 512 then
|
||||
local threat = WD.get('threat')
|
||||
if threat < 512 then
|
||||
return
|
||||
end
|
||||
if math_random(1, wave_defense_table.worm_building_chance) ~= 1 then
|
||||
local worm_building_chance = WD.get('worm_building_chance')
|
||||
if math_random(1, worm_building_chance) ~= 1 then
|
||||
return
|
||||
end
|
||||
if wave_defense_table.index == 0 then
|
||||
|
||||
local index = WD.get('index')
|
||||
if index == 0 then
|
||||
return
|
||||
end
|
||||
local group = wave_defense_table.unit_groups[wave_defense_table.random_group]
|
||||
|
||||
local random_group = WD.get('random_group')
|
||||
local unit_groups = WD.get('unit_groups')
|
||||
local group = unit_groups[random_group]
|
||||
if not group then
|
||||
return
|
||||
end
|
||||
@ -112,13 +126,17 @@ function Public.build_worm()
|
||||
if not unit.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local wave_number = WD.get('wave_number')
|
||||
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)
|
||||
BiterRolls.wave_defense_set_worm_raffle(wave_number)
|
||||
local worm = BiterRolls.wave_defense_roll_worm_name()
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
local r = wave_defense_table.worm_building_density
|
||||
|
||||
local worm_building_density = WD.get('worm_building_density')
|
||||
local r = worm_building_density
|
||||
if
|
||||
unit.surface.count_entities_filtered(
|
||||
{
|
||||
@ -135,52 +153,12 @@ function Public.build_worm()
|
||||
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
|
||||
WD.set('threat', threat - threat_values[worm])
|
||||
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
|
||||
local threat = WD.get('threat')
|
||||
if threat < 25000 then
|
||||
return
|
||||
end
|
||||
local simple_entities =
|
||||
@ -196,7 +174,7 @@ local function shred_simple_entities(entity)
|
||||
if #simple_entities > 1 then
|
||||
table.shuffle_table(simple_entities)
|
||||
end
|
||||
local r = math.floor(wave_defense_table.threat * 0.00004)
|
||||
local r = math.floor(threat * 0.00004)
|
||||
if r < 1 then
|
||||
r = 1
|
||||
end
|
||||
@ -217,71 +195,67 @@ local function shred_simple_entities(entity)
|
||||
if damage_dealt == 0 then
|
||||
return
|
||||
end
|
||||
local threat_cost = math.floor(damage_dealt * wave_defense_table.simple_entity_shredding_cost_modifier)
|
||||
local simple_entity_shredding_cost_modifier = WD.get('simple_entity_shredding_cost_modifier')
|
||||
local threat_cost = math.floor(damage_dealt * simple_entity_shredding_cost_modifier)
|
||||
if threat_cost < 1 then
|
||||
threat_cost = 1
|
||||
end
|
||||
wave_defense_table.threat = wave_defense_table.threat - threat_cost
|
||||
WD.set('threat', threat - threat_cost)
|
||||
end
|
||||
|
||||
local function spawn_unit_spawner_inhabitants(wave_defense_table, entity)
|
||||
local function spawn_unit_spawner_inhabitants(entity)
|
||||
if entity.type ~= 'unit-spawner' then
|
||||
return
|
||||
end
|
||||
local count = 8 + math.floor(wave_defense_table.wave_number * 0.02)
|
||||
local wave_number = WD.get('wave_number')
|
||||
local count = 8 + math.floor(wave_number * 0.02)
|
||||
if count > 128 then
|
||||
count = 128
|
||||
end
|
||||
BiterRolls.wave_defense_set_unit_raffle(wave_defense_table.wave_number)
|
||||
BiterRolls.wave_defense_set_unit_raffle(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'}
|
||||
)
|
||||
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'}
|
||||
)
|
||||
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
|
||||
|
||||
local disable_threat_below_zero = WD.get('disable_threat_below_zero')
|
||||
if entity.type == 'unit' then
|
||||
--acid_nova(entity)
|
||||
if not threat_values[entity.name] then
|
||||
return
|
||||
end
|
||||
if wave_defense_table.disable_threat_below_zero then
|
||||
if wave_defense_table.threat <= 0 then
|
||||
wave_defense_table.threat = 0
|
||||
if disable_threat_below_zero then
|
||||
local threat = WD.get('threat')
|
||||
if threat <= 0 then
|
||||
WD.set('threat', 0)
|
||||
threat = WD.get('threat')
|
||||
end
|
||||
wave_defense_table.threat =
|
||||
math.round(wave_defense_table.threat - threat_values[entity.name] * global.biter_health_boost, 2)
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
remove_unit(entity)
|
||||
else
|
||||
wave_defense_table.threat =
|
||||
math.round(wave_defense_table.threat - threat_values[entity.name] * global.biter_health_boost, 2)
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
remove_unit(entity)
|
||||
end
|
||||
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
|
||||
)
|
||||
local threat = WD.get('threat')
|
||||
WD.set('threat', math.round(threat - threat_values[entity.name] * global.biter_health_boost, 2))
|
||||
end
|
||||
spawn_unit_spawner_inhabitants(wave_defense_table, entity)
|
||||
spawn_unit_spawner_inhabitants(entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -297,7 +271,6 @@ local function on_entity_died(event)
|
||||
end
|
||||
end
|
||||
|
||||
local event = require 'utils.event'
|
||||
event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
||||
return Public
|
||||
|
Loading…
x
Reference in New Issue
Block a user