mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-26 22:56:43 +02:00
Mtn v3 - stateful changes
This commit is contained in:
parent
9aa278b1e9
commit
a45e9ef598
@ -1,7 +1,7 @@
|
||||
[mountain_fortress_v3]
|
||||
map_info_main_caption=M O U N T A I N F O R T R E S S V3
|
||||
map_info_sub_caption= ~~ diggy diggy choo choo ~~
|
||||
map_info_text=[color=red]READ THIS!\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz!\nIf there are any game breaking bugs then this map might be shutdown to hot-fix the issue.[/color]\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn addition, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the train aura prevents biters from spawning when mining entities.\n\nRadars cannot be built near each other.\n\nRPG GUI is disabled inside the train.\n\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the train aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\n\nMining drills have great mining-bonus which also is increased after each research, use them when you can!\n\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
|
||||
map_info_sub_caption= ~~ diggy diggy rocky rocky ~~
|
||||
map_info_text=[color=red][img=utility/danger_icon] READ THIS! [img=utility/danger_icon]\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz!\nIf there are any game breaking bugs then this map might be shutdown to hot-fix the issue.[/color]\n\nCheck out the [img=utility/custom_tag_icon] for information regarding on how one can win the game!\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn addition, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the train aura prevents biters from spawning when mining entities.\n\nRadars cannot be built near each other.\n\nRPG GUI is disabled inside the train.\n\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the train aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\n\nMining drills have great mining-bonus which also is increased after each research, use them when you can!\n\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
|
||||
|
||||
[breached_wall]
|
||||
collapse_start=[color=blue]Mapkeeper:[/color]\nWarning, Collapse has begun!
|
||||
@ -133,3 +133,37 @@ diff_tooltip=Wave Defense is based on amount of players.\nBonus XP on join: __1_
|
||||
[functions]
|
||||
researched_complete=__1__ has been researched!
|
||||
|
||||
[stateful]
|
||||
win_conditions=Win conditions
|
||||
|
||||
rounds_survived=[font=default-bold]Rounds survived: [/font]
|
||||
zone=[font=default-bold]Breach zones: [/font]
|
||||
wave=[font=default-bold]Survive until wave: [/font]
|
||||
mystical_chest=[font=default-bold]Feeding the hungry chest: [/font]
|
||||
enemies_killed=[font=default-bold]Enemies killed: [/font]
|
||||
launch_rockets=[font=default-bold]Rockets launched: [/font]
|
||||
rocks_mined=[font=default-bold]Rocks mined: [/font]
|
||||
trees_mined=[font=default-bold]Trees mined: [/font]
|
||||
production=[font=default-bold]Produce the following items: [/font]
|
||||
production_single=[font=default-bold]Produce the following item: [/font]
|
||||
research=[font=default-bold]Research __1__: [/font]
|
||||
|
||||
locomotive_market_pickaxe=[font=default-bold]Pickaxe upgrades from market: [/font]
|
||||
locomotive_market_health=[font=default-bold]Health upgrades from market: [/font]
|
||||
locomotive_market_xp_points=[font=default-bold]XP points from market: [/font]
|
||||
|
||||
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]
|
||||
|
||||
|
||||
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.
|
||||
|
||||
tooltip_final=[entity=behemoth-biter] Final battle awaits.
|
||||
|
@ -207,7 +207,7 @@ commands.add_command(
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'toggle_collapse',
|
||||
'disable_collapse',
|
||||
'Toggles the collapse feature',
|
||||
function()
|
||||
local player = game.player
|
||||
@ -217,19 +217,21 @@ commands.add_command(
|
||||
player.print("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
if not Collapse.start_now() then
|
||||
Collapse.start_now(true)
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has started collapse!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
if Collapse.get_disable_state() then
|
||||
Collapse.disable_collapse(false)
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled collapse!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
log(player.name .. ', has enabled collapse!')
|
||||
else
|
||||
Collapse.start_now(false)
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has stopped collapse!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
Collapse.disable_collapse(true)
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled collapse!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
log(player.name .. ', has disabled collapse!')
|
||||
end
|
||||
else
|
||||
if not Collapse.start_now() then
|
||||
Collapse.start_now(true)
|
||||
if Collapse.get_disable_state() then
|
||||
Collapse.disable_collapse(false)
|
||||
log('Collapse has started.')
|
||||
else
|
||||
Collapse.start_now(false)
|
||||
Collapse.disable_collapse(true)
|
||||
log('Collapse has stopped.')
|
||||
end
|
||||
end
|
||||
|
@ -28,5 +28,6 @@ Public.linked_chests = require 'maps.mountain_fortress_v3.locomotive.linked_ches
|
||||
Public.market = require 'maps.mountain_fortress_v3.locomotive.market'
|
||||
Public.permission_groups = require 'maps.mountain_fortress_v3.locomotive.permission_groups'
|
||||
Public.spawn_locomotive = require 'maps.mountain_fortress_v3.locomotive.spawn_locomotive'
|
||||
Public.stateful = require 'maps.mountain_fortress_v3.stateful.main'
|
||||
|
||||
return Public
|
||||
|
@ -282,9 +282,17 @@ local function is_protected(e)
|
||||
if string.sub(e.surface.name, 0, #map_name) ~= map_name then
|
||||
return true
|
||||
end
|
||||
|
||||
local boss_map_name = 'boss_room'
|
||||
|
||||
if string.sub(e.surface.name, 0, #boss_map_name) ~= boss_map_name then
|
||||
return true
|
||||
end
|
||||
|
||||
if protect_types[e.type] then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
@ -1658,12 +1658,21 @@ function Public.set_player_to_god(player)
|
||||
return false
|
||||
end
|
||||
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
if string.sub(player.surface.name, 0, #surface.name) == surface.name then
|
||||
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = game.forces.player.get_spawn_position(surface)
|
||||
player.teleport(pos, surface)
|
||||
end
|
||||
else
|
||||
pos = game.forces.player.get_spawn_position(surface)
|
||||
player.teleport(pos, surface)
|
||||
local pos = player.surface.find_non_colliding_position('character', {0, 0}, 3, 0, 5)
|
||||
if pos then
|
||||
player.teleport(pos, player.surface)
|
||||
else
|
||||
player.teleport({pos}, player.surface)
|
||||
end
|
||||
end
|
||||
|
||||
Event.raise(
|
||||
|
@ -5,6 +5,7 @@ local IC_Gui = require 'maps.mountain_fortress_v3.ic.gui'
|
||||
local IC_Minimap = require 'maps.mountain_fortress_v3.ic.minimap'
|
||||
local Difficulty = require 'modules.difficulty_vote_by_amount'
|
||||
local Gui = require 'utils.gui'
|
||||
local Color = require 'utils.color_presets'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
|
||||
local format_number = require 'util'.format_number
|
||||
@ -60,6 +61,10 @@ local function spectate_button(player)
|
||||
return
|
||||
end
|
||||
|
||||
if Public.get('final_battle') then
|
||||
return
|
||||
end
|
||||
|
||||
local b =
|
||||
player.gui.top.add {
|
||||
type = 'sprite-button',
|
||||
@ -541,6 +546,10 @@ Gui.on_click(
|
||||
return
|
||||
end
|
||||
|
||||
if Public.get('final_battle') then
|
||||
return player.print('Not possible during the final battle.', Color.warning)
|
||||
end
|
||||
|
||||
if player.character and player.character.valid then
|
||||
local success = Public.set_player_to_spectator(player)
|
||||
if success then
|
||||
|
@ -6,6 +6,7 @@ local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
|
||||
local deepcopy = table.deepcopy
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
|
||||
@ -807,6 +808,35 @@ function Public.create_wagon(icw, created_entity, delay_surface)
|
||||
return wagon
|
||||
end
|
||||
|
||||
function Public.migrate_wagon(icw, source, target)
|
||||
if not validate_entity(target) then
|
||||
return
|
||||
end
|
||||
|
||||
local target_wagon = target.unit_number
|
||||
local source_wagon = source.unit_number
|
||||
|
||||
for door_id, entity_id in pairs(icw.doors) do
|
||||
if entity_id == source_wagon then
|
||||
icw.doors[door_id] = target_wagon
|
||||
end
|
||||
end
|
||||
for _, surface_data in pairs(icw.surfaces) do
|
||||
if surface_data.name == source_wagon then
|
||||
surface_data.name = tostring(target_wagon)
|
||||
end
|
||||
end
|
||||
|
||||
for unit_number, unit_data in pairs(icw.wagons) do
|
||||
if unit_number == source_wagon then
|
||||
unit_data.surface.name = tostring(target_wagon)
|
||||
unit_data.entity = target
|
||||
icw.wagons[target_wagon] = deepcopy(unit_data)
|
||||
return icw.wagons[target_wagon]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.use_cargo_wagon_door_with_entity(icw, player, door)
|
||||
local player_data = get_player_data(icw, player)
|
||||
if player_data.state then
|
||||
|
@ -139,6 +139,11 @@ function Public.register_wagon(wagon_entity)
|
||||
return Functions.create_wagon(icw, wagon_entity)
|
||||
end
|
||||
|
||||
function Public.migrate_wagon(source, target)
|
||||
local icw = ICW.get()
|
||||
return Functions.migrate_wagon(icw, source, target)
|
||||
end
|
||||
|
||||
local on_player_or_robot_built_tile = Functions.on_player_or_robot_built_tile
|
||||
|
||||
Event.on_init(on_init)
|
||||
|
@ -370,7 +370,7 @@ local function get_driver_action(entity)
|
||||
local total_time = player.online_time + Session.get_session_player(player)
|
||||
|
||||
if total_time and total_time < playtime_required_to_drive_train then
|
||||
player.print('[color=blue][Locomotive][/color] Not enough playtime acquired to drive train.')
|
||||
player.print('[color=blue][Locomotive][/color] Not enough playtime acquired to drive the train.')
|
||||
driver.driving = false
|
||||
return
|
||||
end
|
||||
@ -598,7 +598,6 @@ function Public.is_around_train(entity)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
local upgrades = Public.get('upgrades')
|
||||
|
||||
@ -625,6 +624,12 @@ function Public.render_train_hp()
|
||||
return
|
||||
end
|
||||
|
||||
local health_text = Public.get('health_text')
|
||||
|
||||
if health_text then
|
||||
rendering.destroy(health_text)
|
||||
end
|
||||
|
||||
Public.set(
|
||||
'health_text',
|
||||
rendering.draw_text {
|
||||
@ -724,6 +729,7 @@ local function tick()
|
||||
end
|
||||
|
||||
Event.on_nth_tick(5, tick)
|
||||
Event.on_nth_tick(150, set_carriages)
|
||||
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
|
||||
|
@ -5,6 +5,9 @@ Mountain Fortress v3 is maintained by Gerkiz and hosted by Comfy.
|
||||
Want to host it? Ask Gerkiz#0001 at discord!
|
||||
|
||||
]]
|
||||
-- develop setting
|
||||
local _DEV_MODE = true
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local Public = require 'maps.mountain_fortress_v3.core'
|
||||
local Discord = require 'utils.discord'
|
||||
@ -137,7 +140,7 @@ function Public.reset_map()
|
||||
-- OfflinePlayers.set_offline_players_surface_removal(true)
|
||||
|
||||
RPG.rpg_reset_all_players()
|
||||
RPG.set_surface_name(game.surfaces[this.active_surface_index].name)
|
||||
RPG.set_surface_name({game.surfaces[this.active_surface_index].name, 'boss_room'})
|
||||
RPG.enable_health_and_mana_bars(true)
|
||||
RPG.enable_wave_defense(true)
|
||||
RPG.enable_mana(true)
|
||||
@ -174,7 +177,7 @@ function Public.reset_map()
|
||||
Explosives.set_surface_whitelist({[surface.name] = true})
|
||||
Explosives.check_growth_below_void(true)
|
||||
|
||||
game.forces.player.set_spawn_position({-27, 25}, surface)
|
||||
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)
|
||||
game.forces.player.worker_robots_battery_modifier = 4
|
||||
@ -218,6 +221,7 @@ function Public.reset_map()
|
||||
|
||||
Difficulty.reset_difficulty_poll({closing_timeout = game.tick + 36000})
|
||||
Difficulty.set_gui_width(20)
|
||||
Difficulty.show_gui(false)
|
||||
|
||||
Collapse.set_kill_entities(false)
|
||||
Collapse.set_kill_specific_entities(collapse_kill)
|
||||
@ -259,12 +263,12 @@ function Public.reset_map()
|
||||
Public.set_difficulty()
|
||||
Public.disable_creative()
|
||||
|
||||
if not surface.is_chunk_generated({-20, 22}) then
|
||||
surface.request_to_generate_chunks({-20, 22}, 0.1)
|
||||
if not surface.is_chunk_generated({x = -20, y = 22}) then
|
||||
surface.request_to_generate_chunks({x = -20, y = 22}, 0.1)
|
||||
surface.force_generate_chunk_requests()
|
||||
end
|
||||
|
||||
game.forces.player.set_spawn_position({-27, 25}, surface)
|
||||
game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
|
||||
game.speed = 1
|
||||
|
||||
Task.set_queue_speed(16)
|
||||
@ -276,6 +280,14 @@ function Public.reset_map()
|
||||
this.market_announce = game.tick + 1200
|
||||
this.game_lost = false
|
||||
|
||||
Public.stateful.enable(true)
|
||||
Public.stateful.create()
|
||||
|
||||
if _DEV_MODE then
|
||||
Collapse.disable_collapse(true)
|
||||
WD.disable_spawning_biters(true)
|
||||
end
|
||||
|
||||
Task.set_timeout_in_ticks(25, announce_new_map)
|
||||
end
|
||||
|
||||
|
@ -624,6 +624,8 @@ function Public.add_mystical_chest(player)
|
||||
init_price_check(locomotive, mystical_chest)
|
||||
if player and player.valid then
|
||||
mystical_chest_reward(player)
|
||||
local mystical_chest_completed = Public.get('mystical_chest_completed')
|
||||
Public.set('mystical_chest_completed', mystical_chest_completed + 1)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
74
maps/mountain_fortress_v3/stateful/blueprints.lua
Normal file
74
maps/mountain_fortress_v3/stateful/blueprints.lua
Normal file
@ -0,0 +1,74 @@
|
||||
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 =
|
||||
game.surfaces.music or
|
||||
game.create_surface(
|
||||
map_name,
|
||||
{
|
||||
autoplace_controls = {
|
||||
['coal'] = {frequency = 0, size = 3, richness = 3},
|
||||
['stone'] = {frequency = 0, size = 3, richness = 3},
|
||||
['copper-ore'] = {frequency = 0, size = 3, richness = 3},
|
||||
['iron-ore'] = {frequency = 0, size = 3, richness = 3},
|
||||
['uranium-ore'] = {frequency = 0, size = 3, richness = 3},
|
||||
['crude-oil'] = {frequency = 0, size = 3, richness = 1},
|
||||
['trees'] = {frequency = 0, size = 0, richness = 0},
|
||||
['enemy-base'] = {frequency = 15, size = 0, richness = 1}
|
||||
},
|
||||
cliff_settings = {cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff'},
|
||||
height = 1024,
|
||||
width = 1024,
|
||||
peaceful_mode = false,
|
||||
seed = 1337,
|
||||
starting_area = 'very-low',
|
||||
starting_points = {{x = 0, y = 0}},
|
||||
terrain_segmentation = 'none',
|
||||
water = 'none'
|
||||
}
|
||||
)
|
||||
local position = {x = -500, y = 503}
|
||||
surface.daytime = 0.5
|
||||
surface.freeze_daytime = true
|
||||
surface.min_brightness = 0.3
|
||||
surface.brightness_visual_weights = {1, 1, 1}
|
||||
surface.request_to_generate_chunks(position, 2)
|
||||
surface.request_to_generate_chunks({0, 0}, 2)
|
||||
surface.force_generate_chunk_requests()
|
||||
|
||||
local item = surface.create_entity {name = 'item-on-ground', position = position, stack = {name = 'blueprint', count = 1}}
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
|
||||
local success = item.stack.import_stack(bp)
|
||||
if success <= 0 then
|
||||
local ghosts = item.stack.build_blueprint {surface = surface, force = 'player', position = position, force_build = true}
|
||||
for _, ghost in pairs(ghosts) do
|
||||
local _, ent = ghost.silent_revive({raise_revive = true})
|
||||
if ent and ent.valid then
|
||||
ent.destructible = false
|
||||
ent.minable = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if item.valid then
|
||||
item.destroy()
|
||||
end
|
||||
|
||||
return surface
|
||||
end
|
||||
|
||||
function Public.nuke_world()
|
||||
if game.surfaces.boss_room then
|
||||
game.delete_surface(map_name)
|
||||
end
|
||||
Public.create()
|
||||
end
|
||||
|
||||
return Public
|
427
maps/mountain_fortress_v3/stateful/generate.lua
Normal file
427
maps/mountain_fortress_v3/stateful/generate.lua
Normal file
@ -0,0 +1,427 @@
|
||||
local Event = require 'utils.event'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local Public = require 'maps.mountain_fortress_v3.stateful.table'
|
||||
|
||||
local ceil = math.ceil
|
||||
local queue_task = Task.queue_task
|
||||
local tiles_per_call = 8
|
||||
local total_calls = ceil(1024 / tiles_per_call)
|
||||
local regen_decoratives = false
|
||||
local generate_map = require 'maps.mountain_fortress_v3.stateful.terrain'.heavy_functions
|
||||
|
||||
-- Simple "loop" that is UPS friendly.
|
||||
local function get_position(data)
|
||||
data.yv = data.yv + 1
|
||||
|
||||
if data.yv == 32 then
|
||||
if data.xv == 32 then
|
||||
data.xv = 0
|
||||
end
|
||||
if data.yv == 32 then
|
||||
data.yv = 0
|
||||
end
|
||||
data.xv = data.xv + 1
|
||||
end
|
||||
|
||||
data.position = {x = data.top_x + data.xv, y = data.top_y + data.yv}
|
||||
end
|
||||
|
||||
local function do_tile_inner(tiles, tile, pos)
|
||||
if type(tile) == 'string' then
|
||||
tiles[#tiles + 1] = {name = tile, position = pos}
|
||||
end
|
||||
end
|
||||
|
||||
local function do_tile(x, y, data, shape)
|
||||
local pos = {x, y}
|
||||
|
||||
-- local coords need to be 'centered' to allow for correct rotation and scaling.
|
||||
local tile = shape(data)
|
||||
|
||||
if type(tile) == 'table' then
|
||||
do_tile_inner(data.tiles, tile.tile, pos)
|
||||
|
||||
local hidden_tile = tile.hidden_tile
|
||||
if hidden_tile then
|
||||
data.hidden_tiles[#data.hidden_tiles + 1] = {tile = hidden_tile, position = pos}
|
||||
end
|
||||
|
||||
local entities = tile.entities
|
||||
if entities then
|
||||
for _, entity in ipairs(entities) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.entities[#data.entities + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local buildings = tile.buildings
|
||||
if buildings then
|
||||
for _, entity in ipairs(buildings) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.buildings[#data.buildings + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local decoratives = tile.decoratives
|
||||
if decoratives then
|
||||
for _, decorative in ipairs(decoratives) do
|
||||
data.decoratives[#data.decoratives + 1] = decorative
|
||||
end
|
||||
end
|
||||
else
|
||||
do_tile_inner(data.tiles, tile, pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function do_row(row, data, shape)
|
||||
local y = data.top_y + row
|
||||
local top_x = data.top_x
|
||||
local tiles = data.tiles
|
||||
|
||||
data.y = y
|
||||
|
||||
for x = top_x, top_x + 31 do
|
||||
data.x = x
|
||||
local pos = {data.x, data.y}
|
||||
|
||||
get_position(data)
|
||||
|
||||
-- local coords need to be 'centered' to allow for correct rotation and scaling.
|
||||
local tile = shape(data)
|
||||
|
||||
if type(tile) == 'table' then
|
||||
do_tile_inner(tiles, tile.tile, pos)
|
||||
|
||||
local hidden_tile = tile.hidden_tile
|
||||
if hidden_tile then
|
||||
data.hidden_tiles[#data.hidden_tiles + 1] = {tile = hidden_tile, position = pos}
|
||||
end
|
||||
|
||||
local entities = tile.entities
|
||||
if entities then
|
||||
for _, entity in ipairs(entities) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.entities[#data.entities + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local buildings = tile.buildings
|
||||
if buildings then
|
||||
for _, entity in ipairs(buildings) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.buildings[#data.buildings + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local decoratives = tile.decoratives
|
||||
if decoratives then
|
||||
for _, decorative in ipairs(decoratives) do
|
||||
if not decorative.position then
|
||||
decorative.position = pos
|
||||
end
|
||||
data.decoratives[#data.decoratives + 1] = decorative
|
||||
end
|
||||
end
|
||||
else
|
||||
do_tile_inner(tiles, tile, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_tiles(data)
|
||||
local surface = data.surface
|
||||
surface.set_tiles(data.tiles, true)
|
||||
end
|
||||
|
||||
local function do_place_hidden_tiles(data)
|
||||
local surface = data.surface
|
||||
surface.set_tiles(data.hidden_tiles, true)
|
||||
end
|
||||
|
||||
local function do_place_decoratives(data)
|
||||
local surface = data.surface
|
||||
if regen_decoratives then
|
||||
surface.regenerate_decorative(nil, {{data.top_x / 32, data.top_y / 32}})
|
||||
end
|
||||
|
||||
local dec = data.decoratives
|
||||
if #dec > 0 then
|
||||
surface.create_decoratives({check_collision = true, decoratives = dec})
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_buildings(data)
|
||||
local surface = data.surface
|
||||
local entity
|
||||
local callback
|
||||
for _, e in ipairs(data.buildings) do
|
||||
if e.e_type then
|
||||
local p = e.position
|
||||
if
|
||||
surface.count_entities_filtered {
|
||||
area = {{p.x - 32, p.y - 32}, {p.x + 32, p.y + 32}},
|
||||
type = e.e_type,
|
||||
limit = 1
|
||||
} == 0
|
||||
then
|
||||
entity = surface.create_entity(e)
|
||||
if entity and entity.valid then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.callback then
|
||||
local c = e.callback.callback
|
||||
if c then
|
||||
local d = {callback_data = e.callback.data}
|
||||
if not d then
|
||||
callback = Token.get(c)
|
||||
callback(entity)
|
||||
else
|
||||
callback = Token.get(c)
|
||||
callback(entity, d)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_entities(data)
|
||||
local surface = data.surface
|
||||
local entity
|
||||
local callback
|
||||
for _, e in ipairs(data.entities) do
|
||||
if e.collision then
|
||||
if surface.can_place_entity(e) then
|
||||
entity = surface.create_entity(e)
|
||||
if entity then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.active ~= nil then
|
||||
entity.active = e.active
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.amount then
|
||||
entity.amount = e.amount
|
||||
end
|
||||
if e.callback then
|
||||
callback = Token.get(e.callback)
|
||||
callback({entity = entity})
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
entity = surface.create_entity(e)
|
||||
if entity then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.active ~= nil then
|
||||
entity.active = e.active
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.amount then
|
||||
entity.amount = e.amount
|
||||
end
|
||||
if e.callback then
|
||||
callback = Token.get(e.callback)
|
||||
callback({entity = entity})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function map_gen_action(data)
|
||||
local state = data.y
|
||||
|
||||
if state < 32 then
|
||||
local shape = generate_map
|
||||
if shape == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local count = tiles_per_call
|
||||
|
||||
local y = state + data.top_y
|
||||
local x = data.x
|
||||
|
||||
local max_x = data.top_x + 32
|
||||
|
||||
data.y = y
|
||||
|
||||
repeat
|
||||
count = count - 1
|
||||
get_position(data)
|
||||
do_tile(x, y, data, shape)
|
||||
|
||||
x = x + 1
|
||||
|
||||
if x == max_x then
|
||||
y = y + 1
|
||||
if y == data.top_y + 32 then
|
||||
break
|
||||
end
|
||||
x = data.top_x
|
||||
data.y = y
|
||||
end
|
||||
|
||||
data.x = x
|
||||
until count == 0
|
||||
|
||||
data.y = y - data.top_y
|
||||
return true
|
||||
elseif state == 32 then
|
||||
do_place_tiles(data)
|
||||
data.y = 33
|
||||
return true
|
||||
elseif state == 33 then
|
||||
do_place_hidden_tiles(data)
|
||||
data.y = 34
|
||||
return true
|
||||
elseif state == 34 then
|
||||
do_place_entities(data)
|
||||
data.y = 35
|
||||
return true
|
||||
elseif state == 35 then
|
||||
do_place_decoratives(data)
|
||||
data.y = 36
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local map_gen_action_token = Token.register(map_gen_action)
|
||||
|
||||
--- Adds generation of a Chunk of the map to the queue
|
||||
-- @param event <table> the event table from on_chunk_generated
|
||||
local function schedule_chunk(event)
|
||||
local surface = event.surface
|
||||
local shape = generate_map
|
||||
|
||||
if event.tick < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
if not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not shape then
|
||||
return
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
|
||||
local data = {
|
||||
yv = -0,
|
||||
xv = 0,
|
||||
y = 0,
|
||||
x = area.left_top.x,
|
||||
area = area,
|
||||
top_x = area.left_top.x,
|
||||
top_y = area.left_top.y,
|
||||
surface = surface,
|
||||
tiles = {},
|
||||
hidden_tiles = {},
|
||||
entities = {},
|
||||
buildings = {},
|
||||
decoratives = {},
|
||||
markets = {},
|
||||
treasure = {}
|
||||
}
|
||||
|
||||
if not data.surface or not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
queue_task(map_gen_action_token, data, total_calls)
|
||||
end
|
||||
|
||||
--- Generates a Chunk of map when called
|
||||
-- @param event <table> the event table from on_chunk_generated
|
||||
local function do_chunk(event)
|
||||
local surface = event.surface
|
||||
local shape = generate_map
|
||||
|
||||
if not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not shape then
|
||||
return
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
|
||||
local data = {
|
||||
yv = -0,
|
||||
xv = 0,
|
||||
area = area,
|
||||
top_x = area.left_top.x,
|
||||
top_y = area.left_top.y,
|
||||
surface = surface,
|
||||
tiles = {},
|
||||
hidden_tiles = {},
|
||||
entities = {},
|
||||
buildings = {},
|
||||
decoratives = {},
|
||||
markets = {},
|
||||
treasure = {}
|
||||
}
|
||||
|
||||
if not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
for row = 0, 31 do
|
||||
do_row(row, data, shape)
|
||||
end
|
||||
|
||||
do_place_tiles(data)
|
||||
do_place_hidden_tiles(data)
|
||||
do_place_entities(data)
|
||||
do_place_buildings(data)
|
||||
do_place_decoratives(data)
|
||||
end
|
||||
|
||||
local function on_chunk(event)
|
||||
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
|
||||
do_chunk(event)
|
||||
else
|
||||
schedule_chunk(event)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk)
|
||||
|
||||
return Public
|
534
maps/mountain_fortress_v3/stateful/gui.lua
Normal file
534
maps/mountain_fortress_v3/stateful/gui.lua
Normal file
@ -0,0 +1,534 @@
|
||||
local Event = require 'utils.event'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local Public = require 'maps.mountain_fortress_v3.table'
|
||||
local Gui = require 'utils.gui'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
|
||||
local main_button_name = Gui.uid_name()
|
||||
local main_frame_name = Gui.uid_name()
|
||||
local close_button = Gui.uid_name()
|
||||
local random = math.random
|
||||
|
||||
local function create_particles(surface, name, position, amount, cause_position)
|
||||
local d1 = (-100 + random(0, 200)) * 0.0004
|
||||
local d2 = (-100 + random(0, 200)) * 0.0004
|
||||
|
||||
name = name or 'leaf-particle'
|
||||
|
||||
if cause_position then
|
||||
d1 = (cause_position.x - position.x) * 0.025
|
||||
d2 = (cause_position.y - position.y) * 0.025
|
||||
end
|
||||
|
||||
for _ = 1, amount, 1 do
|
||||
local m = random(4, 10)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle(
|
||||
{
|
||||
name = name,
|
||||
position = position,
|
||||
frame_speed = 1,
|
||||
vertical_speed = 0.130,
|
||||
height = 0,
|
||||
movement = {
|
||||
(m2 - (random(0, m) * 0.01)) + d1,
|
||||
(m2 - (random(0, m) * 0.01)) + d2
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local spread_particles_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
|
||||
|
||||
create_particles(player.surface, particle, player.position, 128)
|
||||
end
|
||||
)
|
||||
|
||||
local function create_button(player)
|
||||
local b =
|
||||
player.gui.top.add(
|
||||
{
|
||||
type = 'sprite-button',
|
||||
name = main_button_name,
|
||||
sprite = 'utility/custom_tag_icon',
|
||||
tooltip = 'Has information about all objectives that needs to be completed'
|
||||
}
|
||||
)
|
||||
b.style.minimal_height = 38
|
||||
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
|
||||
end
|
||||
|
||||
local function spacer(frame)
|
||||
local flow = frame.add({type = 'flow'})
|
||||
flow.style.minimal_height = 2
|
||||
end
|
||||
|
||||
local function objective_frames(stateful, player_frame, objective, data)
|
||||
local objective_name = objective[1]
|
||||
if objective_name == 'supplies' or objective_name == 'single_item' then
|
||||
local supplies = stateful.objectives.supplies
|
||||
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
|
||||
|
||||
if objective_name == 'single_item' then
|
||||
left_flow.add({type = 'label', caption = {'stateful.production_single'}})
|
||||
else
|
||||
left_flow.add({type = 'label', caption = {'stateful.production'}})
|
||||
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 objective[1]() then
|
||||
-- right_flow.add({type = 'label', caption = '[img=utility/check_mark_green]'})
|
||||
-- else
|
||||
-- end
|
||||
|
||||
data.supply = {}
|
||||
|
||||
local flow = player_frame.add({type = 'flow'})
|
||||
local item_table = flow.add({type = 'table', name = 'item_table', column_count = 3})
|
||||
if objective_name ~= 'single_item' then
|
||||
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[1].name, sprite = 'item/' .. supplies[1].name, enabled = false, number = supplies[1].count})
|
||||
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[2].name, sprite = 'item/' .. supplies[2].name, enabled = false, number = supplies[2].count})
|
||||
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[3].name, sprite = 'item/' .. supplies[3].name, enabled = false, number = supplies[3].count})
|
||||
else
|
||||
local single_item = stateful.objectives.single_item
|
||||
data.single_item = item_table.add({type = 'sprite-button', name = single_item.name, sprite = 'item/' .. single_item.name, enabled = false, number = single_item.count})
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if objective_name == 'locomotive_market_selection' then
|
||||
local callback_token = stateful.objectives.locomotive_market_selection[1]
|
||||
local callback_data = stateful.objectives.locomotive_market_selection[2]
|
||||
local callback = Token.get(callback_token)
|
||||
|
||||
local _, locale_left, locale_right = 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})
|
||||
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})
|
||||
data.locomotive_market = locomotive_market
|
||||
return
|
||||
end
|
||||
|
||||
local callback = Token.get(objective[2])
|
||||
|
||||
local _, objective_locale_left, objective_locale_right = callback()
|
||||
|
||||
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
|
||||
|
||||
data.random_objectives = {}
|
||||
|
||||
left_flow.add({type = 'label', caption = objective_locale_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})
|
||||
data.random_objectives[#data.random_objectives + 1] = {name = objective_name, frame = objective_locale_right_label}
|
||||
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 supplies = stateful.objectives.supplies
|
||||
local single_item = stateful.objectives.single_item
|
||||
local callback_token = stateful.objectives.locomotive_market_selection[1]
|
||||
local callback_data = stateful.objectives.locomotive_market_selection[2]
|
||||
local callback_locomotive = Token.get(callback_token)
|
||||
local locomotive_completed, _, locale_right = callback_locomotive(callback_data)
|
||||
|
||||
for i = 1, #players do
|
||||
local player = players[i]
|
||||
local f = player.gui.screen[main_frame_name]
|
||||
local data = Gui.get_data(f)
|
||||
|
||||
if data then
|
||||
if data.rounds_survived and data.rounds_survived.valid then
|
||||
data.rounds_survived.caption = stateful.rounds_survived
|
||||
end
|
||||
if data.randomized_zone_label and data.randomized_zone_label.valid then
|
||||
breached_wall = breached_wall - 1
|
||||
if breached_wall >= stateful.objectives.randomized_zone then
|
||||
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()
|
||||
end
|
||||
else
|
||||
data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]'
|
||||
end
|
||||
end
|
||||
|
||||
if data.randomized_wave_label and data.randomized_wave_label.valid then
|
||||
if wave_number >= stateful.objectives.randomized_wave then
|
||||
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()
|
||||
end
|
||||
else
|
||||
data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]'
|
||||
end
|
||||
end
|
||||
|
||||
if data.supply and next(data.supply) then
|
||||
local items_done = 0
|
||||
for index = 1, #data.supply do
|
||||
local frame = data.supply[index]
|
||||
if frame and frame.valid then
|
||||
local supplies_data = supplies[index]
|
||||
if supplies_data.count == 0 then
|
||||
items_done = items_done + 1
|
||||
frame.number = nil
|
||||
frame.sprite = 'utility/check_mark_green'
|
||||
else
|
||||
frame.number = supplies_data.count
|
||||
end
|
||||
if items_done == 3 then
|
||||
if data.supply_completed and data.supply_completed.valid then
|
||||
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()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if data.single_item and data.single_item.valid then
|
||||
local frame = data.single_item
|
||||
if single_item.count == 0 then
|
||||
frame.number = nil
|
||||
frame.sprite = 'utility/check_mark_green'
|
||||
if not stateful.objectives_completed.single_item then
|
||||
stateful.objectives_completed.single_item = true
|
||||
play_game_won_sound()
|
||||
end
|
||||
else
|
||||
frame.number = single_item.count
|
||||
end
|
||||
end
|
||||
|
||||
if data.locomotive_market and data.locomotive_market.valid then
|
||||
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()
|
||||
end
|
||||
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]
|
||||
local name = frame_data.name
|
||||
local frame = frame_data.frame
|
||||
for objective_index = 1, #stateful.selected_objectives do
|
||||
local objective = stateful.selected_objectives[objective_index]
|
||||
local objective_name = objective[1]
|
||||
local callback = Token.get(objective[2])
|
||||
local completed, _, objective_locale_right = callback()
|
||||
if name == objective_name and frame and frame.valid then
|
||||
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()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_raw()
|
||||
local stateful = Public.get_stateful()
|
||||
local breached_wall = Public.get('breached_wall')
|
||||
local wave_number = WD.get('wave_number')
|
||||
local supplies = stateful.objectives.supplies
|
||||
local single_item = stateful.objectives.single_item
|
||||
local callback_token = stateful.objectives.locomotive_market_selection[1]
|
||||
local callback_data = stateful.objectives.locomotive_market_selection[2]
|
||||
local callback_locomotive = Token.get(callback_token)
|
||||
local locomotive_completed, _, _ = callback_locomotive(callback_data)
|
||||
|
||||
breached_wall = breached_wall - 1
|
||||
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()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
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()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if supplies and next(supplies) then
|
||||
local items_done = 0
|
||||
for index = 1, #supplies do
|
||||
local supplies_data = supplies[index]
|
||||
if supplies_data.count == 0 then
|
||||
items_done = items_done + 1
|
||||
end
|
||||
if items_done == 3 then
|
||||
if not stateful.objectives_completed.supplies then
|
||||
stateful.objectives_completed.supplies = true
|
||||
play_game_won_sound()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if locomotive_completed then
|
||||
if not stateful.objectives_completed.locomotive_market then
|
||||
stateful.objectives_completed.locomotive_market = true
|
||||
play_game_won_sound()
|
||||
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
for objective_index = 1, #stateful.selected_objectives do
|
||||
local objective = stateful.selected_objectives[objective_index]
|
||||
local objective_name = objective[1]
|
||||
local callback = Token.get(objective[2])
|
||||
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()
|
||||
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
|
||||
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'}
|
||||
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]'})
|
||||
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)
|
||||
local player = game.players[event.player_index]
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
if not player.gui.top[main_button_name] then
|
||||
create_button(player)
|
||||
end
|
||||
end
|
||||
|
||||
Gui.on_click(
|
||||
main_button_name,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 stateful Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
|
||||
local player = event.player
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local frame = player.gui.screen[main_frame_name]
|
||||
if player.character and player.character.valid then
|
||||
if frame then
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
else
|
||||
Gui.clear_all_active_frames(player)
|
||||
main_frame(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
close_button,
|
||||
function(event)
|
||||
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 stateful Button')
|
||||
if is_spamming then
|
||||
return
|
||||
end
|
||||
|
||||
local player = event.player
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local frame = player.gui.screen[main_frame_name]
|
||||
|
||||
if frame then
|
||||
Gui.remove_data_recursively(frame)
|
||||
frame.destroy()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
return Public
|
56
maps/mountain_fortress_v3/stateful/main.lua
Normal file
56
maps/mountain_fortress_v3/stateful/main.lua
Normal file
@ -0,0 +1,56 @@
|
||||
local Public = require 'maps.mountain_fortress_v3.stateful.table'
|
||||
local Event = require 'utils.event'
|
||||
local WD = require 'modules.wave_defense.table'
|
||||
|
||||
Public.stateful_gui = require 'maps.mountain_fortress_v3.stateful.gui'
|
||||
Public.stateful_terrain = require 'maps.mountain_fortress_v3.stateful.terrain'
|
||||
Public.stateful_generate = require 'maps.mountain_fortress_v3.stateful.generate'
|
||||
Public.stateful_blueprints = require 'maps.mountain_fortress_v3.stateful.blueprints'
|
||||
|
||||
local random = math.random
|
||||
local shuffle = table.shuffle_table
|
||||
|
||||
Event.add(
|
||||
defines.events.on_research_finished,
|
||||
function(event)
|
||||
local research = event.research
|
||||
if not research then
|
||||
return
|
||||
end
|
||||
|
||||
local name = research.name
|
||||
local objectives = Public.get_stateful('objectives')
|
||||
if not objectives then
|
||||
return
|
||||
end
|
||||
|
||||
if name == objectives.research_level_selection then
|
||||
objectives.research_level_count = objectives.research_level_count + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
Event.on_nth_tick(
|
||||
200,
|
||||
function()
|
||||
local final_battle = Public.get_stateful('final_battle')
|
||||
if not final_battle then
|
||||
return
|
||||
end
|
||||
|
||||
Public.set('final_battle', true)
|
||||
Public.allocate()
|
||||
|
||||
local spawn_positions = Public.stateful_spawn_points
|
||||
local sizeof = Public.sizeof_stateful_spawn_points
|
||||
|
||||
local area = spawn_positions[random(1, sizeof)]
|
||||
|
||||
shuffle(area)
|
||||
|
||||
WD.set_spawn_position(area[1])
|
||||
Event.raise(WD.events.on_spawn_unit_group, {fs = true, bypass = true})
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
523
maps/mountain_fortress_v3/stateful/table.lua
Normal file
523
maps/mountain_fortress_v3/stateful/table.lua
Normal file
@ -0,0 +1,523 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local Server = require 'utils.server'
|
||||
local Token = require 'utils.token'
|
||||
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 Core = require 'utils.core'
|
||||
local Public = require 'maps.mountain_fortress_v3.table'
|
||||
|
||||
local this = {
|
||||
enabled = false,
|
||||
rounds_survived = 0
|
||||
}
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local dataset = 'scenario_settings'
|
||||
local dataset_key = 'mtn_v3'
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local stateful_spawn_points = {
|
||||
{{x = -186, y = -170}, {x = 177, y = 119}},
|
||||
{{x = -190, y = -200}, {x = 160, y = -160}},
|
||||
{{x = -190, y = -0}, {x = 160, y = -0}},
|
||||
{{x = -186, y = -170}, {x = 177, y = 119}},
|
||||
{{x = -160, y = -200}, {x = 160, y = -160}},
|
||||
{{x = 160, y = -200}, {x = 190, y = -160}},
|
||||
{{x = 160, y = 0}, {x = 190, y = 0}},
|
||||
{{x = -186, y = -170}, {x = 177, y = 119}},
|
||||
{{x = 160, y = -160}, {x = 190, y = 160}},
|
||||
{{x = 160, y = 160}, {x = 190, y = 200}},
|
||||
{{x = -160, y = 160}, {x = 160, y = 200}},
|
||||
{{x = -190, y = 160}, {x = -160, y = 200}},
|
||||
{{x = -190, y = -160}, {x = -160, y = 160}}
|
||||
}
|
||||
|
||||
local disabled_items = {
|
||||
['landfill'] = true,
|
||||
['spidertron'] = true,
|
||||
['fluid-wagon'] = true,
|
||||
['cliff-explosives'] = true,
|
||||
['atomic-bomb'] = true,
|
||||
['land-mine'] = true,
|
||||
['loader'] = true,
|
||||
['fast-loader'] = true,
|
||||
['express-loader'] = true
|
||||
}
|
||||
|
||||
local function get_item_produced_count(item_name)
|
||||
local force = game.forces.player
|
||||
|
||||
local production = force.item_production_statistics.input_counts[item_name]
|
||||
if not production then
|
||||
return false
|
||||
end
|
||||
|
||||
return production
|
||||
end
|
||||
|
||||
local function get_entity_mined_count(item_name)
|
||||
local force = game.forces.player
|
||||
|
||||
local count = 0
|
||||
for name, entity_count in pairs(force.entity_build_count_statistics.output_counts) do
|
||||
if name:find(item_name) then
|
||||
count = count + entity_count
|
||||
end
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
local function get_killed_enemies_count(primary, secondary)
|
||||
local force = game.forces.player
|
||||
|
||||
local count = 0
|
||||
for name, entity_count in pairs(force.kill_count_statistics.input_counts) do
|
||||
if name:find(primary) or name:find(secondary) then
|
||||
count = count + entity_count
|
||||
end
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
local apply_settings =
|
||||
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)
|
||||
end
|
||||
)
|
||||
|
||||
local locomotive_market_pickaxe_token =
|
||||
Token.register(
|
||||
function(count)
|
||||
local upgrades = Public.get('upgrades')
|
||||
if upgrades.pickaxe_tier >= count then
|
||||
return true, {'stateful.locomotive_market_pickaxe'}, {'stateful.done', count, count}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_pickaxe'}, {'stateful.not_done', upgrades.pickaxe_tier, count}
|
||||
end
|
||||
)
|
||||
|
||||
local locomotive_market_health_token =
|
||||
Token.register(
|
||||
function(count)
|
||||
local upgrades = Public.get('upgrades')
|
||||
if upgrades.health_upgrades >= count then
|
||||
return true, {'stateful.locomotive_market_health'}, {'stateful.done', count, count}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_health'}, {'stateful.not_done', upgrades.health_upgrades, count}
|
||||
end
|
||||
)
|
||||
|
||||
local locomotive_market_xp_points_token =
|
||||
Token.register(
|
||||
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}
|
||||
end
|
||||
|
||||
return false, {'stateful.locomotive_market_xp_points'}, {'stateful.not_done', upgrades.xp_points_upgrade, count}
|
||||
end
|
||||
)
|
||||
|
||||
local empty_token =
|
||||
Token.register(
|
||||
function()
|
||||
return false
|
||||
end
|
||||
)
|
||||
|
||||
local killed_enemies_token =
|
||||
Token.register(
|
||||
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)}
|
||||
end
|
||||
|
||||
return false, {'stateful.enemies_killed'}, {'stateful.not_done', format_number(enemies_killed, true), format_number(this.objectives.killed_enemies, true)}
|
||||
end
|
||||
)
|
||||
|
||||
local complete_mystical_chest_amount_token =
|
||||
Token.register(
|
||||
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}
|
||||
end
|
||||
return false, {'stateful.mystical_chest'}, {'stateful.not_done', mystical_chest_completed, this.objectives.complete_mystical_chest_amount}
|
||||
end
|
||||
)
|
||||
|
||||
local research_level_selection_token =
|
||||
Token.register(
|
||||
function()
|
||||
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}
|
||||
end
|
||||
return false, {'stateful.research', this.objectives.research_level_selection.name}, {'stateful.not_done', actual, expected}
|
||||
end
|
||||
)
|
||||
|
||||
local trees_farmed_token =
|
||||
Token.register(
|
||||
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)}
|
||||
end
|
||||
return false, {'stateful.trees_mined'}, {'stateful.not_done', format_number(trees, true), format_number(this.objectives.trees_farmed, true)}
|
||||
end
|
||||
)
|
||||
|
||||
local rocks_farmed_token =
|
||||
Token.register(
|
||||
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)}
|
||||
end
|
||||
return false, {'stateful.rocks_mined'}, {'stateful.not_done', format_number(rocks, true), format_number(this.objectives.rocks_farmed, true)}
|
||||
end
|
||||
)
|
||||
|
||||
local rockets_launched_token =
|
||||
Token.register(
|
||||
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)}
|
||||
end
|
||||
return false, {'stateful.launch_rockets'}, {'stateful.not_done', format_number(launched, true), format_number(this.objectives.rockets_launched, true)}
|
||||
end
|
||||
)
|
||||
|
||||
local function scale(setting, limit)
|
||||
local factor = 1.2
|
||||
local scale_value = floor(setting * (factor ^ this.rounds_survived))
|
||||
if limit and scale_value >= limit then
|
||||
return limit
|
||||
end
|
||||
return scale_value
|
||||
end
|
||||
|
||||
local function get_random_items()
|
||||
local recipes = game.forces.player.recipes
|
||||
local items = {}
|
||||
local i = 0
|
||||
|
||||
for _, recipe in pairs(recipes) do
|
||||
if recipe.prototype.energy > 6 and not disabled_items[recipe.name] then
|
||||
items[i] = recipe
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
shuffle(items)
|
||||
|
||||
local container = {
|
||||
[1] = {name = items[1].products[1].name, count = scale(random(100, 5000))},
|
||||
[2] = {name = items[2].products[1].name, count = scale(random(100, 5000))},
|
||||
[3] = {name = items[3].products[1].name, count = scale(random(100, 5000))}
|
||||
}
|
||||
|
||||
return container
|
||||
end
|
||||
|
||||
local function get_random_item()
|
||||
local recipes = game.forces.player.recipes
|
||||
local items = {}
|
||||
local i = 0
|
||||
|
||||
for _, recipe in pairs(recipes) do
|
||||
if recipe.prototype.energy > 1 and not disabled_items[recipe.name] then
|
||||
items[i] = recipe
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
shuffle(items)
|
||||
shuffle(items)
|
||||
|
||||
return {name = items[10].products[1].name, count = scale(random(5000, 100000), 40000000)}
|
||||
end
|
||||
|
||||
local function get_random_research_recipe()
|
||||
-- scale(10, 20)
|
||||
local research_level_list = {
|
||||
'energy-weapons-damage-7',
|
||||
'physical-projectile-damage-7',
|
||||
'refined-flammables-7',
|
||||
'stronger-explosives-7',
|
||||
'mining-productivity-4',
|
||||
'worker-robots-speed-6',
|
||||
'follower-robot-count-7'
|
||||
}
|
||||
|
||||
shuffle(research_level_list)
|
||||
|
||||
return {name = research_level_list[1], count = scale(random(10, 20), 40)}
|
||||
end
|
||||
|
||||
local function get_random_locomotive_tier()
|
||||
local tiers = {
|
||||
'pickaxe',
|
||||
'health',
|
||||
'xp_point'
|
||||
}
|
||||
|
||||
shuffle(tiers)
|
||||
|
||||
local pickaxe_count = scale(random(10, 20), 59)
|
||||
local health_count = scale(random(10, 40), 100)
|
||||
local xp_points_count = scale(random(10, 40), 100)
|
||||
|
||||
if tiers[1] == 'pickaxe' then
|
||||
return {
|
||||
locomotive_market_pickaxe_token,
|
||||
pickaxe_count
|
||||
}
|
||||
end
|
||||
|
||||
if tiers[1] == 'health' then
|
||||
return {
|
||||
locomotive_market_health_token,
|
||||
health_count
|
||||
}
|
||||
end
|
||||
|
||||
if tiers[1] == 'xp_point' then
|
||||
return {
|
||||
locomotive_market_xp_points_token,
|
||||
xp_points_count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function get_random_objectives()
|
||||
local items = {
|
||||
{
|
||||
'supplies',
|
||||
empty_token
|
||||
},
|
||||
{
|
||||
'single_item',
|
||||
empty_token
|
||||
},
|
||||
{
|
||||
'killed_enemies',
|
||||
killed_enemies_token
|
||||
},
|
||||
{
|
||||
'complete_mystical_chest_amount',
|
||||
complete_mystical_chest_amount_token
|
||||
},
|
||||
{
|
||||
'research_level_selection',
|
||||
research_level_selection_token
|
||||
},
|
||||
{
|
||||
'locomotive_market_selection',
|
||||
empty_token
|
||||
},
|
||||
{
|
||||
'trees_farmed',
|
||||
trees_farmed_token
|
||||
},
|
||||
{
|
||||
'rocks_farmed',
|
||||
rocks_farmed_token
|
||||
},
|
||||
{
|
||||
'rockets_launched',
|
||||
rockets_launched_token
|
||||
}
|
||||
}
|
||||
|
||||
shuffle(items)
|
||||
|
||||
return {
|
||||
items[1],
|
||||
items[2],
|
||||
items[3]
|
||||
}
|
||||
end
|
||||
|
||||
function Public.reset_stateful()
|
||||
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.force_chunk = true
|
||||
end
|
||||
|
||||
function Public.migrate_and_create(locomotive)
|
||||
local carriages = Public.get('carriages')
|
||||
local surface = game.get_surface('boss_room')
|
||||
local position = locomotive.position
|
||||
|
||||
for _, entity in pairs(carriages) do
|
||||
if entity and entity.valid and entity.unit_number ~= locomotive.unit_number then
|
||||
local new_position = {x = position.x, y = position.y + 5}
|
||||
local new_wagon = surface.create_entity({name = entity.name, position = new_position, force = 'player', defines.direction.north})
|
||||
if new_wagon and new_wagon.valid then
|
||||
position = new_position
|
||||
ICW.migrate_wagon(entity, new_wagon)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.move_all_players()
|
||||
local market = Public.get('market')
|
||||
if not market or not market.valid then
|
||||
return
|
||||
end
|
||||
local surface = market.surface
|
||||
Core.iter_connected_players(
|
||||
function(player)
|
||||
local pos = surface.find_non_colliding_position('character', market.position, 3, 0, 5)
|
||||
|
||||
if pos then
|
||||
player.teleport(pos, surface)
|
||||
else
|
||||
pos = market.position
|
||||
player.teleport(pos, surface)
|
||||
Public.unstuck(player.index)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
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()
|
||||
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')
|
||||
|
||||
Public.set_target(stateful_locomotive, icw_data)
|
||||
game.forces.player.chart(surface, {{-358, -151}, {358, 151}})
|
||||
Public.migrate_and_create(stateful_locomotive)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_target(target, icw_data)
|
||||
Public.set('locomotive', target)
|
||||
local wave_defense_table = WD.get()
|
||||
wave_defense_table.surface_index = game.get_surface('boss_room').index
|
||||
wave_defense_table.target = target
|
||||
wave_defense_table.spawn_position = {x = -206, y = -80}
|
||||
Public.set('active_surface_index', game.get_surface('boss_room').index)
|
||||
Public.set('icw_locomotive', icw_data)
|
||||
Public.render_train_hp()
|
||||
end
|
||||
|
||||
function Public.increase_enemy_damage_and_health()
|
||||
if this.rounds_survived == 1 then
|
||||
Event.raise(WD.events.on_biters_evolved, {})
|
||||
else
|
||||
for _ = 1, this.rounds_survived do
|
||||
Event.raise(WD.events.on_biters_evolved, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.get_stateful(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_stateful(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.remove_stateful(key, sub_key)
|
||||
if key and sub_key then
|
||||
if this[key] and this[key][sub_key] then
|
||||
this[key][sub_key] = nil
|
||||
end
|
||||
elseif key then
|
||||
if this[key] then
|
||||
this[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.enable(state)
|
||||
this.enabled = state or false
|
||||
end
|
||||
|
||||
Event.on_init(Public.reset_stateful)
|
||||
|
||||
Event.add(
|
||||
Server.events.on_server_started,
|
||||
function()
|
||||
if this.settings_applied then
|
||||
return
|
||||
end
|
||||
|
||||
this.settings_applied = true
|
||||
|
||||
Public.increase_enemy_damage_and_health()
|
||||
|
||||
Server.try_get_data(dataset, dataset_key, apply_settings)
|
||||
end
|
||||
)
|
||||
|
||||
Public.get_item_produced_count = get_item_produced_count
|
||||
Public.get_entity_mined_count = get_entity_mined_count
|
||||
Public.get_killed_enemies_count = get_killed_enemies_count
|
||||
Public.stateful_spawn_points = stateful_spawn_points
|
||||
Public.sizeof_stateful_spawn_points = #stateful_spawn_points
|
||||
|
||||
return Public
|
241
maps/mountain_fortress_v3/stateful/terrain.lua
Normal file
241
maps/mountain_fortress_v3/stateful/terrain.lua
Normal file
@ -0,0 +1,241 @@
|
||||
local Public = require 'maps.mountain_fortress_v3.stateful.table'
|
||||
local map_name = 'boss_room'
|
||||
local random = math.random
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local assign_locomotive_token =
|
||||
Token.register(
|
||||
function(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
entity.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
|
||||
for y = -1, 0, 0.05 do
|
||||
local scale = random(50, 100) * 0.01
|
||||
rendering.draw_sprite(
|
||||
{
|
||||
sprite = 'entity/small-biter',
|
||||
orientation = random(0, 100) * 0.01,
|
||||
x_scale = scale,
|
||||
y_scale = scale,
|
||||
tint = {random(60, 255), random(60, 255), random(60, 255)},
|
||||
render_layer = 'selection-box',
|
||||
target = entity,
|
||||
target_offset = {-0.7 + random(0, 140) * 0.01, y},
|
||||
surface = entity.surface
|
||||
}
|
||||
)
|
||||
end
|
||||
rendering.draw_light(
|
||||
{
|
||||
sprite = 'utility/light_medium',
|
||||
scale = 5.5,
|
||||
intensity = 1,
|
||||
minimum_darkness = 0,
|
||||
oriented = true,
|
||||
color = {255, 255, 255},
|
||||
target = entity,
|
||||
surface = entity.surface,
|
||||
visible = true,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
)
|
||||
entity.color = {random(2, 255), random(60, 255), random(60, 255)}
|
||||
Public.set_stateful('stateful_locomotive', entity)
|
||||
entity.minable = false
|
||||
end
|
||||
)
|
||||
|
||||
local start_ground_tiles = {
|
||||
'grass-1',
|
||||
'grass-1',
|
||||
'grass-2',
|
||||
'sand-2',
|
||||
'grass-1',
|
||||
'grass-4',
|
||||
'sand-2',
|
||||
'grass-3',
|
||||
'grass-4',
|
||||
'grass-2',
|
||||
'sand-3',
|
||||
'grass-4'
|
||||
}
|
||||
|
||||
local mud_tiles = {
|
||||
'water-mud',
|
||||
'water-shallow',
|
||||
'water-mud',
|
||||
'water-shallow',
|
||||
'water-mud',
|
||||
'water-shallow',
|
||||
'water-mud',
|
||||
'water-shallow',
|
||||
'water-mud',
|
||||
'water-shallow'
|
||||
}
|
||||
|
||||
local tree_raffle = {
|
||||
'dry-tree',
|
||||
'tree-01',
|
||||
'tree-02-red',
|
||||
'tree-04',
|
||||
'tree-08-brown'
|
||||
}
|
||||
local size_of_tree_raffle = #tree_raffle
|
||||
|
||||
local function is_out_of_map(p)
|
||||
if p.x < 512 and p.x >= -512 then
|
||||
return
|
||||
end
|
||||
if p.y < 512 and p.y >= -512 then
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function void_tiles(p)
|
||||
if p.y > 480 then
|
||||
return false
|
||||
end
|
||||
if p.y < 160 and p.y >= -160 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function enemy_spawn_positions(p)
|
||||
if p.x < 200 and p.x >= -212 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function draw_rails(data)
|
||||
local entities = data.entities
|
||||
local y = data.yv
|
||||
-- for y = 0, 30, 2 do
|
||||
entities[#entities + 1] = {name = 'straight-rail', position = {0, data.top_y + y}, direction = defines.direction.north, force = 'player'}
|
||||
-- end
|
||||
if data.top_y == -32 then
|
||||
entities[#entities + 1] = {name = 'locomotive', position = {0, -24}, force = 'player', direction = defines.direction.north, callback = assign_locomotive_token}
|
||||
end
|
||||
end
|
||||
|
||||
local function border_chunk(p, data)
|
||||
local decoratives = data.decoratives
|
||||
local tiles = data.tiles
|
||||
local entities = data.entities
|
||||
|
||||
local pos = p
|
||||
|
||||
if pos.y == 0 or pos.y > 0 then
|
||||
if random(1, ceil(pos.y + pos.y) + 64) == 1 then
|
||||
entities[#entities + 1] = {name = tree_raffle[random(1, size_of_tree_raffle)], position = pos, collision = true}
|
||||
end
|
||||
else
|
||||
if random(ceil(pos.y - pos.y) - 64, -1) == -1 then
|
||||
entities[#entities + 1] = {name = tree_raffle[random(1, size_of_tree_raffle)], position = pos, collision = true}
|
||||
end
|
||||
end
|
||||
|
||||
local noise = Public.get_noise('dungeon_sewer', pos, data.seed)
|
||||
local index = floor(noise * 32) % 11 + 1
|
||||
tiles[#tiles + 1] = {name = start_ground_tiles[index], position = pos}
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
local name = 'biter-spawner'
|
||||
if random(1, 4) == 1 then
|
||||
name = 'spitter-spawner'
|
||||
end
|
||||
if enemy_spawn_positions(p) then
|
||||
entities[#entities + 1] = {name = name, position = pos, force = 'enemy', collision = true, active = false}
|
||||
end
|
||||
end
|
||||
|
||||
if not is_out_of_map(pos) then
|
||||
if pos.y == 0 or pos.y >= 0 then
|
||||
if random(1, pos.y + 2) == 1 then
|
||||
decoratives[#decoratives + 1] = {
|
||||
name = 'rock-small',
|
||||
position = pos,
|
||||
amount = random(1, 32)
|
||||
}
|
||||
end
|
||||
if random(1, pos.y + 2) == 1 then
|
||||
decoratives[#decoratives + 1] = {
|
||||
name = 'rock-tiny',
|
||||
position = pos,
|
||||
amount = random(1, 32)
|
||||
}
|
||||
end
|
||||
else
|
||||
if random(pos.y - 2, -1) == -1 then
|
||||
decoratives[#decoratives + 1] = {
|
||||
name = 'rock-small',
|
||||
position = pos,
|
||||
amount = random(1, 32)
|
||||
}
|
||||
end
|
||||
if random(pos.y - 2, -1) == -1 then
|
||||
decoratives[#decoratives + 1] = {
|
||||
name = 'rock-tiny',
|
||||
position = pos,
|
||||
amount = random(1, 32)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function oozy_tiles(p, seed, tiles)
|
||||
local noise = Public.get_noise('no_rocks_2', p, seed)
|
||||
local index = floor(noise * 32) % 9 + 1
|
||||
if noise < -0.3 then
|
||||
local noise_cave_ponds = Public.get_noise('cave_ponds', p, seed)
|
||||
local small_caves = Public.get_noise('small_caves', p, seed)
|
||||
if noise_cave_ponds < 0.45 and noise_cave_ponds > -0.45 then
|
||||
if small_caves > 0.45 then
|
||||
tiles[#tiles + 1] = {name = 'out-of-map', position = p}
|
||||
return
|
||||
end
|
||||
|
||||
if small_caves < -0.45 then
|
||||
tiles[#tiles + 1] = {name = mud_tiles[index], position = p}
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.heavy_functions(data)
|
||||
local surface = data.surface
|
||||
local p = data.position
|
||||
local get_tile = surface.get_tile(p)
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
if not data.seed then
|
||||
data.seed = surface.map_gen_settings.seed
|
||||
end
|
||||
|
||||
if get_tile.valid and get_tile.name == 'out-of-map' then
|
||||
return
|
||||
end
|
||||
|
||||
if void_tiles(p) then
|
||||
data.tiles[#data.tiles + 1] = {name = 'out-of-map', position = p}
|
||||
return
|
||||
end
|
||||
|
||||
border_chunk(p, data)
|
||||
oozy_tiles(p, data.seed, data.tiles)
|
||||
draw_rails(data)
|
||||
end
|
||||
|
||||
return Public
|
@ -173,6 +173,7 @@ function Public.reset_main_table()
|
||||
}
|
||||
this.pickaxe_speed_per_purchase = 0.07
|
||||
this.breached_wall = 1
|
||||
this.final_battle = false
|
||||
this.left_top = {
|
||||
x = 0,
|
||||
y = 0
|
||||
@ -247,6 +248,7 @@ function Public.reset_main_table()
|
||||
this.market_announce = game.tick + 1200
|
||||
this.check_heavy_damage = true
|
||||
this.prestige_system_enabled = false
|
||||
this.mystical_chest_completed = 0
|
||||
this.mystical_chest_enabled = true
|
||||
this.check_if_threat_below_zero = true
|
||||
this.mc_rewards = {
|
||||
|
@ -2801,18 +2801,18 @@ end
|
||||
function Public.heavy_functions(data)
|
||||
local top_y = data.top_y
|
||||
local surface = data.surface
|
||||
local p = data.position
|
||||
local get_tile = surface.get_tile(p)
|
||||
|
||||
local adjusted_zones = Public.get('adjusted_zones')
|
||||
init_terrain(adjusted_zones)
|
||||
|
||||
local map_name = 'mtn_v3'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local p = data.position
|
||||
local get_tile = surface.get_tile(p)
|
||||
|
||||
local adjusted_zones = Public.get('adjusted_zones')
|
||||
init_terrain(adjusted_zones)
|
||||
|
||||
if not data.seed then
|
||||
data.seed = Public.get('random_seed')
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user