--luacheck: ignore require 'modules.rocks_broken_paint_tiles' local Event = require 'utils.event' local Server = require 'utils.server' local BiterRolls = require 'modules.wave_defense.biter_rolls' local BuriedEnemies = require 'maps.amap.buried_enemies' local Loot = require 'maps.amap.loot' local Pets = require 'maps.amap.biter_pets' local RPG_Settings = require 'modules.rpg.table' local Functions = require 'modules.rpg.functions' local Callbacks = require 'maps.amap.functions' local Locomotive = require 'maps.amap.locomotive' local Alert = require 'utils.alert' local Task = require 'utils.task' local Score = require 'comfy_panel.score' local Token = require 'utils.token' -- tables local WPT = require 'maps.amap.table' local WD = require 'modules.wave_defense.table' -- module local Public = {} local random = math.random local floor = math.floor local abs = math.abs local sqrt = math.sqrt local round = math.round local chests = { 'wooden-chest', 'iron-chest', 'steel-chest', 'crash-site-chest-1', 'crash-site-chest-2', 'crash-site-spaceship-wreck-big-1', 'crash-site-spaceship-wreck-big-2', 'crash-site-spaceship-wreck-medium-1', 'crash-site-spaceship-wreck-medium-2', 'crash-site-spaceship-wreck-medium-3' } local size_chests = #chests local treasure_chest_messages = { ({'entity.treasure_1'}), ({'entity.treasure_2'}), ({'entity.treasure_3'}) } local rare_treasure_chest_messages = { ({'entity.treasure_rare_1'}), ({'entity.treasure_rare_2'}), ({'entity.treasure_rare_3'}) } local disabled_threats = { ['entity-ghost'] = true, ['raw-fish'] = true } local defeated_messages = { ({'entity.defeated_1'}), ({'entity.defeated_2'}), ({'entity.defeated_3'}), ({'entity.defeated_4'}) } local protect_types = { ['cargo-wagon'] = true, ['artillery-wagon'] = true, ['fluid-wagon'] = true, ['locomotive'] = true, ['reactor'] = true, ['spidertron'] = true } local reset_game = Token.register( function(data) local this = data.this local Reset_map = data.reset_map if this.soft_reset then HS.set_scores() this.game_reset_tick = nil Reset_map() return end if this.restart then HS.set_scores() local message = ({'entity.reset_game'}) Server.to_discord_bold(message, true) Server.start_scenario('Mountain_Fortress_v3') this.announced_message = true return end if this.shutdown then HS.set_scores() local message = ({'entity.shutdown_game'}) Server.to_discord_bold(message, true) Server.stop_scenario() return end end ) local function exists() local carriages = WPT.get('carriages') local t = {} for i = 1, #carriages do local e = carriages[i] if (e and e.valid) then t[e.unit_number] = true end end return t end local function get_random_weighted(weighted_table, item_index, weight_index) local total_weight = 0 item_index = item_index or 1 weight_index = weight_index or 2 for _, w in pairs(weighted_table) do total_weight = total_weight + w[weight_index] end local index = random() * total_weight local weight_sum = 0 for _, w in pairs(weighted_table) do weight_sum = weight_sum + w[weight_index] if weight_sum >= index then return w[item_index] end end end local function on_entity_removed(data) local entity = data.entity local upgrades = WPT.get('upgrades') local built = { ['land-mine'] = upgrades.landmine.built, ['flamethrower-turret'] = upgrades.flame_turret.built } local validator = { ['land-mine'] = 'landmine', ['flamethrower-turret'] = 'flame_turret' } local name = validator[entity.name] if built[entity.name] and entity.force.index == 1 then upgrades[name].built = upgrades[name].built - 1 if upgrades[name].built <= 0 then upgrades[name].built = 0 end end end local function check_health() local locomotive_health = WPT.get('locomotive_health') local locomotive_max_health = WPT.get('locomotive_max_health') local carriages = WPT.get('carriages') local m = locomotive_health / locomotive_max_health if carriages then for i = 1, #carriages do local entity = carriages[i] if not (entity and entity.valid) then return end if entity.type == 'locomotive' then entity.health = 1000 * m else entity.health = 600 * m end end end end local function check_health_final_damage(final_damage_amount) local carriages = WPT.get('carriages') if carriages then for i = 1, #carriages do local entity = carriages[i] if not (entity and entity.valid) then return end entity.health = entity.health + final_damage_amount end end end local function set_train_final_health(final_damage_amount) if final_damage_amount == 0 then return end local locomotive = WPT.get('locomotive') if not (locomotive and locomotive.valid) then return end local locomotive_health = WPT.get('locomotive_health') local locomotive_max_health = WPT.get('locomotive_max_health') local poison_deployed = WPT.get('poison_deployed') if locomotive_health <= 5000 then if not poison_deployed then for i = 1, 2, 1 do Locomotive.enable_poison_defense() end local p = { position = locomotive.position } local msg = ({'entity.train_taking_damage'}) Alert.alert_all_players_location(p, msg) WPT.set().poison_deployed = true end elseif locomotive_health >= locomotive_max_health then WPT.set().poison_deployed = false end if locomotive_health <= 0 then check_health_final_damage(final_damage_amount) return end WPT.set('locomotive_health', floor(locomotive_health - final_damage_amount)) if locomotive_health > locomotive_max_health then WPT.set('locomotive_health', locomotive_max_health) end locomotive_health = WPT.get('locomotive_health') if locomotive_health <= 0 then Public.loco_died() end check_health() local health_text = WPT.get('health_text') rendering.set_text(health_text, 'HP: ' .. locomotive_health .. ' / ' .. locomotive_max_health) end local function protect_entities(event) local entity = event.entity local dmg = event.final_damage_amount if not dmg then return end if entity.type == 'simple-entity' and dmg >= 300 then entity.health = entity.health + dmg end if entity.force.index ~= 1 then return end --Player Force local function is_protected(e) local map_name = 'mountain_fortress_v3' if string.sub(e.surface.name, 0, #map_name) ~= map_name then return true end if protect_types[e.type] then return true end return false end local units = exists() if is_protected(entity) then if (event.cause and event.cause.valid) then if event.cause.force.index == 2 then if units and units[entity.unit_number] then return set_train_final_health(dmg) end elseif event.cause.force.index == 2 then return else entity.health = entity.health + dmg end elseif not (event.cause and event.cause.valid) then if event.force.index == 2 then if units and units[entity.unit_number] then return set_train_final_health(dmg) end entity.health = entity.health - dmg return end end entity.health = entity.health + dmg end end local function hidden_biter_pet(player, entity) if random(1, 1024) ~= 1 then return end local pos = entity.position BiterRolls.wave_defense_set_unit_raffle(sqrt(pos.x ^ 2 + pos.y ^ 2) * 0.25) local unit if random(1, 3) == 1 then unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = pos}) else unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = pos}) end Pets.biter_pets_tame_unit(game.players[player.index], unit, true) end local function hidden_treasure(player, entity) local rpg = RPG_Settings.get('rpg_t') local magic = rpg[player.index].magicka if magic > 50 then local msg = rare_treasure_chest_messages[random(1, #rare_treasure_chest_messages)] Alert.alert_player(player, 5, msg) Loot.add_rare(entity.surface, entity.position, 'wooden-chest', magic) return end local msg = treasure_chest_messages[random(1, #treasure_chest_messages)] Alert.alert_player(player, 5, msg, nil, nil, 0.3) Loot.add(entity.surface, entity.position, chests[random(1, size_chests)]) end local function biters_chew_rocks_faster(event) if event.entity.force.index ~= 3 then return end --Neutral Force if not event.cause then return end if not event.cause.valid then return end if event.cause.force.index ~= 2 then return end --Enemy Force event.entity.health = event.entity.health - event.final_damage_amount * 7 end local projectiles = {'grenade', 'explosive-rocket', 'grenade', 'explosive-rocket', 'explosive-cannon-projectile'} local function angry_tree(entity, cause, player) if entity.type ~= 'tree' then return end if abs(entity.position.y) < Terrain.level_depth then return end if random(1, 6) == 1 then BuriedEnemies.buried_biter(entity.surface, entity.position) end if random(1, 8) == 1 then BuriedEnemies.buried_worm(entity.surface, entity.position) end if random(1, 32) ~= 1 then return end local position = false if cause then if cause.valid then position = cause.position end end if not position then position = {entity.position.x + (-20 + random(0, 40)), entity.position.y + (-20 + random(0, 40))} end if player then local forest_zone = RPG_Settings.get_value_from_player(player.index, 'forest_zone') if forest_zone and random(1, 32) == 1 then local cbl = Callbacks.power_source_callback local data = {callback_data = Callbacks.laser_turrent_power_source} local e = entity.surface.create_entity( { name = 'laser-turret', position = entity.position, force = 'enemy' } ) local callback = Token.get(cbl) callback(e, data) return end end entity.surface.create_entity( { name = projectiles[random(1, 5)], position = entity.position, force = 'neutral', source = entity.position, target = position, max_range = 16, speed = 0.01 } ) end local function give_coin(player) local coin_amount = WPT.get('coin_amount') local coin_override = WPT.get('coin_override') local forest_zone = RPG_Settings.get_value_from_player(player.index, 'forest_zone') if forest_zone then if random(1, 3) ~= 1 then return end end if coin_amount >= 1 then if coin_override then player.insert({name = 'coin', count = coin_override}) else player.insert({name = 'coin', count = coin_amount}) end end end local mining_events = { { function() end, 300000, 'Nothing' }, { function() end, 16384, 'Nothing' }, { function() end, 4096, 'Nothing' }, { function(entity) if Locomotive.is_around_train(entity) then entity.destroy() return end BuriedEnemies.buried_biter(entity.surface, entity.position, 1) entity.destroy() end, 4096, 'Angry Biter #2' }, { function(entity) if Locomotive.is_around_train(entity) then entity.destroy() return end BuriedEnemies.buried_biter(entity.surface, entity.position) entity.destroy() end, 512, 'Angry Biter #2' }, { function(entity) if Locomotive.is_around_train(entity) then entity.destroy() return end BuriedEnemies.buried_worm(entity.surface, entity.position) entity.destroy() end, 2048, 'Angry Worm' }, { function(entity) if Locomotive.is_around_train(entity) then entity.destroy() return end Traps(entity.surface, entity.position) entity.destroy() end, 2048, 'Dangerous Trap' }, { function(entity, index) if Locomotive.is_around_train(entity) then entity.destroy() return end local player = game.get_player(index) if entity.type == 'tree' then angry_tree(entity, player.character, player) entity.destroy() end end, 1024, 'Angry Tree' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 1024, 'Treasure_Tier_1' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 512, 'Treasure_Tier_2' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 256, 'Treasure_Tier_3' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 128, 'Treasure_Tier_4' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 64, 'Treasure_Tier_5' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 32, 'Treasure_Tier_6' }, { function(entity, index) local player = game.get_player(index) hidden_treasure(player, entity) end, 16, 'Treasure_Tier_7' }, { function(entity, index) local player = game.get_player(index) Public.unstuck_player(index) hidden_biter_pet(player, entity) end, 256, 'Pet' }, { function(entity, index) if Locomotive.is_around_train(entity) then entity.destroy() return end local position = entity.position local surface = entity.surface surface.create_entity({name = 'biter-spawner', position = position, force = 'enemy'}) Public.unstuck_player(index) end, 512, 'Nest' }, { function(entity) local position = entity.position local surface = entity.surface surface.create_entity({name = 'compilatron', position = position, force = 'player'}) end, 64, 'Friendly Compilatron' }, { function(entity) if Locomotive.is_around_train(entity) then entity.destroy() return end local position = entity.position local surface = entity.surface surface.create_entity({name = 'compilatron', position = position, force = 'enemy'}) end, 128, 'Enemy Compilatron' }, { function(entity, index) local position = entity.position local surface = entity.surface surface.create_entity({name = 'car', position = position, force = 'player'}) Public.unstuck_player(index) local player = game.players[index] local msg = ({'entity.found_car', player.name}) Alert.alert_player(player, 15, msg) end, 32, 'Car' } } local function on_player_mined_entity(event) local entity = event.entity local player = game.players[event.player_index] if not player.valid then return end if not entity.valid then return end local rpg = RPG_Settings.get('rpg_t') local rpg_char = rpg[player.index] local map_name = 'mountain_fortress_v3' if string.sub(entity.surface.name, 0, #map_name) ~= map_name then return end local d = { entity = entity } on_entity_removed(d) if disabled_threats[entity.name] then return end local mined_scrap = WPT.get('mined_scrap') if entity.type == 'simple-entity' or entity.type == 'simple-entity-with-owner' or entity.type == 'tree' then WPT.set().mined_scrap = mined_scrap + 1 Mining.on_player_mined_entity(event) if entity.type == 'tree' then if random(1, 3) == 1 then give_coin(player) end else give_coin(player) end if rpg_char.stone_path then entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true) end local func = get_random_weighted(mining_events) func(entity, player.index) end end local function on_robot_mined_entity(event) local entity = event.entity if not entity.valid then return end local map_name = 'mountain_fortress_v3' if string.sub(entity.surface.name, 0, #map_name) ~= map_name then return end local d = { entity = entity } on_entity_removed(d) end local function get_damage(event) local entity = event.entity local damage = event.original_damage_amount + event.original_damage_amount * random(1, 100) if entity.prototype.resistances then if entity.prototype.resistances.physical then damage = damage - entity.prototype.resistances.physical.decrease damage = damage - damage * entity.prototype.resistances.physical.percent end end damage = round(damage, 3) if damage < 1 then damage = 1 end return damage end local function kaboom(entity, target, damage) local base_vector = {target.position.x - entity.position.x, target.position.y - entity.position.y} local vector = {base_vector[1], base_vector[2]} vector[1] = vector[1] * 512 vector[2] = vector[2] * 256 local msg = {'TASTY', 'MUNCH', 'SNACK_TIME', 'OVER 9000!'} entity.surface.create_entity( { name = 'flying-text', position = {entity.position.x + base_vector[1] * 0.5, entity.position.y + base_vector[2] * 0.5}, text = msg[random(1, #msg)], color = {255, 0, 0} } ) if abs(vector[1]) > abs(vector[2]) then local d = abs(vector[1]) if abs(vector[1]) > 0 then vector[1] = vector[1] / d end if abs(vector[2]) > 0 then vector[2] = vector[2] / d end else local d = abs(vector[2]) if abs(vector[2]) > 0 then vector[2] = vector[2] / d end if abs(vector[1]) > 0 and d > 0 then vector[1] = vector[1] / d end end vector[1] = vector[1] * 1.6 vector[2] = vector[2] * 1.6 local a = 0.30 for i = 1, 8, 1 do for x = i * -1 * a, i * a, 1 do for y = i * -1 * a, i * a, 1 do local p = {entity.position.x + x + vector[1] * i, entity.position.y + y + vector[2] * i} entity.surface.create_trivial_smoke({name = 'fire-smoke', position = p}) for _, e in pairs(entity.surface.find_entities({{p[1] - a, p[2] - a}, {p[1] + a, p[2] + a}})) do if e.valid then if e.health then if e.destructible and e.minable then if e.force.index ~= entity.force.index then e.health = e.health - damage * 0.05 if e.health <= 0 then e.die(e.force.name, entity) end end end end end end end end end end local function boss_puncher(event) local cause = event.cause if not cause then return end if not cause.valid then return end if cause.force.index ~= 2 then return end local entity = event.entity if entity.force.index ~= 1 then return end if not entity then return end if not entity.valid then return end if random(1, 10) == 1 then kaboom(cause, entity, get_damage(event)) end end local function on_entity_damaged(event) local entity = event.entity if not (entity and entity.valid) then return end local wave_number = WD.get_wave() local boss_wave_warning = WD.get_alert_boss_wave() local munch_time = WPT.get('munch_time') protect_entities(event) biters_chew_rocks_faster(event) if munch_time then if boss_wave_warning or wave_number >= 1000 then if random(0, 512) == 1 then boss_puncher(event) end end end if WPT.get('explosive_bullets') then ExplosiveBullets.explosive_bullets(event) return end end local function on_player_repaired_entity(event) if not event.entity then return end if not event.entity.valid then return end if not event.entity.health then return end local entity = event.entity local units = exists() if units[entity.unit_number] then local player = game.players[event.player_index] local repair_speed = Functions.get_magicka(player) if repair_speed <= 0 then set_train_final_health(-1) return else set_train_final_health(-repair_speed) return end end end local function on_entity_died(event) local entity = event.entity if not entity.valid then return end local cause = event.cause local map_name = 'mountain_fortress_v3' if string.sub(entity.surface.name, 0, #map_name) ~= map_name then return end local d = { entity = entity } on_entity_removed(d) local player if cause then if cause.valid then if (cause and cause.name == 'character' and cause.player) then player = cause.player end if cause.force.index == 2 or cause.force.index == 3 then entity.destroy() return end end end if disabled_threats[entity.name] then return end local biters_killed = WPT.get('biters_killed') local biters = WPT.get('biters') if entity.type == 'unit' or entity.type == 'unit-spawner' then WPT.set().biters_killed = biters_killed + 1 biters.amount = biters.amount - 1 if biters.amount <= 0 then biters.amount = 0 end if Locomotive.is_around_train(entity) then return end if random(1, 512) == 1 then Traps(entity.surface, entity.position) return end end if entity.type == 'tree' then for _, e in pairs( entity.surface.find_entities_filtered( { area = { {entity.position.x - 4, entity.position.y - 4}, {entity.position.x + 4, entity.position.y + 4} }, name = 'fire-flame-on-tree' } ) ) do if e.valid then e.destroy() return end end if Locomotive.is_around_train(entity) then return end angry_tree(entity, cause, player) return end if entity.type == 'simple-entity' then if Locomotive.is_around_train(entity) then entity.destroy() return end if random(1, 32) == 1 then BuriedEnemies.buried_biter(entity.surface, entity.position) entity.destroy() return end if random(1, 64) == 1 then BuriedEnemies.buried_worm(entity.surface, entity.position) entity.destroy() return end if random(1, 512) == 1 then Traps(entity.surface, entity.position) return end entity.destroy() return end end local function get_sorted_list(column_name, score_list) for _ = 1, #score_list, 1 do for y = 1, #score_list, 1 do if not score_list[y + 1] then break end if score_list[y][column_name] < score_list[y + 1][column_name] then local key = score_list[y] score_list[y] = score_list[y + 1] score_list[y + 1] = key end end end return score_list end local function get_mvps(force) local get_score = Score.get_table().score_table if not get_score[force] then return false end local score = get_score[force] local score_list = {} for _, p in pairs(game.players) do if score.players[p.name] then local killscore = 0 if score.players[p.name].killscore then killscore = score.players[p.name].killscore end local built_entities = 0 if score.players[p.name].built_entities then built_entities = score.players[p.name].built_entities end local mined_entities = 0 if score.players[p.name].mined_entities then mined_entities = score.players[p.name].mined_entities end table.insert(score_list, {name = p.name, killscore = killscore, built_entities = built_entities, mined_entities = mined_entities}) end end local mvp = {} score_list = get_sorted_list('killscore', score_list) mvp.killscore = {name = score_list[1].name, score = score_list[1].killscore} score_list = get_sorted_list('mined_entities', score_list) mvp.mined_entities = {name = score_list[1].name, score = score_list[1].mined_entities} score_list = get_sorted_list('built_entities', score_list) mvp.built_entities = {name = score_list[1].name, score = score_list[1].built_entities} return mvp end local function show_mvps(player) local get_score = Score.get_table().score_table local wave_defense_table = WD.get_table() if not get_score then return end if player.gui.left['mvps'] then return end local frame = player.gui.left.add({type = 'frame', name = 'mvps', direction = 'vertical'}) local l = frame.add({type = 'label', caption = 'MVPs:'}) l.style.font = 'default-listbox' l.style.font_color = {r = 0.55, g = 0.55, b = 0.99} local t = frame.add({type = 'table', column_count = 2}) local mvp = get_mvps('player') if mvp then local wave_defense = t.add({type = 'label', caption = 'Highest Wave >> '}) wave_defense.style.font = 'default-listbox' wave_defense.style.font_color = {r = 0.22, g = 0.77, b = 0.44} local wave_defense_text = t.add({type = 'label', caption = 'This rounds highest wave was: ' .. wave_defense_table.wave_number}) wave_defense_text.style.font = 'default-bold' wave_defense_text.style.font_color = {r = 0.33, g = 0.66, b = 0.9} local defender_label = t.add({type = 'label', caption = 'Defender >> '}) defender_label.style.font = 'default-listbox' defender_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} local defender_label_text = t.add({type = 'label', caption = mvp.killscore.name .. ' with a killing score of ' .. mvp.killscore.score .. ' kills!'}) defender_label_text.style.font = 'default-bold' defender_label_text.style.font_color = {r = 0.33, g = 0.66, b = 0.9} local builder_label = t.add({type = 'label', caption = 'Builder >> '}) builder_label.style.font = 'default-listbox' builder_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} local builder_label_text = t.add({type = 'label', caption = mvp.built_entities.name .. ' built ' .. mvp.built_entities.score .. ' things!'}) builder_label_text.style.font = 'default-bold' builder_label_text.style.font_color = {r = 0.33, g = 0.66, b = 0.9} local miners_label = t.add({type = 'label', caption = 'Miners >> '}) miners_label.style.font = 'default-listbox' miners_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} local miners_label_text = t.add({type = 'label', caption = mvp.mined_entities.name .. ' mined a total of ' .. mvp.mined_entities.score .. ' entities!'}) miners_label_text.style.font = 'default-bold' miners_label_text.style.font_color = {r = 0.33, g = 0.66, b = 0.9} local sent_to_discord = WPT.get('sent_to_discord') if not sent_to_discord then local result = {} table.insert(result, 'HIGHEST WAVE: \\n') table.insert(result, wave_defense_table.wave_number .. '\\n') table.insert(result, '\\n') table.insert(result, 'MVP Defender: \\n') table.insert(result, mvp.killscore.name .. ' with a killing score of ' .. mvp.killscore.score .. ' kills!\\n') table.insert(result, '\\n') table.insert(result, 'MVP Builder: \\n') table.insert(result, mvp.built_entities.name .. ' built ' .. mvp.built_entities.score .. ' things!\\n') table.insert(result, '\\n') table.insert(result, 'MVP Miners: \\n') table.insert(result, mvp.mined_entities.name .. ' mined a total of ' .. mvp.mined_entities.score .. ' entities!\\n') local message = table.concat(result) Server.to_discord_embed(message) WPT.set('sent_to_discord', true) end end end function Public.unstuck_player(index) local player = game.get_player(index) local surface = player.surface local position = surface.find_non_colliding_position('character', player.position, 32, 0.5) if not position then return end player.teleport(position, surface) end function Public.loco_died() local active_surface_index = WPT.get('active_surface_index') local locomotive = WPT.get('locomotive') local surface = game.surfaces[active_surface_index] local wave_defense_table = WD.get_table() if wave_defense_table.game_lost then return end Collapse.start_now(false) if not locomotive.valid then local this = WPT.get() if this.announced_message then return end local data = {} if this.locomotive and this.locomotive.valid then data.position = this.locomotive.position else data.position = {x = 0, y = 0} end local msg = defeated_messages[random(1, #defeated_messages)] Alert.alert_all_players_location(data, msg, nil, 100) local Reset_map = require 'maps.mountain_fortress_v3.main'.reset_map wave_defense_table.game_lost = true wave_defense_table.target = nil local params = { this = this, reset_map = Reset_map } if this.soft_reset then this.game_reset_tick = nil Task.set_timeout_in_ticks(600, reset_game, params) return end if this.restart then if not this.announced_message then game.print(({'entity.notify_restart'}), {r = 0.22, g = 0.88, b = 0.22}) Task.set_timeout_in_ticks(600, reset_game, params) this.announced_message = true return end end if this.shutdown then if not this.announced_message then game.print(({'entity.notify_shutdown'}), {r = 0.22, g = 0.88, b = 0.22}) Task.set_timeout_in_ticks(600, reset_game, params) this.announced_message = true return end end return end local this = WPT.get() this.locomotive_health = 0 this.locomotive.color = {0.49, 0, 255, 1} rendering.set_text(this.health_text, 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health) wave_defense_table.game_lost = true wave_defense_table.target = nil this.game_lost = true local msg = defeated_messages[random(1, #defeated_messages)] local pos = { position = this.locomotive.position } Alert.alert_all_players_location(pos, msg) Server.to_discord_bold(msg, true) game.forces.enemy.set_friend('player', true) game.forces.player.set_friend('enemy', true) local fake_shooter = surface.create_entity({name = 'character', position = this.locomotive.position, force = 'enemy'}) surface.create_entity( { name = 'atomic-rocket', position = this.locomotive.position, force = 'enemy', speed = 1, max_range = 1200, target = this.locomotive, source = fake_shooter } ) surface.spill_item_stack(this.locomotive.position, {name = 'coin', count = 512}, false) this.game_reset_tick = 5400 for _, player in pairs(game.connected_players) do player.play_sound {path = 'utility/game_lost', volume_modifier = 0.75} show_mvps(player) end end local function on_built_entity(event) local entity = event.created_entity if not entity.valid then return end local map_name = 'mountain_fortress_v3' if string.sub(entity.surface.name, 0, #map_name) ~= map_name then return end local upgrades = WPT.get('upgrades') local upg = upgrades local surface = entity.surface local built = { ['land-mine'] = upg.landmine.built, ['flamethrower-turret'] = upg.flame_turret.built } local limit = { ['land-mine'] = upg.landmine.limit, ['flamethrower-turret'] = upg.flame_turret.limit } local validator = { ['land-mine'] = 'landmine', ['flamethrower-turret'] = 'flame_turret' } local name = validator[entity.name] if built[entity.name] and entity.force.index == 1 then if built[entity.name] < limit[entity.name] then upgrades[name].built = built[entity.name] + 1 upgrades.unit_number[name][entity] = entity upgrades.showed_text = false surface.create_entity( { name = 'flying-text', position = entity.position, text = upgrades[name].built .. ' / ' .. limit[entity.name] .. ' ' .. entity.name, color = {r = 0.82, g = 0.11, b = 0.11} } ) else if not upgrades.showed_text then surface.create_entity( { name = 'flying-text', position = entity.position, text = ({'entity.entity_limit_reached', entity.name}), color = {r = 0.82, g = 0.11, b = 0.11} } ) upgrades.showed_text = true end local player = game.players[event.player_index] player.insert({name = entity.name, count = 1}) entity.destroy() end end end local function on_robot_built_entity(event) local entity = event.created_entity if not entity.valid then return end local map_name = 'mountain_fortress_v3' if string.sub(entity.surface.name, 0, #map_name) ~= map_name then return end local upgrades = WPT.get('upgrades') local upg = upgrades local surface = entity.surface local built = { ['land-mine'] = upg.landmine.built, ['flamethrower-turret'] = upg.flame_turret.built } local limit = { ['land-mine'] = upg.landmine.limit, ['flamethrower-turret'] = upg.flame_turret.limit } local validator = { ['land-mine'] = 'landmine', ['flamethrower-turret'] = 'flame_turret' } local name = validator[entity.name] if built[entity.name] and entity.force.index == 1 then if built[entity.name] < limit[entity.name] then upgrades[name].built = built[entity.name] + 1 upgrades.unit_number[name][entity] = entity upgrades.showed_text = false surface.create_entity( { name = 'flying-text', position = entity.position, text = upgrades[name].built .. ' / ' .. limit[entity.name] .. ' ' .. entity.name, color = {r = 0.82, g = 0.11, b = 0.11} } ) else if not upgrades.showed_text then surface.create_entity( { name = 'flying-text', position = entity.position, text = ({'entity.entity_limit_reached', entity.name}), color = {r = 0.82, g = 0.11, b = 0.11} } ) upgrades.showed_text = true end local inventory = event.robot.get_inventory(defines.inventory.robot_cargo) inventory.insert({name = entity.name, count = 1}) entity.destroy() end end end local on_player_or_robot_built_tile = function(event) local surface = game.surfaces[event.surface_index] local map_name = 'mountain_fortress_v3' if string.sub(surface.name, 0, #map_name) ~= map_name then return end local tiles = event.tiles if not tiles then return end for k, v in pairs(tiles) do local old_tile = v.old_tile if old_tile.name == 'black-refined-concrete' then surface.set_tiles({{name = 'black-refined-concrete', position = v.position}}, true) end if old_tile.name == 'blue-refined-concrete' then surface.set_tiles({{name = 'blue-refined-concrete', position = v.position}}, true) end if old_tile.name == 'cyan-refined-concrete' then surface.set_tiles({{name = 'cyan-refined-concrete', position = v.position}}, true) end if old_tile.name == 'hazard-concrete-right' then surface.set_tiles({{name = 'hazard-concrete-right', position = v.position}}, true) end if old_tile.name == 'lab-dark-2' then surface.set_tiles({{name = 'lab-dark-2', position = v.position}}, true) end end end Event.add_event_filter(defines.events.on_entity_damaged, {filter = 'final-damage-amount', comparison = '>', value = 0}) Event.add(defines.events.on_entity_damaged, on_entity_damaged) Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity) Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity) Event.add(defines.events.on_entity_died, on_entity_died) Event.add(defines.events.on_built_entity, on_built_entity) Event.add(defines.events.on_robot_built_entity, on_robot_built_entity) Event.add(defines.events.on_player_built_tile, on_player_or_robot_built_tile) Event.add(defines.events.on_robot_built_tile, on_player_or_robot_built_tile) return Public