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

Mtn v3 - tweak final battle

This commit is contained in:
Gerkiz 2023-09-23 23:00:51 +02:00
parent 1ca9e578b1
commit 7271e9d99f
10 changed files with 236 additions and 31 deletions

View File

@ -44,6 +44,7 @@ local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local JailData = require 'utils.datastore.jail_data' local JailData = require 'utils.datastore.jail_data'
local RPG_Progression = require 'utils.datastore.rpg_data' local RPG_Progression = require 'utils.datastore.rpg_data'
local OfflinePlayers = require 'modules.clear_vacant_players' local OfflinePlayers = require 'modules.clear_vacant_players'
local Beam = require 'modules.render_beam'
-- Use these settings for live -- Use these settings for live
local send_ping_to_channel = Discord.channel_names.mtn_channel local send_ping_to_channel = Discord.channel_names.mtn_channel
@ -179,6 +180,8 @@ function Public.reset_map()
Explosives.set_surface_whitelist({[surface.name] = true}) Explosives.set_surface_whitelist({[surface.name] = true})
Explosives.check_growth_below_void(true) Explosives.check_growth_below_void(true)
Beam.reset_valid_targets()
game.forces.player.set_spawn_position({x = -27, y = 25}, surface) game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
game.forces.player.manual_mining_speed_modifier = 0 game.forces.player.manual_mining_speed_modifier = 0
game.forces.player.set_ammo_damage_modifier('artillery-shell', -0.95) game.forces.player.set_ammo_damage_modifier('artillery-shell', -0.95)

View File

@ -1,6 +1,7 @@
local Public = require 'maps.mountain_fortress_v3.stateful.table' local Public = require 'maps.mountain_fortress_v3.stateful.table'
local Event = require 'utils.event' local Event = require 'utils.event'
local WD = require 'modules.wave_defense.table' local WD = require 'modules.wave_defense.table'
local Beam = require 'modules.render_beam'
Public.stateful_gui = require 'maps.mountain_fortress_v3.stateful.gui' Public.stateful_gui = require 'maps.mountain_fortress_v3.stateful.gui'
Public.stateful_terrain = require 'maps.mountain_fortress_v3.stateful.terrain' Public.stateful_terrain = require 'maps.mountain_fortress_v3.stateful.terrain'
@ -45,15 +46,23 @@ Event.on_nth_tick(
end end
if collection.time_until_attack and collection.time_until_attack <= 0 and collection.survive_for > 0 then if collection.time_until_attack and collection.time_until_attack <= 0 and collection.survive_for > 0 then
local surface = game.get_surface('boss_room')
if not surface or not surface.valid then
return
end
local spawn_positions = Public.stateful_spawn_points local spawn_positions = Public.stateful_spawn_points
local sizeof = Public.sizeof_stateful_spawn_points local sizeof = Public.sizeof_stateful_spawn_points
local rounds_survived = Public.get_stateful('rounds_survived')
local area = spawn_positions[random(1, sizeof)] local area = spawn_positions[random(1, sizeof)]
shuffle(area) shuffle(area)
WD.build_worm_custom()
WD.set_spawn_position(area[1]) WD.set_spawn_position(area[1])
Event.raise(WD.events.on_spawn_unit_group, {fs = true, bypass = true, random_bosses = true, scale = Public.stateful.scale(20, 100)}) Event.raise(WD.events.on_spawn_unit_group, {fs = true, bypass = true, random_bosses = true, scale = Public.stateful.scale(20 * (rounds_survived + 1), 100)})
return return
end end
@ -65,6 +74,31 @@ Event.on_nth_tick(
end end
) )
Event.on_nth_tick(
14400,
-- 200,
function()
local final_battle = Public.get_stateful('final_battle')
if not final_battle then
return
end
local collection = Public.get_stateful('collection')
if not collection then
return
end
local surface = game.get_surface('boss_room')
if not surface or not surface.valid then
return
end
if collection.time_until_attack and collection.time_until_attack <= 0 and collection.survive_for > 0 then
Beam.new_beam(surface, game.tick + 600)
end
end
)
Event.add(defines.events.on_pre_player_died, Public.on_pre_player_died) Event.add(defines.events.on_pre_player_died, Public.on_pre_player_died)
return Public return Public

View File

