--luacheck: ignore --map by mewmew and kyte require 'maps.island_troopers.map_intro' require 'functions.noise_vector_path' require 'modules.shopping_chests' require 'modules.no_turrets' require 'modules.dangerous_goods' require 'modules.rpg' require 'modules.difficulty_vote' require 'maps.island_troopers.enemies' require 'maps.island_troopers.terrain' local Difficulty = require 'modules.difficulty_vote' max_island_radius = 128 local function create_stage_gui(player) if player.gui.top.stage_gui then return end local element = player.gui.top.add({type = 'frame', name = 'stage_gui', caption = ' '}) local style = element.style style.minimal_height = 38 style.maximal_height = 38 style.minimal_width = 140 style.top_padding = 2 style.left_padding = 4 style.right_padding = 4 style.bottom_padding = 2 style.font_color = {r = 155, g = 85, b = 25} style.font = 'default-large-bold' end function update_stage_gui() if not global.stages then return end local caption = 'Level: ' .. global.current_level caption = caption .. ' | Stage: ' local stage = global.current_stage if stage > #global.stages - 1 then stage = #global.stages - 1 end caption = caption .. stage caption = caption .. '/' caption = caption .. #global.stages - 1 caption = caption .. ' | Bugs remaining: ' caption = caption .. global.alive_enemies for _, player in pairs(game.connected_players) do if player.gui.top.stage_gui then player.gui.top.stage_gui.caption = caption end end end local function bring_players() local surface = game.surfaces[1] for _, player in pairs(game.connected_players) do if player.position.y < -1 then if player.character then if player.character.valid then local p = surface.find_non_colliding_position('character', {0, 2}, 8, 0.5) if not p then player.teleport({0, 2}, surface) end player.teleport(p, surface) end end end end end local function drift_corpses_toward_beach() local surface = game.surfaces[1] for _, corpse in pairs(surface.find_entities_filtered({name = 'character-corpse'})) do if corpse.position.y < 0 then if surface.get_tile(corpse.position).collides_with('resource-layer') then corpse.clone { position = {corpse.position.x, corpse.position.y + (math.random(50, 250) * 0.01)}, surface = surface, force = corpse.force.name } corpse.destroy() end end end end local function get_island_size() local r_min = global.current_level + 16 if r_min > math.floor(max_island_radius * 0.5) then r_min = math.floor(max_island_radius * 0.5) end local r_max = global.current_level * 2 + 32 if r_max > max_island_radius then r_max = max_island_radius end return math.random(r_min, r_max) end local function set_next_level() global.alive_enemies = 0 global.alive_boss_enemy_count = 0 global.current_level = global.current_level + 1 if global.current_level > 1 then bring_players() end global.current_stage = 1 global.stage_amount = math.floor(global.current_level * 0.33) + 3 if global.stage_amount > 9 then global.stage_amount = 9 end global.path_tiles = nil local island_size = get_island_size() global.stages = {} global.stages[1] = { path_length = 16 + island_size * 1.5, size = island_size } for i = 1, global.stage_amount - 1, 1 do island_size = get_island_size() global.stages[#global.stages + 1] = { path_length = 16 + island_size * 1.5, size = island_size } end global.stages[#global.stages + 1] = { path_length = max_island_radius * 7, size = false } --game.print("Level " .. global.current_level) update_stage_gui() global.gamestate = 2 end local function earn_credits(amount) for _, player in pairs(game.connected_players) do player.play_sound {path = 'utility/armor_insert', volume_modifier = 0.85} end game.print(amount .. ' credits have been transfered to the factory.', {r = 255, g = 215, b = 0}) global.credits = global.credits + amount end local function slowmo() if not global.slowmo then global.slowmo = 0.15 end game.speed = global.slowmo global.slowmo = global.slowmo + 0.01 if game.speed < 1 then return end for _, p in pairs(game.connected_players) do if p.gui.left['slowmo_cam'] then p.gui.left['slowmo_cam'].destroy() end end global.slowmo = nil global.gamestate = 4 end local function wait_until_stage_is_beaten() if global.alive_enemies > 0 then return end local reward_amount = false local gamestate = 2 local base_reward = 250 * global.current_level if global.stages[global.current_stage].size then if global.current_stage < #global.stages - 1 then reward_amount = base_reward + global.current_stage * global.current_level * 50 else reward_amount = base_reward + global.current_stage * global.current_level * 150 end else game.print('Final Stage complete!') game.print('Level is collapsing !!', {r = 255, g = 0, b = 0}) gamestate = 5 end if reward_amount then earn_credits(reward_amount) update_stage_gui() end global.current_stage = global.current_stage + 1 global.gamestate = gamestate end local function on_player_joined_game(event) local player = game.players[event.player_index] create_stage_gui(player) if player.gui.left['slowmo_cam'] then player.gui.left['slowmo_cam'].destroy() end update_stage_gui() if player.online_time > 0 then return end player.insert({name = 'pistol', count = 1}) player.insert({name = 'firearm-magazine', count = 32}) end local function on_init() Difficulty.get() game.create_force('enemy_spawners') game.forces.enemy_spawners.set_friend('enemy', true) game.forces.enemy.set_friend('enemy_spawners', true) local surface = game.surfaces[1] surface.request_to_generate_chunks({x = 0, y = 0}, 16) surface.force_generate_chunk_requests() --global.tree_raffle = {} --for _, e in pairs(game.entity_prototypes) do -- if e.type == "tree" then -- table.insert(global.tree_raffle, e.name) -- end --end local blacklist = { ['dark-mud-decal'] = true, ['sand-dune-decal'] = true, ['light-mud-decal'] = true, ['puberty-decal'] = true, ['sand-decal'] = true, ['red-desert-decal'] = true } global.decorative_names = {} for k, v in pairs(game.decorative_prototypes) do if not blacklist[k] then if v.autoplace_specification then global.decorative_names[#global.decorative_names + 1] = k end end end Difficulty.difficulty_poll_closing_timeout = 3600 * 10 global.level_vectors = {} global.alive_boss_enemy_entities = {} global.current_level = 0 global.gamestate = 1 game.forces.player.set_spawn_position({0, 2}, surface) end local msg = { 'We got the brainbug!', 'Good job troopers!', "I'm doing my part!" } local function on_entity_died(event) local entity = event.entity if not entity.valid then return end if entity.force.name == 'enemy_spawners' then if entity.type == 'unit' then return end global.alive_enemies = global.alive_enemies - 1 return end if entity.force.name ~= 'enemy' then return end global.alive_enemies = global.alive_enemies - 1 update_stage_gui() if entity.type ~= 'unit' then return end if not global.alive_boss_enemy_entities[entity.unit_number] then return end global.alive_boss_enemy_entities[entity.unit_number] = nil global.alive_boss_enemy_count = global.alive_boss_enemy_count - 1 if global.alive_boss_enemy_count == 0 then for _, p in pairs(game.connected_players) do if p.gui.left['slowmo_cam'] then p.gui.left['slowmo_cam'].destroy() end local frame = p.gui.left.add({type = 'frame', name = 'slowmo_cam', caption = msg[math.random(1, #msg)]}) local camera = frame.add({type = 'camera', name = 'mini_cam_element', position = entity.position, zoom = 1.5, surface_index = 1}) camera.style.minimal_width = 400 camera.style.minimal_height = 400 end global.gamestate = 8 end end local gamestate_functions = { [1] = set_next_level, [2] = draw_path_to_next_stage, [3] = draw_the_island, [4] = wait_until_stage_is_beaten, [5] = kill_the_level, [8] = slowmo } local function on_tick() gamestate_functions[global.gamestate]() if game.tick % 150 == 0 then drift_corpses_toward_beach() end end local event = require 'utils.event' event.on_init(on_init) event.add(defines.events.on_tick, on_tick) event.add(defines.events.on_entity_died, on_entity_died) event.add(defines.events.on_player_joined_game, on_player_joined_game) require 'functions.boss_unit'