mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-26 03:52:22 +02:00
Mtn v3 - add endgame content
Players must complete 5 randomized objectives to win the game. Winning the game will reset the game but increment the rounds_won key, which will make the game harder the more rounds the players survive.
This commit is contained in:
parent
dcb881b49d
commit
94666b740f
@ -152,18 +152,34 @@ locomotive_market_pickaxe=[font=default-bold]Pickaxe upgrades from market: [/fon
|
||||
locomotive_market_health=[font=default-bold]Health upgrades from market: [/font]
|
||||
locomotive_market_xp_points=[font=default-bold]XP points from market: [/font]
|
||||
|
||||
rounds_survived_tooltip=Winning the game increases this number by 1.\nLosing, decreases it by 1.
|
||||
zone_tooltip=Complete this objective by breaching/moving forward until you've reached the given zone.
|
||||
wave_tooltip=Complete this objective by surviving until the given wave.
|
||||
production_tooltip=Complete this objective by producing the given item(s).
|
||||
locomotive_tooltip=Complete this objective by purchasing the following item X times.
|
||||
time_until_attack_tooltip=Time in either minutes or seconds until the biters attack.
|
||||
generic_tooltip=Complete this and this objective will be marked as complete.
|
||||
win_conditions_tooltip=In order to win the game, you must complete all these objectives that are listed below! [img=utility/force_editor_icon]
|
||||
tooltip_failed=You've failed to complete this objective. [img=utility/not_available]
|
||||
tooltip_not_completed=This objective has not been completed. [img=utility/not_available]
|
||||
tooltip_completed=This objective has been completed. [img=utility/check_mark_green]
|
||||
tooltip_final=[entity=behemoth-biter] Final battle awaits.
|
||||
warp_tooltip=This is the time you have left before the train enters the boss zone.\nBe sure to pick up everything that you might need.
|
||||
|
||||
clock=within __3__/__4__ __5__ [img=utility/clock]
|
||||
not_done=__1__/__2__ [img=utility/not_available]
|
||||
not_done_empty=[img=utility/not_available]
|
||||
done=__2__/__2__ [img=utility/check_mark_green]
|
||||
done_empty=[img=utility/check_mark_green]
|
||||
|
||||
final_boss_message_start=[font=default-bold][color=blue]Mapkeeper:[/color]\nGet ready! Final battle awaits.[/font]
|
||||
time_until_attack=[font=default-bold]Time until annihilation:[/font]
|
||||
biter_sprites=[entity=behemoth-biter][entity=behemoth-biter][entity=behemoth-biter][entity=behemoth-biter][entity=behemoth-biter][entity=behemoth-biter][item=atomic-bomb]
|
||||
nom=GLHF! [img=utility/notification]
|
||||
won=Battle survived! [img=utility/check_mark_green]
|
||||
|
||||
win_conditions_tooltip=In order to win the game, you must complete all these objectives that are listed below! [img=utility/force_editor_icon]
|
||||
tooltip_failed=You've failed to complete this objective. [img=utility/not_available]
|
||||
tooltip_completed=This objective has been complete. [img=utility/check_mark_green]
|
||||
tooltip_1=Breaching zone: __1__ will mark this objective as complete.\nNote the main [entity=locomotive] needs to stay in this zone.
|
||||
tooltip_2=Surviving until wave: __1__ will mark this objective as complete.
|
||||
tooltip_3=Producing all the required items will mark this objective as complete.
|
||||
survive_for=[font=default-bold]Survive for:[/font]
|
||||
game_won=[font=default-bold]Game won! [/font][img=utility/check_mark_green]
|
||||
gather=[font=default-bold]Gather your belongings![/font]
|
||||
warp=[font=default-bold]Time until boss arena: [/font]
|
||||
|
||||
tooltip_final=[entity=behemoth-biter] Final battle awaits.
|
||||
|
@ -185,6 +185,36 @@ commands.add_command(
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'toggle_end_game',
|
||||
'Usable only for admins - initiates the final battle!',
|
||||
function()
|
||||
local player = game.player
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
if not player.admin then
|
||||
player.print("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
|
||||
local this = Public.get()
|
||||
|
||||
if not this.final_battle_are_you_sure then
|
||||
this.final_battle_are_you_sure = true
|
||||
player.print('[WARNING] This command will trigger the final battle, ONLY run this command again if you really want to do this!', Color.warning)
|
||||
return
|
||||
end
|
||||
|
||||
Public.stateful.set_stateful('final_battle', true)
|
||||
Public.set('final_battle', true)
|
||||
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
|
||||
this.final_battle_are_you_sure = nil
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'get_queue_speed',
|
||||
'Usable only for admins - gets the queue speed of this map!',
|
||||
|
@ -1415,6 +1415,11 @@ function Public.on_player_joined_game(event)
|
||||
-- top['mod_gui_top_frame'].destroy()
|
||||
-- end
|
||||
|
||||
local final_battle = Public.get('final_battle')
|
||||
if final_battle then
|
||||
return
|
||||
end
|
||||
|
||||
if player.surface.index ~= active_surface_index then
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
|
@ -608,6 +608,11 @@ local function do_chunk(event)
|
||||
end
|
||||
|
||||
local function on_chunk(event)
|
||||
local final_battle = Public.get('final_battle')
|
||||
if final_battle then
|
||||
return
|
||||
end
|
||||
|
||||
local force_chunk = Public.get('force_chunk')
|
||||
local stop_chunk = Public.get('stop_chunk')
|
||||
if stop_chunk then
|
||||
|
@ -3,8 +3,10 @@ local Public = {}
|
||||
local ICW = require 'maps.mountain_fortress_v3.icw.table'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local Task = require 'utils.task'
|
||||
local Gui = require 'utils.gui'
|
||||
local Token = require 'utils.token'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local Core = require 'utils.core'
|
||||
|
||||
local deepcopy = table.deepcopy
|
||||
local random = math.random
|
||||
@ -202,6 +204,22 @@ local function input_filtered(wagon_inventory, chest, chest_inventory, free_slot
|
||||
end
|
||||
end
|
||||
|
||||
function Public.disable_auto_minimap()
|
||||
local icw = ICW.get()
|
||||
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
local data = Public.get_player_data(icw, player)
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
Gui.clear_all_active_frames(player)
|
||||
data.auto = false
|
||||
Public.kill_minimap(player)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
function Public.hazardous_debris()
|
||||
local surface = WPT.get('loco_surface')
|
||||
if not surface or not surface.valid then
|
||||
@ -209,6 +227,7 @@ function Public.hazardous_debris()
|
||||
end
|
||||
local icw = ICW.get()
|
||||
local speed = icw.speed
|
||||
local final_battle = icw.final_battle
|
||||
|
||||
local hazardous_debris = icw.hazardous_debris
|
||||
if not hazardous_debris then
|
||||
@ -217,55 +236,109 @@ function Public.hazardous_debris()
|
||||
|
||||
local create = surface.create_entity
|
||||
|
||||
for _ = 1, 16 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'shotgun-pellet', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
if final_battle then
|
||||
for _ = 1, 16 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'slowdown-capsule', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'cannon-projectile', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'slowdown-capsule', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 4 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'atomic-bomb-wave-spawns-nuke-shockwave-explosion',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
for _ = 1, 4 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'atomic-bomb-wave-spawns-nuke-shockwave-explosion',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'uranium-cannon-projectile',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'slowdown-capsule',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
for _ = 1, 16 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'shotgun-pellet', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create({name = 'cannon-projectile', position = position, force = 'neutral', target = {position[1], position[2] + fallout_width * 2}, speed = speed})
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 4 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'atomic-bomb-wave-spawns-nuke-shockwave-explosion',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
for _ = 1, 6 * speed, 1 do
|
||||
local position = fallout_debris[random(1, size_of_debris)]
|
||||
local p = {x = position[1], y = position[2]}
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
create(
|
||||
{
|
||||
name = 'uranium-cannon-projectile',
|
||||
position = position,
|
||||
force = 'neutral',
|
||||
target = {position[1], position[2] + fallout_width * 2},
|
||||
speed = speed
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -813,6 +886,8 @@ function Public.migrate_wagon(icw, source, target)
|
||||
return
|
||||
end
|
||||
|
||||
target.minable = false
|
||||
|
||||
local target_wagon = target.unit_number
|
||||
local source_wagon = source.unit_number
|
||||
|
||||
|
@ -24,6 +24,7 @@ function Public.reset()
|
||||
this.doors = {}
|
||||
this.wagons = {}
|
||||
this.speed = 0.1
|
||||
this.final_battle = false
|
||||
this.hazardous_debris = true
|
||||
this.current_wagon_index = nil
|
||||
this.trains = {}
|
||||
@ -53,6 +54,17 @@ function Public.get(key)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set(key, value)
|
||||
if key and (value or value == false) then
|
||||
this[key] = value
|
||||
return this[key]
|
||||
elseif key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_wagon_area(tbl)
|
||||
if not tbl then
|
||||
return
|
||||
|
@ -460,6 +460,7 @@ local function on_research_finished(event)
|
||||
local message = ({'locomotive.discharge_unlocked'})
|
||||
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
|
||||
end
|
||||
|
||||
if name == 'artillery' then
|
||||
local message = ({'locomotive.artillery_unlocked'})
|
||||
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
|
||||
|
@ -6,7 +6,7 @@ Want to host it? Ask Gerkiz#0001 at discord!
|
||||
|
||||
]]
|
||||
-- develop setting
|
||||
local _DEV_MODE = true
|
||||
local _DEV_MODE = false
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local Public = require 'maps.mountain_fortress_v3.core'
|
||||
@ -282,6 +282,7 @@ function Public.reset_map()
|
||||
|
||||
Public.stateful.enable(true)
|
||||
Public.stateful.create()
|
||||
Public.stateful.reset_stateful()
|
||||
|
||||
if _DEV_MODE then
|
||||
Collapse.disable_collapse(true)
|
||||
|
@ -2,7 +2,7 @@ local Public = require 'maps.mountain_fortress_v3.stateful.table'
|
||||
local map_name = 'boss_room'
|
||||
|
||||
local bp =
|
||||
'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'
|
||||
|
||||
function Public.create()
|
||||
local surface =
|
||||
@ -71,4 +71,20 @@ function Public.nuke_world()
|
||||
Public.create()
|
||||
end
|
||||
|
||||
function Public.nuke_blueprint()
|
||||
local position = {x = -500, y = 503}
|
||||
local surface = game.get_surface('boss_room')
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local radius = 512
|
||||
local area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}
|
||||
for _, entity in pairs(surface.find_entities_filtered {area = area, name = 'programmable-speaker'}) do
|
||||
if entity and entity.valid then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
||||
|
@ -409,13 +409,16 @@ local function do_chunk(event)
|
||||
end
|
||||
|
||||
local function on_chunk(event)
|
||||
local force_chunk_until = Public.get_stateful('force_chunk_until')
|
||||
local force_chunk = Public.get_stateful('force_chunk')
|
||||
local stop_chunk = Public.get_stateful('stop_chunk')
|
||||
if stop_chunk then
|
||||
return
|
||||
end
|
||||
|
||||
if force_chunk then
|
||||
local tick = game.tick
|
||||
|
||||
if force_chunk and force_chunk_until > tick then
|
||||
do_chunk(event)
|
||||
else
|
||||
schedule_chunk(event)
|
||||
|
@ -5,11 +5,15 @@ local Gui = require 'utils.gui'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Core = require 'utils.core'
|
||||
local Server = require 'utils.server'
|
||||
|
||||
local main_button_name = Gui.uid_name()
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local boss_frame_name = Gui.uid_name()
|
||||
local close_button = Gui.uid_name()
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
|
||||
local function create_particles(surface, name, position, amount, cause_position)
|
||||
local d1 = (-100 + random(0, 200)) * 0.0004
|
||||
@ -56,6 +60,22 @@ local spread_particles_token =
|
||||
end
|
||||
)
|
||||
|
||||
local warn_player_sound_token =
|
||||
Token.register(
|
||||
function(event)
|
||||
local player_index = event.player_index
|
||||
local player = game.get_player(player_index)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
local particle = event.particle
|
||||
|
||||
player.play_sound {path = 'utility/new_objective', volume_modifier = 0.75}
|
||||
|
||||
create_particles(player.surface, particle, player.position, 128)
|
||||
end
|
||||
)
|
||||
|
||||
local function create_button(player)
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
@ -70,20 +90,51 @@ local function create_button(player)
|
||||
b.style.maximal_height = 38
|
||||
end
|
||||
|
||||
local function play_game_won_sound()
|
||||
local players = game.connected_players
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
player.play_sound {path = 'utility/game_won', volume_modifier = 0.75}
|
||||
Task.set_timeout_in_ticks(10, spread_particles_token, {player_index = player.index, particle = 'iron-ore-particle'})
|
||||
Task.set_timeout_in_ticks(15, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(20, spread_particles_token, {player_index = player.index, particle = 'copper-ore-particle'})
|
||||
Task.set_timeout_in_ticks(25, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(30, spread_particles_token, {player_index = player.index, particle = 'stone-particle'})
|
||||
Task.set_timeout_in_ticks(35, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(40, spread_particles_token, {player_index = player.index, particle = 'coal-particle'})
|
||||
Task.set_timeout_in_ticks(45, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
end
|
||||
local function play_game_won()
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
player.play_sound {path = 'utility/game_won', volume_modifier = 0.75}
|
||||
Task.set_timeout_in_ticks(10, spread_particles_token, {player_index = player.index, particle = 'iron-ore-particle'})
|
||||
Task.set_timeout_in_ticks(15, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(20, spread_particles_token, {player_index = player.index, particle = 'copper-ore-particle'})
|
||||
Task.set_timeout_in_ticks(25, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(30, spread_particles_token, {player_index = player.index, particle = 'stone-particle'})
|
||||
Task.set_timeout_in_ticks(35, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(40, spread_particles_token, {player_index = player.index, particle = 'coal-particle'})
|
||||
Task.set_timeout_in_ticks(45, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function play_achievement_unlocked()
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
player.play_sound {path = 'utility/achievement_unlocked', volume_modifier = 0.75}
|
||||
Task.set_timeout_in_ticks(10, spread_particles_token, {player_index = player.index, particle = 'iron-ore-particle'})
|
||||
Task.set_timeout_in_ticks(15, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(20, spread_particles_token, {player_index = player.index, particle = 'copper-ore-particle'})
|
||||
Task.set_timeout_in_ticks(25, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(30, spread_particles_token, {player_index = player.index, particle = 'stone-particle'})
|
||||
Task.set_timeout_in_ticks(35, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(40, spread_particles_token, {player_index = player.index, particle = 'coal-particle'})
|
||||
Task.set_timeout_in_ticks(45, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function alert_players_sound()
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
Task.set_timeout_in_ticks(10, warn_player_sound_token, {player_index = player.index, particle = 'iron-ore-particle'})
|
||||
Task.set_timeout_in_ticks(20, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(30, warn_player_sound_token, {player_index = player.index, particle = 'copper-ore-particle'})
|
||||
Task.set_timeout_in_ticks(40, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(50, warn_player_sound_token, {player_index = player.index, particle = 'stone-particle'})
|
||||
Task.set_timeout_in_ticks(60, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
Task.set_timeout_in_ticks(70, warn_player_sound_token, {player_index = player.index, particle = 'coal-particle'})
|
||||
Task.set_timeout_in_ticks(80, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function spacer(frame)
|
||||
@ -102,16 +153,20 @@ local function objective_frames(stateful, player_frame, objective, data)
|
||||
left_flow.style.horizontally_stretchable = true
|
||||
|
||||
if objective_name == 'single_item' then
|
||||
left_flow.add({type = 'label', caption = {'stateful.production_single'}})
|
||||
left_flow.add({type = 'label', caption = {'stateful.production_single'}, tooltip = {'stateful.production_tooltip'}})
|
||||
else
|
||||
left_flow.add({type = 'label', caption = {'stateful.production'}})
|
||||
left_flow.add({type = 'label', caption = {'stateful.production'}, tooltip = {'stateful.production_tooltip'}})
|
||||
end
|
||||
player_frame.add({type = 'line', direction = 'vertical'})
|
||||
local right_flow = tbl.add({type = 'flow'})
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
right_flow.style.horizontally_stretchable = true
|
||||
|
||||
data.supply_completed = right_flow.add({type = 'label', caption = '[img=utility/not_available]'})
|
||||
if stateful.objectives_completed.supplies then
|
||||
data.supply_completed = right_flow.add({type = 'label', caption = ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
|
||||
else
|
||||
data.supply_completed = right_flow.add({type = 'label', caption = ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
|
||||
end
|
||||
-- if objective[1]() then
|
||||
-- right_flow.add({type = 'label', caption = '[img=utility/check_mark_green]'})
|
||||
-- else
|
||||
@ -138,26 +193,26 @@ local function objective_frames(stateful, player_frame, objective, data)
|
||||
local callback_data = stateful.objectives.locomotive_market_selection[2]
|
||||
local callback = Token.get(callback_token)
|
||||
|
||||
local _, locale_left, locale_right = callback(callback_data)
|
||||
local _, locale_left, locale_right, tooltip = callback(callback_data)
|
||||
local tbl = player_frame.add {type = 'table', column_count = 2}
|
||||
tbl.style.horizontally_stretchable = true
|
||||
local left_flow = tbl.add({type = 'flow'})
|
||||
left_flow.style.horizontal_align = 'left'
|
||||
left_flow.style.horizontally_stretchable = true
|
||||
|
||||
left_flow.add({type = 'label', caption = locale_left})
|
||||
left_flow.add({type = 'label', caption = locale_left, tooltip = {'stateful.locomotive_tooltip'}})
|
||||
local right_flow = tbl.add({type = 'flow'})
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
right_flow.style.horizontally_stretchable = true
|
||||
|
||||
local locomotive_market = right_flow.add({type = 'label', caption = locale_right})
|
||||
local locomotive_market = right_flow.add({type = 'label', caption = locale_right, tooltip = tooltip})
|
||||
data.locomotive_market = locomotive_market
|
||||
return
|
||||
end
|
||||
|
||||
local callback = Token.get(objective[2])
|
||||
|
||||
local _, objective_locale_left, objective_locale_right = callback()
|
||||
local _, objective_locale_left, objective_locale_right, tooltip_left, tooltip_right = callback()
|
||||
|
||||
local tbl = player_frame.add {type = 'table', column_count = 2}
|
||||
tbl.style.horizontally_stretchable = true
|
||||
@ -167,20 +222,275 @@ local function objective_frames(stateful, player_frame, objective, data)
|
||||
|
||||
data.random_objectives = {}
|
||||
|
||||
left_flow.add({type = 'label', caption = objective_locale_left})
|
||||
left_flow.add({type = 'label', caption = objective_locale_left, tooltip = tooltip_left})
|
||||
local right_flow = tbl.add({type = 'flow'})
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
right_flow.style.horizontally_stretchable = true
|
||||
|
||||
local objective_locale_right_label = right_flow.add({type = 'label', caption = objective_locale_right})
|
||||
local objective_locale_right_label = right_flow.add({type = 'label', caption = objective_locale_right, tooltip = tooltip_right})
|
||||
data.random_objectives[#data.random_objectives + 1] = {name = objective_name, frame = objective_locale_right_label}
|
||||
end
|
||||
|
||||
local function boss_frame(player, alert)
|
||||
local main_winning_frame = player.gui.screen[main_frame_name]
|
||||
if main_winning_frame then
|
||||
Gui.remove_data_recursively(main_winning_frame)
|
||||
main_winning_frame.destroy()
|
||||
end
|
||||
local main_player_boss_frame = player.gui.screen[boss_frame_name]
|
||||
if main_player_boss_frame then
|
||||
Gui.remove_data_recursively(main_player_boss_frame)
|
||||
main_player_boss_frame.destroy()
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
local stateful = Public.get_stateful()
|
||||
local collection = stateful.collection
|
||||
|
||||
local frame = player.gui.screen.add {type = 'frame', name = boss_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical'}
|
||||
if not alert then
|
||||
frame.location = {x = 1, y = 45}
|
||||
else
|
||||
frame.location = {x = 1, y = 123}
|
||||
end
|
||||
frame.style.maximal_height = 500
|
||||
frame.style.minimal_width = 200
|
||||
frame.style.maximal_width = 400
|
||||
local rounds_survived_tbl = frame.add {type = 'table', column_count = 2}
|
||||
rounds_survived_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local rounds_survived_left_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_left_flow.style.horizontal_align = 'left'
|
||||
rounds_survived_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
rounds_survived_left_flow.add({type = 'label', caption = {'stateful.rounds_survived'}, tooltip = {'stateful.rounds_survived_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local rounds_survived_right_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_right_flow.style.horizontal_align = 'right'
|
||||
rounds_survived_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
data.rounds_survived_label = rounds_survived_right_flow.add({type = 'label', caption = stateful.rounds_survived})
|
||||
spacer(frame)
|
||||
|
||||
frame.add({type = 'line'})
|
||||
|
||||
spacer(frame)
|
||||
|
||||
if not collection.game_won then
|
||||
local objective_tbl = frame.add {type = 'table', column_count = 2}
|
||||
objective_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local attack_left_flow = objective_tbl.add({type = 'flow'})
|
||||
attack_left_flow.style.horizontal_align = 'left'
|
||||
attack_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
attack_left_flow.add({type = 'label', caption = {'stateful.time_until_attack'}, tooltip = {'stateful.time_until_attack_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local attack_right_flow = objective_tbl.add({type = 'flow'})
|
||||
attack_right_flow.style.horizontal_align = 'right'
|
||||
attack_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
local time_left = floor(collection.time_until_attack / 60 / 60) .. 'm'
|
||||
|
||||
if collection.time_until_attack / 60 / 60 <= 0 then
|
||||
time_left = floor(collection.time_until_attack / 60) .. 's'
|
||||
end
|
||||
|
||||
if collection.time_until_attack <= 0 then
|
||||
data.time_until_attack = attack_right_flow.add({type = 'label', caption = {'stateful.nom'}})
|
||||
else
|
||||
data.time_until_attack = attack_right_flow.add({type = 'label', caption = time_left})
|
||||
end
|
||||
|
||||
if collection.time_until_attack <= 0 then
|
||||
local survive_for_left_flow = objective_tbl.add({type = 'flow'})
|
||||
survive_for_left_flow.style.horizontal_align = 'left'
|
||||
survive_for_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
survive_for_left_flow.add({type = 'label', caption = {'stateful.survive_for'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local survive_for_right_flow = objective_tbl.add({type = 'flow'})
|
||||
survive_for_right_flow.style.horizontal_align = 'right'
|
||||
survive_for_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
local survive_for_timer = floor(collection.survive_for / 60 / 60) .. 'm'
|
||||
|
||||
if collection.survive_for / 60 / 60 <= 0 then
|
||||
survive_for_timer = floor(collection.survive_for / 60) .. 's'
|
||||
end
|
||||
|
||||
if collection.survive_for <= 0 then
|
||||
data.survive_for = survive_for_right_flow.add({type = 'label', caption = {'stateful.won'}})
|
||||
else
|
||||
data.survive_for = survive_for_right_flow.add({type = 'label', caption = survive_for_timer})
|
||||
end
|
||||
end
|
||||
-- new frame
|
||||
local biter_sprites_tbl = objective_tbl.add({type = 'flow'})
|
||||
biter_sprites_tbl.style.horizontal_align = 'left'
|
||||
biter_sprites_tbl.style.horizontally_stretchable = true
|
||||
|
||||
biter_sprites_tbl.add({type = 'label', caption = {'stateful.biter_sprites'}})
|
||||
else
|
||||
local objective_tbl = frame.add {type = 'table', column_count = 2}
|
||||
objective_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local game_won_left_flow = objective_tbl.add({type = 'flow'})
|
||||
game_won_left_flow.style.horizontal_align = 'left'
|
||||
game_won_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
game_won_left_flow.add({type = 'label', caption = {'stateful.game_won'}})
|
||||
end
|
||||
|
||||
local close = frame.add({type = 'button', name = close_button, caption = 'Close'})
|
||||
close.style.horizontally_stretchable = true
|
||||
Gui.set_data(frame, data)
|
||||
end
|
||||
|
||||
local function refresh_boss_frame()
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
boss_frame(player)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function main_frame(player)
|
||||
local main_player_frame = player.gui.screen[main_frame_name]
|
||||
if main_player_frame then
|
||||
Gui.remove_data_recursively(main_player_frame)
|
||||
main_player_frame.destroy()
|
||||
end
|
||||
|
||||
local data = {}
|
||||
|
||||
local stateful = Public.get_stateful()
|
||||
local breached_wall = Public.get('breached_wall')
|
||||
breached_wall = breached_wall - 1
|
||||
local wave_number = WD.get('wave_number')
|
||||
|
||||
local frame = player.gui.screen.add {type = 'frame', name = main_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical', tooltip = {'stateful.win_conditions_tooltip'}}
|
||||
frame.location = {x = 1, y = 45}
|
||||
frame.style.maximal_height = 500
|
||||
frame.style.minimal_width = 200
|
||||
frame.style.maximal_width = 400
|
||||
local rounds_survived_tbl = frame.add {type = 'table', column_count = 2}
|
||||
rounds_survived_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local rounds_survived_left_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_left_flow.style.horizontal_align = 'left'
|
||||
rounds_survived_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
rounds_survived_left_flow.add({type = 'label', caption = {'stateful.rounds_survived'}, tooltip = {'stateful.rounds_survived_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local rounds_survived_right_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_right_flow.style.horizontal_align = 'right'
|
||||
rounds_survived_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
data.rounds_survived_label = rounds_survived_right_flow.add({type = 'label', caption = stateful.rounds_survived})
|
||||
spacer(frame)
|
||||
|
||||
frame.add({type = 'line'})
|
||||
|
||||
spacer(frame)
|
||||
|
||||
if stateful.objectives_completed.boss_time then
|
||||
local objective_tbl = frame.add {type = 'table', column_count = 2}
|
||||
objective_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local gather_warning_flow = objective_tbl.add({type = 'flow'})
|
||||
gather_warning_flow.style.horizontal_align = 'left'
|
||||
gather_warning_flow.style.horizontally_stretchable = true
|
||||
|
||||
gather_warning_flow.add({type = 'label', caption = {'stateful.gather'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
|
||||
local warn_timer_flow_left = objective_tbl.add({type = 'flow'})
|
||||
warn_timer_flow_left.style.horizontal_align = 'left'
|
||||
warn_timer_flow_left.style.horizontally_stretchable = true
|
||||
|
||||
warn_timer_flow_left.add({type = 'label', caption = {'stateful.warp'}, tooltip = {'stateful.warp_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
|
||||
local warn_timer_flow_right = objective_tbl.add({type = 'flow'})
|
||||
warn_timer_flow_right.style.horizontal_align = 'right'
|
||||
warn_timer_flow_right.style.horizontally_stretchable = true
|
||||
|
||||
local time_left = floor(stateful.collection.gather_time / 60 / 60) .. 'm'
|
||||
|
||||
if stateful.collection.gather_time / 60 / 60 <= 0 then
|
||||
time_left = floor(stateful.collection.gather_time / 60) .. 's'
|
||||
end
|
||||
|
||||
data.gather_time_label = warn_timer_flow_right.add({type = 'label', caption = time_left})
|
||||
else
|
||||
local objective_tbl = frame.add {type = 'table', column_count = 2}
|
||||
objective_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local zone_left_flow = objective_tbl.add({type = 'flow'})
|
||||
zone_left_flow.style.horizontal_align = 'left'
|
||||
zone_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
zone_left_flow.add({type = 'label', caption = {'stateful.zone'}, tooltip = {'stateful.zone_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local zone_right_flow = objective_tbl.add({type = 'flow'})
|
||||
zone_right_flow.style.horizontal_align = 'right'
|
||||
zone_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
if breached_wall >= stateful.objectives.randomized_zone then
|
||||
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
|
||||
else
|
||||
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
|
||||
end
|
||||
|
||||
-- new frame
|
||||
local wave_left_flow = objective_tbl.add({type = 'flow'})
|
||||
wave_left_flow.style.horizontal_align = 'left'
|
||||
wave_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
wave_left_flow.add({type = 'label', caption = {'stateful.wave'}, tooltip = {'stateful.wave_tooltip'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local wave_right_flow = objective_tbl.add({type = 'flow'})
|
||||
wave_right_flow.style.horizontal_align = 'right'
|
||||
wave_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
if wave_number >= stateful.objectives.randomized_wave then
|
||||
data.randomized_wave_label = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
|
||||
else
|
||||
local randomized_wave = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
|
||||
data.randomized_wave_label = randomized_wave
|
||||
end
|
||||
|
||||
--dynamic conditions
|
||||
|
||||
for index = 1, #stateful.selected_objectives do
|
||||
local objective = stateful.selected_objectives[index]
|
||||
objective_frames(stateful, frame, objective, data)
|
||||
end
|
||||
end
|
||||
|
||||
-- warn players
|
||||
spacer(frame)
|
||||
frame.add({type = 'line'})
|
||||
spacer(frame)
|
||||
local final_label = frame.add({type = 'label', caption = {'stateful.tooltip_final'}})
|
||||
final_label.style.single_line = false
|
||||
spacer(frame)
|
||||
frame.add({type = 'line'})
|
||||
spacer(frame)
|
||||
|
||||
local close = frame.add({type = 'button', name = close_button, caption = 'Close'})
|
||||
close.style.horizontally_stretchable = true
|
||||
Gui.set_data(frame, data)
|
||||
end
|
||||
|
||||
local function update_data()
|
||||
local players = game.connected_players
|
||||
local stateful = Public.get_stateful()
|
||||
local breached_wall = Public.get('breached_wall')
|
||||
local wave_number = WD.get('wave_number')
|
||||
local collection = stateful.collection
|
||||
local supplies = stateful.objectives.supplies
|
||||
local single_item = stateful.objectives.single_item
|
||||
local callback_token = stateful.objectives.locomotive_market_selection[1]
|
||||
@ -191,7 +501,9 @@ local function update_data()
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local f = player.gui.screen[main_frame_name]
|
||||
local b = player.gui.screen[boss_frame_name]
|
||||
local data = Gui.get_data(f)
|
||||
local data_boss = Gui.get_data(b)
|
||||
|
||||
if data then
|
||||
if data.rounds_survived and data.rounds_survived.valid then
|
||||
@ -203,7 +515,7 @@ local function update_data()
|
||||
data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]'
|
||||
if not stateful.objectives_completed.randomized_zone_label then
|
||||
stateful.objectives_completed.randomized_zone_label = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
else
|
||||
data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]'
|
||||
@ -215,7 +527,7 @@ local function update_data()
|
||||
data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]'
|
||||
if not stateful.objectives_completed.randomized_wave_label then
|
||||
stateful.objectives_completed.randomized_wave_label = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
else
|
||||
data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]'
|
||||
@ -240,7 +552,7 @@ local function update_data()
|
||||
data.supply_completed.caption = ' [img=utility/check_mark_green]'
|
||||
if not stateful.objectives_completed.supplies then
|
||||
stateful.objectives_completed.supplies = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -255,7 +567,7 @@ local function update_data()
|
||||
frame.sprite = 'utility/check_mark_green'
|
||||
if not stateful.objectives_completed.single_item then
|
||||
stateful.objectives_completed.single_item = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
else
|
||||
frame.number = single_item.count
|
||||
@ -266,10 +578,19 @@ local function update_data()
|
||||
data.locomotive_market.caption = locale_right
|
||||
if locomotive_completed and not stateful.objectives_completed.locomotive_market then
|
||||
stateful.objectives_completed.locomotive_market = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
end
|
||||
|
||||
if data.gather_time_label and data.gather_time_label.valid then
|
||||
local time_left = floor(stateful.collection.gather_time / 60 / 60) .. 'm'
|
||||
|
||||
if stateful.collection.gather_time / 60 / 60 <= 0 then
|
||||
time_left = floor(stateful.collection.gather_time / 60) .. 's'
|
||||
end
|
||||
data.gather_time_label.caption = time_left
|
||||
end
|
||||
|
||||
if data.random_objectives and next(data.random_objectives) then
|
||||
for index = 1, #data.random_objectives do
|
||||
local frame_data = data.random_objectives[index]
|
||||
@ -284,13 +605,45 @@ local function update_data()
|
||||
frame.caption = objective_locale_right
|
||||
if completed and not stateful.objectives_completed[objective_name] then
|
||||
stateful.objectives_completed[objective_name] = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if data_boss then
|
||||
if data_boss.time_until_attack and data_boss.time_until_attack.valid then
|
||||
local time_left = floor(collection.time_until_attack / 60 / 60) .. 'm'
|
||||
if collection.time_until_attack / 60 / 60 < 1 then
|
||||
time_left = floor(collection.time_until_attack / 60) .. 's'
|
||||
end
|
||||
|
||||
if collection.time_until_attack <= 0 then
|
||||
data_boss.time_until_attack.caption = {'stateful.nom'}
|
||||
if not stateful.objectives_completed.warn_players then
|
||||
stateful.objectives_completed.warn_players = true
|
||||
alert_players_sound()
|
||||
refresh_boss_frame()
|
||||
end
|
||||
else
|
||||
data_boss.time_until_attack.caption = time_left
|
||||
end
|
||||
end
|
||||
if data_boss.survive_for and data_boss.survive_for.valid then
|
||||
local survive_for_timer = floor(collection.survive_for / 60 / 60) .. 'm'
|
||||
|
||||
if collection.survive_for / 60 / 60 <= 1 then
|
||||
survive_for_timer = floor(collection.survive_for / 60) .. 's'
|
||||
end
|
||||
|
||||
if collection.survive_for <= 0 then
|
||||
data_boss.survive_for.caption = {'stateful.won'}
|
||||
else
|
||||
data_boss.survive_for.caption = survive_for_timer
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -298,6 +651,8 @@ local function update_raw()
|
||||
local stateful = Public.get_stateful()
|
||||
local breached_wall = Public.get('breached_wall')
|
||||
local wave_number = WD.get('wave_number')
|
||||
local collection = stateful.collection
|
||||
local tick = game.tick
|
||||
local supplies = stateful.objectives.supplies
|
||||
local single_item = stateful.objectives.single_item
|
||||
local callback_token = stateful.objectives.locomotive_market_selection[1]
|
||||
@ -309,7 +664,8 @@ local function update_raw()
|
||||
if breached_wall >= stateful.objectives.randomized_zone then
|
||||
if not stateful.objectives_completed.randomized_zone_label then
|
||||
stateful.objectives_completed.randomized_zone_label = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
Server.to_discord_embed('Objective: **breach zone** has been complete!')
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
@ -317,7 +673,8 @@ local function update_raw()
|
||||
if wave_number >= stateful.objectives.randomized_wave then
|
||||
if not stateful.objectives_completed.randomized_wave_label then
|
||||
stateful.objectives_completed.randomized_wave_label = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
Server.to_discord_embed('Objective: **survive until wave** has been complete!')
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
@ -332,7 +689,8 @@ local function update_raw()
|
||||
if items_done == 3 then
|
||||
if not stateful.objectives_completed.supplies then
|
||||
stateful.objectives_completed.supplies = true
|
||||
play_game_won_sound()
|
||||
Server.to_discord_embed('Objective: **produce 3 items multiple times** has been complete!')
|
||||
play_achievement_unlocked()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
@ -342,15 +700,53 @@ local function update_raw()
|
||||
if single_item and single_item.count == 0 then
|
||||
if not stateful.objectives_completed.single_item then
|
||||
stateful.objectives_completed.single_item = true
|
||||
play_game_won_sound()
|
||||
play_achievement_unlocked()
|
||||
Server.to_discord_embed('Objective: **produce an item multiple times** has been completed!')
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if collection.time_until_attack then
|
||||
collection.time_until_attack = collection.time_until_attack_timer - tick
|
||||
if collection.time_until_attack > 0 then
|
||||
collection.time_until_attack = collection.time_until_attack
|
||||
elseif collection.time_until_attack and collection.time_until_attack < 0 then
|
||||
collection.time_until_attack = 0
|
||||
if not collection.nuke_blueprint then
|
||||
collection.nuke_blueprint = true
|
||||
Public.stateful_blueprints.nuke_blueprint()
|
||||
refresh_boss_frame()
|
||||
end
|
||||
end
|
||||
end
|
||||
if collection.survive_for and collection.survive_for_timer then
|
||||
collection.survive_for = collection.survive_for_timer - tick
|
||||
if not collection.survive_for_alerted and collection.time_until_attack == 0 then
|
||||
collection.survive_for_alerted = true
|
||||
refresh_boss_frame()
|
||||
end
|
||||
if collection.survive_for > 0 then
|
||||
collection.survive_for = collection.survive_for
|
||||
elseif collection.survive_for and collection.survive_for < 0 then
|
||||
collection.survive_for = 0
|
||||
if collection.game_won and not collection.game_won_notified then
|
||||
collection.game_won_notified = true
|
||||
refresh_boss_frame()
|
||||
play_game_won()
|
||||
local locomotive = Public.get('locomotive')
|
||||
if locomotive and locomotive.valid then
|
||||
locomotive.surface.spill_item_stack(locomotive.position, {name = 'coin', count = 512}, false)
|
||||
Public.set('game_reset_tick', 5400)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if locomotive_completed then
|
||||
if not stateful.objectives_completed.locomotive_market then
|
||||
stateful.objectives_completed.locomotive_market = true
|
||||
play_game_won_sound()
|
||||
Server.to_discord_embed('Objective: **locomotive purchase** has been completed!')
|
||||
play_achievement_unlocked()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
@ -362,110 +758,34 @@ local function update_raw()
|
||||
local completed, _, _ = callback()
|
||||
if completed and completed == true and not stateful.objectives_completed[objective_name] then
|
||||
stateful.objectives_completed[objective_name] = true
|
||||
play_game_won_sound()
|
||||
Server.to_discord_embed('Objective: **' .. objective_name .. '** has been completed!')
|
||||
play_achievement_unlocked()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function main_frame(player)
|
||||
local main_player_frame = player.gui.screen[main_frame_name]
|
||||
if main_player_frame then
|
||||
Gui.remove_data_recursively(main_player_frame)
|
||||
main_player_frame.destroy()
|
||||
return
|
||||
if stateful.collection.gather_time and tick >= stateful.collection.gather_time then
|
||||
stateful.collection.final_battle = true
|
||||
Public.set('final_battle', true)
|
||||
end
|
||||
|
||||
local data = {}
|
||||
if stateful.objectives_completed_count == 5 and not stateful.objectives_completed.boss_time then
|
||||
stateful.objectives_completed.boss_time = true
|
||||
Server.to_discord_embed('All objectives has been completed!')
|
||||
stateful.collection.gather_time = tick + 54000
|
||||
play_achievement_unlocked()
|
||||
|
||||
local stateful = Public.get_stateful()
|
||||
local breached_wall = Public.get('breached_wall')
|
||||
breached_wall = breached_wall - 1
|
||||
local wave_number = WD.get('wave_number')
|
||||
|
||||
local frame = player.gui.screen.add {type = 'frame', name = main_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical'}
|
||||
frame.location = {x = 1, y = 45}
|
||||
frame.style.maximal_height = 500
|
||||
frame.style.minimal_width = 200
|
||||
frame.style.maximal_width = 400
|
||||
local rounds_survived_tbl = frame.add {type = 'table', column_count = 2}
|
||||
rounds_survived_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local rounds_survived_left_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_left_flow.style.horizontal_align = 'left'
|
||||
rounds_survived_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
rounds_survived_left_flow.add({type = 'label', caption = {'stateful.rounds_survived'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local rounds_survived_right_flow = rounds_survived_tbl.add({type = 'flow'})
|
||||
rounds_survived_right_flow.style.horizontal_align = 'right'
|
||||
rounds_survived_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
data.rounds_survived_label = rounds_survived_right_flow.add({type = 'label', caption = stateful.rounds_survived})
|
||||
spacer(frame)
|
||||
|
||||
frame.add({type = 'line'})
|
||||
|
||||
spacer(frame)
|
||||
|
||||
local objective_tbl = frame.add {type = 'table', column_count = 2}
|
||||
objective_tbl.style.horizontally_stretchable = true
|
||||
|
||||
local zone_left_flow = objective_tbl.add({type = 'flow'})
|
||||
zone_left_flow.style.horizontal_align = 'left'
|
||||
zone_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
zone_left_flow.add({type = 'label', caption = {'stateful.zone'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local zone_right_flow = objective_tbl.add({type = 'flow'})
|
||||
zone_right_flow.style.horizontal_align = 'right'
|
||||
zone_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
if breached_wall >= stateful.objectives.randomized_zone then
|
||||
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]'})
|
||||
else
|
||||
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]'})
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
local frame = player.gui.screen[main_frame_name]
|
||||
if frame then
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
boss_frame(player)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- new frame
|
||||
local wave_left_flow = objective_tbl.add({type = 'flow'})
|
||||
wave_left_flow.style.horizontal_align = 'left'
|
||||
wave_left_flow.style.horizontally_stretchable = true
|
||||
|
||||
wave_left_flow.add({type = 'label', caption = {'stateful.wave'}})
|
||||
frame.add({type = 'line', direction = 'vertical'})
|
||||
local wave_right_flow = objective_tbl.add({type = 'flow'})
|
||||
wave_right_flow.style.horizontal_align = 'right'
|
||||
wave_right_flow.style.horizontally_stretchable = true
|
||||
|
||||
if wave_number >= stateful.objectives.randomized_wave then
|
||||
data.randomized_wave_label = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]'})
|
||||
else
|
||||
local randomized_wave = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]'})
|
||||
data.randomized_wave_label = randomized_wave
|
||||
end
|
||||
|
||||
--dynamic conditions
|
||||
|
||||
for index = 1, #stateful.selected_objectives do
|
||||
local objective = stateful.selected_objectives[index]
|
||||
objective_frames(stateful, frame, objective, data)
|
||||
end
|
||||
|
||||
-- warn players
|
||||
spacer(frame)
|
||||
frame.add({type = 'line'})
|
||||
spacer(frame)
|
||||
local final_label = frame.add({type = 'label', caption = {'stateful.tooltip_final'}})
|
||||
final_label.style.single_line = false
|
||||
spacer(frame)
|
||||
frame.add({type = 'line'})
|
||||
spacer(frame)
|
||||
|
||||
local close = frame.add({type = 'button', name = close_button, caption = 'Close'})
|
||||
close.style.horizontally_stretchable = true
|
||||
Gui.set_data(frame, data)
|
||||
-- update_world_gui(player)
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
@ -482,7 +802,7 @@ end
|
||||
Gui.on_click(
|
||||
main_button_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 stateful Button')
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 open stateful Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
@ -492,8 +812,19 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
local frame = player.gui.screen[main_frame_name]
|
||||
if player.character and player.character.valid then
|
||||
local final_battle = Public.get_stateful('final_battle')
|
||||
|
||||
if final_battle then
|
||||
local frame = player.gui.screen[boss_frame_name]
|
||||
if frame then
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
else
|
||||
Gui.clear_all_active_frames(player)
|
||||
boss_frame(player)
|
||||
end
|
||||
else
|
||||
local frame = player.gui.screen[main_frame_name]
|
||||
if frame then
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
@ -508,7 +839,7 @@ Gui.on_click(
|
||||
Gui.on_click(
|
||||
close_button,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 stateful Button')
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 close stateful Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
@ -524,6 +855,13 @@ Gui.on_click(
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
end
|
||||
|
||||
local frame_boss = player.gui.screen[boss_frame_name]
|
||||
|
||||
if frame_boss then
|
||||
Gui.remove_data_recursively(frame_boss)
|
||||
frame_boss.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
@ -531,4 +869,6 @@ Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.on_nth_tick(60, update_data)
|
||||
Event.on_nth_tick(120, update_raw)
|
||||
|
||||
Public.boss_frame = boss_frame
|
||||
|
||||
return Public
|
||||
|
@ -38,18 +38,31 @@ Event.on_nth_tick(
|
||||
return
|
||||
end
|
||||
|
||||
Public.set('final_battle', true)
|
||||
Public.allocate()
|
||||
|
||||
local spawn_positions = Public.stateful_spawn_points
|
||||
local sizeof = Public.sizeof_stateful_spawn_points
|
||||
local collection = Public.get_stateful('collection')
|
||||
if not collection then
|
||||
return
|
||||
end
|
||||
|
||||
local area = spawn_positions[random(1, sizeof)]
|
||||
if collection.time_until_attack and collection.time_until_attack <= 0 and collection.survive_for > 0 then
|
||||
local spawn_positions = Public.stateful_spawn_points
|
||||
local sizeof = Public.sizeof_stateful_spawn_points
|
||||
|
||||
shuffle(area)
|
||||
local area = spawn_positions[random(1, sizeof)]
|
||||
|
||||
WD.set_spawn_position(area[1])
|
||||
Event.raise(WD.events.on_spawn_unit_group, {fs = true, bypass = true})
|
||||
shuffle(area)
|
||||
|
||||
WD.set_spawn_position(area[1])
|
||||
Event.raise(WD.events.on_spawn_unit_group, {fs = true, bypass = true})
|
||||
return
|
||||
end
|
||||
|
||||
if collection.time_until_attack and collection.survive_for and collection.survive_for == 0 then
|
||||
if not collection.game_won then
|
||||
collection.game_won = true
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
@ -6,8 +6,12 @@ local shuffle = table.shuffle_table
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local format_number = require 'util'.format_number
|
||||
local ICW = require 'maps.mountain_fortress_v3.icw.main'
|
||||
local ICWF = require 'maps.mountain_fortress_v3.icw.functions'
|
||||
local ICWT = require 'maps.mountain_fortress_v3.icw.table'
|
||||
local Core = require 'utils.core'
|
||||
local Public = require 'maps.mountain_fortress_v3.table'
|
||||
local Task = require 'utils.task'
|
||||
local Alert = require 'utils.alert'
|
||||
|
||||
local this = {
|
||||
enabled = false,
|
||||
@ -91,15 +95,10 @@ local function get_killed_enemies_count(primary, secondary)
|
||||
return count
|
||||
end
|
||||
|
||||
local apply_settings =
|
||||
local move_all_players_token =
|
||||
Token.register(
|
||||
function(data)
|
||||
local settings = data and data.value or nil
|
||||
if not settings then
|
||||
return
|
||||
end
|
||||
|
||||
Server.set_data(dataset, dataset_key, settings)
|
||||
function()
|
||||
Public.move_all_players()
|
||||
end
|
||||
)
|
||||
|
||||
@ -108,10 +107,10 @@ local locomotive_market_pickaxe_token =
|
||||
function(count)
|
||||
local upgrades = Public.get('upgrades')
|
||||
if upgrades.pickaxe_tier >= count then
|
||||
return true, {'stateful.locomotive_market_pickaxe'}, {'stateful.done', count, count}
|
||||
return true, {'stateful.locomotive_market_pickaxe'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_pickaxe'}, {'stateful.not_done', upgrades.pickaxe_tier, count}
|
||||
return false, {'stateful.locomotive_market_pickaxe'}, {'stateful.not_done', upgrades.pickaxe_tier, count}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -120,10 +119,10 @@ local locomotive_market_health_token =
|
||||
function(count)
|
||||
local upgrades = Public.get('upgrades')
|
||||
if upgrades.health_upgrades >= count then
|
||||
return true, {'stateful.locomotive_market_health'}, {'stateful.done', count, count}
|
||||
return true, {'stateful.locomotive_market_health'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_health'}, {'stateful.not_done', upgrades.health_upgrades, count}
|
||||
return false, {'stateful.locomotive_market_health'}, {'stateful.not_done', upgrades.health_upgrades, count}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -132,10 +131,10 @@ local locomotive_market_xp_points_token =
|
||||
function(count)
|
||||
local upgrades = Public.get('upgrades')
|
||||
if upgrades.xp_points_upgrade >= count then
|
||||
return true, {'stateful.locomotive_market_xp_points'}, {'stateful.done', count, count}
|
||||
return true, {'stateful.locomotive_market_xp_points'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_xp_points'}, {'stateful.not_done', upgrades.xp_points_upgrade, count}
|
||||
return false, {'stateful.locomotive_market_xp_points'}, {'stateful.not_done', upgrades.xp_points_upgrade, count}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -151,10 +150,10 @@ local killed_enemies_token =
|
||||
function()
|
||||
local enemies_killed = Public.get_killed_enemies_count('biter', 'spitter')
|
||||
if enemies_killed >= this.objectives.killed_enemies then
|
||||
return true, {'stateful.enemies_killed'}, {'stateful.done', format_number(this.objectives.killed_enemies, true), format_number(this.objectives.killed_enemies)}
|
||||
return true, {'stateful.enemies_killed'}, {'stateful.done', format_number(this.objectives.killed_enemies, true), format_number(this.objectives.killed_enemies)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
|
||||
return false, {'stateful.enemies_killed'}, {'stateful.not_done', format_number(enemies_killed, true), format_number(this.objectives.killed_enemies, true)}
|
||||
return false, {'stateful.enemies_killed'}, {'stateful.not_done', format_number(enemies_killed, true), format_number(this.objectives.killed_enemies, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -163,9 +162,9 @@ local complete_mystical_chest_amount_token =
|
||||
function()
|
||||
local mystical_chest_completed = Public.get('mystical_chest_completed')
|
||||
if mystical_chest_completed >= this.objectives.complete_mystical_chest_amount then
|
||||
return true, {'stateful.mystical_chest'}, {'stateful.done', this.objectives.complete_mystical_chest_amount, this.objectives.complete_mystical_chest_amount}
|
||||
return true, {'stateful.mystical_chest'}, {'stateful.done', this.objectives.complete_mystical_chest_amount, this.objectives.complete_mystical_chest_amount}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
return false, {'stateful.mystical_chest'}, {'stateful.not_done', mystical_chest_completed, this.objectives.complete_mystical_chest_amount}
|
||||
return false, {'stateful.mystical_chest'}, {'stateful.not_done', mystical_chest_completed, this.objectives.complete_mystical_chest_amount}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -175,9 +174,9 @@ local research_level_selection_token =
|
||||
local actual = this.objectives.research_level_count
|
||||
local expected = this.objectives.research_level_selection.count
|
||||
if actual >= expected then
|
||||
return true, {'stateful.research', this.objectives.research_level_selection.name}, {'stateful.done', expected, expected}
|
||||
return true, {'stateful.research', this.objectives.research_level_selection.name}, {'stateful.done', expected, expected}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
return false, {'stateful.research', this.objectives.research_level_selection.name}, {'stateful.not_done', actual, expected}
|
||||
return false, {'stateful.research', this.objectives.research_level_selection.name}, {'stateful.not_done', actual, expected}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -186,9 +185,9 @@ local trees_farmed_token =
|
||||
function()
|
||||
local trees = get_entity_mined_count('tree')
|
||||
if trees >= this.objectives.trees_farmed then
|
||||
return true, {'stateful.trees_mined'}, {'stateful.done', format_number(this.objectives.trees_farmed, true), format_number(this.objectives.trees_farmed, true)}
|
||||
return true, {'stateful.trees_mined'}, {'stateful.done', format_number(this.objectives.trees_farmed, true), format_number(this.objectives.trees_farmed, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
return false, {'stateful.trees_mined'}, {'stateful.not_done', format_number(trees, true), format_number(this.objectives.trees_farmed, true)}
|
||||
return false, {'stateful.trees_mined'}, {'stateful.not_done', format_number(trees, true), format_number(this.objectives.trees_farmed, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -197,9 +196,9 @@ local rocks_farmed_token =
|
||||
function()
|
||||
local rocks = get_entity_mined_count('rock')
|
||||
if rocks >= this.objectives.rocks_farmed then
|
||||
return true, {'stateful.rocks_mined'}, {'stateful.done', format_number(this.objectives.rocks_farmed, true), format_number(this.objectives.rocks_farmed, true)}
|
||||
return true, {'stateful.rocks_mined'}, {'stateful.done', format_number(this.objectives.rocks_farmed, true), format_number(this.objectives.rocks_farmed, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
return false, {'stateful.rocks_mined'}, {'stateful.not_done', format_number(rocks, true), format_number(this.objectives.rocks_farmed, true)}
|
||||
return false, {'stateful.rocks_mined'}, {'stateful.not_done', format_number(rocks, true), format_number(this.objectives.rocks_farmed, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -208,9 +207,9 @@ local rockets_launched_token =
|
||||
function()
|
||||
local launched = game.forces.player.rockets_launched
|
||||
if launched >= this.objectives.rockets_launched then
|
||||
return true, {'stateful.launch_rockets'}, {'stateful.done', format_number(this.objectives.rockets_launched, true), format_number(this.objectives.rockets_launched, true)}
|
||||
return true, {'stateful.launch_rockets'}, {'stateful.done', format_number(this.objectives.rockets_launched, true), format_number(this.objectives.rockets_launched, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
|
||||
end
|
||||
return false, {'stateful.launch_rockets'}, {'stateful.not_done', format_number(launched, true), format_number(this.objectives.rockets_launched, true)}
|
||||
return false, {'stateful.launch_rockets'}, {'stateful.not_done', format_number(launched, true), format_number(this.objectives.rockets_launched, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
|
||||
end
|
||||
)
|
||||
|
||||
@ -365,6 +364,58 @@ local function get_random_objectives()
|
||||
}
|
||||
end
|
||||
|
||||
local apply_settings_token =
|
||||
Token.register(
|
||||
function(data)
|
||||
local settings = data and data.value or nil
|
||||
if not settings then
|
||||
return
|
||||
end
|
||||
|
||||
local rounds_survived = settings.rounds_survived
|
||||
|
||||
Public.increase_enemy_damage_and_health()
|
||||
|
||||
this.rounds_survived = rounds_survived
|
||||
this.objectives_completed = {}
|
||||
this.objectives_completed_count = 0
|
||||
this.final_battle = false
|
||||
this.selected_objectives = get_random_objectives()
|
||||
this.objectives = {
|
||||
randomized_zone = scale(random(7, 20), 40),
|
||||
randomized_wave = scale(random(500, 2000), 4000),
|
||||
supplies = get_random_items(),
|
||||
single_item = get_random_item(),
|
||||
killed_enemies = scale(random(500000, 3000000), 10000000),
|
||||
complete_mystical_chest_amount = scale(random(10, 50), 500),
|
||||
research_level_selection = get_random_research_recipe(),
|
||||
research_level_count = 0,
|
||||
locomotive_market_selection = get_random_locomotive_tier(),
|
||||
trees_farmed = scale(random(5000, 100000), 400000),
|
||||
rocks_farmed = scale(random(50000, 500000), 4000000),
|
||||
rockets_launched = scale(random(100, 500), 5000)
|
||||
}
|
||||
this.collection = {
|
||||
time_until_attack = nil,
|
||||
time_until_attack_timer = nil,
|
||||
survive_for = nil,
|
||||
survive_for_timer = nil
|
||||
}
|
||||
this.force_chunk = true
|
||||
this.force_chunk_until = game.tick + 1000
|
||||
|
||||
Server.set_data(dataset, dataset_key, settings)
|
||||
end
|
||||
)
|
||||
|
||||
function Public.save_settings()
|
||||
local settings = {
|
||||
rounds_survived = this.rounds_survived
|
||||
}
|
||||
|
||||
Server.set_data(dataset, dataset_key, settings)
|
||||
end
|
||||
|
||||
function Public.reset_stateful()
|
||||
this.objectives_completed = {}
|
||||
this.objectives_completed_count = 0
|
||||
@ -384,12 +435,22 @@ function Public.reset_stateful()
|
||||
rocks_farmed = scale(random(50000, 500000), 4000000),
|
||||
rockets_launched = scale(random(100, 500), 5000)
|
||||
}
|
||||
this.collection = {
|
||||
time_until_attack = nil,
|
||||
time_until_attack_timer = nil,
|
||||
survive_for = nil,
|
||||
survive_for_timer = nil
|
||||
}
|
||||
this.force_chunk = true
|
||||
this.force_chunk_until = game.tick + 1000
|
||||
end
|
||||
|
||||
function Public.migrate_and_create(locomotive)
|
||||
local carriages = Public.get('carriages')
|
||||
local surface = game.get_surface('boss_room')
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
local position = locomotive.position
|
||||
|
||||
for _, entity in pairs(carriages) do
|
||||
@ -409,17 +470,32 @@ function Public.move_all_players()
|
||||
if not market or not market.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = market.surface
|
||||
local spawn_pos = surface.find_non_colliding_position('character', market.position, 3, 0, 5)
|
||||
|
||||
if spawn_pos then
|
||||
game.forces.player.set_spawn_position(spawn_pos, surface)
|
||||
else
|
||||
game.forces.player.set_spawn_position(market.position, surface)
|
||||
end
|
||||
|
||||
ICWF.disable_auto_minimap()
|
||||
|
||||
local message = ({'stateful.final_boss_message_start'})
|
||||
Alert.alert_all_players(50, message, nil, nil, 1)
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
local pos = surface.find_non_colliding_position('character', market.position, 3, 0, 5)
|
||||
|
||||
Public.stateful_gui.boss_frame(player, true)
|
||||
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = market.position
|
||||
player.teleport(pos, surface)
|
||||
Public.unstuck(player.index)
|
||||
Public.unstuck_player(player.index)
|
||||
end
|
||||
end
|
||||
)
|
||||
@ -429,11 +505,41 @@ function Public.allocate()
|
||||
local stateful_locomotive = Public.get_stateful('stateful_locomotive')
|
||||
local stateful_locomotive_migrated = Public.get_stateful('stateful_locomotive_migrated')
|
||||
if stateful_locomotive and not stateful_locomotive_migrated then
|
||||
-- Public.move_all_players()
|
||||
Task.set_timeout_in_ticks(100, move_all_players_token, {})
|
||||
|
||||
Public.set_stateful('stateful_locomotive_migrated', true)
|
||||
local locomotive = Public.get('locomotive')
|
||||
local icw_data = ICW.migrate_wagon(locomotive, stateful_locomotive)
|
||||
local surface = game.get_surface('boss_room')
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
ICWT.set('speed', 0.3)
|
||||
ICWT.set('final_battle', true)
|
||||
|
||||
local collection = Public.get_stateful('collection')
|
||||
if not collection then
|
||||
return
|
||||
end
|
||||
|
||||
Server.to_discord_embed('Final boss wave is occuring soon!')
|
||||
|
||||
WD.set('final_boss', true)
|
||||
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
local wd = player.gui.top['wave_defense']
|
||||
if wd and wd.valid then
|
||||
wd.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
collection.time_until_attack = 54000 + game.tick
|
||||
collection.time_until_attack_timer = 54000 + game.tick
|
||||
collection.survive_for = collection.time_until_attack_timer + scale(random(18000, 54000), 216000)
|
||||
collection.survive_for_timer = collection.survive_for
|
||||
|
||||
Public.set_target(stateful_locomotive, icw_data)
|
||||
game.forces.player.chart(surface, {{-358, -151}, {358, 151}})
|
||||
@ -508,9 +614,7 @@ Event.add(
|
||||
|
||||
this.settings_applied = true
|
||||
|
||||
Public.increase_enemy_damage_and_health()
|
||||
|
||||
Server.try_get_data(dataset, dataset_key, apply_settings)
|
||||
Server.try_get_data(dataset, dataset_key, apply_settings_token)
|
||||
end
|
||||
)
|
||||
|
||||
|
@ -66,10 +66,19 @@ local function get_threat_gain()
|
||||
end
|
||||
|
||||
function Public.update_gui(player)
|
||||
local final_boss = Public.get('final_boss')
|
||||
if final_boss then
|
||||
if player.gui.top.wave_defense and player.gui.top.wave_defense.valid then
|
||||
player.gui.top.wave_defense.destroy()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top.wave_defense then
|
||||
create_gui(player)
|
||||
end
|
||||
local gui = player.gui.top.wave_defense
|
||||
|
||||
local biter_health_boost = 1
|
||||
local biter_health_boosts = BiterHealthBooster.get('biter_health_boost')
|
||||
if biter_health_boost then
|
||||
|
@ -1252,6 +1252,7 @@ Event.on_nth_tick(
|
||||
if game_lost then
|
||||
return
|
||||
end
|
||||
local final_boss = Public.get('final_boss')
|
||||
|
||||
local paused = Public.get('paused')
|
||||
if paused then
|
||||
@ -1286,6 +1287,10 @@ Event.on_nth_tick(
|
||||
tick_tasks_t2[t2]()
|
||||
end
|
||||
|
||||
if final_boss then
|
||||
return
|
||||
end
|
||||
|
||||
local players = game.connected_players
|
||||
for _, player in pairs(players) do
|
||||
Public.update_gui(player)
|
||||
@ -1306,6 +1311,11 @@ 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
|
||||
return
|
||||
end
|
||||
|
||||
local tick_to_spawn_unit_groups = Public.get('tick_to_spawn_unit_groups')
|
||||
local tick = game.tick
|
||||
local will_not_spawn = tick % tick_to_spawn_unit_groups ~= 0
|
||||
|
@ -70,6 +70,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.max_active_biters = 1280
|
||||
this.max_active_unit_groups = 32
|
||||
this.max_biter_age = 3600 * 60
|
||||
|
Loading…
x
Reference in New Issue
Block a user