1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-03 13:12:11 +02:00

Merge pull request #167 from ComfyFactory/rpg_wavedefense_refactor

Refactor of wave defense and changes to modules
This commit is contained in:
Gerkiz 2021-11-14 21:05:54 +01:00 committed by GitHub
commit 111403feae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 680 additions and 376 deletions

View File

@ -1,7 +1,7 @@
[mountain_fortress_v3]
map_info_main_caption=M O U N T A I N F O R T R E S S V3
map_info_sub_caption= ~~ diggy diggy choo choo ~~
map_info_text=[color=red]First, an announcement!\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz![/color]\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn additon, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the locomotive aura prevents biters from spawning when mining entities.\n\nRPG GUI is disabled inside the locomotive.\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the locomotive aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
map_info_text=[color=red]READ THIS!\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz!\nIf there are any game breaking bugs then this map might be shutdown to hot-fix the issue.[/color]\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn additon, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the locomotive aura prevents biters from spawning when mining entities.\n\nRPG GUI is disabled inside the locomotive.\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the locomotive aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
[breached_wall]
collapse_start=[color=blue]Mapkeeper:[/color]\nWarning, Collapse has begun!

View File

@ -4,7 +4,6 @@ local Server = require 'utils.server'
local WPT = require 'maps.mountain_fortress_v3.table'
local Collapse = require 'modules.collapse'
local WD = require 'modules.wave_defense.table'
local WDM = require 'modules.wave_defense.main'
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
@ -206,28 +205,4 @@ if _DEBUG then
end
end
)
commands.add_command(
'spawn_wave',
'Enabled only on SP',
function()
local p
local player = game.player
if game.is_multiplayer() then
return
end
if player and player.valid then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
WD.enable_debug()
WDM.spawn_unit_group(true)
p('Spawning wave!')
end
end
)
end

View File

@ -326,21 +326,21 @@ local function on_entity_damaged(event)
--Process boss unit health bars
local boss = health_pool[3]
if boss then
if boss.last_update + 10 < game.tick then
set_boss_healthbar(health_pool[1], boss.max_health, boss.healthbar_id)
boss.last_update = game.tick
end
if boss and boss.healthbar_id then
set_boss_healthbar(health_pool[1], boss.max_health, boss.healthbar_id)
end
--Reduce health pool
health_pool[1] = health_pool[1] - damage
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
biter.health = health_pool[1] * health_pool[2]
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(biter.prototype.max_health * m)
biter.health = final_health
--Proceed to kill entity if health is 0
if biter.health > 0 then
if biter.health > 0 and health_pool[1] > 0 then
return
end
@ -374,7 +374,7 @@ local function on_entity_died(event)
if health_pool then
Task.set_timeout_in_ticks(30, removeUnit, {unit_number = unit_number})
if health_pool[3] then
if health_pool[3] and health_pool[3].healthbar_id then
if this.enable_boss_loot then
if random(1, 128) == 1 then
LootDrop.drop_loot(biter, wave_count)
@ -445,10 +445,12 @@ function Public.add_unit(unit, health_multiplier)
if not health_multiplier then
health_multiplier = this.biter_health_boost
end
local health = floor(unit.prototype.max_health * health_multiplier)
local xp_modifier = round(1 / health_multiplier, 5)
this.biter_health_boost_units[unit.unit_number] = {
floor(unit.prototype.max_health * health_multiplier),
xp_modifier
health,
xp_modifier,
{max_health = health}
}
check_clear_table()
@ -470,7 +472,7 @@ function Public.add_boss_unit(unit, health_multiplier, health_bar_size)
this.biter_health_boost_units[unit.unit_number] = {
health,
xp_modifier,
{max_health = health, healthbar_id = create_boss_healthbar(unit, health_bar_size), last_update = game.tick}
{max_health = health, healthbar_id = create_boss_healthbar(unit, health_bar_size)}
}
check_clear_table()

View File

@ -1,4 +1,4 @@
local RPG = require 'modules.rpg.table'
local Public = require 'modules.rpg.table'
local Utils = require 'utils.core'
local Color = require 'utils.color_presets'
@ -7,7 +7,7 @@ local round = math.round
local validate_args = function(data)
local player = data.player
local target = data.target
local rpg_t = RPG.get_value_from_player(target.index)
local rpg_t = Public.get_value_from_player(target.index)
if not target then
return false
@ -66,7 +66,7 @@ local print_stats = function(target)
if not target then
return
end
local rpg_t = RPG.get_value_from_player(target.index)
local rpg_t = Public.get_value_from_player(target.index)
if not rpg_t then
return
end
@ -126,3 +126,79 @@ commands.add_command(
end
end
)
if _DEBUG then
commands.add_command(
'rpg_debug_module',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
Public.toggle_debug()
end
)
commands.add_command(
'rpg_debug_one_punch',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
Public.toggle_debug_one_punch()
end
)
commands.add_command(
'rpg_cheat_stats',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
local data = Public.get('rpg_t')
for k, _ in pairs(data) do
data[k].dexterity = 999
data[k].enable_entity_spawn = true
data[k].explosive_bullets = true
data[k].level = 500
data[k].magicka = 999
data[k].mana = 50000
data[k].mana_max = 50000
data[k].one_punch = true
data[k].stone_path = true
data[k].strength = 999
data[k].vitality = 999
data[k].xp = 456456
local p = game.get_player(k)
if p and p.valid then
Public.update_player_stats(p)
end
end
end
)
end
return Public

View File

@ -15,6 +15,7 @@ Public.settings = Settings
local Spells = require 'modules.rpg.spells'
Public.spells = Spells
require 'modules.rpg.commands'
local Commands = require 'modules.rpg.commands'
Public.commands = Commands
return Public

View File

@ -13,6 +13,7 @@ local points_per_level = Public.points_per_level
local settings_level = Public.gui_settings_levels
local floor = math.floor
local random = math.random
local round = math.round
--RPG Frames
local main_frame_name = Public.main_frame_name
@ -392,7 +393,7 @@ function Public.update_health(player)
local f = player.gui.screen[main_frame_name]
local data = Gui.get_data(f)
if data.health and data.health.valid then
data.health.caption = (math.round(player.character.health * 10) / 10)
data.health.caption = (round(player.character.health * 10) / 10)
end
local shield_gui = player.character.get_inventory(defines.inventory.character_armor)
if not shield_gui.is_empty() then
@ -496,6 +497,28 @@ function Public.get_melee_modifier(player)
return (rpg_t.strength - 10) * 0.10
end
function Public.get_final_damage_modifier(player)
local rpg_t = Public.get_value_from_player(player.index)
local rng = random(10, 35) * 0.01
return (rpg_t.strength - 10) * rng
end
function Public.get_final_damage(player, entity, original_damage_amount)
local modifier = Public.get_final_damage_modifier(player)
local damage = original_damage_amount + original_damage_amount * modifier
if entity.prototype.resistances then
if entity.prototype.resistances.physical then
damage = damage - entity.prototype.resistances.physical.decrease
damage = damage - damage * entity.prototype.resistances.physical.percent
end
end
damage = round(damage, 3)
if damage < 1 then
damage = 1
end
return damage
end
function Public.get_heal_modifier(player)
local rpg_t = Public.get_value_from_player(player.index)
return (rpg_t.vitality - 10) * 0.06
@ -554,7 +577,7 @@ function Public.get_one_punch_chance(player)
if rpg_t.strength < 100 then
return 0
end
local chance = math.round(rpg_t.strength * 0.01, 1)
local chance = round(rpg_t.strength * 0.012, 1)
if chance > 100 then
chance = 100
end
@ -564,7 +587,7 @@ end
function Public.get_extra_following_robots(player)
local rpg_t = Public.get_value_from_player(player.index)
local strength = rpg_t.strength
local count = math.round(strength / 2 * 0.03, 3)
local count = round(strength / 2 * 0.03, 3)
return count
end
@ -734,7 +757,7 @@ function Public.gain_xp(player, amount, added_to_pool, text)
Public.debug_log('RPG - ' .. player.name .. ' got org xp: ' .. amount)
local fee = amount - add_to_global_pool(amount, true)
Public.debug_log('RPG - ' .. player.name .. ' got fee: ' .. fee)
amount = math.round(amount, 3) - fee
amount = round(amount, 3) - fee
if rpg_extra.difficulty then
amount = amount + rpg_extra.difficulty
end
@ -743,7 +766,7 @@ function Public.gain_xp(player, amount, added_to_pool, text)
Public.debug_log('RPG - ' .. player.name .. ' got org xp: ' .. amount)
end
rpg_t.xp = math.round(rpg_t.xp + amount, 3)
rpg_t.xp = round(rpg_t.xp + amount, 3)
rpg_t.xp_since_last_floaty_text = rpg_t.xp_since_last_floaty_text + amount
if not experience_levels[rpg_t.level + 1] then