@ -15,6 +15,7 @@ local Alert = require 'utils.alert'
local IC = require 'maps.mountain_fortress_v3.ic.table' local IC = require 'maps.mountain_fortress_v3.ic.table'
local RPG = require 'modules.rpg.table' local RPG = require 'modules.rpg.table'
local BiterHealthBooster = require 'modules.biter_health_booster_v2' local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Beam = require 'modules.render_beam'
local this = { local this = {
enabled = false, enabled = false,
@ -788,6 +789,8 @@ function Public.allocate()
if stateful_locomotive and not stateful_locomotive_migrated then if stateful_locomotive and not stateful_locomotive_migrated then
Task.set_timeout_in_ticks(100, move_all_players_token, {}) Task.set_timeout_in_ticks(100, move_all_players_token, {})
Beam.new_valid_targets({'wall', 'turret', 'furnace', 'gate'})
Public.soft_reset.add_schedule_to_delete_surface() Public.soft_reset.add_schedule_to_delete_surface()
Public.set_stateful('stateful_locomotive_migrated', true) Public.set_stateful('stateful_locomotive_migrated', true)
local locomotive = Public.get('locomotive') local locomotive = Public.get('locomotive')
@ -809,7 +812,7 @@ function Public.allocate()
Server.to_discord_embed('Final boss wave is occuring soon!') Server.to_discord_embed('Final boss wave is occuring soon!')
WD.set('final_boss', true) WD.set('final_battle', true)
Core.iter_connected_players( Core.iter_connected_players(
function(player) function(player)

View File

@ -14,6 +14,17 @@ local this = {
'artillery-wagon', 'artillery-wagon',
'artillery-turret', 'artillery-turret',
'spidertron' 'spidertron'
},
backup_valid_targets = {
'character',
'tank',
'car',
'locomotive',
'cargo-wagon',
'fluid-wagon',
'artillery-wagon',
'artillery-turret',
'spidertron'
} }
} }
@ -55,7 +66,7 @@ function Public:new_target()
return return
end end
local position local position
local entities = surface.find_entities_filtered {type = this.valid_targets} local entities = surface.find_entities_filtered {type = this.valid_targets, force = 'player'}
if entities and #entities > 0 then if entities and #entities > 0 then
position = entities[random(#entities)].position position = entities[random(#entities)].position
end end
@ -146,7 +157,7 @@ function Public:notify_new_beam()
return return
end end
game.print('[Orbital] A new orbital strike has been spotted at: [gps=' .. self.position.x .. ',' .. self.position.y .. ',' .. surface.name .. ']') game.print('[color=yellow][Orbital][/color] A new orbital strike has been spotted at: [gps=' .. self.position.x .. ',' .. self.position.y .. ',' .. surface.name .. ']')
end end
end end
@ -233,7 +244,7 @@ function Public:damage_entities_nearby()
if entity.valid then if entity.valid then
if entity.health then if entity.health then
if entity.force.name ~= 'enemy' then if entity.force.name ~= 'enemy' then
entity.damage(damage, 'enemy') entity.damage(damage, 'enemy', 'explosion')
end end
end end
end end
@ -245,7 +256,8 @@ end
---@return boolean|integer ---@return boolean|integer
function Public:validate() function Public:validate()
if not self.render_id then if not self.render_id then
return self:new_render() self:new_render()
return false
end end
if rendering.is_valid(self.render_id) then if rendering.is_valid(self.render_id) then
return true return true
@ -297,7 +309,7 @@ end
--- Creates a new render. --- Creates a new render.
---@param sprite string ---@param sprite string
---@param surface userdata ---@param surface LuaSurface
---@param ttl integer|nil ---@param ttl integer|nil
---@param scalar table|nil ---@param scalar table|nil
---@param delayed number|nil ---@param delayed number|nil
@ -329,13 +341,30 @@ function Public.new(sprite, surface, ttl, scalar, delayed)
end end
--- Creates a new defined beam --- Creates a new defined beam
---@param surface userdata ---@param surface LuaSurface
function Public.new_beam(surface) ---@param ttl number|nil
Public.new(Gui.beam, surface) function Public.new_beam(surface, ttl)
Public.new(Gui.beam, surface, ttl)
end
--- Defines new targets as valid targets
---@param targets table
function Public.new_valid_targets(targets)
if targets and type(targets) == 'table' then
this.backup_valid_targets = this.valid_targets
this.valid_targets = targets
else
error('New valid targets needs to be of type table', 2)
end
end
--- Defaults the valid targets
function Public.reset_valid_targets()
this.valid_targets = this.backup_valid_targets
end end
--- Creates a new defined beam with a delayed action --- Creates a new defined beam with a delayed action
---@param surface userdata ---@param surface LuaSurface
---@param time number ---@param time number
function Public.new_beam_delayed(surface, time) function Public.new_beam_delayed(surface, time)
Public.new(Gui.beam, surface, nil, nil, time) Public.new(Gui.beam, surface, nil, nil, time)

View File

@ -22,7 +22,8 @@ local this = {
frenzy_burst_length = 160, frenzy_burst_length = 160,
update_rate = 60, update_rate = 60,
enabled = true, enabled = true,
track_bosses_only = true track_bosses_only = true,
wave_number = 0
}, },
target_settings = {} target_settings = {}
} }

