diff --git a/control.lua b/control.lua index d2997e72..694ea364 100644 --- a/control.lua +++ b/control.lua @@ -42,6 +42,7 @@ require 'utils.gui.config' require 'utils.gui.poll' require 'utils.gui.server_select' require 'utils.freeplay' +require 'utils.remote_chunks' ---------------- !ENABLE MODULES HERE ---------------- --require 'modules.rpg.main' diff --git a/locale/en/mtn_fortress_v3.cfg b/locale/en/mtn_fortress_v3.cfg index cf415d63..29eebc90 100644 --- a/locale/en/mtn_fortress_v3.cfg +++ b/locale/en/mtn_fortress_v3.cfg @@ -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 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! +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!\nCompleting/winning the map increases the difficulty (damage/health).\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! @@ -152,7 +152,7 @@ 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. +rounds_survived_tooltip=Winning the game increases this number by 1.\nThis number resets as of now each month. 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). diff --git a/maps/mountain_fortress_v3/breached_wall.lua b/maps/mountain_fortress_v3/breached_wall.lua index e4bf2270..d688c027 100644 --- a/maps/mountain_fortress_v3/breached_wall.lua +++ b/maps/mountain_fortress_v3/breached_wall.lua @@ -316,7 +316,7 @@ local function distance(player) end end - if not Collapse.start_now() then + if not Collapse.get_start_now() then clear_breach_text_and_render() Collapse.start_now(true) local data = { @@ -325,7 +325,7 @@ local function distance(player) Task.set_timeout_in_ticks(550, collapse_message, data) end - if Collapse.start_now() then + if Collapse.get_start_now() then clear_breach_text_and_render() end @@ -337,6 +337,11 @@ local function distance(player) end local function on_player_changed_position(event) + local final_battle = Public.get('final_battle') + if final_battle then + return + end + local player = game.get_player(event.player_index) if not player or not player.valid then return @@ -361,6 +366,11 @@ local function on_player_changed_position(event) end local function on_player_driving_changed_state(event) + local final_battle = Public.get('final_battle') + if final_battle then + return + end + local player = game.players[event.player_index] if not (player and player.valid) then return diff --git a/maps/mountain_fortress_v3/entities.lua b/maps/mountain_fortress_v3/entities.lua index 7b710319..053c05dd 100644 --- a/maps/mountain_fortress_v3/entities.lua +++ b/maps/mountain_fortress_v3/entities.lua @@ -276,21 +276,25 @@ local function set_train_final_health(final_damage_amount, repair) rendering.set_text(health_text, 'HP: ' .. round(locomotive_health) .. ' / ' .. round(locomotive_max_health)) end -local function is_protected(e) - local map_name = 'mtn_v3' +local function is_protected(data, e) + if data.final_battle then + local boss_map_name = 'boss_room' + if string.sub(e.surface.name, 0, #boss_map_name) ~= boss_map_name then + return true + end - if string.sub(e.surface.name, 0, #map_name) ~= map_name then - return true - end + if protect_types[e.type] then + return true + end + else + local map_name = 'mtn_v3' + 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 + if protect_types[e.type] then + return true + end end return false @@ -319,7 +323,7 @@ local function protect_entities(data) end local carriages_numbers = Public.get('carriages_numbers') - if is_protected(entity) then + if is_protected(data, entity) then if (cause and cause.valid) then if Public.valid_enemy_forces[cause.force.name] then if carriages_numbers and carriages_numbers[entity.unit_number] then @@ -914,13 +918,15 @@ local function on_entity_damaged(event) local wave_number = WD.get_wave() local boss_wave_warning = WD.get_alert_boss_wave() local munch_time = Public.get('munch_time') + local final_battle = Public.get('final_battle') local data = { cause = cause, entity = entity, final_damage_amount = final_damage_amount, original_damage_amount = original_damage_amount, - force = force + force = force, + final_battle = final_battle } protect_entities(data) diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua index 36f6baf6..b7eb6f86 100644 --- a/maps/mountain_fortress_v3/functions.lua +++ b/maps/mountain_fortress_v3/functions.lua @@ -28,15 +28,14 @@ local this = { magic_crafters = {index = 1}, magic_fluid_crafters = {index = 1}, art_table = {index = 1}, - surface_cleared = false -} - -local starting_items = { - ['pistol'] = 1, - ['firearm-magazine'] = 16, - ['rail'] = 16, - ['wood'] = 16, - ['explosives'] = 32 + surface_cleared = false, + starting_items = { + ['pistol'] = 1, + ['firearm-magazine'] = 16, + ['rail'] = 16, + ['wood'] = 16, + ['explosives'] = 32 + } } local random_respawn_messages = { @@ -1405,7 +1404,7 @@ function Public.on_player_joined_game(event) local death_message = ({'main.death_mode_warning'}) Alert.alert_player(player, 15, death_message) end - for item, amount in pairs(starting_items) do + for item, amount in pairs(this.starting_items) do player.insert({name = item, count = amount}) end end @@ -1417,6 +1416,19 @@ function Public.on_player_joined_game(event) local final_battle = Public.get('final_battle') if final_battle then + local boss_room = game.get_surface('boss_room') + if not boss_room or not boss_room.valid then + return + end + if player.surface.index ~= boss_room.index then + local pos = boss_room.find_non_colliding_position('character', game.forces.player.get_spawn_position(boss_room), 3, 0, 5) + if pos then + player.teleport(pos, boss_room) + else + pos = game.forces.player.get_spawn_position(boss_room) + player.teleport(pos, boss_room) + end + end return end @@ -1739,6 +1751,14 @@ Public.light_oil_ammo = {name = 'light-oil', amount = 100} Public.artillery_shell_ammo = {name = 'artillery-shell', count = 15} Public.laser_turrent_power_source = {buffer_size = 2400000, power_production = 40000} +function Public.get_func(key) + if key then + return this[key] + else + return this + end +end + function Public.reset_func_table() this.power_sources = {index = 1} this.refill_turrets = {index = 1} diff --git a/maps/mountain_fortress_v3/gui.lua b/maps/mountain_fortress_v3/gui.lua index eec4b6f0..20019d65 100644 --- a/maps/mountain_fortress_v3/gui.lua +++ b/maps/mountain_fortress_v3/gui.lua @@ -7,6 +7,7 @@ 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 Polls = require 'utils.gui.poll' local format_number = require 'util'.format_number @@ -202,6 +203,7 @@ local function on_player_joined_game(event) end local function changed_surface(player) + local poll_button = Polls.main_button_name local rpg_button = RPG.draw_main_frame_name local rpg_frame = RPG.main_frame_name local rpg_settings = RPG.settings_frame_name @@ -213,6 +215,7 @@ local function changed_surface(player) local spectate = player.gui.top[spectate_button_name] local minimap_button = player.gui.top['minimap_button'] local rpg_b = player.gui.top[rpg_button] + local poll_b = player.gui.top[poll_button] local rpg_f = player.gui.screen[rpg_frame] local rpg_s = player.gui.screen[rpg_settings] local diff = player.gui.top[Difficulty.top_button_name] @@ -248,6 +251,9 @@ local function changed_surface(player) if rpg_b and not rpg_b.visible then rpg_b.visible = true end + if poll_b and not poll_b.visible then + poll_b.visible = true + end if minimap_button and not minimap_button.visible then minimap_button.visible = false end @@ -284,6 +290,9 @@ local function changed_surface(player) if rpg_b then rpg_b.visible = false end + if poll_b then + poll_b.visible = false + end if spell_cast_buttons and spell_cast_buttons.visible then spell_cast_buttons.visible = false end @@ -311,6 +320,15 @@ local function changed_surface(player) end end else + if poll_b then + poll_b.visible = false + end + if rpg_b then + rpg_b.visible = false + end + if spectate then + spectate.visible = false + end if info and info.visible then info.visible = false end diff --git a/maps/mountain_fortress_v3/icw/functions.lua b/maps/mountain_fortress_v3/icw/functions.lua index 5dd7cbb1..b4e34baf 100644 --- a/maps/mountain_fortress_v3/icw/functions.lua +++ b/maps/mountain_fortress_v3/icw/functions.lua @@ -15,9 +15,9 @@ local sqrt = math.sqrt local fallout_width = 64 local fallout_debris = {} -for x = fallout_width * -1 - 32, fallout_width + 32, 1 do +for x = fallout_width * -1 - 42, fallout_width + 42, 1 do if x < -31 or x > 31 then - for y = fallout_width * -1 - 32, fallout_width + 32, 1 do + for y = fallout_width * -1 - 42, fallout_width + 42, 1 do local position = {x = x, y = y} local fallout = sqrt(position.x ^ 2 + position.y ^ 2) if fallout > fallout_width then diff --git a/maps/mountain_fortress_v3/icw/table.lua b/maps/mountain_fortress_v3/icw/table.lua index f919d434..ecf98f2e 100644 --- a/maps/mountain_fortress_v3/icw/table.lua +++ b/maps/mountain_fortress_v3/icw/table.lua @@ -39,10 +39,10 @@ function Public.reset() } this.wagon_areas = { - ['cargo-wagon'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 80}}, - ['artillery-wagon'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 80}}, - ['fluid-wagon'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 80}}, - ['locomotive'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 80}} + ['cargo-wagon'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 100}}, + ['artillery-wagon'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 100}}, + ['fluid-wagon'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 100}}, + ['locomotive'] = {left_top = {x = -40, y = 0}, right_bottom = {x = 40, y = 100}} } end diff --git a/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua b/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua index 89c76004..43743d1f 100644 --- a/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua +++ b/maps/mountain_fortress_v3/locomotive/spawn_locomotive.lua @@ -112,8 +112,9 @@ local set_loco_tiles = name = 'crash-site-chest-2' end if surface.can_place_entity({name = name, position = p[i]}) then - local e = surface.create_entity({name = name, position = p[i], force = 'player', create_build_effect_smoke = false}) + local e = surface.create_entity({name = name, position = p[i], force = 'neutral', create_build_effect_smoke = false}) e.minable = false + e.destructible = true local inventory = e.get_inventory(defines.inventory.chest) inventory.insert(cargo_boxes[i]) end diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index 4a341e83..65a186e9 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -121,6 +121,8 @@ function Public.reset_map() this.active_surface_index = Public.create_surface() -- this.soft_reset_counter = Public.get_reset_counter() + Public.stateful.clear_all_frames() + Autostash.insert_into_furnace(true) Autostash.insert_into_wagon(true) Autostash.bottom_button(true) @@ -248,6 +250,7 @@ function Public.reset_map() wave_defense_table.game_lost = false wave_defense_table.spawn_position = {x = 0, y = 84} WD.alert_boss_wave(true) + WD.enable_side_target(true) WD.remove_entities(true) WD.enable_threat_log(false) -- creates waaaay to many entries in the global table WD.check_collapse_position(true) @@ -438,7 +441,7 @@ local collapse_after_wave_200 = function() if not collapse_grace then return end - if Collapse.start_now() then + if Collapse.get_start_now() then return end diff --git a/maps/mountain_fortress_v3/stateful/blueprints.lua b/maps/mountain_fortress_v3/stateful/blueprints.lua index 2e8ddeaa..2c94230e 100644 --- a/maps/mountain_fortress_v3/stateful/blueprints.lua +++ b/maps/mountain_fortress_v3/stateful/blueprints.lua @@ -1,43 +1,31 @@ local Public = require 'maps.mountain_fortress_v3.stateful.table' local map_name = 'boss_room' +local Token = require 'utils.token' +local Task = require 'utils.task' + +local blueprint_token = + Token.register( + function() + Public.blueprint() + end +) 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' - } - ) +function Public.blueprint() local position = {x = -500, y = 503} + local surface = game.get_surface(map_name) + if not surface or not surface.valid then + return + end + 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.request_to_generate_chunks(position, 1) + surface.request_to_generate_chunks({0, 0}, 1) surface.force_generate_chunk_requests() local item = surface.create_entity {name = 'item-on-ground', position = position, stack = {name = 'blueprint', count = 1}} @@ -60,15 +48,45 @@ function Public.create() 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) +function Public.create() + local surface = game.get_surface(map_name) + if surface and surface.valid then + surface.clear() + Task.set_timeout_in_ticks(60, blueprint_token, {}) + return end - Public.create() + + surface = + 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' + } + ) + + Public.blueprint() + + return surface end function Public.nuke_blueprint() diff --git a/maps/mountain_fortress_v3/stateful/generate.lua b/maps/mountain_fortress_v3/stateful/generate.lua index 9dad5b3a..46ff41c3 100644 --- a/maps/mountain_fortress_v3/stateful/generate.lua +++ b/maps/mountain_fortress_v3/stateful/generate.lua @@ -14,7 +14,7 @@ local generate_map = require 'maps.mountain_fortress_v3.stateful.terrain'.heavy_ -- 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 @@ -216,6 +216,9 @@ local function do_place_entities(data) if e.active ~= nil then entity.active = e.active end + if e.destructible ~= nil then + entity.destructible = e.destructible + end if e.force then entity.force = e.force end @@ -237,6 +240,9 @@ local function do_place_entities(data) if e.active ~= nil then entity.active = e.active end + if e.destructible ~= nil then + entity.destructible = e.destructible + end if e.force then entity.force = e.force end @@ -409,16 +415,13 @@ 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 - local tick = game.tick - - if force_chunk and force_chunk_until > tick then + if force_chunk then do_chunk(event) else schedule_chunk(event) diff --git a/maps/mountain_fortress_v3/stateful/gui.lua b/maps/mountain_fortress_v3/stateful/gui.lua index 9b21733b..c9aad7ec 100644 --- a/maps/mountain_fortress_v3/stateful/gui.lua +++ b/maps/mountain_fortress_v3/stateful/gui.lua @@ -60,6 +60,24 @@ local spread_particles_token = end ) +local function clear_all_frames() + Core.iter_players( + function(player) + local b_frame = player.gui.screen[boss_frame_name] + if b_frame then + Gui.remove_data_recursively(b_frame) + b_frame.destroy() + end + + local frame = player.gui.screen[main_frame_name] + if frame then + Gui.remove_data_recursively(frame) + frame.destroy() + end + end + ) +end + local warn_player_sound_token = Token.register( function(event) @@ -220,8 +238,6 @@ local function objective_frames(stateful, player_frame, objective, data) left_flow.style.horizontal_align = 'left' left_flow.style.horizontally_stretchable = true - data.random_objectives = {} - 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' @@ -293,7 +309,7 @@ local function boss_frame(player, alert) local time_left = floor(collection.time_until_attack / 60 / 60) .. 'm' - if collection.time_until_attack / 60 / 60 <= 0 then + if collection.time_until_attack / 60 / 60 <= 1 then time_left = floor(collection.time_until_attack / 60) .. 's' end @@ -316,7 +332,7 @@ local function boss_frame(player, alert) local survive_for_timer = floor(collection.survive_for / 60 / 60) .. 'm' - if collection.survive_for / 60 / 60 <= 0 then + if collection.survive_for / 60 / 60 <= 1 then survive_for_timer = floor(collection.survive_for / 60) .. 's' end @@ -396,16 +412,19 @@ local function main_frame(player) 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_objective_tbl = frame.add {type = 'table', column_count = 2} + gather_objective_tbl.style.horizontally_stretchable = true - local gather_warning_flow = objective_tbl.add({type = 'flow'}) + local gather_warning_flow = gather_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 objective_tbl = frame.add {type = 'table', column_count = 2} + objective_tbl.style.horizontally_stretchable = true + 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 @@ -419,7 +438,7 @@ local function main_frame(player) local time_left = floor(stateful.collection.gather_time / 60 / 60) .. 'm' - if stateful.collection.gather_time / 60 / 60 <= 0 then + if stateful.collection.gather_time / 60 / 60 <= 1 then time_left = floor(stateful.collection.gather_time / 60) .. 's' end @@ -463,6 +482,7 @@ local function main_frame(player) end --dynamic conditions + data.random_objectives = {} for index = 1, #stateful.selected_objectives do local objective = stateful.selected_objectives[index] @@ -496,7 +516,7 @@ local function update_data() 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) + local _, _, locale_right = callback_locomotive(callback_data) for i = 1, #players do local player = players[i] @@ -506,17 +526,13 @@ local function update_data() local data_boss = Gui.get_data(b) if data then - if data.rounds_survived and data.rounds_survived.valid then - data.rounds_survived.caption = stateful.rounds_survived + if data.rounds_survived_label and data.rounds_survived_label.valid then + data.rounds_survived_label.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_achievement_unlocked() - end else data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]' end @@ -525,10 +541,6 @@ local function update_data() 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_achievement_unlocked() - end else data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]' end @@ -540,19 +552,23 @@ local function update_data() 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_achievement_unlocked() + local count = Public.stateful.get_item_produced_count(supplies_data.name) + if count then + if not supplies_data.total then + supplies_data.total = supplies_data.count + end + supplies_data.count = supplies_data.total - count + 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 + frame.tooltip = supplies_data.total .. ' / ' .. 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]' end end end @@ -562,30 +578,30 @@ local function update_data() 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_achievement_unlocked() + local count = Public.stateful.get_item_produced_count(single_item.name) + if count then + if not single_item.total then + single_item.total = single_item.count + end + single_item.count = single_item.total - count + if single_item.count == 0 then + frame.number = nil + frame.sprite = 'utility/check_mark_green' + else + frame.number = single_item.count + frame.tooltip = single_item.total .. ' / ' .. count 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_achievement_unlocked() - end end - if data.gather_time_label and data.gather_time_label.valid then + if stateful.collection.gather_time and 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 + if stateful.collection.gather_time / 60 / 60 <= 1 then time_left = floor(stateful.collection.gather_time / 60) .. 's' end data.gather_time_label.caption = time_left @@ -600,20 +616,20 @@ local function update_data() local objective = stateful.selected_objectives[objective_index] local objective_name = objective[1] local callback = Token.get(objective[2]) - local completed, _, objective_locale_right = callback() + local _, _, 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_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 + if data_boss.rounds_survived_label and data_boss.rounds_survived_label.valid then + data_boss.rounds_survived_label.caption = stateful.rounds_survived + end + + if collection.time_until_attack and 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' @@ -630,7 +646,7 @@ local function update_data() data_boss.time_until_attack.caption = time_left end end - if data_boss.survive_for and data_boss.survive_for.valid then + if collection.survive_for and 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 @@ -648,6 +664,12 @@ local function update_data() end local function update_raw() + local game_lost = Public.get('game_lost') + if game_lost then + clear_all_frames() + return + end + local stateful = Public.get_stateful() local breached_wall = Public.get('breached_wall') local wave_number = WD.get('wave_number') @@ -683,26 +705,42 @@ local function update_raw() 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 - 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 + local count = Public.stateful.get_item_produced_count(supplies_data.name) + if count then + if not supplies_data.total then + supplies_data.total = supplies_data.count + end + supplies_data.count = supplies_data.total - count + 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 + 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 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_achievement_unlocked() - Server.to_discord_embed('Objective: **produce an item multiple times** has been completed!') - stateful.objectives_completed_count = stateful.objectives_completed_count + 1 + if single_item then + local count = Public.stateful.get_item_produced_count(single_item.name) + if count then + if not single_item.total then + single_item.total = single_item.count + end + single_item.count = single_item.total - count + if single_item.count == 0 then + if not stateful.objectives_completed.single_item then + stateful.objectives_completed.single_item = true + 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 end end @@ -719,6 +757,21 @@ local function update_raw() end end end + + if collection.gather_time then + collection.gather_time = collection.gather_time_timer - tick + if collection.gather_time > 0 then + collection.gather_time = collection.gather_time + elseif collection.gather_time and collection.gather_time <= 0 then + collection.gather_time = 0 + if not collection.gather_time_done then + collection.gather_time_done = true + stateful.final_battle = true + Public.set('final_battle', true) + 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 @@ -733,6 +786,8 @@ local function update_raw() collection.game_won_notified = true refresh_boss_frame() play_game_won() + stateful.rounds_survived = stateful.rounds_survived + 1 + Public.stateful.save_settings() local locomotive = Public.get('locomotive') if locomotive and locomotive.valid then locomotive.surface.spill_item_stack(locomotive.position, {name = 'coin', count = 512}, false) @@ -764,15 +819,11 @@ local function update_raw() end end - if stateful.collection.gather_time and tick >= stateful.collection.gather_time then - stateful.collection.final_battle = true - Public.set('final_battle', true) - end - 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 + stateful.collection.gather_time_timer = tick + 54000 play_achievement_unlocked() Core.iter_connected_players( @@ -781,7 +832,7 @@ local function update_raw() if frame then Gui.remove_data_recursively(frame) frame.destroy() - boss_frame(player) + main_frame(player) end end ) @@ -807,6 +858,12 @@ Gui.on_click( return end + local game_lost = Public.get('game_lost') + if game_lost then + clear_all_frames() + return + end + local player = event.player if not player or not player.valid then return @@ -870,5 +927,6 @@ Event.on_nth_tick(60, update_data) Event.on_nth_tick(120, update_raw) Public.boss_frame = boss_frame +Public.clear_all_frames = clear_all_frames return Public diff --git a/maps/mountain_fortress_v3/stateful/main.lua b/maps/mountain_fortress_v3/stateful/main.lua index 996e9aa0..ac2511fb 100644 --- a/maps/mountain_fortress_v3/stateful/main.lua +++ b/maps/mountain_fortress_v3/stateful/main.lua @@ -23,8 +23,7 @@ Event.add( if not objectives then return end - - if name == objectives.research_level_selection then + if name == objectives.research_level_selection.name then objectives.research_level_count = objectives.research_level_count + 1 end end diff --git a/maps/mountain_fortress_v3/stateful/table.lua b/maps/mountain_fortress_v3/stateful/table.lua index a04a64fa..8a247d8f 100644 --- a/maps/mountain_fortress_v3/stateful/table.lua +++ b/maps/mountain_fortress_v3/stateful/table.lua @@ -12,10 +12,14 @@ local Core = require 'utils.core' local Public = require 'maps.mountain_fortress_v3.table' local Task = require 'utils.task' local Alert = require 'utils.alert' +local IC = require 'maps.mountain_fortress_v3.ic.table' +local RPG = require 'modules.rpg.table' local this = { enabled = false, - rounds_survived = 0 + rounds_survived = 0, + buffs = {}, + reset_after = 60 } local random = math.random @@ -58,6 +62,49 @@ local disabled_items = { ['express-loader'] = true } +local function get_random_buff() + local buffs = { + { + name = 'character_running_speed_modifier', + modifier = 'force', + state = 0.04 + }, + { + name = 'manual_mining_speed_modifier', + modifier = 'force', + state = 0.05 + }, + { + name = 'character_reach_distance_bonus', + modifier = 'force', + state = 0.02 + }, + { + name = 'manual_crafting_speed_modifier', + modifier = 'force', + state = 0.04 + }, + { + name = 'xp_bonus', + modifier = 'rpg', + state = 0.02 + }, + { + name = 'items_startup', + modifier = 'start', + items = { + {name = 'iron-plate', count = 100}, + {name = 'copper-plate', count = 100} + } + } + } + + shuffle(buffs) + shuffle(buffs) + + return buffs[1] +end + local function get_item_produced_count(item_name) local force = game.forces.player @@ -242,6 +289,14 @@ local function get_random_items() [3] = {name = items[3].products[1].name, count = scale(random(100, 5000))} } + if this.test_mode then + container = { + [1] = {name = items[1].products[1].name, count = 1}, + [2] = {name = items[2].products[1].name, count = 1}, + [3] = {name = items[3].products[1].name, count = 1} + } + end + return container end @@ -260,6 +315,10 @@ local function get_random_item() shuffle(items) shuffle(items) + if this.test_mode then + return {name = items[10].products[1].name, count = 1} + end + return {name = items[10].products[1].name, count = scale(random(5000, 100000), 40000000)} end @@ -277,6 +336,10 @@ local function get_random_research_recipe() shuffle(research_level_list) + if this.test_mode then + return {name = research_level_list[1], count = 1} + end + return {name = research_level_list[1], count = scale(random(10, 20), 40)} end @@ -293,6 +356,12 @@ local function get_random_locomotive_tier() local health_count = scale(random(10, 40), 100) local xp_points_count = scale(random(10, 40), 100) + if this.test_mode then + pickaxe_count = 1 + health_count = 1 + xp_points_count = 1 + end + if tiers[1] == 'pickaxe' then return { locomotive_market_pickaxe_token, @@ -368,14 +437,82 @@ local apply_settings_token = Token.register( function(data) local settings = data and data.value or nil + local new_value = Server.get_current_date() + if not settings then + settings = { + rounds_survived = 0 + } + + if new_value then + settings.current_date = tonumber(new_value) + else + settings.current_date = 0 + end + + Server.set_data(dataset, dataset_key, settings) return end + if not settings.current_date then + if new_value then + settings.current_date = tonumber(new_value) + else + settings.current_date = 0 + end + Server.set_data(dataset, dataset_key, settings) + end + + local old_value = settings.current_date + if old_value then + old_value = tonumber(old_value) + local new_value = Server.get_current_date() + local time_to_reset = (new_value - old_value) + if time_to_reset then + if time_to_reset > this.reset_after then + if new_value then + settings.current_date = tonumber(new_value) + else + settings.current_date = 0 + end + settings.test_mode = false + settings.rounds_survived = 0 + settings.buffs = {} + + Server.set_data(dataset, dataset_key, settings) + end + end + end + local rounds_survived = settings.rounds_survived Public.increase_enemy_damage_and_health() + local starting_items = Public.get_func('starting_items') + + if settings.buffs and next(settings.buffs) then + local force = game.forces.player + for _, buff in pairs(settings.buffs) do + if buff then + if buff.modifier == 'force' then + force[buff.name] = force[buff.name] + buff.state + end + if buff.modifier == 'rpg' then + local rpg_extra = RPG.get('rpg_extra') + rpg_extra.difficulty = buff.state + end + if buff.modifier == 'start' then + for _, item in pairs(buff.items) do + if item then + starting_items[item.name] = item.count + end + end + end + end + end + end + + this.buffs = settings.buffs this.rounds_survived = rounds_survived this.objectives_completed = {} this.objectives_completed_count = 0 @@ -409,40 +546,63 @@ local apply_settings_token = ) function Public.save_settings() + this.buffs[#this.buffs + 1] = get_random_buff() + local settings = { - rounds_survived = this.rounds_survived + rounds_survived = this.rounds_survived, + test_mode = this.test_mode, + buffs = this.buffs } Server.set_data(dataset, dataset_key, settings) end function Public.reset_stateful() + this.test_mode = false 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) - } + if this.test_mode then + this.objectives = { + randomized_zone = 2, + randomized_wave = 2, + supplies = get_random_items(), + single_item = get_random_item(), + killed_enemies = 10, + complete_mystical_chest_amount = 1, + research_level_selection = get_random_research_recipe(), + research_level_count = 0, + locomotive_market_selection = get_random_locomotive_tier(), + trees_farmed = 10, + rocks_farmed = 10, + rockets_launched = 1 + } + else + 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) + } + end this.collection = { time_until_attack = nil, time_until_attack_timer = nil, survive_for = nil, survive_for_timer = nil } + this.stateful_locomotive_migrated = false this.force_chunk = true - this.force_chunk_until = game.tick + 1000 end function Public.migrate_and_create(locomotive) @@ -518,6 +678,8 @@ function Public.allocate() ICWT.set('speed', 0.3) ICWT.set('final_battle', true) + IC.set('allowed_surface', 'boss_room') + local collection = Public.get_stateful('collection') if not collection then return @@ -552,6 +714,7 @@ function Public.set_target(target, icw_data) 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.enable_side_target = false 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) @@ -618,6 +781,30 @@ Event.add( end ) +Server.on_data_set_changed( + dataset, + function(data) + if data.key ~= dataset_key then + return + end + if not data.value then + return + end + + if data.value.test_mode then + Public.reset_stateful() + Public.stateful.clear_all_frames() + game.print('[Stateful] Test round settings received.') + this.test_mode = true + elseif data.value.test_mode == false then + Public.reset_stateful() + Public.stateful.clear_all_frames() + game.print('[Stateful] Test round settings has been disabled.') + this.test_mode = false + end + 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 diff --git a/maps/mountain_fortress_v3/stateful/terrain.lua b/maps/mountain_fortress_v3/stateful/terrain.lua index bf505d4f..7cf5fb3d 100644 --- a/maps/mountain_fortress_v3/stateful/terrain.lua +++ b/maps/mountain_fortress_v3/stateful/terrain.lua @@ -152,7 +152,7 @@ local function border_chunk(p, data) name = 'spitter-spawner' end if enemy_spawn_positions(p) then - entities[#entities + 1] = {name = name, position = pos, force = 'enemy', collision = true, active = false} + entities[#entities + 1] = {name = name, position = pos, force = 'enemy', collision = true, active = false, destructible = false} end end diff --git a/maps/mountain_fortress_v3/surface.lua b/maps/mountain_fortress_v3/surface.lua index ad7c7100..82f8036b 100644 --- a/maps/mountain_fortress_v3/surface.lua +++ b/maps/mountain_fortress_v3/surface.lua @@ -15,9 +15,8 @@ Global.register( end ) -local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['rail'] = 16, ['wood'] = 16, ['explosives'] = 32} - function Public.create_surface() + local starting_items = Public.get_func('starting_items') local map_gen_settings = { ['seed'] = math.random(10000, 99999), ['width'] = zone_settings.zone_width, diff --git a/maps/mountain_fortress_v3/table.lua b/maps/mountain_fortress_v3/table.lua index b474a0a7..0e287ff1 100644 --- a/maps/mountain_fortress_v3/table.lua +++ b/maps/mountain_fortress_v3/table.lua @@ -193,7 +193,7 @@ function Public.reset_main_table() this.outside_chests = {} this.chests_linked_to = {} this.placed_trains_in_zone = { - limit = 2, + limit = 1, randomized = false, zones = {} } diff --git a/maps/mountain_fortress_v3/terrain.lua b/maps/mountain_fortress_v3/terrain.lua index 28accbf7..98f573c7 100644 --- a/maps/mountain_fortress_v3/terrain.lua +++ b/maps/mountain_fortress_v3/terrain.lua @@ -246,7 +246,7 @@ local function place_wagon(data, adjusted_zones) local placed_trains_in_zone = Public.get('placed_trains_in_zone') if not placed_trains_in_zone.randomized then - placed_trains_in_zone.limit = random(1, 2) + placed_trains_in_zone.limit = random(0, 1) placed_trains_in_zone.randomized = true placed_trains_in_zone = Public.get('placed_trains_in_zone') end diff --git a/maps/scrap_towny_ffa/nauvis.lua b/maps/scrap_towny_ffa/nauvis.lua index 2ba3de1b..9a1743fa 100644 --- a/maps/scrap_towny_ffa/nauvis.lua +++ b/maps/scrap_towny_ffa/nauvis.lua @@ -166,7 +166,6 @@ function Public.initialize() } mgs.seed = math_random(100000, 9999999) - log(serpent.block(mgs)) if not this.active_surface_index then this.active_surface_index = game.create_surface('towny', mgs).index else diff --git a/modules/collapse.lua b/modules/collapse.lua index 62ebaf0a..e0e51b56 100644 --- a/modules/collapse.lua +++ b/modules/collapse.lua @@ -279,6 +279,10 @@ function Public.start_now(state) return this.start_now end +function Public.get_start_now() + return this.start_now +end + function Public.set_max_line_size(size) if not size then print_debug(22) diff --git a/modules/difficulty_vote_by_amount.lua b/modules/difficulty_vote_by_amount.lua index e59343b8..3536e01e 100644 --- a/modules/difficulty_vote_by_amount.lua +++ b/modules/difficulty_vote_by_amount.lua @@ -80,6 +80,10 @@ local function clear_main_frame(player) end function Public.difficulty_gui() + if not this.show_gui then + return + end + local tooltip = 'Current difficulty of the map is ' .. this.difficulties[this.index].name .. '.' for _, player in pairs(game.connected_players) do @@ -150,6 +154,13 @@ local function poll_difficulty(player) clear_main_frame(player) end + if not this.show_gui then + if player.gui.center[main_frame_name] then + clear_main_frame(player) + end + return + end + if game.tick > this.closing_timeout then if player.online_time ~= 0 then local t = math.abs(math.floor((this.closing_timeout - game.tick) / 3600)) @@ -283,9 +294,6 @@ local function on_player_joined_game(event) end local function on_player_left_game(event) - if not this.show_gui then - return - end if game.tick > this.closing_timeout then return end diff --git a/modules/rpg/settings.lua b/modules/rpg/settings.lua index 46f8ca9a..68e271d6 100644 --- a/modules/rpg/settings.lua +++ b/modules/rpg/settings.lua @@ -709,6 +709,10 @@ function Public.extra_settings(player) Gui.set_data(save_button, data) + if not main_frame or not main_frame.valid then + return + end + player.opened = main_frame main_frame.auto_center = true end diff --git a/modules/wave_defense/main.lua b/modules/wave_defense/main.lua index f92ae92f..3749157b 100644 --- a/modules/wave_defense/main.lua +++ b/modules/wave_defense/main.lua @@ -827,37 +827,39 @@ local function get_main_command(group) Public.debug_print('get_commmands - distance_to_target:' .. distance_to_target .. ' steps:' .. steps) Public.debug_print('get_commmands - vector ' .. vector[1] .. '_' .. vector[2]) - for _ = 1, steps, 1 do - local old_position = group_position - group_position.x = group_position.x + vector[1] - group_position.y = group_position.y + vector[2] - local obstacles = - group.surface.find_entities_filtered { - position = old_position, - radius = step_length / 2, - type = {'simple-entity', 'tree'}, - limit = 50 - } - if obstacles then - shuffle_distance(obstacles, old_position) - for ii = 1, #obstacles, 1 do - if obstacles[ii].valid then - commands[#commands + 1] = { - type = defines.command.attack, - target = obstacles[ii], - distraction = defines.distraction.by_anything - } + if Public.get('enable_side_target') then + for _ = 1, steps, 1 do + local old_position = group_position + group_position.x = group_position.x + vector[1] + group_position.y = group_position.y + vector[2] + local obstacles = + group.surface.find_entities_filtered { + position = old_position, + radius = step_length / 2, + type = {'simple-entity', 'tree'}, + limit = 50 + } + if obstacles then + shuffle_distance(obstacles, old_position) + for ii = 1, #obstacles, 1 do + if obstacles[ii].valid then + commands[#commands + 1] = { + type = defines.command.attack, + target = obstacles[ii], + distraction = defines.distraction.by_anything + } + end end end - end - local position = group.surface.find_non_colliding_position('behemoth-biter', group_position, step_length, 1) - if position then - commands[#commands + 1] = { - type = defines.command.attack_area, - destination = {x = position.x, y = position.y}, - radius = 16, - distraction = defines.distraction.by_anything - } + local position = group.surface.find_non_colliding_position('behemoth-biter', group_position, step_length, 1) + if position then + commands[#commands + 1] = { + type = defines.command.attack_area, + destination = {x = position.x, y = position.y}, + radius = 16, + distraction = defines.distraction.by_anything + } + end end end @@ -1255,7 +1257,7 @@ Event.on_nth_tick( local final_boss = Public.get('final_boss') local paused = Public.get('paused') - if paused then + if paused and not final_boss then local players = game.connected_players for _, player in pairs(players) do Public.update_gui(player) diff --git a/modules/wave_defense/pause_waves.lua b/modules/wave_defense/pause_waves.lua index 853edc77..175150f0 100644 --- a/modules/wave_defense/pause_waves.lua +++ b/modules/wave_defense/pause_waves.lua @@ -240,6 +240,11 @@ Event.on_nth_tick( return end + local final_boss = Public.get('final_boss') + if final_boss then + return + end + local paused = Public.get('paused') if paused then return diff --git a/modules/wave_defense/threat_events.lua b/modules/wave_defense/threat_events.lua index 48858e45..1d45ee8f 100644 --- a/modules/wave_defense/threat_events.lua +++ b/modules/wave_defense/threat_events.lua @@ -216,6 +216,11 @@ else end function Public.build_nest() + local final_boss = Public.get('final_boss') + if final_boss then + return + end + local threat = Public.get('threat') if threat < 1024 then return @@ -232,8 +237,9 @@ function Public.build_nest() end function Public.build_worm() + local final_boss = Public.get('final_boss') local threat = Public.get('threat') - if threat < 512 then + if threat < 512 and not final_boss then return end local worm_building_chance = Public.get('worm_building_chance') --[[@as integer]] diff --git a/utils/commands/misc.lua b/utils/commands/misc.lua index 672d462d..eaf527d3 100644 --- a/utils/commands/misc.lua +++ b/utils/commands/misc.lua @@ -250,6 +250,8 @@ commands.add_command( game.print('[CREATIVE] ' .. player.name .. ' has activated creative-mode!', Color.warning) Server.to_discord_bold(table.concat {'[Creative] ' .. player.name .. ' has activated creative-mode!'}) + Modifiers.set('creative_enabled', true) + for _, iter_player in pairs(game.connected_players) do if iter_player.character ~= nil then if iter_player.get_inventory(defines.inventory.character_armor) then @@ -290,6 +292,7 @@ commands.add_command( end iter_player.print('[CREATIVE] Inserted all base items.', Color.success) this.creative_enabled = true + this.creative_are_you_sure = false end end end @@ -482,6 +485,7 @@ end Event.on_init( function() + Modifiers.set('creative_enabled', false) this.creative_are_you_sure = false this.creative_enabled = false this.spaghetti_are_you_sure = false @@ -490,6 +494,7 @@ Event.on_init( ) function Public.reset() + Modifiers.set('creative_enabled', false) this.creative_are_you_sure = false this.creative_enabled = false this.spaghetti_are_you_sure = false diff --git a/utils/datastore/jail_data.lua b/utils/datastore/jail_data.lua index ef75dfdf..563b4f28 100644 --- a/utils/datastore/jail_data.lua +++ b/utils/datastore/jail_data.lua @@ -366,7 +366,12 @@ local function teleport_player_to_gulag(player, action) if get_tile.valid and get_tile.name == 'out-of-map' then player.teleport(surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 128, 1), surface.name) else - player.teleport(surface.find_non_colliding_position('character', p, 128, 1), surface.name) + local valid_to_teleport = surface.find_non_colliding_position('character', p, 128, 1) + if valid_to_teleport then + player.teleport(valid_to_teleport, surface.name) + else + player.teleport(game.forces.player.get_spawn_position(surface), surface.name) + end end get_player_data(player, true) diff --git a/utils/gui/poll.lua b/utils/gui/poll.lua index dd025c09..59435a4a 100644 --- a/utils/gui/poll.lua +++ b/utils/gui/poll.lua @@ -6,7 +6,7 @@ local session = require 'utils.datastore.session_data' local Config = require 'utils.gui.config' local SpamProtection = require 'utils.spam_protection' -local Class = {} +local Public = {} local insert = table.insert @@ -1266,7 +1266,7 @@ Gui.on_click( Gui.on_click(poll_view_vote_name, vote) -function Class.reset() +function Public.reset() for k, _ in pairs(polls) do polls[k] = nil end @@ -1286,11 +1286,11 @@ function Class.reset() end end -function Class.get_no_notify_players() +function Public.get_no_notify_players() return no_notify_players end -function Class.validate(data) +function Public.validate(data) if type(data) ~= 'table' then return false, 'argument must be of type table' end @@ -1328,8 +1328,8 @@ function Class.validate(data) return true end -function Class.poll(data) - local suc, error = Class.validate(data) +function Public.poll(data) + local suc, error = Public.validate(data) if not suc then return false, error end @@ -1383,7 +1383,7 @@ function Class.poll(data) return true, id end -function Class.poll_result(id) +function Public.poll_result(id) if type(id) ~= 'number' then return 'poll-id must be a number' end @@ -1411,7 +1411,7 @@ function Class.poll_result(id) return table.concat {'poll #', id, ' not found'} end -function Class.send_poll_result_to_discord(id) +function Public.send_poll_result_to_discord(id) if type(id) ~= 'number' then Server.to_discord_embed('poll-id must be a number') return @@ -1428,4 +1428,6 @@ function Class.send_poll_result_to_discord(id) Server.to_discord_embed(message) end -return Class +Public.main_button_name = main_button_name + +return Public diff --git a/utils/player_modifiers.lua b/utils/player_modifiers.lua index 651ceadf..54e0dbef 100644 --- a/utils/player_modifiers.lua +++ b/utils/player_modifiers.lua @@ -75,7 +75,7 @@ function Public.update_player_modifiers(player) if disabled_modifiers and disabled_modifiers[k] then player[modifier] = 0 else - if modifiers[k] == 'character_inventory_slots_bonus' then + if modifiers[k] == 'character_inventory_slots_bonus' and not this.creative_enabled then local inv = player.get_inventory(defines.inventory.character_main) if inv and #inv > this.rpg_inventory_slot_limit + 80 then player[modifier] = this.rpg_inventory_slot_limit - 20 @@ -106,8 +106,10 @@ function Public.update_single_modifier(player, modifier, category, value) end player_modifiers[k][category] = value - if category == 'rpg' and modifiers[k] == 'character_inventory_slots_bonus' and player_modifiers[k][category] >= this.rpg_inventory_slot_limit then - player_modifiers[k][category] = this.rpg_inventory_slot_limit - player.force.character_inventory_slots_bonus + if not this.creative_enabled then + if category == 'rpg' and modifiers[k] == 'character_inventory_slots_bonus' and player_modifiers[k][category] >= this.rpg_inventory_slot_limit then + player_modifiers[k][category] = this.rpg_inventory_slot_limit - player.force.character_inventory_slots_bonus + end end else player_modifiers[k] = value diff --git a/utils/remote_chunks.lua b/utils/remote_chunks.lua new file mode 100644 index 00000000..e41ca244 --- /dev/null +++ b/utils/remote_chunks.lua @@ -0,0 +1,79 @@ +local Global = require 'utils.global' +local Event = require 'utils.event' +local this = { + chunks = {} +} + +Global.register( + this, + function(tbl) + this = tbl + end +) + +local Public = {} + +function Public.get_chunk_and_remove() + local chunk + this.current_index, chunk = next(this.chunks, this.current_index) + + if this.current_index and this.chunks[this.current_index] then + this.chunks[this.current_index] = nil + return chunk + end +end + +function Public.apply_tiles(tiles) + if tiles and next(tiles) then + local surface = game.get_surface('nauvis') + surface.set_tiles(tiles, true) + end +end + +function Public.apply_entities(entities) + if entities and next(entities) then + local surface = game.get_surface('nauvis') + for _, e in ipairs(entities) do + if e then + surface.create_entity(e) + end + end + end +end + +function Public.apply_decoratives(decoratives) + if decoratives and next(decoratives) then + local surface = game.get_surface('nauvis') + surface.create_decoratives({check_collision = true, decoratives = decoratives}) + end +end + +Event.add( + defines.events.on_chunk_generated, + function(event) + local left_top = event.area.left_top + local surface = event.surface + local map_name = this.map_name + + if not map_name then + return + end + + if string.sub(surface.name, 0, #map_name) ~= map_name then + return + end + + local seed = surface.map_gen_settings.seed + + if not surface.generate_with_lab_tiles then + surface.generate_with_lab_tiles = true + end + + this.chunks[#this.chunks + 1] = { + seed = seed, + left_top = left_top + } + end +) + +return Public