View File

@ -22,9 +22,18 @@ local main_frame_name = Public.main_frame_name
local sub = string.sub
local round = math.round
local floor = math.floor
local random = math.random
local abs = math.abs
local function log_one_punch(callback)
local debug = Public.get('rpg_extra').debug_one_punch
if not debug then
return
end
callback()
end
local function on_gui_click(event)
if not event then
return
@ -428,8 +437,96 @@ local function give_player_flameboots(player)
end
end
local function has_health_boost(entity, damage, final_damage_amount, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] + final_damage_amount)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
else
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
else
--Handle vanilla damage.
entity.health = entity.health + final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
end
return get_health_pool
end
local function set_health_boost(entity, damage, cause)
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
get_health_pool = health_pool[1]
--Set entity health relative to health pool
local max_health = health_pool[3].max_health
local m = health_pool[1] / max_health
local final_health = round(entity.prototype.max_health * m)
health_pool[1] = round(health_pool[1] - damage)
--Set entity health relative to health pool
entity.health = final_health
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
end
end
end
end
return get_health_pool
end
--Melee damage modifier
local function one_punch(character, target, damage)
local function one_punch(character, target, damage, get_health_pool)
if not (target and target.valid) then
return
end
local base_vector = {target.position.x - character.position.x, target.position.y - character.position.y}
local vector = {base_vector[1], base_vector[2]}
@ -473,7 +570,7 @@ local function one_punch(character, target, damage)
vector[1] = vector[1] * 1.5
vector[2] = vector[2] * 1.5
local a = 0.25
local a = 0.45
local cs = character.surface
local cp = character.position
@ -488,9 +585,35 @@ local function one_punch(character, target, damage)
if e.health then
if e.destructible and e.minable and e.force.index ~= 3 then
if e.force.index ~= character.force.index then
e.health = e.health - damage * 0.05
if e.health <= 0 then
e.die(e.force.name, character)
if get_health_pool then
local max_unit_health = floor(get_health_pool * 0.00015)
if max_unit_health <= 0 then
max_unit_health = 4
end
if max_unit_health >= 15 then
max_unit_health = 15
end
local final = floor(damage * max_unit_health)
character.surface.create_entity(
{
name = 'flying-text',
position = character.position,
text = '' .. final,
color = {255, 0, 0}
}
)
character.surface.create_entity({name = 'blood-explosion-huge', position = character.position})
set_health_boost(e, final, character)
if e.valid and e.health <= 0 and get_health_pool <= 0 then
e.die(e.force.name, character)
end
else
if e.valid then
e.health = e.health - damage * 0.05
if e.health <= 0 then
e.die(e.force.name, character)
end
end
end
end
end
@ -543,6 +666,8 @@ local function on_entity_damaged(event)
local entity = event.entity
local cause = event.cause
local original_damage_amount = event.original_damage_amount
local final_damage_amount = event.final_damage_amount
if
cause.get_inventory(defines.inventory.character_ammo)[cause.selected_gun_index].valid_for_read or
@ -594,31 +719,10 @@ local function on_entity_damaged(event)
cause.health = cause.health + Public.get_life_on_hit(cause.player)
--Calculate modified damage.
local damage = event.original_damage_amount + event.original_damage_amount * Public.get_melee_modifier(cause.player)
if entity.prototype.resistances then
if entity.prototype.resistances.physical then
damage = damage - entity.prototype.resistances.physical.decrease
damage = damage - damage * entity.prototype.resistances.physical.percent
end
end
damage = round(damage, 3)
if damage < 1 then
damage = 1
end
local damage = Public.get_final_damage(cause.player, entity, original_damage_amount)
local enable_one_punch = Public.get('rpg_extra').enable_one_punch
local rpg_t = Public.get_value_from_player(cause.player.index)
--Cause a one punch.
if enable_one_punch then
if rpg_t.one_punch then
if random(0, 999) < Public.get_one_punch_chance(cause.player) * 10 then
one_punch(cause, entity, damage) -- only kill the biters if their health is below or equal to zero
return
end
end
end
--Floating messages and particle effects.
if random(1, 7) == 1 then
damage = damage * random(250, 350) * 0.01
@ -644,38 +748,30 @@ local function on_entity_damaged(event)
)
end
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local get_health_pool = has_health_boost(entity, damage, final_damage_amount, cause)
--Handle the custom health pool of the biter health booster, if it is used in the map.
if biter_health_boost then
local health_pool = biter_health_boost_units[entity.unit_number]
if health_pool then
health_pool[1] = health_pool[1] + event.final_damage_amount
health_pool[1] = health_pool[1] - damage
--Set entity health relative to health pool
entity.health = health_pool[1] * health_pool[2]
if health_pool[1] <= 0 then
local entity_number = entity.unit_number
entity.die(entity.force.name, cause)
if biter_health_boost_units[entity_number] then
biter_health_boost_units[entity_number] = nil
--Cause a one punch.
if enable_one_punch then
if rpg_t.one_punch then
local chance = Public.get_one_punch_chance(cause.player) * 10
local chance_to_hit = random(0, 999)
local success = chance_to_hit < chance
log_one_punch(
function()
if success then
print('[OnePunch]: Chance: ' .. chance .. ' Chance to hit: ' .. chance_to_hit .. ' Success: true' .. ' Damage: ' .. damage)
else
print('[OnePunch]: Chance: ' .. chance .. ' Chance to hit: ' .. chance_to_hit .. ' Success: false' .. ' Damage: ' .. damage)
end
end
)
if success then
one_punch(cause, entity, damage, get_health_pool) -- only kill the biters if their health is below or equal to zero
return
end
return
end
end
--Handle vanilla damage.
entity.health = entity.health + event.final_damage_amount
entity.health = entity.health - damage
if entity.health <= 0 then
entity.die(cause.force.name, cause)
end
local is_explosive_bullets_enabled = Public.get_explosive_bullets()
if is_explosive_bullets_enabled then
Public.explosive_bullets(event)