View File

@ -66,8 +66,8 @@ local function get_threat_gain()
end end
function Public.update_gui(player) function Public.update_gui(player)
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
if final_boss then if final_battle then
if player.gui.top.wave_defense and player.gui.top.wave_defense.valid then if player.gui.top.wave_defense and player.gui.top.wave_defense.valid then
player.gui.top.wave_defense.destroy() player.gui.top.wave_defense.destroy()
end end

View File

@ -476,8 +476,8 @@ local function get_active_unit_groups_count()
return count return count
end end
local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_settings) local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_settings)
if not forceSpawn then if not force_spawn then
if not is_boss_biter then if not is_boss_biter then
if not can_units_spawn() then if not can_units_spawn() then
return return
@ -556,7 +556,15 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_se
local generated_units = Public.get('generated_units') local generated_units = Public.get('generated_units')
generated_units.active_biters[biter.unit_number] = {entity = biter, spawn_tick = game.tick} if is_boss_biter then
if not generated_units.boss_units then
generated_units.boss_units = {}
end
generated_units.boss_units[#generated_units.boss_units + 1] = biter
else
generated_units.active_biters[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
end
local active_biter_count = Public.get('active_biter_count') local active_biter_count = Public.get('active_biter_count')
Public.set('active_biter_count', active_biter_count + 1) Public.set('active_biter_count', active_biter_count + 1)
local active_biter_threat = Public.get('active_biter_threat') local active_biter_threat = Public.get('active_biter_threat')
@ -564,6 +572,71 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_se
return biter return biter
end end
local function spawn_worm(surface, position, is_boss_worm)
local boosted_health = BiterHealthBooster.get('biter_health_boost')
local name = Public.wave_defense_roll_worm_name()
local old_position = position
local enable_random_spawn_positions = Public.get('enable_random_spawn_positions')
if enable_random_spawn_positions then
if random(1, 3) == 1 then
position = {x = (-1 * (position.x + random(1, 10))), y = (position.y + random(1, 10))}
else
position = {x = (position.x + random(1, 10)), y = (position.y + random(1, 10))}
end
end
position = surface.find_non_colliding_position('steel-chest', position, 3, 1)
if not position then
position = old_position
end
local force = 'enemy'
local es_settings = Public.get_es('settings')
if es_settings.enabled then
force = 'aggressors'
end
local worm = surface.create_entity({name = name, position = position, force = force})
local increase_health_per_wave = Public.get('increase_health_per_wave')
local boost_units_when_wave_is_above = Public.get('boost_units_when_wave_is_above')
local boost_bosses_when_wave_is_above = Public.get('boost_bosses_when_wave_is_above')
local wave_number = Public.get('wave_number')
if (increase_health_per_wave and (wave_number >= boost_units_when_wave_is_above)) and not is_boss_worm then
local modified_unit_health = Public.get('modified_unit_health')
local unit_settings = Public.get('unit_settings')
local final_health = round(modified_unit_health.current_value * unit_settings.worm_unit_settings[worm.name], 3)
if final_health < 1 then
final_health = 1
end
Public.debug_print_health('final_health - unit: ' .. worm.name .. ' with h-m: ' .. final_health)
BiterHealthBooster.add_unit(worm, final_health)
end
if is_boss_worm then
if (wave_number >= boost_bosses_when_wave_is_above) then
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 = Public.get('modified_boss_unit_health')
BiterHealthBooster.add_boss_unit(worm, modified_boss_unit_health.current_value, 0.55)
else
local sum = boosted_health * 5
BiterHealthBooster.add_boss_unit(worm, sum, 0.55)
end
else
local sum = boosted_health * 5
BiterHealthBooster.add_boss_unit(worm, sum, 0.55)
end
end
return worm
end
local function increase_biter_damage(force) local function increase_biter_damage(force)
local increase_damage_per_wave = Public.get('increase_damage_per_wave') local increase_damage_per_wave = Public.get('increase_damage_per_wave')
if not increase_damage_per_wave then if not increase_damage_per_wave then
@ -1140,7 +1213,6 @@ local function spawn_unit_group(fs, only_bosses)
Public.set('boss_wave', false) Public.set('boss_wave', false)
end end
else else
event_data.boss_wave = true
local count = fs.scale or 30 local count = fs.scale or 30
event_data.spawn_count = count event_data.spawn_count = count
for _ = 1, count, 1 do for _ = 1, count, 1 do
@ -1272,10 +1344,10 @@ Event.on_nth_tick(
if game_lost then if game_lost then
return return
end end
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
local paused = Public.get('paused') local paused = Public.get('paused')
if paused and not final_boss then if paused and not final_battle then
local players = game.connected_players local players = game.connected_players
for _, player in pairs(players) do for _, player in pairs(players) do
Public.update_gui(player) Public.update_gui(player)
@ -1307,7 +1379,7 @@ Event.on_nth_tick(
tick_tasks_t2[t2]() tick_tasks_t2[t2]()
end end
if final_boss then if final_battle then
return return
end end
@ -1335,8 +1407,8 @@ Event.add(Public.events.on_spawn_unit_group, spawn_unit_group)
Event.on_nth_tick( Event.on_nth_tick(
50, 50,
function() function()
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
if final_boss then if final_battle then
return return
end end
@ -1364,5 +1436,6 @@ Event.on_nth_tick(
Public.set_next_wave = set_next_wave Public.set_next_wave = set_next_wave
Public.normalize_spawn_position = normalize_spawn_position Public.normalize_spawn_position = normalize_spawn_position
Public.check_if_near_target = check_if_near_target Public.check_if_near_target = check_if_near_target
Public.spawn_worm = spawn_worm
return Public return Public

View File

@ -240,8 +240,8 @@ Event.on_nth_tick(
return return
end end
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
if final_boss then if final_battle then
return return
end end

View File

@ -71,7 +71,7 @@ function Public.reset_wave_defense()
this.get_random_close_spawner_attempts = 5 this.get_random_close_spawner_attempts = 5
this.group_size = 2 this.group_size = 2
this.last_wave = game.tick this.last_wave = game.tick
this.final_boss = false this.final_battle = false
this.max_active_biters = 1280 this.max_active_biters = 1280
this.max_active_unit_groups = 32 this.max_active_unit_groups = 32
this.max_biter_age = 3600 * 60 this.max_biter_age = 3600 * 60

View File

@ -216,8 +216,8 @@ else
end end
function Public.build_nest() function Public.build_nest()
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
if final_boss then if final_battle then
return return
end end
@ -237,14 +237,14 @@ function Public.build_nest()
end end
function Public.build_worm() function Public.build_worm()
local final_boss = Public.get('final_boss') local final_battle = Public.get('final_battle')
local threat = Public.get('threat') local threat = Public.get('threat')
if threat < 512 and not final_boss then if threat < 512 and not final_battle then
return return
end end
local worm_building_chance = Public.get('worm_building_chance') --[[@as integer]] local worm_building_chance = Public.get('worm_building_chance') --[[@as integer]]
if random(1, worm_building_chance) ~= 1 then if not final_battle and random(1, worm_building_chance) ~= 1 then
return return
end end
@ -321,6 +321,68 @@ function Public.build_worm()
Public.set('threat', threat - Public.threat_values[worm]) Public.set('threat', threat - Public.threat_values[worm])
end end
function Public.build_worm_custom()
local unit_groups_size = Public.get('unit_groups_size')
if unit_groups_size == 0 then
return
end
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local generated_units = Public.get('generated_units')
local group = generated_units.boss_units
if not group then
return
end
if not next(group) then
return
end
local unit
generated_units.boss_unit_index, unit = next(group, generated_units.boss_unit_index)
if not unit or not unit.valid then
table.remove(group, generated_units.boss_unit_index)
return
end
local wave_number = Public.get('wave_number')
local position = unit.surface.find_non_colliding_position('assembling-machine-1', unit.position, 8, 1)
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 = Public.get('worm_building_density')
local r = worm_building_density
if
unit.surface.count_entities_filtered(
{
type = 'turret',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
local u = unit.surface.create_entity({name = worm, position = position, force = unit.force})
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health.current_value, 0.5)
table.remove(group, generated_units.boss_unit_index)
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()
end
local function shred_simple_entities(entity) local function shred_simple_entities(entity)
local threat = Public.get('threat') local threat = Public.get('threat')
if threat < 5000 then if threat < 5000 then