1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-03 13:12:11 +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 RPG_Progression = require 'utils.datastore.rpg_data'
local OfflinePlayers = require 'modules.clear_vacant_players'
local Beam = require 'modules.render_beam'
-- Use these settings for live
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.check_growth_below_void(true)
Beam.reset_valid_targets()
game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
game.forces.player.manual_mining_speed_modifier = 0
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 Event = require 'utils.event'
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_terrain = require 'maps.mountain_fortress_v3.stateful.terrain'
@ -45,15 +46,23 @@ Event.on_nth_tick(
end
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 sizeof = Public.sizeof_stateful_spawn_points
local rounds_survived = Public.get_stateful('rounds_survived')
local area = spawn_positions[random(1, sizeof)]
shuffle(area)
WD.build_worm_custom()
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
end
@ -65,6 +74,31 @@ Event.on_nth_tick(
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)
return Public

View File

@ -15,6 +15,7 @@ local Alert = require 'utils.alert'
local IC = require 'maps.mountain_fortress_v3.ic.table'
local RPG = require 'modules.rpg.table'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Beam = require 'modules.render_beam'
local this = {
enabled = false,
@ -788,6 +789,8 @@ function Public.allocate()
if stateful_locomotive and not stateful_locomotive_migrated then
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.set_stateful('stateful_locomotive_migrated', true)
local locomotive = Public.get('locomotive')
@ -809,7 +812,7 @@ function Public.allocate()
Server.to_discord_embed('Final boss wave is occuring soon!')
WD.set('final_boss', true)
WD.set('final_battle', true)
Core.iter_connected_players(
function(player)

View File

@ -14,6 +14,17 @@ local this = {
'artillery-wagon',
'artillery-turret',
'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
end
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
position = entities[random(#entities)].position
end
@ -146,7 +157,7 @@ function Public:notify_new_beam()
return
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
@ -233,7 +244,7 @@ function Public:damage_entities_nearby()
if entity.valid then
if entity.health then
if entity.force.name ~= 'enemy' then
entity.damage(damage, 'enemy')
entity.damage(damage, 'enemy', 'explosion')
end
end
end
@ -245,7 +256,8 @@ end
---@return boolean|integer
function Public:validate()
if not self.render_id then
return self:new_render()
self:new_render()
return false
end
if rendering.is_valid(self.render_id) then
return true
@ -297,7 +309,7 @@ end
--- Creates a new render.
---@param sprite string
---@param surface userdata
---@param surface LuaSurface
---@param ttl integer|nil
---@param scalar table|nil
---@param delayed number|nil
@ -329,13 +341,30 @@ function Public.new(sprite, surface, ttl, scalar, delayed)
end
--- Creates a new defined beam
---@param surface userdata
function Public.new_beam(surface)
Public.new(Gui.beam, surface)
---@param surface LuaSurface
---@param ttl number|nil
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
--- Creates a new defined beam with a delayed action
---@param surface userdata
---@param surface LuaSurface
---@param time number
function Public.new_beam_delayed(surface, time)
Public.new(Gui.beam, surface, nil, nil, time)

View File

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

View File

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

View File

@ -476,8 +476,8 @@ local function get_active_unit_groups_count()
return count
end
local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_settings)
if not forceSpawn then
local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_settings)
if not force_spawn then
if not is_boss_biter then
if not can_units_spawn() then
return
@ -556,7 +556,15 @@ local function spawn_biter(surface, position, forceSpawn, is_boss_biter, unit_se
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')
Public.set('active_biter_count', active_biter_count + 1)
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
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 increase_damage_per_wave = Public.get('increase_damage_per_wave')
if not increase_damage_per_wave then
@ -1140,7 +1213,6 @@ local function spawn_unit_group(fs, only_bosses)
Public.set('boss_wave', false)
end
else
event_data.boss_wave = true
local count = fs.scale or 30
event_data.spawn_count = count
for _ = 1, count, 1 do
@ -1272,10 +1344,10 @@ Event.on_nth_tick(
if game_lost then
return
end
local final_boss = Public.get('final_boss')
local final_battle = Public.get('final_battle')
local paused = Public.get('paused')
if paused and not final_boss then
if paused and not final_battle then
local players = game.connected_players
for _, player in pairs(players) do
Public.update_gui(player)
@ -1307,7 +1379,7 @@ Event.on_nth_tick(
tick_tasks_t2[t2]()
end
if final_boss then
if final_battle then
return
end
@ -1335,8 +1407,8 @@ Event.add(Public.events.on_spawn_unit_group, spawn_unit_group)
Event.on_nth_tick(
50,
function()
local final_boss = Public.get('final_boss')
if final_boss then
local final_battle = Public.get('final_battle')
if final_battle then
return
end
@ -1364,5 +1436,6 @@ Event.on_nth_tick(
Public.set_next_wave = set_next_wave
Public.normalize_spawn_position = normalize_spawn_position
Public.check_if_near_target = check_if_near_target
Public.spawn_worm = spawn_worm
return Public

View File

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

View File

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

View File

@ -216,8 +216,8 @@ else
end
function Public.build_nest()
local final_boss = Public.get('final_boss')
if final_boss then
local final_battle = Public.get('final_battle')
if final_battle then
return
end
@ -237,14 +237,14 @@ function Public.build_nest()
end
function Public.build_worm()
local final_boss = Public.get('final_boss')
local final_battle = Public.get('final_battle')
local threat = Public.get('threat')
if threat < 512 and not final_boss then
if threat < 512 and not final_battle then
return
end
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
end
@ -321,6 +321,68 @@ function Public.build_worm()
Public.set('threat', threat - Public.threat_values[worm])
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 threat = Public.get('threat')
if threat < 5000 then