View File

@ -36,7 +36,7 @@ local Public = {}
Public.points_per_level = 5
Public.experience_levels = {0}
for a = 1, 9999, 1 do
for a = 1, 4999, 1 do -- max level
Public.experience_levels[#Public.experience_levels + 1] = Public.experience_levels[#Public.experience_levels] + a * 8
end
@ -235,6 +235,17 @@ function Public.toggle_debug()
return this.rpg_extra.debug
end
--- Toggle debug - when you need to troubleshoot.
function Public.toggle_debug_one_punch()
if this.rpg_extra.debug_one_punch then
this.rpg_extra.debug_one_punch = false
else
this.rpg_extra.debug_one_punch = true
end
return this.rpg_extra.debug_one_punch
end
--- Debug only - when you need to troubleshoot.
---@param str <string>
function Public.debug_log(str)

View File

@ -1,9 +1,7 @@
local WD = require 'modules.wave_defense.table'
local Public = {}
local Public = require 'modules.wave_defense.table'
function Public.wave_defense_roll_biter_name()
local biter_raffle = WD.get('biter_raffle')
local biter_raffle = Public.get('biter_raffle')
local max_chance = 0
for k, v in pairs(biter_raffle) do
max_chance = max_chance + v
@ -19,7 +17,7 @@ function Public.wave_defense_roll_biter_name()
end
function Public.wave_defense_roll_spitter_name()
local spitter_raffle = WD.get('spitter_raffle')
local spitter_raffle = Public.get('spitter_raffle')
local max_chance = 0
for k, v in pairs(spitter_raffle) do
max_chance = max_chance + v
@ -35,7 +33,7 @@ function Public.wave_defense_roll_spitter_name()
end
function Public.wave_defense_set_unit_raffle(level)
WD.set(
Public.set(
'biter_raffle',
{
['small-biter'] = 1000 - level * 1.75,
@ -45,7 +43,7 @@ function Public.wave_defense_set_unit_raffle(level)
}
)
WD.set(
Public.set(
'spitter_raffle',
{
['small-spitter'] = 1000 - level * 1.75,
@ -55,8 +53,8 @@ function Public.wave_defense_set_unit_raffle(level)
}
)
local biter_raffle = WD.get('biter_raffle')
local spitter_raffle = WD.get('spitter_raffle')
local biter_raffle = Public.get('biter_raffle')
local spitter_raffle = Public.get('spitter_raffle')
if level > 500 then
biter_raffle['medium-biter'] = 500 - (level - 500)
spitter_raffle['medium-spitter'] = 500 - (level - 500)
@ -80,7 +78,7 @@ function Public.wave_defense_set_unit_raffle(level)
end
function Public.wave_defense_roll_worm_name()
local worm_raffle = WD.get('worm_raffle')
local worm_raffle = Public.get('worm_raffle')
local max_chance = 0
for k, v in pairs(worm_raffle) do
max_chance = max_chance + v
@ -96,7 +94,7 @@ function Public.wave_defense_roll_worm_name()
end
function Public.wave_defense_set_worm_raffle(level)
WD.set(
Public.set(
'worm_raffle',
{
['small-worm-turret'] = 1000 - level * 1.75,
@ -105,7 +103,7 @@ function Public.wave_defense_set_worm_raffle(level)
['behemoth-worm-turret'] = 0
}
)
local worm_raffle = WD.get('worm_raffle')
local worm_raffle = Public.get('worm_raffle')
if level > 500 then
worm_raffle['medium-worm-turret'] = 500 - (level - 500)

View File

@ -1,8 +1,7 @@
local Public = require 'modules.wave_defense.table'
local Event = require 'utils.event'
local Global = require 'utils.global'
local BiterRolls = require 'modules.wave_defense.biter_rolls'
local BiterHealthBooster = require 'modules.biter_health_booster'
local WD = require 'modules.wave_defense.table'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Diff = require 'modules.difficulty_vote_by_amount'
local traps = {}
@ -14,7 +13,6 @@ Global.register(
end
)
local Public = {}
local floor = math.floor
local random = math.random
local abs = math.abs
@ -62,7 +60,7 @@ local function spawn_biters(data)
local surface = data.surface
local position = data.position
local h = floor(abs(position.y))
local wave_number = WD.get('wave_number')
local wave_number = Public.get('wave_number')
local d = Diff.get()
if not position then
@ -87,13 +85,13 @@ local function spawn_biters(data)
boosted_health = boosted_health * 2
end
BiterRolls.wave_defense_set_unit_raffle(h * 0.20)
Public.wave_defense_set_unit_raffle(h * 0.20)
local unit
if random(1, 3) == 1 then
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position})
unit = surface.create_entity({name = Public.wave_defense_roll_spitter_name(), position = position})
else
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position})
unit = surface.create_entity({name = Public.wave_defense_roll_biter_name(), position = position})
end
if random(1, 45) == 1 then
@ -104,7 +102,7 @@ local function spawn_biters(data)
end
local function spawn_worms(data)
local wave_number = WD.get('wave_number')
local wave_number = Public.get('wave_number')
local d = Diff.get()
local m = 0.0015
if d.difficulty_vote_index then
@ -123,8 +121,8 @@ local function spawn_worms(data)
local surface = data.surface
local position = data.position
BiterRolls.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
local unit = surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = position})
Public.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
local unit = surface.create_entity({name = Public.wave_defense_roll_worm_name(), position = position})
if random(1, 45) == 1 then
BiterHealthBooster.add_unit(unit, boosted_health)

View File

@ -0,0 +1,44 @@
local Public = require 'modules.wave_defense.table'
if _DEBUG then
commands.add_command(
'wd_debug_module',
'',
function(cmd)
local player = game.player
local param = tostring(cmd.parameter)
if param == nil then
return
end
if not (player and player.valid) then
return
end
if not player.admin then
return
end
if param == 'spawn_wave' then
return Public.spawn_unit_group(true, true)
end
if param == 'log_all' then
return Public.toggle_debug()
end
if param == 'debug_health' then
local this = Public.get()
Public.toggle_debug_health()
this.next_wave = 1000
this.wave_interval = 200
this.wave_enforced = true
this.debug_only_on_wave_500 = true
end
end
)
end
return Public

View File

@ -0,0 +1,24 @@
local Public = require 'modules.wave_defense.table'
local Biter_Rolls = require 'modules.wave_defense.biter_rolls'
Public.biter_rolls = Biter_Rolls
local Buried_enemies = require 'modules.wave_defense.buried_enemies'
Public.buried_enemies = Buried_enemies
local Commands = require 'modules.wave_defense.commands'
Public.commands = Commands
local Gui = require 'modules.wave_defense.gui'
Public.gui = Gui
local Side_targets = require 'modules.wave_defense.side_targets'
Public.side_targets = Side_targets
local Threat_events = require 'modules.wave_defense.threat_events'
Public.threat_events = Threat_events
local Threat_values = require 'modules.wave_defense.threat_values'
Public.threat_value = Threat_values
return Public

View File

