From c6040cdaedb4bc23a9ceaeddbb6353d995286542 Mon Sep 17 00:00:00 2001 From: itamzxm <36615577+itamzxm@users.noreply.github.com> Date: Thu, 7 Jan 2021 23:48:24 +0800 Subject: [PATCH] Add files via upload --- maps/amap/basic_markets.lua | 308 ++++++++ maps/amap/biter_pets.lua | 200 +++++ maps/amap/buried_enemies.lua | 256 +++++++ maps/amap/caves.lua | 251 ++++++ maps/amap/entities.lua | 1382 ++++++++++++++++++++++++++++++++++ maps/amap/functions.lua | 794 +++++++++++++++++++ maps/amap/loot.lua | 157 ++++ maps/amap/main.lua | 403 ++++++++++ maps/amap/rock.lua | 95 +++ maps/amap/soft_reset.lua | 114 +++ maps/amap/sort.lua | 482 ++++++++++++ maps/amap/surface.lua | 73 ++ maps/amap/table.lua | 172 +++++ 13 files changed, 4687 insertions(+) create mode 100644 maps/amap/basic_markets.lua create mode 100644 maps/amap/biter_pets.lua create mode 100644 maps/amap/buried_enemies.lua create mode 100644 maps/amap/caves.lua create mode 100644 maps/amap/entities.lua create mode 100644 maps/amap/functions.lua create mode 100644 maps/amap/loot.lua create mode 100644 maps/amap/main.lua create mode 100644 maps/amap/rock.lua create mode 100644 maps/amap/soft_reset.lua create mode 100644 maps/amap/sort.lua create mode 100644 maps/amap/surface.lua create mode 100644 maps/amap/table.lua diff --git a/maps/amap/basic_markets.lua b/maps/amap/basic_markets.lua new file mode 100644 index 00000000..dbe39d2d --- /dev/null +++ b/maps/amap/basic_markets.lua @@ -0,0 +1,308 @@ +local Public = {} + +local market = {} +local random = math.random +local floor = math.floor + +local blacklist = { + ['cargo-wagon'] = true, + ['locomotive'] = true, + ['artillery-wagon'] = true, + ['artillery-turret'] = true, + ['fluid-wagon'] = true, + ['land-mine'] = true, + ['car'] = true, + ['tank'] = true, + ['spidertron'] = true +} + +market.weapons = { + ['pistol'] = {value = 10, rarity = 1}, + ['submachine-gun'] = {value = 50, rarity = 2}, + ['shotgun'] = {value = 40, rarity = 2}, + ['combat-shotgun'] = {value = 400, rarity = 5}, + ['rocket-launcher'] = {value = 500, rarity = 6}, + ['flamethrower'] = {value = 750, rarity = 6}, + ['land-mine'] = {value = 3, rarity = 5} +} + +market.ammo = { + ['firearm-magazine'] = {value = 3, rarity = 1}, + ['piercing-rounds-magazine'] = {value = 6, rarity = 4}, + ['uranium-rounds-magazine'] = {value = 20, rarity = 8}, + ['shotgun-shell'] = {value = 3, rarity = 1}, + ['piercing-shotgun-shell'] = {value = 8, rarity = 5}, + ['cannon-shell'] = {value = 8, rarity = 4}, + ['explosive-cannon-shell'] = {value = 12, rarity = 5}, + ['uranium-cannon-shell'] = {value = 16, rarity = 7}, + ['explosive-uranium-cannon-shell'] = {value = 20, rarity = 8}, + ['artillery-shell'] = {value = 64, rarity = 7}, + ['rocket'] = {value = 45, rarity = 7}, + ['explosive-rocket'] = {value = 50, rarity = 7}, + ['atomic-bomb'] = {value = 11000, rarity = 10}, + ['flamethrower-ammo'] = {value = 20, rarity = 6}, + ['explosives'] = {value = 3, rarity = 1} +} + +market.caspules = { + ['grenade'] = {value = 16, rarity = 2}, + ['cluster-grenade'] = {value = 64, rarity = 5}, + ['poison-capsule'] = {value = 32, rarity = 6}, + ['slowdown-capsule'] = {value = 8, rarity = 1}, + ['defender-capsule'] = {value = 8, rarity = 1}, + ['distractor-capsule'] = {value = 20, rarity = 9}, + ['destroyer-capsule'] = {value = 32, rarity = 12}, + ['discharge-defense-remote'] = {value = 2000, rarity = 8}, + ['artillery-targeting-remote'] = {value = 32, rarity = 7}, + ['raw-fish'] = {value = 6, rarity = 1} +} + +market.armor = { + ['light-armor'] = {value = 25, rarity = 1}, + ['heavy-armor'] = {value = 250, rarity = 4}, + ['modular-armor'] = {value = 750, rarity = 5}, + ['power-armor'] = {value = 2500, rarity = 6}, + ['power-armor-mk2'] = {value = 20000, rarity = 10} +} + +market.equipment = { + ['solar-panel-equipment'] = {value = 240, rarity = 3}, + ['fusion-reactor-equipment'] = {value = 9000, rarity = 7}, + ['energy-shield-equipment'] = {value = 400, rarity = 6}, + ['energy-shield-mk2-equipment'] = {value = 4000, rarity = 8}, + ['battery-equipment'] = {value = 160, rarity = 2}, + ['battery-mk2-equipment'] = {value = 2000, rarity = 8}, + ['personal-laser-defense-equipment'] = {value = 2500, rarity = 7}, + ['discharge-defense-equipment'] = {value = 8000, rarity = 7}, + ['belt-immunity-equipment'] = {value = 200, rarity = 1}, + ['exoskeleton-equipment'] = {value = 800, rarity = 3}, + ['personal-roboport-equipment'] = {value = 500, rarity = 3}, + ['personal-roboport-mk2-equipment'] = {value = 5000, rarity = 8}, + ['night-vision-equipment'] = {value = 250, rarity = 1} +} + +market.defense = { + ['stone-wall'] = {value = 4, rarity = 1}, + ['gate'] = {value = 8, rarity = 1}, + ['repair-pack'] = {value = 8, rarity = 1}, + ['gun-turret'] = {value = 64, rarity = 1}, + ['laser-turret'] = {value = 1024, rarity = 6}, + ['flamethrower-turret'] = {value = 2048, rarity = 6}, + ['artillery-turret'] = {value = 8192, rarity = 8}, + ['rocket-silo'] = {value = 64000, rarity = 10} +} + +market.logistic = { + ['wooden-chest'] = {value = 3, rarity = 1}, + ['iron-chest'] = {value = 10, rarity = 2}, + ['steel-chest'] = {value = 24, rarity = 3}, + ['storage-tank'] = {value = 32, rarity = 4}, + ['transport-belt'] = {value = 4, rarity = 1}, + ['fast-transport-belt'] = {value = 8, rarity = 4}, + ['express-transport-belt'] = {value = 24, rarity = 7}, + ['underground-belt'] = {value = 8, rarity = 1}, + ['fast-underground-belt'] = {value = 32, rarity = 4}, + ['express-underground-belt'] = {value = 64, rarity = 7}, + ['splitter'] = {value = 16, rarity = 1}, + ['fast-splitter'] = {value = 48, rarity = 4}, + ['express-splitter'] = {value = 128, rarity = 7}, + ['loader'] = {value = 256, rarity = 2}, + ['fast-loader'] = {value = 512, rarity = 5}, + ['express-loader'] = {value = 768, rarity = 8}, + ['burner-inserter'] = {value = 4, rarity = 1}, + ['inserter'] = {value = 8, rarity = 1}, + ['long-handed-inserter'] = {value = 12, rarity = 2}, + ['fast-inserter'] = {value = 16, rarity = 4}, + ['filter-inserter'] = {value = 24, rarity = 5}, + ['stack-inserter'] = {value = 96, rarity = 6}, + ['stack-filter-inserter'] = {value = 128, rarity = 7}, + ['small-electric-pole'] = {value = 2, rarity = 1}, + ['medium-electric-pole'] = {value = 12, rarity = 4}, + ['big-electric-pole'] = {value = 24, rarity = 5}, + ['substation'] = {value = 96, rarity = 8}, + ['pipe'] = {value = 2, rarity = 1}, + ['pipe-to-ground'] = {value = 8, rarity = 1}, + ['pump'] = {value = 16, rarity = 4}, + ['logistic-robot'] = {value = 28, rarity = 5}, + ['construction-robot'] = {value = 28, rarity = 3}, + ['logistic-chest-active-provider'] = {value = 128, rarity = 7}, + ['logistic-chest-passive-provider'] = {value = 128, rarity = 6}, + ['logistic-chest-storage'] = {value = 128, rarity = 6}, + ['logistic-chest-buffer'] = {value = 128, rarity = 7}, + ['logistic-chest-requester'] = {value = 128, rarity = 7}, + ['roboport'] = {value = 4096, rarity = 8} +} + +market.vehicles = { + ['rail'] = {value = 4, rarity = 1}, + ['train-stop'] = {value = 32, rarity = 3}, + ['rail-signal'] = {value = 8, rarity = 5}, + ['rail-chain-signal'] = {value = 8, rarity = 5}, + ['locomotive'] = {value = 400, rarity = 4}, + ['cargo-wagon'] = {value = 200, rarity = 4}, + ['fluid-wagon'] = {value = 300, rarity = 5}, + ['artillery-wagon'] = {value = 8192, rarity = 8}, + ['car'] = {value = 80, rarity = 1}, + ['tank'] = {value = 1800, rarity = 5} +} + +market.wire = { + ['small-lamp'] = {value = 4, rarity = 1}, + ['red-wire'] = {value = 4, rarity = 1}, + ['green-wire'] = {value = 4, rarity = 1}, + ['arithmetic-combinator'] = {value = 16, rarity = 1}, + ['decider-combinator'] = {value = 16, rarity = 1}, + ['constant-combinator'] = {value = 16, rarity = 1}, + ['power-switch'] = {value = 16, rarity = 1}, + ['programmable-speaker'] = {value = 24, rarity = 1} +} + +local function get_types() + local types = {} + for k, _ in pairs(market) do + types[#types + 1] = k + end + return types +end + +local function get_resource_market_sells() + local sells = { + {price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'wood', count = 50}}, + {price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}}, + {price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}}, + {price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'stone', count = 50}}, + {price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'coal', count = 50}}, + {price = {{'coin', random(8, 16)}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}}, + {price = {{'coin', random(2, 4)}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 1}} + } + table.shuffle_table(sells) + return sells +end + +local function get_resource_market_buys() + local buys = { + {price = {{'wood', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'iron-ore', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'copper-ore', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'stone', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'coal', random(10, 12)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'uranium-ore', random(8, 10)}}, offer = {type = 'give-item', item = 'coin'}}, + {price = {{'water-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(1, 2)}}, + {price = {{'lubricant-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(3, 6)}}, + {price = {{'sulfuric-acid-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(4, 8)}}, + {price = {{'light-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(2, 4)}}, + {price = {{'heavy-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(2, 4)}}, + {price = {{'petroleum-gas-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = random(3, 5)}} + } + table.shuffle_table(buys) + return buys +end + +local function get_market_item_list(rarity) + if rarity < 1 then + rarity = 1 + end + if rarity > 10 then + rarity = 10 + end + local types = get_types() + local list = {} + for i = 1, 9 do + local branch = market[types[i]] + for k, item in pairs(branch) do + --if item.rarity <= rarity and item.rarity + 7 >= rarity then + if item.rarity <= rarity then + local price = random(floor(item.value * 0.75), floor(item.value * 1.25)) + if price < 1 then + price = 1 + end + if price > 64000 then + price = 64000 + end + list[#list + 1] = {price = {{'coin', price}}, offer = {type = 'give-item', item = k}} + end + end + end + if #list == 0 then + return false + end + return list +end + +function Public.get_random_item(rarity, sell, buy) + rarity = rarity or 0 + local items = get_market_item_list(rarity) + if not items then + return + end + if #items > 0 then + table.shuffle_table(items) + end + + local items_return = {} + + for i = 1, 25, 1 do + local item = items[i] + if not item then + break + end + if not blacklist[item.offer.item] then + items_return[#items_return + 1] = items[i] + end + end + + if sell then + local sells = get_resource_market_sells() + for i = 1, random(1, 25), 1 do + items_return[#items_return + 1] = sells[i] + end + end + + if buy then + local buys = get_resource_market_buys() + for i = 1, random(1, 25), 1 do + items_return[#items_return + 1] = buys[i] + end + end + + return items_return +end + +function Public.mountain_market(surface, position, rarity, buy) + local types = get_types() + table.shuffle_table(types) + local items = get_market_item_list(rarity) + if not items then + return + end + if #items > 0 then + table.shuffle_table(items) + end + local mrk = surface.create_entity({name = 'market', position = position, force = 'neutral'}) + + for i = 1, random(5, 10), 1 do + local item = items[i] + if not item then + break + end + if not blacklist[item.offer.item] then + mrk.add_market_item(items[i]) + end + end + + local sells = get_resource_market_sells() + for i = 1, random(1, 3), 1 do + mrk.add_market_item(sells[i]) + end + + if buy then + local buys = get_resource_market_buys() + for i = 1, random(1, 3), 1 do + mrk.add_market_item(buys[i]) + end + end + + return mrk +end + +return Public diff --git a/maps/amap/biter_pets.lua b/maps/amap/biter_pets.lua new file mode 100644 index 00000000..bf4e4ac8 --- /dev/null +++ b/maps/amap/biter_pets.lua @@ -0,0 +1,200 @@ +local WPT = require 'maps.amap.table' + +local nom_msg = {'munch', 'munch', 'yum'} + +local Public = {} +local random = math.random +local floor = math.floor + +local function feed_floaty_text(unit) + unit.surface.create_entity( + { + name = 'flying-text', + position = unit.position, + text = nom_msg[random(1, #nom_msg)], + color = {random(50, 100), 0, 255} + } + ) +end + +local function floaty_hearts(entity, c) + local position = {x = entity.position.x - 0.75, y = entity.position.y - 1} + local b = 1.35 + for _ = 1, c, 1 do + local p = { + (position.x + 0.4) + (b * -1 + random(0, b * 20) * 0.1), + position.y + (b * -1 + random(0, b * 20) * 0.1) + } + entity.surface.create_entity({name = 'flying-text', position = p, text = '♥', color = {random(150, 255), 0, 255}}) + end +end + +local function tame_unit_effects(player, entity) + floaty_hearts(entity, 7) + + rendering.draw_text { + text = '~' .. player.name .. "'s pet~", + surface = player.surface, + target = entity, + target_offset = {0, -2.6}, + color = { + r = player.color.r * 0.6 + 0.25, + g = player.color.g * 0.6 + 0.25, + b = player.color.b * 0.6 + 0.25, + a = 1 + }, + scale = 1.05, + font = 'default-large-semibold', + alignment = 'center', + scale_with_zoom = false + } +end + +local function find_unit(player, entity) + local units = + player.surface.find_entities_filtered( + { + type = 'unit', + area = {{entity.position.x - 1, entity.position.y - 1}, {entity.position.x + 1, entity.position.y + 1}}, + limit = 1 + } + ) + return units[1] +end + +local function feed_pet(unit) + if unit.prototype.max_health == unit.health then + return + end + unit.health = unit.health + 8 + floor(unit.prototype.max_health * 0.05) + feed_floaty_text(unit) + floaty_hearts(unit, random(1, 2)) + return true +end + +local function is_valid_player(player, unit) + if not player.character then + return + end + if not player.character.valid then + return + end + if player.surface.index ~= unit.surface.index then + return + end + return true +end + +function Public.biter_pets_tame_unit(player, unit, forced) + local biter_pets = WPT.get('biter_pets') + + if biter_pets[player.index] then + return false + end + + if not forced then + if random(1, floor(unit.prototype.max_health * 0.01) + 1) ~= 1 then + feed_floaty_text(unit) + return true + end + end + if unit.force.index == player.force.index then + return false + end + unit.ai_settings.allow_destroy_when_commands_fail = false + unit.ai_settings.allow_try_return_to_spawner = false + unit.force = player.force + unit.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy}) + biter_pets[player.index] = {last_command = 0, entity = unit} + tame_unit_effects(player, unit) + return true +end + +function Public.tame_unit_for_closest_player(unit) + local valid_players = {} + for _, player in pairs(game.connected_players) do + if is_valid_player(player, unit) then + table.insert(valid_players, player) + end + end + + local nearest_player = valid_players[1] + if not nearest_player then + return + end + + Public.biter_pets_tame_unit(nearest_player, unit, true) +end + +local function command_unit(entity, player) + if entity.surface ~= player.surface then + return + end + local square_distance = (player.position.x - entity.position.x) ^ 2 + (player.position.y - entity.position.y) ^ 2 + + --Pet will follow, if the player is between a distance of 8 to 160 tiles away from it. + if square_distance < 64 or square_distance > 25600 then + entity.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy}) + else + entity.set_command( + { + type = defines.command.go_to_location, + destination_entity = player.character, + radius = 4, + distraction = defines.distraction.by_damage + } + ) + end +end + +local function on_player_changed_position(event) + local biter_pets = WPT.get('biter_pets') + + if random(1, 100) ~= 1 then + return + end + local player = game.players[event.player_index] + if not biter_pets[player.index] then + return + end + if not biter_pets[player.index].entity then + biter_pets[player.index] = nil + return + end + if not biter_pets[player.index].entity.valid then + biter_pets[player.index] = nil + return + end + if not player.character then + return + end + if biter_pets[player.index].last_command + 600 > game.tick then + return + end + biter_pets[player.index].last_command = game.tick + command_unit(biter_pets[player.index].entity, player) +end + +local function on_player_dropped_item(event) + local player = game.players[event.player_index] + if event.entity.stack.name ~= 'raw-fish' then + return + end + local unit = find_unit(player, event.entity) + if not unit then + return + end + if Public.biter_pets_tame_unit(player, unit, false) then + event.entity.destroy() + return + end + if unit.force.index == player.force.index then + feed_pet(unit) + end +end + +local event = require 'utils.event' +event.add(defines.events.on_player_dropped_item, on_player_dropped_item) +event.add(defines.events.on_player_changed_position, on_player_changed_position) + +return Public diff --git a/maps/amap/buried_enemies.lua b/maps/amap/buried_enemies.lua new file mode 100644 index 00000000..76504b9e --- /dev/null +++ b/maps/amap/buried_enemies.lua @@ -0,0 +1,256 @@ +local Event = require 'utils.event' +local Global = require 'utils.global' +local BiterRolls = require 'modules.wave_defense.biter_rolls' +local BiterHealthBooster = require 'modules.biter_health_booster' +local WD = require 'modules.wave_defense.table' +local WPT = require 'maps.amap.table' + +local traps = {} + +Global.register( + traps, + function(t) + traps = t + end +) + +local Public = {} +local floor = math.floor +local random = math.random +local abs = math.abs +local sqrt = math.sqrt + +local spawn_amount_rolls = {} +for a = 48, 1, -1 do + spawn_amount_rolls[#spawn_amount_rolls + 1] = floor(a ^ 5) +end + +local random_particles = { + 'dirt-2-stone-particle-medium', + 'dirt-4-dust-particle', + 'coal-particle' +} + +local s_random_particles = #random_particles + +local function create_particles(data) + local surface = data.surface + local position = data.position + local amount = data.amount + + if not surface or not surface.valid then + return + end + for i = 1, amount, 1 do + local m = random(6, 12) + local m2 = m * 0.005 + + surface.create_particle( + { + name = random_particles[random(1, s_random_particles)], + position = position, + frame_speed = 0.1, + vertical_speed = 0.1, + height = 0.1, + movement = {m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01)} + } + ) + end +end + +local function spawn_biters(data) + local surface = data.surface + if not (surface and surface.valid) then + return + end + local position = data.position + local h = floor(abs(position.y)) + local wave_number = WD.get('wave_number') + local max_biters = WPT.get('biters') + + + if max_biters.amount >= max_biters.limit then + return + end + + if not position then + position = surface.find_non_colliding_position('small-biter', position, 10, 1) + if not position then + return + end + end + + local function trigger_health() + local m = 0.0015 + + m = m * 1.05 + + local boosted_health = 1.25 + + if wave_number <= 10 then + wave_number = 10 + end + + boosted_health = boosted_health * (wave_number * 0.02) + + local sum = boosted_health * 5 + + sum = sum + m + + if sum >= 100 then + sum = 100 + end + + return sum + end + + BiterRolls.wave_defense_set_unit_raffle(h * 0.20) + + local unit + if random(1, 3) == 1 then + unit = surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position}) + max_biters.amount = max_biters.amount + 1 + else + unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position}) + max_biters.amount = max_biters.amount + 1 + end + + if random(1, 32) == 1 then + local sum = trigger_health() + max_biters.amount = max_biters.amount + 1 + BiterHealthBooster.add_boss_unit(unit, sum, 0.38) + end +end + +local function spawn_worms(data) + local max_biters = WPT.get('biters') + + if max_biters.amount >= max_biters.limit then + return + end + + local surface = data.surface + if not (surface and surface.valid) then + return + end + local position = data.position + BiterRolls.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20) + surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = position}) + max_biters.amount = max_biters.amount + 1 +end + +function Public.buried_biter(surface, position, max) + if not (surface and surface.valid) then + return + end + if not position then + return + end + if not position.x then + return + end + if not position.y then + return + end + + local amount = 8 + local a = 0 + max = max or random(4, 6) + + local ticks = amount * 30 + ticks = ticks + 90 + for t = 1, ticks, 1 do + if not traps[game.tick + t] then + traps[game.tick + t] = {} + end + + traps[game.tick + t][#traps[game.tick + t] + 1] = { + callback = 'create_particles', + data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4} + } + + if t > 90 then + if t % 30 == 29 then + a = a + 1 + traps[game.tick + t][#traps[game.tick + t] + 1] = { + callback = 'spawn_biters', + data = {surface = surface, position = {x = position.x, y = position.y}} + } + if a >= max then + break + end + end + end + end +end + +function Public.buried_worm(surface, position) + if not (surface and surface.valid) then + return + end + if not position then + return + end + if not position.x then + return + end + if not position.y then + return + end + + local amount = 8 + + local ticks = amount * 30 + ticks = ticks + 90 + local a = false + for t = 1, ticks, 1 do + if not traps[game.tick + t] then + traps[game.tick + t] = {} + end + + traps[game.tick + t][#traps[game.tick + t] + 1] = { + callback = 'create_particles', + data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4} + } + + if not a then + traps[game.tick + t][#traps[game.tick + t] + 1] = { + callback = 'spawn_worms', + data = {surface = surface, position = {x = position.x, y = position.y}} + } + a = true + end + end +end + +local callbacks = { + ['create_particles'] = create_particles, + ['spawn_biters'] = spawn_biters, + ['spawn_worms'] = spawn_worms +} + +local function on_tick() + local t = game.tick + if not traps[t] then + return + end + for _, token in pairs(traps[t]) do + local callback = token.callback + local data = token.data + local cbl = callbacks[callback] + if callbacks[callback] then + cbl(data) + end + end + traps[t] = nil +end + +function Public.reset() + for k, _ in pairs(traps) do + traps[k] = nil + end +end + +Event.add(defines.events.on_tick, on_tick) + +return Public diff --git a/maps/amap/caves.lua b/maps/amap/caves.lua new file mode 100644 index 00000000..80b34d06 --- /dev/null +++ b/maps/amap/caves.lua @@ -0,0 +1,251 @@ +--[[ +Exchange Strings + +>>>eNp1UT1oFEEUfi/nkcsJonBNwMQrUtjsES/aHOFmTCMp1M5+b +29OB/Z2ztldSLRwixQWQpo0pkmKNCZgJ2gXsVHQIGpjd5LGwiJBE +AvhnNnd2VvX5IN5fPO9/xmAC3AbYuxTgKhdOeMI201vRMmk6ojBg +ElLSJaXpxwZdpkluAqO6N7uLtGeKvNYf9Xq2D7TskqI5QqXwitWK +PuB8P5VAsmYnyRGba2eDaXt8bCf5EZZJODOwZ3X0dos6DN6BPXRS +B/Fhso/hBQqA5WWonTZEV4ghWv5LAi4d7dlhyutnmT3Q+Y5q61+6 +AZ84HImKwuN+RgzxYy+4H4QStbqcNufsuYbzWs6zjo17sTyVxoLM +cqOy3s9gPp1dZb01oj4sPb8xrcHGwSTqRs0JUepst8xyrIht+ipr +jlDrubqJN1/5kjSNFAt0qgKHZPEuaadiMf3Dh+/+P2ljX+eHX+62 +aEEj4yCOKkScCIzm081XplVwNQcktT1leCH9xo/CJZ1Rk2b7SfKR +M0JwPPnzLV+EcxobVOmRrEX45fZ5NCQz6S4h3qIRV18Vpu32sQNs +8kwoXSdIr1kvNPjEJXfhPwM3fGG70zbN7n+hUH+/4j8HgVljp7wD +VXdsJuZ76VsGvWeHyfNjW7REoyhvvvAetn9CzJb1cQ=<<< +]] +local random = math.random +local Alert = require 'utils.alert' +require "player_modifiers" +require "modules.rocks_broken_paint_tiles" +require "modules.rocks_heal_over_time" +require "modules.rocks_yield_ore_veins" +require "modules.no_deconstruction_of_neutral_entities" +local MT = require "maps.amap.basic_markets" +local asdasd = require 'modules.rpg.table' +local Loot = require "maps.amap.loot" +local get_noise = require "utils.get_noise" +local Player_modifiers = require "player_modifiers" +local math_random = math.random +local math_floor = math.floor +local math_abs = math.abs +local Public = {} +local BiterRolls = require 'modules.wave_defense.biter_rolls' +local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"} +local size_of_rock_raffle = #rock_raffle +local Pets = require 'maps.amap.biter_pets' +local function place_entity(surface, position) + if math_random(1, 3) ~= 1 then + surface.create_entity({name = rock_raffle[math_random(1, size_of_rock_raffle)], position = position, force = "neutral"}) + end +end + +local function is_scrap_area(noise) + if noise > 0.63 then return end + if noise < -0.63 then return end + if noise > 0.35 then return true end + if noise < -0.35 then return true end +end + +local function hidden_treasure(player, entity) + + local rpg = asdasd.get('rpg_t') + + local magic = rpg[player.index].magicka + + local msg = '哦,看啊,你找到了一个宝藏!' + + Alert.alert_player(player, 5, msg) + + + Loot.add_rare(entity.surface, entity.position, 'wooden-chest', magic) + + +end + +local function move_away_things(surface, area) + for _, e in pairs(surface.find_entities_filtered({type = {"unit-spawner", "turret", "unit", "tree"}, area = area})) do + local position = surface.find_non_colliding_position(e.name, e.position, 128, 4) + if position then + surface.create_entity({name = e.name, position = position, force = "enemy"}) + e.destroy() + end + end +end + +local vectors = {{0,0}, {1,0}, {-1,0}, {0,1}, {0,-1}} +local function hidden_biter_pet(player, entity) + + local pos = entity.position + + BiterRolls.wave_defense_set_unit_raffle(math.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_biter(player, entity) + + + local pos = entity.position + + BiterRolls.wave_defense_set_unit_raffle(math.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 +end +local function on_player_mined_entity(event) + local entity = event.entity + if not entity.valid then return end + if entity.type ~= "simple-entity" then return end + local surface = entity.surface + for _, v in pairs(vectors) do + local position = {entity.position.x + v[1], entity.position.y + v[2]} + if not surface.get_tile(position).collides_with("resource-layer") then + surface.set_tiles({{name = "landfill", position = position}}, true) + end + end + if event.player_index then game.players[event.player_index].insert({name = "coin", count = 1}) end + local player = game.players[event.player_index] + --修复挖矿石路 + local rpg = asdasd.get('rpg_t') + local rpg_char = rpg[player.index] + if rpg_char.stone_path then + + entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true) + end + + --挖出汽车 +if random(1,712) < 2 then + local position = {entity.position.x , entity.position.y } + --local player = game.players[event.player_index] + surface.create_entity({name = 'car', position = position, force = 'player'}) + Public.unstuck_player(player.index) + local msg = ({'found a car', 'you'}) + Alert.alert_player(player, 15, msg) + end + --挖出虫巢 + +if random(1,120) < 2 then + + local position = {entity.position.x , entity.position.y } + local player = game.players[event.player_index] + surface.create_entity({name = 'biter-spawner', position = position, force = 'enemy'}) + Public.unstuck_player(player.index) + end + --挖出宝藏 + if random(1,150) < 2 then + + local player = game.players[event.player_index] + + hidden_treasure(player,entity) + + end + --挖出宠物 + if random(1,170) < 3 then + local player = game.players[event.player_index] + hidden_biter_pet(player,entity) + end + --来挖个虫子 + if random(1,100) < 3 then + local player = game.players[event.player_index] + hidden_biter(player,entity) + end +end + +local function on_entity_died(event) + if not event.entity.valid then return end + on_player_mined_entity(event) +end + +--图块生成时 +local function on_chunk_generated(event) + local surface = event.surface + local seed = surface.map_gen_settings.seed + local left_top_x = event.area.left_top.x + local left_top_y = event.area.left_top.y + local set_tiles = surface.set_tiles + local get_tile = surface.get_tile + local position + local noise + for x = 0, 31, 1 do + for y = 0, 31, 1 do + position = {x = left_top_x + x, y = left_top_y + y} + if not get_tile(position).collides_with("resource-layer") then + noise = get_noise("scrapyard", position, seed) + if is_scrap_area(noise) then + set_tiles({{name = "dirt-" .. math_floor(math_abs(noise) * 12) % 4 + 3, position = position}}, true) + if x+y > 33 and x+y < 40 then + local b = math_random(1,200) + --宝藏 + if b < 3 then + local chest = 'iron-chest' + Loot.add(surface, position, chest) + end + --中立建筑 + + + + --在我上面添加代码 + end + --商店代码 + if y == 1 then + if x == 1 then + local a = math_random(1,8) + if a == 1 then + local q =math_abs(position.x)/20 + local w =math_abs(position.y)/20 + local maxs =q+w+15 + -- game.print(maxs) + MT.mountain_market(surface,position,maxs) + end + end + end + + place_entity(surface, position) + end + end + end + end + + move_away_things(surface, event.area) +end + +local function on_player_joined_game(event) + local player = game.players[event.player_index] + local modifiers = Player_modifiers.get_table() + --modifiers[player.index].character_mining_speed_modifier["caves"] = 3 + Player_modifiers.update_player_modifiers(player) +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 +local function on_init() + global.rocks_yield_ore_maximum_amount = 999 + global.rocks_yield_ore_base_amount = 100 + global.rocks_yield_ore_distance_modifier = 0.025 +end + +local Event = require 'utils.event' +Event.on_init(on_init) +Event.add(defines.events.on_chunk_generated, on_chunk_generated) +Event.add(defines.events.on_player_joined_game, on_player_joined_game) +Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) +Event.add(defines.events.on_entity_died, on_entity_died) + +require "modules.rocks_yield_ore" \ No newline at end of file diff --git a/maps/amap/entities.lua b/maps/amap/entities.lua new file mode 100644 index 00000000..63720e81 --- /dev/null +++ b/maps/amap/entities.lua @@ -0,0 +1,1382 @@ +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 diff --git a/maps/amap/functions.lua b/maps/amap/functions.lua new file mode 100644 index 00000000..f0ebe523 --- /dev/null +++ b/maps/amap/functions.lua @@ -0,0 +1,794 @@ +local Token = require 'utils.token' +local Task = require 'utils.task' +local Event = require 'utils.event' +local Global = require 'utils.global' +local Alert = require 'utils.alert' +local WPT = require 'maps.amap.table' +local WD = require 'modules.wave_defense.table' +local math2d = require 'math2d' +local Commands = require 'commands.misc' +local RPG = require 'modules.rpg.table' + +local this = { + power_sources = {index = 1}, + refill_turrets = {index = 1}, + magic_crafters = {index = 1}, + magic_fluid_crafters = {index = 1}, + art_table = {index = 1}, + surface_cleared = false +} + +local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['car'] = 1} + +Global.register( + this, + function(t) + this = t + end +) + +local Public = {} + +local random = math.random +local floor = math.floor +local remove = table.remove +local sqrt = math.sqrt +local magic_crafters_per_tick = 3 +local magic_fluid_crafters_per_tick = 8 +local tile_damage = 50 + +local artillery_target_entities = { + 'character', + 'tank', + 'car', + 'radar', + 'lab', + 'furnace', + 'locomotive', + 'cargo-wagon', + 'fluid-wagon', + 'artillery-wagon', + 'artillery-turret', + 'laser-turret', + 'gun-turret', + 'flamethrower-turret', + 'silo', + 'spidertron' +} + +function Public.get_player_data(player, remove_user_data) + local players = WPT.get('players') + if remove_user_data then + if players[player.index] then + players[player.index] = nil + end + end + if not players[player.index] then + players[player.index] = {} + end + return players[player.index] +end + +local get_player_data = Public.get_player_data + +local function debug_str(msg) + local debug = WPT.get('debug') + if not debug then + return + end + print('Mtn: ' .. msg) +end + +local function show_text(msg, pos, color, surface) + if color == nil then + surface.create_entity({name = 'flying-text', position = pos, text = msg}) + else + surface.create_entity({name = 'flying-text', position = pos, text = msg, color = color}) + end +end + +local function fast_remove(tbl, index) + local count = #tbl + if index > count then + return + elseif index < count then + tbl[index] = tbl[count] + end + + tbl[count] = nil +end + +local function do_refill_turrets() + local refill_turrets = this.refill_turrets + local index = refill_turrets.index + + if index > #refill_turrets then + refill_turrets.index = 1 + return + end + + local turret_data = refill_turrets[index] + local turret = turret_data.turret + + if not turret.valid then + fast_remove(refill_turrets, index) + return + end + + refill_turrets.index = index + 1 + + local data = turret_data.data + if data.liquid then + turret.fluidbox[1] = data + elseif data then + turret.insert(data) + end +end + +local function do_turret_energy() + local power_sources = this.power_sources + + for index = 1, #power_sources do + local ps_data = power_sources[index] + if not (ps_data and ps_data.valid) then + fast_remove(power_sources, index) + return + end + + ps_data.energy = 0xfffff + end +end + +local function do_magic_crafters() + local magic_crafters = this.magic_crafters + local limit = #magic_crafters + if limit == 0 then + return + end + + local index = magic_crafters.index + + for i = 1, magic_crafters_per_tick do + if index > limit then + index = 1 + end + + local data = magic_crafters[index] + + local entity = data.entity + if not entity.valid then + fast_remove(magic_crafters, index) + limit = limit - 1 + if limit == 0 then + return + end + else + index = index + 1 + + local tick = game.tick + local last_tick = data.last_tick + local rate = data.rate + + local count = (tick - last_tick) * rate + + local fcount = floor(count) + + if fcount > 1 then + fcount = 1 + end + + if fcount > 0 then + entity.get_output_inventory().insert {name = data.item, count = fcount} + data.last_tick = tick - (count - fcount) / rate + end + end + end + + magic_crafters.index = index +end + +local function do_magic_fluid_crafters() + local magic_fluid_crafters = this.magic_fluid_crafters + local limit = #magic_fluid_crafters + + if limit == 0 then + return + end + + local index = magic_fluid_crafters.index + + for i = 1, magic_fluid_crafters_per_tick do + if index > limit then + index = 1 + end + + local data = magic_fluid_crafters[index] + + local entity = data.entity + if not entity.valid then + fast_remove(magic_fluid_crafters, index) + limit = limit - 1 + if limit == 0 then + return + end + else + index = index + 1 + + local tick = game.tick + local last_tick = data.last_tick + local rate = data.rate + + local count = (tick - last_tick) * rate + + local fcount = floor(count) + + if fcount > 0 then + local fluidbox_index = data.fluidbox_index + local fb = entity.fluidbox + + local fb_data = fb[fluidbox_index] or {name = data.item, amount = 0} + fb_data.amount = fb_data.amount + fcount + fb[fluidbox_index] = fb_data + + data.last_tick = tick - (count - fcount) / rate + end + end + end + + magic_fluid_crafters.index = index +end + + + + + + +local function tick() + do_magic_crafters() + do_magic_fluid_crafters() +end + +Public.deactivate_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.active = false + entity.operable = false + entity.destructible = false + end + end +) + +Public.neutral_force = + Token.register( + function(entity) + if entity and entity.valid then + entity.force = 'neutral' + end + end +) + +Public.enemy_force = + Token.register( + function(entity) + if entity and entity.valid then + entity.force = 'enemy' + end + end +) + +Public.active_not_destructible_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.active = true + entity.operable = false + entity.destructible = false + end + end +) + +Public.disable_minable_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.minable = false + end + end +) + +Public.disable_minable_and_ICW_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.minable = false + ICW.register_wagon(entity, true) + end + end +) + +Public.disable_destructible_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.destructible = false + entity.minable = false + end + end +) +Public.disable_active_callback = + Token.register( + function(entity) + if entity and entity.valid then + entity.active = false + end + end +) + +local disable_active_callback = Public.disable_active_callback + + +Public.power_source_callback = + Token.register( + function(turret) + local power_sources = this.power_sources + power_sources[#power_sources + 1] = turret + end +) + +Public.magic_item_crafting_callback = + Token.register( + function(entity, data) + local callback_data = data.callback_data + if not (entity and entity.valid) then + return + end + + entity.minable = false + entity.destructible = false + entity.operable = false + + local force = game.forces.player + + local tech = callback_data.tech + if tech then + if not force.technologies[tech].researched then + entity.destroy() + return + end + end + + local recipe = callback_data.recipe + if recipe then + entity.set_recipe(recipe) + else + local furance_item = callback_data.furance_item + if furance_item then + local inv = entity.get_inventory(defines.inventory.furnace_result) + inv.insert(furance_item) + end + end + + local p = entity.position + local x, y = p.x, p.y + local distance = sqrt(x * x + y * y) + + local output = callback_data.output + if #output == 0 then + add_magic_crafter_output(entity, output, distance) + else + for i = 1, #output do + local o = output[i] + add_magic_crafter_output(entity, o, distance) + end + end + + if not callback_data.keep_active then + Task.set_timeout_in_ticks(2, disable_active_callback, entity) -- causes problems with refineries. + end + end +) + +Public.magic_item_crafting_callback_weighted = + Token.register( + function(entity, data) + local callback_data = data.callback_data + if not (entity and entity.valid) then + return + end + + entity.minable = false + entity.destructible = false + entity.operable = false + + local weights = callback_data.weights + local loot = callback_data.loot + + local p = entity.position + + local i = random() * weights.total + + local index = table.binary_search(weights, i) + if (index < 0) then + index = bit32.bnot(index) + end + + local stack = loot[index].stack + if not stack then + return + end + + local force = game.forces.player + + local tech = stack.tech + if tech then + if force.technologies[tech] then + if not force.technologies[tech].researched then + entity.destroy() + return + end + end + end + + local recipe = stack.recipe + if recipe then + entity.set_recipe(recipe) + else + local furance_item = stack.furance_item + if furance_item then + local inv = entity.get_inventory(defines.inventory.furnace_result) + inv.insert(furance_item) + end + end + + local x, y = p.x, p.y + local distance = sqrt(x * x + y * y) + + local output = stack.output + if #output == 0 then + add_magic_crafter_output(entity, output, distance) + else + for o_i = 1, #output do + local o = output[o_i] + add_magic_crafter_output(entity, o, distance) + end + end + + if not callback_data.keep_active then + Task.set_timeout_in_ticks(2, disable_active_callback, entity) -- causes problems with refineries. + end + end +) + +function Public.prepare_weighted_loot(loot) + local total = 0 + local weights = {} + + for i = 1, #loot do + local v = loot[i] + total = total + v.weight + weights[#weights + 1] = total + end + + weights.total = total + + return weights +end + +function Public.do_random_loot(entity, weights, loot) + if not entity.valid then + return + end + + entity.operable = false + --entity.destructible = false + + local i = random() * weights.total + + local index = table.binary_search(weights, i) + if (index < 0) then + index = bit32.bnot(index) + end + + local stack = loot[index].stack + if not stack then + return + end + + local df = stack.distance_factor + local count + if df then + local p = entity.position + local x, y = p.x, p.y + local d = sqrt(x * x + y * y) + + count = stack.count + d * df + else + count = stack.count + end + + entity.insert {name = stack.name, count = count} +end + +function Public.remove_offline_players() + local offline_players_enabled = WPT.get('offline_players_enabled') + if not offline_players_enabled then + return + end + local offline_players = WPT.get('offline_players') + local active_surface_index = WPT.get('active_surface_index') + local surface = game.surfaces[active_surface_index] + local player_inv = {} + local items = {} + if #offline_players > 0 then + local later = {} + for i = 1, #offline_players, 1 do + if offline_players[i] and game.players[offline_players[i].index] and game.players[offline_players[i].index].connected then + offline_players[i] = nil + else + if offline_players[i] and game.players[offline_players[i].index] and offline_players[i].tick < game.tick - 54000 then + local name = offline_players[i].name + player_inv[1] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_main) + player_inv[2] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_armor) + player_inv[3] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_guns) + player_inv[4] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_ammo) + player_inv[5] = game.players[offline_players[i].index].get_inventory(defines.inventory.character_trash) + local pos = game.forces.player.get_spawn_position(surface) + local e = + surface.create_entity( + { + name = 'character', + position = pos, + force = 'neutral' + } + ) + local inv = e.get_inventory(defines.inventory.character_main) + e.character_inventory_slots_bonus = #player_inv[1] + for ii = 1, 5, 1 do + if player_inv[ii].valid then + for iii = 1, #player_inv[ii], 1 do + if player_inv[ii][iii].valid then + items[#items + 1] = player_inv[ii][iii] + end + end + end + end + if #items > 0 then + for item = 1, #items, 1 do + if items[item].valid then + inv.insert(items[item]) + end + end + + local message = ({'main.cleaner', name}) + local data = { + position = pos + } + Alert.alert_all_players_location(data, message) + + e.die('neutral') + else + e.destroy() + end + + for ii = 1, 5, 1 do + if player_inv[ii].valid then + player_inv[ii].clear() + end + end + offline_players[i] = nil + else + later[#later + 1] = offline_players[i] + end + end + end + for k, _ in pairs(offline_players) do + offline_players[k] = nil + end + if #later > 0 then + for i = 1, #later, 1 do + offline_players[#offline_players + 1] = later[i] + end + end + end +end + +local function calc_players() + local players = game.connected_players + local check_afk_players = WPT.get('check_afk_players') + if not check_afk_players then + return #players + end + local total = 0 + for i = 1, #players do + local player = players[i] + if player.afk_time < 36000 then + total = total + 1 + end + end + if total <= 0 then + total = 1 + end + return total +end + + +function Public.on_player_joined_game(event) + local active_surface_index = WPT.get('active_surface_index') + local player = game.players[event.player_index] + local surface = game.surfaces[active_surface_index] + + player.print('保护火箭发射井,当火箭发射被摧毁时游戏则失败。抵御虫子进攻,建造产线,通过发射火箭来赢得游戏!') + player.print('地图纪录: \n 通关纪录:无 \n 最久存活:290波 \n 瓶子科技:红绿灰蓝瓶 \n 最高等级:117级 \n 纪录编写时间:1.7') + player.print('QQ群:701077913') + local reward = require 'maps.amap.main'.reward + local player_data = get_player_data(player) + if not player_data.first_join then + + for item, amount in pairs(starting_items) do + player.insert({name = item, count = amount}) + end + player_data.first_join = true + end + if player.surface.index ~= active_surface_index then + player.teleport({x=0,y=0}, surface) + else + local p = {x = player.position.x, y = player.position.y} + local get_tile = surface.get_tile(p) + if get_tile.valid and get_tile.name == 'out-of-map' then + player.teleport({x=0,y=0}, surface) + end + end + +end + + +function Public.is_creativity_mode_on() + local creative_enabled = Commands.get('creative_enabled') + if creative_enabled then + WD.set('next_wave', 1000) + Collapse.start_now(true) + Public.set_difficulty() + end +end + +function Public.disable_creative() + local creative_enabled = Commands.get('creative_enabled') + if creative_enabled then + Commands.set('creative_enabled', false) + end +end + +function Public.on_pre_player_left_game(event) + local offline_players_enabled = WPT.get('offline_players_enabled') + if not offline_players_enabled then + return + end + + local offline_players = WPT.get('offline_players') + local player = game.players[event.player_index] + local ticker = game.tick + if player.character then + offline_players[#offline_players + 1] = { + index = event.player_index, + name = player.name, + tick = ticker + } + end +end + +function Public.on_player_respawned(event) + local player = game.get_player(event.player_index) + if not (player and player.valid) then + return + end + local player_data = get_player_data(player) + if player_data.died then + player_data.died = nil + end +end + +function Public.on_player_died(event) + local player = game.get_player(event.player_index) + if not (player and player.valid) then + return + end + local player_data = get_player_data(player) + player_data.died = true +end + +function Public.on_player_changed_position(event) + local active_surface_index = WPT.get('active_surface_index') + if not active_surface_index then + return + end + local player = game.players[event.player_index] + local map_name = 'amap' + + if string.sub(player.surface.name, 0, #map_name) ~= map_name then + return + end + + local position = player.position + local surface = game.surfaces[active_surface_index] + + local p = {x = player.position.x, y = player.position.y} + local get_tile = surface.get_tile(p) + local config_tile = WPT.get('void_or_tile') + if config_tile == 'lab-dark-2' then + if get_tile.valid and get_tile.name == 'lab-dark-2' then + if random(1, 2) == 1 then + if random(1, 2) == 1 then + show_text('This path is not for players!', p, {r = 0.98, g = 0.66, b = 0.22}, surface) + end + player.surface.create_entity({name = 'fire-flame', position = player.position}) + player.character.health = player.character.health - tile_damage + if player.character.health == 0 then + player.character.die() + local message = ({'main.death_message_' .. random(1, 7), player.name}) + game.print(message, {r = 0.98, g = 0.66, b = 0.22}) + end + end + end + end + + if position.y >= 74 then + player.teleport({position.x, position.y - 1}, surface) + player.print(({'main.forcefield'}), {r = 0.98, g = 0.66, b = 0.22}) + if player.character then + player.character.health = player.character.health - 5 + player.character.surface.create_entity({name = 'water-splash', position = position}) + if player.character.health <= 0 then + player.character.die('enemy') + end + end + end +end + +local disable_recipes = function() + local force = game.forces.player + force.recipes['car'].enabled = false + force.recipes['tank'].enabled = false + force.recipes['pistol'].enabled = false + force.recipes['spidertron-remote'].enabled = false +end + +function Public.disable_tech() + game.forces.player.technologies['landfill'].enabled = false + game.forces.player.technologies['spidertron'].enabled = false + game.forces.player.technologies['spidertron'].researched = false + disable_recipes() +end + +local disable_tech = Public.disable_tech + + +Public.firearm_magazine_ammo = {name = 'firearm-magazine', count = 200} +Public.piercing_rounds_magazine_ammo = {name = 'piercing-rounds-magazine', count = 200} +Public.uranium_rounds_magazine_ammo = {name = 'uranium-rounds-magazine', count = 200} +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.reset_table() + this.power_sources = {index = 1} + this.refill_turrets = {index = 1} + this.magic_crafters = {index = 1} + this.magic_fluid_crafters = {index = 1} +end + +local on_player_joined_game = Public.on_player_joined_game +local on_player_respawned = Public.on_player_respawned +local on_player_died = Public.on_player_died +local on_player_changed_position = Public.on_player_changed_position +local on_pre_player_left_game = Public.on_pre_player_left_game + +Event.add(defines.events.on_player_joined_game, on_player_joined_game) +Event.add(defines.events.on_player_respawned, on_player_respawned) +Event.add(defines.events.on_player_died, on_player_died) +--Event.add(defines.events.on_player_changed_position, on_player_changed_position) +Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game) +Event.on_nth_tick(10, tick) +Event.on_nth_tick(5, do_turret_energy) + +return Public diff --git a/maps/amap/loot.lua b/maps/amap/loot.lua new file mode 100644 index 00000000..5ca68dd7 --- /dev/null +++ b/maps/amap/loot.lua @@ -0,0 +1,157 @@ +local LootRaffle = require 'functions.loot_raffle' + +local Public = {} +local random = math.random +local abs = math.abs +local floor = math.floor +local sqrt = math.sqrt + +local blacklist = { + ['atomic-bomb'] = true, + ['cargo-wagon'] = true, + ['car'] = true, + ['tank'] = true, + ['spidertron'] = true, + ['locomotive'] = true, + ['artillery-wagon'] = true, + ['artillery-turret'] = true, + ['landfill'] = true, + ['discharge-defense-equipment'] = true, + ['discharge-defense-remote'] = true, + ['fluid-wagon'] = true, + ['pistol'] = true +} + +function Public.get_distance(position) + local difficulty = sqrt(position.x ^ 2 + position.y ^ 2) * 0.0001 + return difficulty +end + +function Public.add(surface, position, chest) + local budget = 48 + abs(position.y) * 1.75 + budget = budget * random(25, 175) * 0.01 + + if random(1, 128) == 1 then + budget = budget * 4 + chest = 'crash-site-chest-' .. random(1, 2) + end + if random(1, 256) == 1 then + budget = budget * 4 + chest = 'crash-site-chest-' .. random(1, 2) + end + + budget = floor(budget) + 1 + + local amount = random(1, 5) + local base_amount = 12 * amount + local distance_mod = Public.get_distance(position) + + local result = base_amount + budget + distance_mod + + local c = game.entity_prototypes[chest] + local slots = c.get_inventory_size(defines.inventory.chest) + + local item_stacks = LootRaffle.roll(result, slots, blacklist) + local container = surface.create_entity({name = chest, position = position, force = 'neutral'}) + for _, item_stack in pairs(item_stacks) do + container.insert(item_stack) + end + container.minable = false + + if random(1, 8) == 1 then + container.insert({name = 'coin', count = random(1, 32)}) + elseif random(1, 32) == 1 then + container.insert({name = 'coin', count = random(1, 128)}) + elseif random(1, 128) == 1 then + container.insert({name = 'coin', count = random(1, 256)}) + end + + for _ = 1, 3, 1 do + if random(1, 8) == 1 then + container.insert({name = 'explosives', count = random(25, 50)}) + else + break + end + end +end + +function Public.add_rare(surface, position, chest, magic) + local budget = magic * 48 + abs(position.y) * 1.75 + budget = budget * random(25, 175) * 0.01 + + if random(1, 128) == 1 then + budget = budget * 6 + chest = 'crash-site-chest-' .. random(1, 2) + end + if random(1, 128) == 1 then + budget = budget * 6 + chest = 'crash-site-chest-' .. random(1, 2) + end + + local amount = random(1, 5) + local base_amount = 12 * amount + local distance_mod = Public.get_distance(position) + + budget = floor(budget) + 1 + + local result = base_amount + budget + distance_mod + + local c = game.entity_prototypes[chest] + local slots = c.get_inventory_size(defines.inventory.chest) + + local item_stacks = LootRaffle.roll(result, slots, blacklist) + local container = surface.create_entity({name = chest, position = position, force = 'neutral'}) + for _, item_stack in pairs(item_stacks) do + container.insert(item_stack) + end + container.minable = false + + for _ = 1, 3, 1 do + if random(1, 8) == 1 then + container.insert({name = 'explosives', count = random(25, 50)}) + else + break + end + end +end + +function Public.cool(surface, position, chest, magic) + local budget = magic * 48 + abs(position.y) * 1.75 + budget = budget * random(25, 175) * 0.01 + + if random(1, 128) == 1 then + budget = budget * 6 + chest = 'crash-site-chest-' .. random(1, 2) + end + if random(1, 128) == 1 then + budget = budget * 6 + chest = 'crash-site-chest-' .. random(1, 2) + end + + local amount = random(1, 5) + local base_amount = 12 * amount + local distance_mod = Public.get_distance(position) + + budget = floor(budget) + 1 + + local result = base_amount + budget + distance_mod + + local c = game.entity_prototypes[chest] + local slots = c.get_inventory_size(defines.inventory.chest) + + local item_stacks = LootRaffle.roll(result, slots, blacklist) + local container = surface.create_entity({name = chest, position = position, force = 'neutral'}) + for _, item_stack in pairs(item_stacks) do + container.insert(item_stack) + end + + + for _ = 1, 3, 1 do + if random(1, 8) == 1 then + container.insert({name = 'explosives', count = random(25, 50)}) + else + break + end + end +end +return Public diff --git a/maps/amap/main.lua b/maps/amap/main.lua new file mode 100644 index 00000000..a03f3fb4 --- /dev/null +++ b/maps/amap/main.lua @@ -0,0 +1,403 @@ +require 'modules.rpg.main' +local Functions = require 'maps.amap.functions' +local IC = require 'maps.amap.ic.table' +local CS = require 'maps.amap.surface' +local Event = require 'utils.event' +local WD = require 'modules.wave_defense.table' +local Map = require 'modules.map_info' +local AntiGrief = require 'antigrief' +local Explosives = require 'modules.explosives' +local WPT = require 'maps.amap.table' +local Autostash = require 'modules.autostash' +local BuriedEnemies = require 'maps.amap.buried_enemies' +local RPG_Settings = require 'modules.rpg.table' +local RPG_Func = require 'modules.rpg.functions' +local Commands = require 'commands.misc' +local Task = require 'utils.task' +local Token = require 'utils.token' +local Alert = require 'utils.alert' +local rock = require 'maps.amap.rock' +local RPG = require 'modules.rpg.table' +biter = {} +local h = 1 +local k = 10 +local last = 0 +require 'modules.burden' +require "modules.spawners_contain_biters" +require 'modules.biters_yield_coins' +require 'maps.amap.sort' +local Public = {} +local floor = math.floor +local remove = table.remove + +--加载地形 +require 'maps.amap.caves' + +require 'maps.amap.ic.main' +require 'modules.shotgun_buff' +require 'modules.no_deconstruction_of_neutral_entities' +require 'modules.spawners_contain_biters' +require 'modules.wave_defense.main' +require 'modules.charging_station' + +local init_new_force = function() + local new_force = game.forces.protectors + local enemy = game.forces.enemy + if not new_force then + new_force = game.create_force('protectors') + end + new_force.set_friend('enemy', true) + enemy.set_friend('protectors', true) +end + +function Public.reward() +return(k) +end +function Public.reset_map() + +local this = WPT.get() +local wave_defense_table = WD.get_table() + +--创建一个地表 +this.active_surface_index = CS.create_surface() + + Autostash.insert_into_furnace(true) + Autostash.bottom_button(true) + BuriedEnemies.reset() + IC.reset() + IC.allowed_surface('amap') + game.reset_time_played() + WPT.reset_table() + + --记得后面改为失去一半经验!并且修订技能! + local rpg_t = RPG.get('rpg_t') + for k, p in pairs(game.connected_players) do + local player = game.connected_players[k] + rpg_t[player.index].xp = rpg_t[player.index].xp / 3 + rpg_t[player.index].level = 1 + rpg_t[player.index].strength = 10 + rpg_t[player.index].magicka = 10 + rpg_t[player.index].dexterity = 10 + rpg_t[player.index].vitality = 10 + rpg_t[player.index].mana_max = 0 + rpg_t[player.index].points_to_distribute = 0 + if rpg_t[player.index].xp > 5000 then + rpg_t[player.index].xp = 5000 + end + end + + RPG_Settings.set_surface_name('amap') + RPG_Settings.enable_health_and_mana_bars(true) + RPG_Settings.enable_wave_defense(true) + RPG_Settings.enable_mana(true) + RPG_Settings.enable_flame_boots(true) + RPG_Settings.enable_stone_path(true) + RPG_Settings.enable_one_punch(true) + RPG_Settings.enable_one_punch_globally(false) + RPG_Settings.enable_auto_allocate(true) + RPG_Settings.disable_cooldowns_on_spells() + + --初始化部队 + init_new_force() + + + local surface = game.surfaces[this.active_surface_index] + Explosives.set_surface_whitelist({[surface.name] = true}) + game.forces.player.set_spawn_position({0, 0}, surface) + + + + local players = game.connected_players + for i = 1, #players do + local player = players[i] + Commands.insert_all_items(player) + end + + --生产火箭发射井 + rock.spawn(surface,{x=0,y=10}) + rock.market(surface) + + WD.reset_wave_defense() + wave_defense_table.surface_index = this.active_surface_index + --记得修改目标! + wave_defense_table.target = this.rock + wave_defense_table.nest_building_density = 32 + wave_defense_table.game_lost = false + --生成随机位置! + local positions = {x = 200, y = 200} + positions.x = math.random(-200,200) + positions.y = math.random(-200,200) + + if positions.y < 75 and positions.y > -75 then + + if positions.y < 0 then + positions.y = positions.y - 100 + else + positions.y = positions.y + 100 + end + end + if positions.x < 75 and positions.x > -75 then + if positions.x < 0 then + positions.x = positions.x - 100 + else + positions.x = positions.x + 100 + end + end + + wave_defense_table.spawn_position = positions + --game.print(positions) + WD.alert_boss_wave(true) + WD.clear_corpses(false) + WD.remove_entities(true) + WD.enable_threat_log(true) + WD.set_disable_threat_below_zero(true) + WD.set_biter_health_boost(2.5) + WD.set().next_wave = game.tick + 7000* 15 + --初始化虫子科技 + biter.d=false + biter.c=false + biter.b=false + biter.a=false + + Functions.disable_tech() + game.forces.player.set_spawn_position({0, 0}, surface) + + Task.start_queue() + Task.set_queue_speed(16) + + this.chunk_load_tick = game.tick + 1200 + this.game_lost = false + last = 0 + k=0 + --setting() +end + +local setting = function() +local map_gen_settings = {} +game.map_settings.enemy_evolution.destroy_factor = 0.001 + game.map_settings.enemy_evolution.pollution_factor = 0.000001 + game.map_settings.enemy_expansion.enabled = true + game.map_settings.enemy_expansion.min_expansion_cooldown = 6000 + game.map_settings.enemy_expansion.max_expansion_cooldown = 24000 + game.map_settings.enemy_evolution.time_factor = 0.00006 + game.map_settings.enemy_expansion.max_expansion_distance = 20 + game.map_settings.enemy_expansion.settler_group_min_size = 20 + game.map_settings.enemy_expansion.settler_group_max_size = 50 +end + +local on_init = function() + + Public.reset_map() + + + local T = Map.Pop_info() + T.localised_category = 'amap' + T.main_caption_color = {r = 150, g = 150, b = 0} + T.sub_caption_color = {r = 0, g = 150, b = 0} + + + + Explosives.set_whitelist_entity('character') + Explosives.set_whitelist_entity('spidertron') + Explosives.set_whitelist_entity('car') + Explosives.set_whitelist_entity('tank') + --地图设置 + + setting() +end +local is_player_valid = function() + local players = game.connected_players + for _, player in pairs(players) do + if player.connected and not player.character or not player.character.valid then + if not player.admin then + local player_data = Functions.get_player_data(player) + if player_data.died then + return + end + player.set_controller {type = defines.controllers.god} + player.create_character() + end + end + end +end + + +local has_the_game_ended = function() + local game_reset_tick = WPT.get('game_reset_tick') + if game_reset_tick then + if game_reset_tick < 0 then + return + end + + local this = WPT.get() + + this.game_reset_tick = this.game_reset_tick - 30 + if this.game_reset_tick % 1800 == 0 then + if this.game_reset_tick > 0 then + local cause_msg + if this.restart then + cause_msg = 'restart' + + end + + game.print(({'main.reset_in', cause_msg, this.game_reset_tick / 60}), {r = 0.22, g = 0.88, b = 0.22}) + end + + if this.soft_reset and this.game_reset_tick == 0 then + this.game_reset_tick = nil + Public.reset_map() + return + end + + + end + end +end + +local chunk_load = function() + local chunk_load_tick = WPT.get('chunk_load_tick') + if chunk_load_tick then + if chunk_load_tick < game.tick then + WPT.get().chunk_load_tick = nil + Task.set_queue_speed(2) + end + end +end +local biterbuff = function() +if h ~= 5 then +h=h+0.2 +WD.set_biter_health_boost(h) + + +game.print('虫子已获得增强,强度系数为:' .. h .. '.') +end +end +local rondom = function(player) +local rpg_t = RPG.get('rpg_t') +local q = math.random(0,8) +if q == 7 then +player.print('你的数字为7,哦,很抱歉,什么都没有。') +elseif q == 6 then +rpg_t[player.index].strength = rpg_t[player.index].strength + 15 +player.print('你的数字为6,你获得了15点力量点奖励!') +elseif q == 5 then +player.print('你的数字为5,你获得了15点魔法点奖励!') +rpg_t[player.index].magicka =rpg_t[player.index].magicka +15 +elseif q == 4 then +player.print('你的数字为4,你获得了15点敏捷点奖励!') +rpg_t[player.index].dexterity = rpg_t[player.index].dexterity+15 +elseif q == 3 then +player.print('你的数字为3,你获得了15点活力点奖励!') +rpg_t[player.index].vitality = rpg_t[player.index].vitality+15 +elseif q == 2 then +player.print('你的数字为2,你获得了10点技能点奖励!') +rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+10 +elseif q == 1 then +player.print('你的数字为1,你获得了2000金币奖励!') +player.insert{name='coin', count = '2000'} +elseif q == 0 then +player.print('你的数字为0,哦,你真倒霉,你失去了1000金币!如果你连1K都没有,我就不拿了吧。') +player.remove_item{name='coin', count = '1000'} +else +player.print('?发生什么事了(你因为开小差没有参与转盘抽奖!)') +end +end +local timereward = function() + local wave_number = WD.get('wave_number') + if last < wave_number then + if wave_number % 25 == 0 then + game.print('是时候转动命运之轮了,看看你会获得什么吧!',{r = 0.22, g = 0.88, b = 0.22}) + --biterbuff() + for k, p in pairs(game.connected_players) do + local player = game.connected_players[k] +rondom(player) + k=k+1 + end +last = wave_number + end + +end +end + + + +local biterup = function() + local wave_number = WD.get('wave_number') + if wave_number == 100 and biter.a == false then + WD.set_biter_health_boost(3) + game.print('虫族护甲科技研究完成,获得50%的生命值提升!', {r = 0.22, g = 0.88, b = 0.22}) + biter.a = true + end + if wave_number == 250 and biter.b == false then + local wave_defense_table = WD.get_table() + local positions = {x = 500, y = 500} + positions.x = math.random(-555,555) + positions.y = math.random(-555,555) + + if positions.y < 350 and positions.y > -350 then + + if positions.y < 0 then + positions.y = positions.y - 350 + else + positions.y = positions.y + 350 + end + end + if positions.x < 350 and positions.x > -350 then + if positions.x < 0 then + positions.x = positions.x - 350 + else + positions.x = positions.x + 350 + end + end + + wave_defense_table.spawn_position = positions + game.print('虫族经过讨论决定更换进攻地点!', {r = 0.22, g = 0.88, b = 0.22}) + biter.b=true + end + if wave_number == 400 and biter.c == false then + + game.map_settings.enemy_evolution.time_factor = 0.006 + game.print('虫族地热循环技术研究成功,时间进化因子提升100%!', {r = 0.22, g = 0.88, b = 0.22}) + biter.c=true + end + + if wave_number == 550 and biter.d == false then + + WD.set_biter_health_boost(4) + game.print('虫族启用新型护甲进行战斗', {r = 0.22, g = 0.88, b = 0.22}) + biter.d=true + end +end +--时钟任务 +local on_tick = function() + local tick = game.tick + + if tick % 40 == 0 then +timereward() + is_player_valid() + has_the_game_ended() + chunk_load() + + -- biterup() + end + +end + +function on_research_finished(Event) + + local rpg_t = RPG.get('rpg_t') + for k, p in pairs(game.connected_players) do + local player = game.connected_players[k] + + rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+3 + player.insert{name='coin', count = '100'} + game.print('科技研发完成,所有玩家奖励3技能点,100金币。', {r = 0.22, g = 0.88, b = 0.22}) + k=k+1 + end + end + + +Event.on_init(on_init) +Event.on_nth_tick(10, on_tick) +Event.add(defines.events.on_research_finished, on_research_finished) +return Public \ No newline at end of file diff --git a/maps/amap/rock.lua b/maps/amap/rock.lua new file mode 100644 index 00000000..f1d6f8ee --- /dev/null +++ b/maps/amap/rock.lua @@ -0,0 +1,95 @@ +local WPT = require 'maps.amap.table' +local Event = require 'utils.event' +local Public = {} +local Alert = require 'utils.alert' +local WD = require 'modules.wave_defense.table' +local RPG = require 'modules.rpg.table' +local wave_defense_table = WD.get_table() +local Task = require 'utils.task' +function Public.spawn(surface, position) + local this = WPT.get() + this.rock = surface.create_entity{name = "rocket-silo", position = position, force=game.forces.player} + + this.rock.minable = false + game.forces.player.set_spawn_position({0,0}, surface) +end + +function Public.market(surface) +local market = surface.create_entity{name = "market", position = {x=0, y=-10}, force=game.forces.player} + local market_items = { + {price = {{"coin", 10}}, offer = {type = 'give-item', item = "raw-fish", count = 1}}, + {price = {{"coin", 1000}}, offer = {type = 'give-item', item = 'car', count = 1}}, + {price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'tank', count = 1}}, + {price = {{"coin", 20000}}, offer = {type = 'give-item', item = 'spidertron', count = 1}} + --{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'locomotive', count = 1}}, + --{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'cargo-wagon', count = 1}}, + --{price = {{"coin", 5000}}, offer = {type = 'give-item', item = 'fluid-wagon', count = 1}} + } +market.last_user = nil + if market ~= nil then + market.destructible = false + if market ~= nil then + for _, item in pairs(market_items) do + market.add_market_item(item) + end + end + end +end +local function abc () +local this = WPT.get() + + +wave_defense_table.game_lost = true + wave_defense_table.target = nil + this.game_lost = true + + game.forces.enemy.set_friend('player', true) +game.print('设置敌军友好') + game.forces.player.set_friend('enemy', true) +game.print('设置敌军友好') + --reset_map() + this.game_reset_tick=5400 + +end + +local function on_rocket_launched(Event) +local wave_number = WD.get('wave_number') +for _, p in pairs(game.connected_players) do + Alert.alert_player(player, 25, '你通关了,你一定是第一个通关的吧?通关波数:' .. wave_number .. '。NB 就完事了') + end +local rpg_t = RPG.get('rpg_t') + for k, p in pairs(game.connected_players) do + local player = game.connected_players[k] + + rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute+100 + player.insert{name='coin', count = '3000'} + game.print('科技研发完成,所有玩家奖励100技能点,3000金币。', {r = 0.22, g = 0.88, b = 0.22}) + end +end +local function on_entity_died(Event) +local this = WPT.get() +if Event.entity == this.rock then + + game.print('游戏失败!游戏稍后将自动重启',{r = 1, g = 0, b = 0, a = 0.5}) + local wave_number = WD.get('wave_number') + + for _, p in pairs(game.connected_players) do + + Alert.alert_player(p, 25, '火箭发射井被摧毁了,游戏失败!你存活了' .. wave_number .. '波,下次好运。') + + end + local Reset_map = require 'maps.amap.main'.reset_map + wave_defense_table.game_lost = true + wave_defense_table.target = nil + game.forces.enemy.set_friend('player', true) +--game.print('设置右军友好') + game.forces.player.set_friend('enemy', true) +--game.print('设置敌军友好') + Reset_map() + + --abc() +end +end +Event.add(defines.events.on_rocket_launched, on_rocket_launched) +Event.add(defines.events.on_entity_died, on_entity_died) +return Public \ No newline at end of file diff --git a/maps/amap/soft_reset.lua b/maps/amap/soft_reset.lua new file mode 100644 index 00000000..3536aa82 --- /dev/null +++ b/maps/amap/soft_reset.lua @@ -0,0 +1,114 @@ +local Server = require 'utils.server' +local Session = require 'utils.datastore.session_data' +local Modifers = require 'player_modifiers' +local WPT = require 'maps.mountain_fortress_v3.table' + +local mapkeeper = '[color=blue]Mapkeeper:[/color]' + +local Public = {} + +local function reset_forces(new_surface, old_surface) + for _, f in pairs(game.forces) do + local spawn = { + x = game.forces.player.get_spawn_position(old_surface).x, + y = game.forces.player.get_spawn_position(old_surface).y + } + f.reset() + f.reset_evolution() + f.set_spawn_position(spawn, new_surface) + end + for _, tech in pairs(game.forces.player.technologies) do + tech.researched = false + game.forces.player.set_saved_technology_progress(tech, 0) + end +end + +local function teleport_players(surface) + game.forces.player.set_spawn_position({-27, 25}, surface) + + for _, player in pairs(game.connected_players) do + player.teleport( + surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5), + surface + ) + end +end + +local function equip_players(player_starting_items, data) + for k, player in pairs(game.players) do + if player.character and player.character.valid then + player.character.destroy() + end + if player.connected then + if not player.character then + player.set_controller({type = defines.controllers.god}) + player.create_character() + end + player.clear_items_inside() + Modifers.update_player_modifiers(player) + for item, amount in pairs(player_starting_items) do + player.insert({name = item, count = amount}) + end + else + data.players[player.index] = nil + Session.clear_player(player) + game.remove_offline_players({player.index}) + end + end +end + +function Public.soft_reset_map(old_surface, map_gen_settings, player_starting_items) + local this = WPT.get() + + if not this.soft_reset_counter then + this.soft_reset_counter = 0 + end + if not this.original_surface_name then + this.original_surface_name = old_surface.name + end + this.soft_reset_counter = this.soft_reset_counter + 1 + + local new_surface = + game.create_surface(this.original_surface_name .. '_' .. tostring(this.soft_reset_counter), map_gen_settings) + new_surface.request_to_generate_chunks({0, 0}, 0.5) + new_surface.force_generate_chunk_requests() + + reset_forces(new_surface, old_surface) + teleport_players(new_surface) + equip_players(player_starting_items, this) + + game.delete_surface(old_surface) + + local radius = 512 + local area = {{x = -radius, y = -radius}, {x = radius, y = radius}} + for _, entity in pairs(new_surface.find_entities_filtered {area = area, type = 'logistic-robot'}) do + entity.destroy() + end + + for _, entity in pairs(new_surface.find_entities_filtered {area = area, type = 'construction-robot'}) do + entity.destroy() + end + + local message = table.concat({mapkeeper .. ' Welcome to ', this.original_surface_name, '!'}) + local message_to_discord = table.concat({'** Welcome to ', this.original_surface_name, '! **'}) + + if this.soft_reset_counter > 1 then + message = + table.concat( + { + mapkeeper, + ' The world has been reshaped, welcome to ', + this.original_surface_name, + ' number ', + tostring(this.soft_reset_counter), + '!' + } + ) + end + game.print(message, {r = 0.98, g = 0.66, b = 0.22}) + Server.to_discord_embed(message_to_discord) + + return new_surface +end + +return Public diff --git a/maps/amap/sort.lua b/maps/amap/sort.lua new file mode 100644 index 00000000..e3fee8ce --- /dev/null +++ b/maps/amap/sort.lua @@ -0,0 +1,482 @@ +--this adds a button that stashes/sorts your inventory into nearby chests in some kind of intelligent way - mewmew +-- modified by gerkiz + +local Global = require 'utils.global' +local Event = require 'utils.event' +local math_floor = math.floor +local print_color = {r = 120, g = 255, b = 0} + +local autostash = { + floating_text_y_offsets = {}, + whitelist = {}, + insert_into_wagon = false +} + +local Public = {} + +Global.register( + autostash, + function(t) + autostash = t + end +) + +local function create_floaty_text(surface, position, name, count) + if autostash.floating_text_y_offsets[position.x .. '_' .. position.y] then + autostash.floating_text_y_offsets[position.x .. '_' .. position.y] = + autostash.floating_text_y_offsets[position.x .. '_' .. position.y] - 0.5 + else + autostash.floating_text_y_offsets[position.x .. '_' .. position.y] = 0 + end + surface.create_entity( + { + name = 'flying-text', + position = { + position.x, + position.y + autostash.floating_text_y_offsets[position.x .. '_' .. position.y] + }, + text = {'', '-', count, ' ', game.item_prototypes[name].localised_name}, + color = {r = 255, g = 255, b = 255} + } + ) +end + +local function chest_is_valid(chest) + if chest.type == 'cargo-wagon' then + local t = {} + local chest_inventory = chest.get_inventory(defines.inventory.cargo_wagon) + for index = 1, 40 do + if chest_inventory.get_filter(index) ~= nil then + local n = chest_inventory.get_filter(index) + t[n] = true + end + end + + if not next(t) then + return false, {} + end + + return true, t + end + + for _, e in pairs( + chest.surface.find_entities_filtered( + { + type = {'inserter', 'loader'}, + area = {{chest.position.x - 1, chest.position.y - 1}, {chest.position.x + 1, chest.position.y + 1}} + } + ) + ) do + if e.name ~= 'long-handed-inserter' then + if e.position.x == chest.position.x then + if e.direction == 0 or e.direction == 4 then + return false + end + end + if e.position.y == chest.position.y then + if e.direction == 2 or e.direction == 6 then + return false + end + end + end + end + + local i1 = chest.surface.find_entity('long-handed-inserter', {chest.position.x - 2, chest.position.y}) + if i1 then + if i1.direction == 2 or i1.direction == 6 then + return false + end + end + local i2 = chest.surface.find_entity('long-handed-inserter', {chest.position.x + 2, chest.position.y}) + if i2 then + if i2.direction == 2 or i2.direction == 6 then + return false + end + end + + local i3 = chest.surface.find_entity('long-handed-inserter', {chest.position.x, chest.position.y - 2}) + if i3 then + if i3.direction == 0 or i3.direction == 4 then + return false + end + end + local i4 = chest.surface.find_entity('long-handed-inserter', {chest.position.x, chest.position.y + 2}) + if i4 then + if i4.direction == 0 or i4.direction == 4 then + return false + end + end + + return true +end + +local function sort_entities_by_distance(position, entities) + local t = {} + local distance + local index + local size_of_entities = #entities + if size_of_entities < 2 then + return + end + + for _, entity in pairs(entities) do + distance = (entity.position.x - position.x) ^ 2 + (entity.position.y - position.y) ^ 2 + index = math_floor(distance) + 1 + if not t[index] then + t[index] = {} + end + table.insert(t[index], entity) + end + + local i = 0 + for _, range in pairs(t) do + for _, entity in pairs(range) do + i = i + 1 + entities[i] = entity + end + end +end + +local function get_nearby_chests(player, a) + local r = player.force.character_reach_distance_bonus + 10 + local r_square = r * r + local chests = {} + local size_of_chests = 0 + local area = {{player.position.x - r, player.position.y - r}, {player.position.x + r, player.position.y + r}} + + area = a or area + + local container_type = {'container', 'logistic-container', 'furnace'} + local containers = {} + local i = 0 + + if autostash.insert_into_wagon then + table.insert(container_type, 'cargo-wagon') + end + + for _, e in pairs(player.surface.find_entities_filtered({type = container_type, area = area, force = 'player'})) do + if ((player.position.x - e.position.x) ^ 2 + (player.position.y - e.position.y) ^ 2) <= r_square then + i = i + 1 + containers[i] = e + end + end + sort_entities_by_distance(player.position, containers) + for _, entity in pairs(containers) do + size_of_chests = size_of_chests + 1 + chests[size_of_chests] = entity + end + + return chests +end + +local function does_inventory_contain_item_type(inventory, item_subgroup) + for name, _ in pairs(inventory.get_contents()) do + local t = game.item_prototypes[name] + if t and t.subgroup.name == item_subgroup then + return true + end + end + return false +end + +local function insert_item_into_chest(player_inventory, chests, filtered_chests, name, count, wagon) + local container = { + ['container'] = true, + ['logistic-container'] = true + } + + local to_insert = math.floor(count / #chests) + local variator = count % #chests + + if wagon then + -- Attempt to load filtered cargo wagon + for _, chest in pairs(chests) do + if chest.type == 'cargo-wagon' then + local chest_inventory = chest.get_inventory(defines.inventory.cargo_wagon) + if chest_inventory.can_insert({name = name, count = count}) then + local inserted_count = chest_inventory.insert({name = name, count = count}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end + end + + --Attempt to store into furnaces. + for _, chest in pairs(chests) do + local chest_inventory = chest.get_inventory(defines.inventory.furnace_source) + if chest_inventory and chest.type == 'furnace' then + if chest_inventory.can_insert({name = name, count = count}) then + local inserted_count = chest_inventory.insert({name = name, count = count}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end + + for _, chest in pairs(chests) do + if chest.type == 'furnace' then + local amount = to_insert + if variator > 0 then + amount = amount + 1 + variator = variator - 1 + end + if amount <= 0 then + return + end + local chest_inventory = chest.get_inventory(defines.inventory.chest) + if chest_inventory.can_insert({name = name, count = amount}) then + local inserted_count = chest_inventory.insert({name = name, count = amount}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + end + end + end + + --Attempt to store in chests that already have the same item. + for _, chest in pairs(chests) do + if container[chest.type] then + local chest_inventory = chest.get_inventory(defines.inventory.chest) + if chest_inventory.can_insert({name = name, count = count}) then + if chest_inventory.find_item_stack(name) then + local inserted_count = chest_inventory.insert({name = name, count = count}) + + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end + end + + --Attempt to store in empty chests. + for _, chest in pairs(filtered_chests) do + if container[chest.type] then + local chest_inventory = chest.get_inventory(defines.inventory.chest) + if chest_inventory.can_insert({name = name, count = count}) then + if chest_inventory.is_empty() then + local inserted_count = chest_inventory.insert({name = name, count = count}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end + end + + --Attempt to store in chests with same item subgroup. + local item_subgroup = game.item_prototypes[name].subgroup.name + if item_subgroup then + for _, chest in pairs(filtered_chests) do + if container[chest.type] then + local chest_inventory = chest.get_inventory(defines.inventory.chest) + if chest_inventory.can_insert({name = name, count = count}) then + if does_inventory_contain_item_type(chest_inventory, item_subgroup) then + local inserted_count = chest_inventory.insert({name = name, count = count}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end + end + end + + --Attempt to store in mixed chests. + for _, chest in pairs(filtered_chests) do + if container[chest.type] then + local chest_inventory = chest.get_inventory(defines.inventory.chest) + if chest_inventory.can_insert({name = name, count = count}) then + local inserted_count = chest_inventory.insert({name = name, count = count}) + player_inventory.remove({name = name, count = inserted_count}) + create_floaty_text(chest.surface, chest.position, name, inserted_count) + count = count - inserted_count + if count <= 0 then + return + end + end + end + end +end + +local function auto_stash(player, event) + local button = event.button + local shift = event.shift + if not player.character then + player.print('It seems that you are not in the realm of the living.', print_color) + return + end + if not player.character.valid then + player.print('It seems that you are not in the realm of the living.', print_color) + return + end + local inventory = player.get_inventory(defines.inventory.character_main) + if inventory.is_empty() then + player.print('Inventory is empty.', print_color) + return + end + local chests + local r = 1 + local area = {{player.position.x - r, player.position.y - r}, {player.position.x + r, player.position.y + r}} + if shift then + if + button == defines.mouse_button_type.right or + button == defines.mouse_button_type.left and autostash.insert_into_wagon + then + chests = get_nearby_chests(player, area) + end + else + chests = get_nearby_chests(player) + end + + if not chests[1] then + player.print('No valid nearby containers found.', print_color) + return + end + + local filtered_chests = {} + local filtered_allowed + for _, e in pairs(chests) do + local is_valid, t = chest_is_valid(e) + filtered_allowed = t + if is_valid then + filtered_chests[#filtered_chests + 1] = e + end + end + + autostash.floating_text_y_offsets = {} + + local hotbar_items = {} + for i = 1, 100, 1 do + local prototype = player.get_quick_bar_slot(i) + if prototype then + hotbar_items[prototype.name] = true + end + end + + for name, count in pairs(inventory.get_contents()) do + local is_resource = autostash.whitelist[name] + + if not inventory.find_item_stack(name).grid and not hotbar_items[name] then + if shift and autostash.insert_into_wagon then + if button == defines.mouse_button_type.left then + if is_resource then + insert_item_into_chest(inventory, chests, filtered_chests, name, count, true) + end + end + if button == defines.mouse_button_type.right then + if filtered_allowed and is_resource and filtered_allowed[name] then + insert_item_into_chest(inventory, chests, filtered_chests, name, count, true) + end + end + elseif button == defines.mouse_button_type.right then + if is_resource then + insert_item_into_chest(inventory, chests, filtered_chests, name, count) + end + elseif button == defines.mouse_button_type.left then + insert_item_into_chest(inventory, chests, filtered_chests, name, count) + end + end + end + + local c = autostash.floating_text_y_offsets + for k, _ in pairs(c) do + autostash.floating_text_y_offsets[k] = nil + end +end + +local function create_gui_button(player) + if player.gui.top.auto_stash then + return + end + local tooltip + if autostash.insert_into_wagon then + tooltip = + 'Sort your inventory into nearby chests.\nLMB: Everything, excluding quickbar items.\nRMB: Only ores.\nSHIFT+LMB: Only ores to wagon\nSHIFT+RMB: Only ores onto filtered slots to wagon.' + else + tooltip = 'Sort your inventory into nearby chests.\nLMB: Everything, excluding quickbar items.\nRMB: Only ores.' + end + local b = + player.gui.top.add( + { + type = 'sprite-button', + sprite = 'item/wooden-chest', + name = 'auto_stash', + tooltip = tooltip + } + ) + b.style.font_color = {r = 0.11, g = 0.8, b = 0.44} + b.style.font = 'heading-1' + b.style.minimal_height = 38 + b.style.minimal_width = 38 + b.style.maximal_height = 38 + b.style.maximal_width = 38 + b.style.padding = 1 + b.style.margin = 0 +end + +local function do_whitelist() + local resources = game.entity_prototypes + autostash.whitelist = {} + for k, _ in pairs(resources) do + if resources[k] and resources[k].type == 'resource' and resources[k].mineable_properties then + if resources[k].mineable_properties.products[1] then + local r = resources[k].mineable_properties.products[1].name + autostash.whitelist[r] = true + elseif resources[k].mineable_properties.products[2] then + local r = resources[k].mineable_properties.products[2].name + autostash.whitelist[r] = true + end + end + end +end + +local function on_player_joined_game(event) + create_gui_button(game.players[event.player_index]) +end + +local function on_gui_click(event) + if not event.element then + return + end + if not event.element.valid then + return + end + if event.element.name == 'auto_stash' then + auto_stash(game.players[event.player_index], event) + end +end + +function Public.insert_into_wagon(value) + if value then + autostash.insert_into_wagon = value or false + end +end + +Event.on_configuration_changed = function() + do_whitelist() + log('[Autostash] on_configuration_changed was called, rebuilding resource whitelist.') +end + +Event.on_init(do_whitelist) +Event.add(defines.events.on_player_joined_game, on_player_joined_game) +Event.add(defines.events.on_gui_click, on_gui_click) + +return Public diff --git a/maps/amap/surface.lua b/maps/amap/surface.lua new file mode 100644 index 00000000..7da1e5f8 --- /dev/null +++ b/maps/amap/surface.lua @@ -0,0 +1,73 @@ +local Global = require 'utils.global' +local surface_name = 'amap' +local WPT = require 'maps.amap.table' +local Reset = require 'maps.amap.soft_reset' + +local Public = {} + +local this = { + active_surface_index = nil, + surface_name = surface_name +} + +Global.register( + this, + function(tbl) + this = tbl + end +) + +local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['car'] = 1} + +function Public.create_surface() + local map_gen_settings = { + ['seed'] = math.random(10000, 99999), + ['starting_area'] = 1.1, + ['default_enable_all_autoplace_controls'] = true + + } + map_gen_settings.autoplace_controls = { + ["coal"] = {frequency = "1", size = "1", richness = "0.7"}, + ["stone"] = {frequency = "1", size = "1", richness = "0.7"}, + ["copper-ore"] = {frequency = "1", size = "2", richness = "0.7"}, + ["iron-ore"] = {frequency = "1", size = "2", richness = "0.7"}, + ["crude-oil"] = {frequency = "1", size = "2", richness = "1"}, + ["trees"] = {frequency = "1", size = "0.5", richness = "0.7"}, + ["enemy-base"] = {frequency = "4", size = "2", richness = "1"}, + --["starting_area"] = 1.2, + } + if not this.active_surface_index then + this.active_surface_index = game.create_surface(surface_name, map_gen_settings).index + else + this.active_surface_index = Reset.soft_reset_map(game.surfaces[this.active_surface_index], map_gen_settings, starting_items).index + end + + if not this.cleared_nauvis then + local mgs = game.surfaces['nauvis'].map_gen_settings + mgs.width = 16 + mgs.height = 16 + game.surfaces['nauvis'].map_gen_settings = mgs + game.surfaces['nauvis'].clear() + this.cleared_nauvis = true + end + + return this.active_surface_index +end + +function Public.get_active_surface() + return this.active_surface +end + +function Public.get_surface_name() + return this.surface_name +end + +function Public.get(key) + if key then + return this[key] + else + return this + end +end + +return Public diff --git a/maps/amap/table.lua b/maps/amap/table.lua new file mode 100644 index 00000000..4b6fb433 --- /dev/null +++ b/maps/amap/table.lua @@ -0,0 +1,172 @@ +local Global = require 'utils.global' +local Event = require 'utils.event' + +local this = { + players = {}, + traps = {} +} +local Public = {} + +Global.register( + this, + function(tbl) + this = tbl + end +) + +Public.level_depth = 704 +Public.level_width = 512 +function Public.reset_table() +-- @start + -- these 3 are in case of stop/start/reloading the instance. + this.rock = nil + this.soft_reset = true + this.restart = false + this.shutdown = false + this.announced_message = false + this.game_saved = false + -- @end + this.icw_locomotive = nil + this.debug = false + this.game_lost = false + this.fullness_enabled = true + this.locomotive_health = 10000 + this.locomotive_max_health = 10000 + this.gap_between_zones = { + set = false, + gap = 900, + neg_gap = -500, + highest_pos = 0 + } + this.force_chunk = false + this.train_upgrades = 0 + this.biter_pets = {} + this.flamethrower_damage = {} + this.mined_scrap = 0 + this.biters_killed = 0 + this.cleared_nauvis = false + this.locomotive_xp_aura = 40 + this.locomotive_pos = {tbl = {}} + this.trusted_only_car_tanks = true + this.xp_points = 0 + this.xp_points_upgrade = 0 + --!grief prevention + this.enable_arties = 6 -- default to callback 6 + --!snip + this.poison_deployed = false + this.upgrades = { + showed_text = false, + landmine = { + limit = 25, + bought = 0, + built = 0 + }, + flame_turret = { + limit = 6, + bought = 0, + built = 0 + }, + unit_number = { + landmine = {}, + flame_turret = {} + } + } + this.aura_upgrades = 0 + this.pickaxe_tier = 1 + this.pickaxe_speed_per_purchase = 0.10 + this.health_upgrades = 0 + this.breached_wall = 1 + this.left_top = { + x = 0, + y = 0 + } + this.biters = { + amount = 0, + limit = 512 + } + this.traps = {} + this.munch_time = true + this.coin_amount = 1 + this.difficulty_set = false + this.bonus_xp_on_join = 250 + this.main_market_items = {} + this.spill_items_to_surface = false + this.outside_chests = {} + this.chests_linked_to = {} + this.chest_limit_outside_upgrades = 1 + this.placed_trains_in_zone = { + placed = 0, + positions = {}, + limit = 2, + randomized = false + } + this.marked_fixed_prices = { + chest_limit_cost = 3000, + health_cost = 10000, + pickaxe_cost = 3000, + aura_cost = 4000, + xp_point_boost_cost = 5000, + explosive_bullets_cost = 20000, + flamethrower_turrets_cost = 3000, + land_mine_cost = 2, + skill_reset_cost = 100000 + } + this.collapse_grace = true + this.explosive_bullets = false + this.locomotive_biter = nil + this.disconnect_wagon = false + this.offline_players_enabled = true + this.offline_players = {} + this.collapse_amount = false + this.collapse_speed = false + this.spawn_near_collapse = { + active = true, + total_pos = 35, + compare = -150, + compare_next = 200, + distance_from = 2 + } + this.spidertron_unlocked_at_wave = 11 + -- this.void_or_tile = 'lab-dark-2' + this.void_or_tile = 'out-of-map' + this.validate_spider = {} + this.check_afk_players = true + this.winter_mode = false + this.sent_to_discord = false + this.difficulty = { + multiply = 0.25, + highest = 10 + } + + --!reset player tables + for _, player in pairs(this.players) do + player.died = false + end + +end +function Public.get(key) + if key then + return this[key] + else + return this + end +end + +function Public.set(key, value) + if key and (value or value == false) then + this[key] = value + return this[key] + elseif key then + return this[key] + else + return this + end +end + +local on_init = function() + Public.reset_table() +end + +Event.on_init(on_init) + +return Public \ No newline at end of file