@ -1,4 +1,4 @@
local WD = require 'modules.wave_defense.table'
local Public = require 'modules.wave_defense.table'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local function create_gui(player)
@ -53,8 +53,8 @@ end
--display threat gain/loss per minute during last 15 minutes
local function get_threat_gain()
local threat_log_index = WD.get('threat_log_index')
local threat_log = WD.get('threat_log')
local threat_log_index = Public.get('threat_log_index')
local threat_log = Public.get('threat_log')
local past_index = threat_log_index - 900
if past_index < 1 then
past_index = 1
@ -63,7 +63,7 @@ local function get_threat_gain()
return gain
end
local function update_gui(player)
function Public.update_gui(player)
if not player.gui.top.wave_defense then
create_gui(player)
end
@ -74,12 +74,12 @@ local function update_gui(player)
biter_health_boost = biter_health_boosts
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')
local wave_number = Public.get('wave_number')
local next_wave = Public.get('next_wave')
local last_wave = Public.get('last_wave')
local max_active_biters = Public.get('max_active_biters')
local threat = Public.get('threat')
local enable_threat_log = Public.get('enable_threat_log')
gui.label.caption = {'wave_defense.gui_2'}
gui.wave_number.caption = wave_number
@ -125,4 +125,4 @@ local function update_gui(player)
end
end
return update_gui
return Public

View File

@ -1,15 +1,9 @@
local Public = require 'modules.wave_defense.core'
local Event = require 'utils.event'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Difficulty = require 'modules.difficulty_vote_by_amount'
local BiterRolls = require 'modules.wave_defense.biter_rolls'
local SideTargets = require 'modules.wave_defense.side_targets'
local ThreatEvent = require 'modules.wave_defense.threat_events'
local update_gui = require 'modules.wave_defense.gui'
local threat_values = require 'modules.wave_defense.threat_values'
local WD = require 'modules.wave_defense.table'
local Alert = require 'utils.alert'
local Public = {}
local math_random = math.random
local math_floor = math.floor
local table_insert = table.insert
@ -43,13 +37,21 @@ end
local group_size_modifier_raffle_size = #group_size_modifier_raffle
local function debug_print(msg)
local debug = WD.get('debug')
local debug = Public.get('debug')
if not debug then
return
end
print('WaveDefense: ' .. msg)
end
local function debug_print_health(msg)
local debug = Public.get('debug_health')
if not debug then
return
end
print('[HEALTHBOOSTER]: ' .. msg)
end
local function valid(userdata)
if not (userdata and userdata.valid) then
return false
@ -67,7 +69,7 @@ local function shuffle(tbl)
end
local function find_initial_spot(surface, position)
local spot = WD.get('spot')
local spot = Public.get('spot')
if not spot then
local pos = surface.find_non_colliding_position('rocket-silo', position, 128, 1)
if not pos then
@ -93,10 +95,10 @@ local function find_initial_spot(surface, position)
pos = position
end
WD.set('spot', pos)
Public.set('spot', pos)
return pos
else
spot = WD.get('spot')
spot = Public.get('spot')
return spot
end
end
@ -190,7 +192,7 @@ local function fill_tiles(entity, size)
end
local function get_spawn_pos()
local surface_index = WD.get('surface_index')
local surface_index = Public.get('surface_index')
local surface = game.surfaces[surface_index]
if not surface then
return debug_print('get_spawn_pos - surface was not valid?')
@ -200,11 +202,11 @@ local function get_spawn_pos()
::retry::
local initial_position = WD.get('spawn_position')
local initial_position = Public.get('spawn_position')
local located_position = find_initial_spot(surface, initial_position)
local valid_position = surface.find_non_colliding_position('stone-furnace', located_position, 32, 1)
local debug = WD.get('debug')
local debug = Public.get('debug')
if debug then
if valid_position then
local x = valid_position.x
@ -214,15 +216,15 @@ local function get_spawn_pos()
end
if not valid_position then
local remove_entities = WD.get('remove_entities')
local remove_entities = Public.get('remove_entities')
if remove_entities then
c = c + 1
valid_position = WD.get('spawn_position')
valid_position = Public.get('spawn_position')
debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
remove_trees({surface = surface, position = valid_position, valid = true})
remove_rocks({surface = surface, position = valid_position, valid = true})
fill_tiles({surface = surface, position = valid_position, valid = true})
WD.set('spot', 'nil')
Public.set('spot', 'nil')
if c == 5 then
return debug_print('get_spawn_pos - we could not find a spawning pos?')
end
@ -238,7 +240,7 @@ local function get_spawn_pos()
end
local function is_unit_valid(biter)
local max_biter_age = WD.get('max_biter_age')
local max_biter_age = Public.get('max_biter_age')
if not biter.entity then
debug_print('is_unit_valid - unit destroyed - does no longer exist')
return false
@ -259,39 +261,39 @@ local function is_unit_valid(biter)
end
local function refresh_active_unit_threat()
local active_biter_threat = WD.get('active_biter_threat')
local active_biters = WD.get('active_biters')
local active_biter_threat = Public.get('active_biter_threat')
local active_biters = Public.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 valid(biter.entity) then
biter_threat = biter_threat + threat_values[biter.entity.name]
biter_threat = biter_threat + Public.threat_values[biter.entity.name]
else
active_biters[k] = nil
end
end
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
WD.set('active_biter_threat', math_round(biter_threat * biter_health_boost, 2))
Public.set('active_biter_threat', math_round(biter_threat * biter_health_boost, 2))
debug_print('refresh_active_unit_threat - new value ' .. active_biter_threat)
end
local function time_out_biters()
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')
local active_biters = Public.get('active_biters')
local active_biter_count = Public.get('active_biter_count')
local active_biter_threat = Public.get('active_biter_threat')
if active_biter_count >= 100 and #active_biters <= 10 then
WD.set('active_biter_count', 50)
Public.set('active_biter_count', 50)
end
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
for k, biter in pairs(active_biters) do
if not is_unit_valid(biter) then
WD.set('active_biter_count', active_biter_count - 1)
Public.set('active_biter_count', active_biter_count - 1)
if biter.entity then
if biter.entity.valid then
WD.set('active_biter_threat', active_biter_threat - math_round(threat_values[biter.entity.name] * biter_health_boost, 2))
Public.set('active_biter_threat', active_biter_threat - math_round(Public.threat_values[biter.entity.name] * biter_health_boost, 2))
if biter.entity.force.index == 2 then
biter.entity.destroy()
end
@ -304,9 +306,9 @@ local function time_out_biters()
end
local function get_random_close_spawner()
local nests = WD.get('nests')
local target = WD.get('target')
local get_random_close_spawner_attempts = WD.get('get_random_close_spawner_attempts')
local nests = Public.get('nests')
local target = Public.get('target')
local get_random_close_spawner_attempts = Public.get('get_random_close_spawner_attempts')
local center = target.position
local spawner
local retries = 0
@ -337,7 +339,7 @@ end
local function get_random_character()
local characters = {}
local surface_index = WD.get('surface_index')
local surface_index = Public.get('surface_index')
local p = game.connected_players
for _, player in pairs(p) do
if player.character then
@ -355,20 +357,20 @@ local function get_random_character()
end
local function set_main_target()
local target = WD.get('target')
local target = Public.get('target')
if target then
if target.valid then
return
end
end
local unit_groups_size = WD.get('unit_groups_size')
local unit_groups_size = Public.get('unit_groups_size')
if unit_groups_size < 0 then
unit_groups_size = 0
end
WD.set('unit_groups_size', unit_groups_size)
Public.set('unit_groups_size', unit_groups_size)
local sec_target = SideTargets.get_side_target()
local sec_target = Public.get_side_target()
if not sec_target then
sec_target = get_random_character()
end
@ -376,7 +378,7 @@ local function set_main_target()
return
end
WD.set('target', sec_target)
Public.set('target', sec_target)
debug_print('set_main_target -- New main target ' .. sec_target.name .. ' at position x' .. sec_target.position.x .. ' y' .. sec_target.position.y .. ' selected.')
end
@ -389,15 +391,15 @@ local function set_group_spawn_position(surface)
if not position then
return
end
WD.set('spawn_position', {x = position.x, y = position.y})
Public.set('spawn_position', {x = position.x, y = position.y})
local spawn_position = get_spawn_pos()
debug_print('set_group_spawn_position -- Changed position to x' .. spawn_position.x .. ' y' .. spawn_position.y .. '.')
end
local function set_enemy_evolution()
local wave_number = WD.get('wave_number')
local biter_health_boost = WD.get('biter_health_boost')
local threat = WD.get('threat')
local wave_number = Public.get('wave_number')
local biter_health_boost = Public.get('biter_health_boost')
local threat = Public.get('threat')
local evolution_factor = wave_number * 0.001
local biter_h_boost = 1
local enemy = game.forces.enemy
@ -416,7 +418,7 @@ local function set_enemy_evolution()
end
BiterHealthBooster.set('biter_health_boost', biter_h_boost)
WD.set('biter_health_boost', biter_h_boost)
Public.set('biter_health_boost', biter_h_boost)
if enemy.evolution_factor == 1 and evolution_factor == 1 then
return
@ -426,7 +428,7 @@ local function set_enemy_evolution()
end
local function can_units_spawn()
local threat = WD.get('threat')
local threat = Public.get('threat')
if threat <= 0 then
debug_print('can_units_spawn - threat too low')
@ -434,15 +436,15 @@ local function can_units_spawn()
return false
end
local active_biter_count = WD.get('active_biter_count')
local max_active_biters = WD.get('max_active_biters')
local active_biter_count = Public.get('active_biter_count')
local max_active_biters = Public.get('max_active_biters')
if active_biter_count >= max_active_biters then
debug_print('can_units_spawn - active biter count too high')
time_out_biters()
return false
end
local active_biter_threat = WD.get('active_biter_threat')
local active_biter_threat = Public.get('active_biter_threat')
if active_biter_threat >= threat then
debug_print('can_units_spawn - active biter threat too high (' .. active_biter_threat .. ')')
time_out_biters()
@ -452,7 +454,7 @@ local function can_units_spawn()
end
local function get_active_unit_groups_count()
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
local count = 0
for k, g in pairs(unit_groups) do
@ -462,18 +464,18 @@ local function get_active_unit_groups_count()
else
g.destroy()
unit_groups[k] = nil
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size - 1)
end
else
unit_groups[k] = nil
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
local unit_group_last_command = WD.get('unit_group_last_command')
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size - 1)
local unit_group_last_command = Public.get('unit_group_last_command')
if unit_group_last_command[k] then
unit_group_last_command[k] = nil
end
local unit_group_pos = WD.get('unit_group_pos')
local unit_group_pos = Public.get('unit_group_pos')
local positions = unit_group_pos.positions
if positions[k] then
positions[k] = nil
@ -497,9 +499,9 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter)
local name
if math_random(1, 100) > 73 then
name = BiterRolls.wave_defense_roll_spitter_name()
name = Public.wave_defense_roll_spitter_name()
else
name = BiterRolls.wave_defense_roll_biter_name()
name = Public.wave_defense_roll_biter_name()
end
local old_position = position
@ -514,17 +516,17 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter)
biter.ai_settings.allow_try_return_to_spawner = false
biter.ai_settings.do_separation = true
local increase_health_per_wave = WD.get('increase_health_per_wave')
local increase_health_per_wave = Public.get('increase_health_per_wave')
if increase_health_per_wave and not is_boss_biter then
local modified_unit_health = WD.get('modified_unit_health')
local modified_unit_health = Public.get('modified_unit_health')
BiterHealthBooster.add_unit(biter, modified_unit_health.current_value)
end
if is_boss_biter then
local increase_boss_health_per_wave = WD.get('increase_boss_health_per_wave')
local increase_boss_health_per_wave = Public.get('increase_boss_health_per_wave')
if increase_boss_health_per_wave then
local modified_boss_unit_health = WD.get('modified_boss_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
BiterHealthBooster.add_boss_unit(biter, modified_boss_unit_health, 0.55)
else
local sum = boosted_health * 5
@ -533,16 +535,16 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter)
end
end
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))
Public.set('active_biters')[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
local active_biter_count = Public.get('active_biter_count')
Public.set('active_biter_count', active_biter_count + 1)
local active_biter_threat = Public.get('active_biter_threat')
Public.set('active_biter_threat', active_biter_threat + math_round(Public.threat_values[name] * boosted_health, 2))
return biter
end
local function increase_biter_damage()
local increase_damage_per_wave = WD.get('increase_damage_per_wave')
local increase_damage_per_wave = Public.get('increase_damage_per_wave')
if not increase_damage_per_wave then
return
end
@ -562,42 +564,42 @@ local function increase_biter_damage()
end
local function increase_biters_health()
local increase_health_per_wave = WD.get('increase_health_per_wave')
local increase_health_per_wave = Public.get('increase_health_per_wave')
if not increase_health_per_wave then
return
end
local boosted_health = BiterHealthBooster.get('biter_health_boost')
local wave_number = WD.get('wave_number')
local wave_number = Public.get('wave_number')
-- this sets normal units health
local modified_unit_health = WD.get('modified_unit_health')
local modified_unit_health = Public.get('modified_unit_health')
if modified_unit_health.current_value > modified_unit_health.limit_value then
modified_unit_health.current_value = modified_unit_health.limit_value
end
debug_print('[HEALTHBOOSTER] > Normal Units Health Boosted: ' .. modified_unit_health.current_value)
WD.set('modified_unit_health').current_value = modified_unit_health.current_value + modified_unit_health.health_increase_per_boss_wave
debug_print_health('modified_unit_health.current_value: ' .. modified_unit_health.current_value)
Public.set('modified_unit_health').current_value = modified_unit_health.current_value + modified_unit_health.health_increase_per_boss_wave
-- this sets boss units health
if boosted_health == 1 then
boosted_health = 1.25
end
boosted_health = boosted_health * (wave_number * 0.04)
local sum = boosted_health * 5
debug_print('[HEALTHBOOSTER] > Boss Health Boosted: ' .. sum)
if sum >= 300 then
sum = 300
boosted_health = math_round(boosted_health * (wave_number * 0.04), 3)
debug_print_health('boosted_health: ' .. boosted_health)
if boosted_health >= 300 then
boosted_health = 300
end
WD.set('modified_boss_unit_health', sum)
Public.set('modified_boss_unit_health', boosted_health)
end
local function set_next_wave()
local wave_number = WD.get('wave_number')
WD.set('wave_number', wave_number + 1)
wave_number = WD.get('wave_number')
local wave_number = Public.get('wave_number')
Public.set('wave_number', wave_number + 1)
wave_number = Public.get('wave_number')
local threat_gain_multiplier = WD.get('threat_gain_multiplier')
local threat_gain_multiplier = Public.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)
@ -605,9 +607,9 @@ local function set_next_wave()
if wave_number % 25 == 0 then
increase_biter_damage()
increase_biters_health()
WD.set('boss_wave', true)
WD.set('boss_wave_warning', true)
local alert_boss_wave = WD.get('alert_boss_wave')
Public.set('boss_wave', true)
Public.set('boss_wave_warning', true)
local alert_boss_wave = Public.get('alert_boss_wave')
local spawn_position = get_spawn_pos()
if alert_boss_wave then
local msg = 'Boss Wave: ' .. wave_number
@ -618,26 +620,26 @@ local function set_next_wave()
end
threat_gain = threat_gain * 2
else
local boss_wave_warning = WD.get('boss_wave_warning')
local boss_wave_warning = Public.get('boss_wave_warning')
if boss_wave_warning then
WD.set('boss_wave_warning', false)
Public.set('boss_wave_warning', false)
end
end
local threat = WD.get('threat')
WD.set('threat', threat + math_floor(threat_gain))
local threat = Public.get('threat')
Public.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')
local wave_enforced = Public.get('wave_enforced')
local next_wave = Public.get('next_wave')
local wave_interval = Public.get('wave_interval')
if not wave_enforced then
WD.set('last_wave', next_wave)
WD.set('next_wave', game.tick + wave_interval)
Public.set('last_wave', next_wave)
Public.set('next_wave', game.tick + wave_interval)
end
local clear_corpses = WD.get('clear_corpses')
local clear_corpses = Public.get('clear_corpses')
if clear_corpses then
local surface_index = WD.get('surface_index')
local surface_index = Public.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
@ -648,7 +650,7 @@ local function set_next_wave()
end
local function reform_group(group)
local unit_group_command_step_length = WD.get('unit_group_command_step_length')
local unit_group_command_step_length = Public.get('unit_group_command_step_length')
local group_position = {x = group.position.x, y = group.position.y}
local step_length = unit_group_command_step_length
local position = group.surface.find_non_colliding_position('biter-spawner', group_position, step_length, 4)
@ -658,28 +660,28 @@ local function reform_group(group)
new_group.add_member(biter)
end
debug_print('Creating new unit group, because old one was stuck.')
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
unit_groups[new_group.group_number] = new_group
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size + 1)
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size + 1)
return new_group
else
debug_print('Destroying stuck group.')
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
if unit_groups[group.group_number] then
local unit_group_last_command = WD.get('unit_group_last_command')
local unit_group_last_command = Public.get('unit_group_last_command')
if unit_group_last_command[group.group_number] then
unit_group_last_command[group.group_number] = nil
end
local unit_group_pos = WD.get('unit_group_pos')
local unit_group_pos = Public.get('unit_group_pos')
local positions = unit_group_pos.positions
if positions[group.group_number] then
positions[group.group_number] = nil
end
table.remove(unit_groups, group.group_number)
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size - 1)
end
group.destroy()
end
@ -687,13 +689,13 @@ local function reform_group(group)
end
local function get_side_targets(group)
local unit_group_command_step_length = WD.get('unit_group_command_step_length')
local unit_group_command_step_length = Public.get('unit_group_command_step_length')
local commands = {}
local group_position = {x = group.position.x, y = group.position.y}
local step_length = unit_group_command_step_length
local side_target = SideTargets.get_side_target()
local side_target = Public.get_side_target()
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))
local steps = math_floor(distance_to_target / step_length) + 1
@ -730,12 +732,12 @@ local function get_side_targets(group)
end
local function get_main_command(group)
local unit_group_command_step_length = WD.get('unit_group_command_step_length')
local unit_group_command_step_length = Public.get('unit_group_command_step_length')
local commands = {}
local group_position = {x = group.position.x, y = group.position.y}
local step_length = unit_group_command_step_length
local target = WD.get('target')
local target = Public.get('target')
if not valid(target) then
return
end
@ -808,8 +810,8 @@ local function command_to_main_target(group, bypass)
if not valid(group) then
return
end
local unit_group_last_command = WD.get('unit_group_last_command')
local unit_group_command_delay = WD.get('unit_group_command_delay')
local unit_group_last_command = Public.get('unit_group_last_command')
local unit_group_command_delay = Public.get('unit_group_command_delay')
if not bypass then
if not unit_group_last_command[group.group_number] then
unit_group_last_command[group.group_number] = game.tick - (unit_group_command_delay + 1)
@ -822,7 +824,7 @@ local function command_to_main_target(group, bypass)
end
end
local fill_tiles_so_biter_can_path = WD.get('fill_tiles_so_biter_can_path')
local fill_tiles_so_biter_can_path = Public.get('fill_tiles_so_biter_can_path')
if fill_tiles_so_biter_can_path then
fill_tiles(group, 10)
end
@ -839,7 +841,7 @@ local function command_to_main_target(group, bypass)
debug_print('get_main_command - got commands')
local surface_index = WD.get('surface_index')
local surface_index = Public.get('surface_index')
if group.surface.index ~= surface_index then
return
@ -859,8 +861,8 @@ local function command_to_main_target(group, bypass)
end
local function command_to_side_target(group)
local unit_group_last_command = WD.get('unit_group_last_command')
local unit_group_command_delay = WD.get('unit_group_command_delay')
local unit_group_last_command = Public.get('unit_group_last_command')
local unit_group_command_delay = Public.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
@ -890,17 +892,17 @@ local function command_to_side_target(group)
end
local function give_side_commands_to_group()
local enable_side_target = WD.get('enable_side_target')
local enable_side_target = Public.get('enable_side_target')
if not enable_side_target then
return
end
local target = WD.get('target')
local target = Public.get('target')
if not valid(target) then
return
end
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
for k, group in pairs(unit_groups) do
if type(group) ~= 'number' then
if group.valid then
@ -913,12 +915,12 @@ local function give_side_commands_to_group()
end
local function give_main_command_to_group()
local target = WD.get('target')
local target = Public.get('target')
if not valid(target) then
return
end
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
for k, group in pairs(unit_groups) do
if type(group) ~= 'number' then
if group.valid then
@ -932,7 +934,7 @@ local function give_main_command_to_group()
end
end
local function spawn_unit_group(fs)
local function spawn_unit_group(fs, only_bosses)
if fs then
debug_print('spawn_unit_group - forcing new biters')
else
@ -941,13 +943,13 @@ local function spawn_unit_group(fs)
return
end
end
local target = WD.get('target')
local target = Public.get('target')
if not valid(target) then
debug_print('spawn_unit_group - Target was not valid?')
return
end
local max_active_unit_groups = WD.get('max_active_unit_groups')
local max_active_unit_groups = Public.get('max_active_unit_groups')
if fs then
debug_print('spawn_unit_group - forcing new biters')
else
@ -956,8 +958,8 @@ local function spawn_unit_group(fs)
return
end
end
local surface_index = WD.get('surface_index')
local remove_entities = WD.get('remove_entities')
local surface_index = Public.get('surface_index')
local remove_entities = Public.get('remove_entities')
local surface = game.surfaces[surface_index]
set_group_spawn_position(surface)
@ -985,29 +987,31 @@ local function spawn_unit_group(fs)
fill_tiles({surface = surface, position = spawn_position, valid = true})
end
local wave_number = WD.get('wave_number')
BiterRolls.wave_defense_set_unit_raffle(wave_number)
local wave_number = Public.get('wave_number')
Public.wave_defense_set_unit_raffle(wave_number)
debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y)
local unit_group_pos = WD.get('unit_group_pos')
local unit_group_pos = Public.get('unit_group_pos')
local unit_group = surface.create_unit_group({position = spawn_position, force = 'enemy'})
unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0}
local average_unit_group_size = WD.get('average_unit_group_size')
local average_unit_group_size = Public.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, spawn_position, fs)
if not biter then
debug_print('spawn_unit_group - No biters were found?')
break
end
unit_group.add_member(biter)
if not only_bosses then
for _ = 1, group_size, 1 do
local biter = spawn_biter(surface, spawn_position, fs)
if not biter then
debug_print('spawn_unit_group - No biters were found?')
break
end
unit_group.add_member(biter)
-- command_to_side_target(unit_group)
-- command_to_side_target(unit_group)
end
end
local boss_wave = WD.get('boss_wave')
if boss_wave then
local boss_wave = Public.get('boss_wave')
if boss_wave or only_bosses then
local count = math_random(1, math_floor(wave_number * 0.01) + 2)
if count > 16 then
count = 16
@ -1023,24 +1027,24 @@ local function spawn_unit_group(fs)
end
unit_group.add_member(biter)
end
WD.set('boss_wave', false)
Public.set('boss_wave', false)
end
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
unit_groups[unit_group.group_number] = unit_group
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size + 1)
local unit_groups_size = Public.get('unit_groups_size')
Public.set('unit_groups_size', unit_groups_size + 1)
if math_random(1, 2) == 1 then
WD.set('random_group', unit_group)
Public.set('random_group', unit_group)
end
WD.set('spot', 'nil')
Public.set('spot', 'nil')
return true
end
local function check_group_positions()
local unit_groups = WD.get('unit_groups')
local unit_group_pos = WD.get('unit_group_pos')
local target = WD.get('target')
local unit_groups = Public.get('unit_groups')
local unit_group_pos = Public.get('unit_group_pos')
local target = Public.get('target')
if not valid(target) then
return
end
@ -1072,11 +1076,11 @@ local function check_group_positions()
end
local function log_threat()
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')
local threat_log_index = Public.get('threat_log_index')
Public.set('threat_log_index', threat_log_index + 1)
local threat_log = Public.get('threat_log')
local threat = Public.get('threat')
threat_log_index = Public.get('threat_log_index')
threat_log[threat_log_index] = threat
if threat_log_index > 900 then
threat_log[threat_log_index - 901] = nil
@ -1087,8 +1091,8 @@ local tick_tasks = {
[30] = set_main_target,
[60] = set_enemy_evolution,
[120] = give_main_command_to_group,
[150] = ThreatEvent.build_nest,
[180] = ThreatEvent.build_worm,
[150] = Public.build_nest,
[180] = Public.build_worm,
[1200] = give_side_commands_to_group,
[3600] = time_out_biters,
[7200] = refresh_active_unit_threat
@ -1096,17 +1100,17 @@ local tick_tasks = {
local function t1()
local tick = game.tick
local game_lost = WD.get('game_lost')
local game_lost = Public.get('game_lost')
if game_lost then
return
end
local paused = WD.get('paused')
local paused = Public.get('paused')
if paused then
return
end
local next_wave = WD.get('next_wave')
local next_wave = Public.get('next_wave')
if tick > next_wave then
set_next_wave()
end
@ -1121,14 +1125,14 @@ local function t1()
tick_tasks[t2](true)
end
local resolve_pathing = WD.get('resolve_pathing')
local resolve_pathing = Public.get('resolve_pathing')
if resolve_pathing then
if tick % 60 == 0 then
check_group_positions()
end
end
local enable_threat_log = WD.get('enable_threat_log')
local enable_threat_log = Public.get('enable_threat_log')
if enable_threat_log then
if tick % 60 == 0 then
log_threat()
@ -1136,22 +1140,38 @@ local function t1()
end
local players = game.connected_players
for _, player in pairs(players) do
update_gui(player)
Public.update_gui(player)
end
end
local function t2()
local game_lost = WD.get('game_lost')
local game_lost = Public.get('game_lost')
if game_lost then
return
end
local paused = WD.get('paused')
local paused = Public.get('paused')
if paused then
return
end
spawn_unit_group()
local debug_only_on_wave_500 = Public.get('debug_only_on_wave_500')
if debug_only_on_wave_500 then
local valid_waves = {
[500] = true,
[1000] = true,
[1500] = true,
[2000] = true,
[2500] = true
}
local wave_number = Public.get('wave_number')
if valid_waves[wave_number] then
Public.set('wave_enforced', false)
spawn_unit_group()
end
else
spawn_unit_group()
end
end
Public.spawn_unit_group = spawn_unit_group

View File

@ -1,5 +1,4 @@
local WD = require 'modules.wave_defense.table'
local Public = {}
local Public = require 'modules.wave_defense.table'
local side_target_types = {
['accumulator'] = true,
['assembling-machine'] = true,
@ -18,29 +17,29 @@ local side_target_types = {
}
local function get_random_target()
local side_target_count = WD.get('side_target_count')
local side_targets = WD.get('side_targets')
local side_target_count = Public.get('side_target_count')
local side_targets = Public.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)
Public.set('side_target_count', side_target_count - 1)
return
end
if not side_targets[r].valid then
table.remove(side_targets, r)
WD.set('side_target_count', side_target_count - 1)
Public.set('side_target_count', side_target_count - 1)
return
end
side_targets = WD.get('side_targets')
side_targets = Public.get('side_targets')
return side_targets[r]
end
function Public.get_side_target()
local enable_side_target = WD.get('enable_side_target')
local enable_side_target = Public.get('enable_side_target')
if not enable_side_target then
return
end
local side_target_count = WD.get('side_target_count')
local side_target_count = Public.get('side_target_count')
for _ = 1, 512, 1 do
if side_target_count == 0 then
return
@ -53,27 +52,27 @@ function Public.get_side_target()
end
local function add_entity(entity)
local enable_side_target = WD.get('enable_side_target')
local enable_side_target = Public.get('enable_side_target')
if not enable_side_target then
return
end
local surface_index = WD.get('surface_index')
local surface_index = Public.get('surface_index')
--skip entities that are on another surface
if entity.surface.index ~= surface_index then
return
end
local side_target_count = WD.get('side_target_count')
local side_target_count = Public.get('side_target_count')
if side_target_count >= 512 then
return
end
local side_targets = WD.get('side_targets')
local side_targets = Public.get('side_targets')
--add entity to the side target list
table.insert(side_targets, entity)
WD.set('side_target_count', side_target_count + 1)
Public.set('side_target_count', side_target_count + 1)
end
local function on_built_entity(event)

View File

@ -11,17 +11,6 @@ Global.register(
end
)
function Public.debug_module()
this.next_wave = 1000
this.wave_interval = 500
this.wave_enforced = true
this.debug = true
end
function Public.enable_debug()
this.debug = true
end
function Public.reset_wave_defense()
this.boss_wave = false
this.boss_wave_warning = false
@ -32,6 +21,7 @@ function Public.reset_wave_defense()
this.average_unit_group_size = 35
this.biter_raffle = {}
this.debug = false
this.debug_health = false
this.paused = false
this.game_lost = false
this.get_random_close_spawner_attempts = 5
@ -232,6 +222,28 @@ function Public.pause(boolean)
this.paused = boolean or false
end
--- Toggle debug - when you need to troubleshoot.
function Public.toggle_debug()
if this.debug then
this.debug = false
else
this.debug = true
end
return this.debug
end
--- Toggle debug - when you need to troubleshoot.
function Public.toggle_debug_health()
if this.debug_health then
this.debug_health = false
else
this.debug_health = true
end
return this.debug_health
end
local on_init = function()
Public.reset_wave_defense()
end

View File

@ -1,14 +1,21 @@
local WD = require 'modules.wave_defense.table'
local threat_values = require 'modules.wave_defense.threat_values'
local Public = require 'modules.wave_defense.table'
local Event = require 'utils.event'
local BiterRolls = require 'modules.wave_defense.biter_rolls'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local math_random = math.random
local Public = {}
local function is_boss(entity)
local unit_number = entity.unit_number
local biter_health_boost_units = BiterHealthBooster.get('biter_health_boost_units')
local unit = biter_health_boost_units[unit_number]
if unit and unit[3] and unit[3].healthbar_id then
return true
else
return false
end
end
local function remove_unit(entity)
local active_biters = WD.get('active_biters')
local active_biters = Public.get('active_biters')
local unit_number = entity.unit_number
if not active_biters[unit_number] then
return
@ -18,24 +25,24 @@ local function remove_unit(entity)
if biter_health_boost_units[unit_number] then
m = 1 / biter_health_boost_units[unit_number][2]
end
local active_threat_loss = math.round(threat_values[entity.name] * m, 2)
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)
local active_threat_loss = math.round(Public.threat_values[entity.name] * m, 2)
local active_biter_threat = Public.get('active_biter_threat')
Public.set('active_biter_threat', active_biter_threat - active_threat_loss)
local active_biter_count = Public.get('active_biter_count')
Public.set('active_biter_count', active_biter_count - 1)
active_biters[unit_number] = nil
if active_biter_count <= 0 then
WD.set('active_biter_count', 0)
Public.set('active_biter_count', 0)
end
if active_biter_threat <= 0 then
WD.set('active_biter_threat', 0)
Public.set('active_biter_threat', 0)
end
end
local function place_nest_near_unit_group()
local unit_groups = WD.get('unit_groups')
local random_group = WD.get('random_group')
local unit_groups = Public.get('unit_groups')
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
@ -64,7 +71,7 @@ local function place_nest_near_unit_group()
if not position then
return
end
local r = WD.get('nest_building_density')
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
@ -76,27 +83,35 @@ local function place_nest_near_unit_group()
then
return
end
local modified_boss_unit_health = WD.get('modified_boss_unit_health')
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health)
local nests = WD.get('nests')
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
local nests = Public.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()
local threat = WD.get('threat')
WD.set('threat', threat - threat_values[name])
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
end
function Public.build_nest()
local threat = WD.get('threat')
local threat = Public.get('threat')
if threat < 1024 then
return
end
local unit_groups_size = WD.get('unit_groups_size')
local unit_groups_size = Public.get('unit_groups_size')
if unit_groups_size == 0 then
return
end
@ -108,25 +123,25 @@ function Public.build_nest()
end
function Public.build_worm()
local threat = WD.get('threat')
local threat = Public.get('threat')
if threat < 512 then
return
end
local worm_building_chance = WD.get('worm_building_chance')
local worm_building_chance = Public.get('worm_building_chance')
if math_random(1, worm_building_chance) ~= 1 then
return
end
local unit_groups_size = WD.get('unit_groups_size')
local unit_groups_size = Public.get('unit_groups_size')
if unit_groups_size == 0 then
return
end
local random_group = WD.get('random_group')
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local unit_groups = WD.get('unit_groups')
local unit_groups = Public.get('unit_groups')
local group = unit_groups[random_group.group_number]
if not group then
return
@ -145,15 +160,17 @@ function Public.build_worm()
return
end
local wave_number = WD.get('wave_number')
local boss = is_boss(unit)
local wave_number = Public.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_number)
local worm = BiterRolls.wave_defense_roll_worm_name()
Public.wave_defense_set_worm_raffle(wave_number)
local worm = Public.wave_defense_roll_worm_name()
if not position then
return
end
local worm_building_density = WD.get('worm_building_density')
local worm_building_density = Public.get('worm_building_density')
local r = worm_building_density
if
unit.surface.count_entities_filtered(
@ -166,19 +183,25 @@ function Public.build_worm()
then
return
end
local modified_boss_unit_health = WD.get('modified_boss_unit_health')
local u = unit.surface.create_entity({name = worm, position = position, force = unit.force})
BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
if boss then
BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health)
else
BiterHealthBooster.add_unit(u, modified_unit_health.current_value)
end
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()
WD.set('threat', threat - threat_values[worm])
Public.set('threat', threat - Public.threat_values[worm])
end
local function shred_simple_entities(entity)
local threat = WD.get('threat')
local threat = Public.get('threat')
if threat < 25000 then
return
end
@ -216,30 +239,30 @@ local function shred_simple_entities(entity)
if damage_dealt == 0 then
return
end
local simple_entity_shredding_cost_modifier = WD.get('simple_entity_shredding_cost_modifier')
local simple_entity_shredding_cost_modifier = Public.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
WD.set('threat', threat - threat_cost)
Public.set('threat', threat - threat_cost)
end
local function spawn_unit_spawner_inhabitants(entity)
if entity.type ~= 'unit-spawner' then
return
end
local wave_number = WD.get('wave_number')
local wave_number = Public.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_number)
Public.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 = Public.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 = Public.wave_defense_roll_biter_name(), position = position, force = 'enemy'})
end
end
end
@ -250,34 +273,34 @@ local function on_entity_died(event)
return
end
local disable_threat_below_zero = WD.get('disable_threat_below_zero')
local disable_threat_below_zero = Public.get('disable_threat_below_zero')
local biter_health_boost = BiterHealthBooster.get('biter_health_boost')
if entity.type == 'unit' then
--acid_nova(entity)
if not threat_values[entity.name] then
if not Public.threat_values[entity.name] then
return
end
if disable_threat_below_zero then
local threat = WD.get('threat')
local threat = Public.get('threat')
if threat <= 0 then
WD.set('threat', 0)
Public.set('threat', 0)
remove_unit(entity)
return
end
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2))
remove_unit(entity)
else
local threat = WD.get('threat')
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
local threat = Public.get('threat')
Public.set('threat', math.round(threat - Public.threat_values[entity.name] * 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
local threat = WD.get('threat')
WD.set('threat', math.round(threat - threat_values[entity.name] * biter_health_boost, 2))
if Public.threat_values[entity.name] then
local threat = Public.get('threat')
Public.set('threat', math.round(threat - Public.threat_values[entity.name] * biter_health_boost, 2))
end
spawn_unit_spawner_inhabitants(entity)
end

View File

@ -1,4 +1,6 @@
local t = {
local Public = require 'modules.wave_defense.table'
Public.threat_values = {
['biter-spawner'] = 128,
['spitter-spawner'] = 128,
['behemoth-biter'] = 64,
@ -15,4 +17,4 @@ local t = {
['behemoth-worm-turret'] = 128
}
return t
return Public