mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-03-17 21:08:08 +02:00
April fools maps (#1404)
* Upload pinguin scenario * Fix relative path * Pinguin scenario modularization * Update enemy_turrets.lua Added energy interface controls to limit power available to enemy laser turrets, with laser_shots_per_level constant for balancing. * Update floor_is_lava.lua Now spawns fire under players when level is half of max. * Explosion Scare Module Added explosion_scare module. Chooses players to randomly explode (non-damaging) a number of times before switching to new targets. Explosion intensity increases as module increases. * Update pinguin.lua Removed comment block over modules. * Added New Module: permanent_factory Has a very small chance to make an entity unminable and undestructible when placed. * MeteOres Added new module: MeteOres. Spawns a random meteor that damages entities, creates ore, and spawns biters. * Update meteOres.lua Added explosion to meteor * Added Auto Build Added auto_build module. Selects random players, and automatically builds the item in their cursor nearby for a while, before changing targets. * New module: Unorganized Recipes Added a new module to hide recipe groups and subgroups for random players. This leads to "unorganized" crafting menus. * Update auto_build.lua Fixed typo. I must have changed base targets to 0 instead of the global level when preparing this file for commit. * Add Biter Ores Module Add new module. Spawns ores on death of biters, worms, and spawners, based on difficulty of biter and level. looks for ores on the tile the biter dies on to add to, otherwise looks nearby for an ore type and uses that, otherwise decides on a new ore type to spawn. This should allow players to set up "farms" for their ores, creating reasonable ore patches. Contains a RANDOM_ORES constant that will make the search radius small and ensure random ores are placed instead. * Update biter_ores.lua Found typo. radius should be .1 not 1 for tile directly beneath biter. * Updated Existing Modules Got luacheck setup in my IDE so we don't have to wait for RedMew to run it. Fixed white-space and other linting errors. * Split AF scenarios * Add alien biomes module * Draft april-fools scenarios * Fix draft issues --------- Co-authored-by: R. Nukem <Reoisasa@gmail.com>
This commit is contained in:
parent
2efc9b2604
commit
acc257b8b6
@ -169,7 +169,7 @@ stds.factorio = {
|
||||
fields = {
|
||||
"by_pixel", "distance", "findfirstentity", "positiontostr", "formattime", "moveposition", "oppositedirection",
|
||||
"ismoduleavailable", "multiplystripes", "format_number", "increment", "color", "conditional_return",
|
||||
"add_shift", "merge", "premul_color", "encode", "decode", "insert_safe",
|
||||
"add_shift", "merge", "premul_color", "encode", "decode", "insert_safe", "list_to_map",
|
||||
table = {
|
||||
fields = {
|
||||
"compare", "deepcopy", "shallow_copy"
|
||||
|
3358
map_gen/data/presets/antarctica.lua
Normal file
3358
map_gen/data/presets/antarctica.lua
Normal file
File diff suppressed because it is too large
Load Diff
2065
map_gen/data/presets/antarctica_earth.lua
Normal file
2065
map_gen/data/presets/antarctica_earth.lua
Normal file
File diff suppressed because it is too large
Load Diff
240
map_gen/maps/april_fools/2019.lua
Normal file
240
map_gen/maps/april_fools/2019.lua
Normal file
@ -0,0 +1,240 @@
|
||||
-- this file contains all information related to map generation and control of new features.
|
||||
-- a new feature has a chance to be added or increased every time a research is completed
|
||||
-- or a rocket is launched, until its max capacity
|
||||
-- Setup the scenario map information because everyone gets upset if you don't
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
ScenarioInfo.set_map_name('Pinguin')
|
||||
ScenarioInfo.set_map_description('You are Pinguins in Antarctica!')
|
||||
ScenarioInfo.set_map_extra_info('Watch out for Icebergs!')
|
||||
|
||||
--- Config
|
||||
local config = global.config
|
||||
config.currency = nil
|
||||
config.market.enabled = false
|
||||
config.player_rewards.enabled = false
|
||||
config.redmew_qol.set_alt_on_create = false
|
||||
|
||||
local restart_command = require 'map_gen.maps.april_fools.scenario.restart_command'
|
||||
restart_command({scenario_name = 'april-fools-2019'})
|
||||
|
||||
-- == MAP GEN =================================================================
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local RS = require 'map_gen.shared.redmew_surface'
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
|
||||
--[[
|
||||
Scale the map.
|
||||
The pictures are originally quite large to preserve detail.
|
||||
Will need to scale the map differently depending on which map you use.
|
||||
Antarctica map at .5 scale: Antarctica is 46 chunks tall
|
||||
Earth map at .5 scale: Antarctica is 4 chunks tall
|
||||
]]
|
||||
|
||||
local map_scale = _DEBUG and 0.1 or 20
|
||||
local pic = require 'map_gen.data.presets.antarctica'
|
||||
-- local pic = require 'map_gen.data.presets.antarctica_earth'
|
||||
|
||||
local shape = b.picture(pic)
|
||||
shape = b.scale(shape, map_scale, map_scale)
|
||||
|
||||
local map = b.change_tile(shape, false, 'deepwater')
|
||||
-- Override map gen selections
|
||||
RS.set_map_gen_settings({ MGSP.water_very_low })
|
||||
|
||||
-- == MODULES IMPORT ==========================================================
|
||||
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local modules = {
|
||||
require 'map_gen.maps.april_fools.modules.alternative_biters', -- Spawns a random biters on every player that has alt-mode turned on
|
||||
require 'map_gen.maps.april_fools.modules.crazy_chat_colors', -- Chance to change player's color every time they send a message in chat
|
||||
require 'map_gen.maps.april_fools.modules.crazy_toolbar', -- Randomly replaces quickbar slots with new items
|
||||
require 'map_gen.maps.april_fools.modules.enemy_turrets', -- Chance to change turret to enemy force, and give it ammo/fuel/power
|
||||
require 'map_gen.maps.april_fools.modules.floor_is_lava', -- Does minor damage to a player when afk for a few second
|
||||
require 'map_gen.maps.april_fools.modules.golden_goose', -- Randomly selected players will drop coins for a time, before changing targets
|
||||
require 'map_gen.maps.april_fools.modules.marathon_mode', -- Enables expensive recipes and increases technology multiplier
|
||||
require 'map_gen.maps.april_fools.modules.orphan_crafting', -- Chance to give the player an additional single underground belt or pipe-to-ground
|
||||
require 'map_gen.maps.april_fools.modules.random_ores', -- Chance to change an ore to a random ore when a mining drill is placed
|
||||
require 'map_gen.maps.april_fools.modules.rotate_entities', -- Chance to randomly rotate an entity when rotated by a player
|
||||
require 'map_gen.maps.april_fools.modules.rotate_inserters', -- Chance to randomly rotate an inserter when built
|
||||
require 'map_gen.maps.april_fools.modules.rotten_egg', -- Randomly selected players will produce pollution for a time, before changing targets
|
||||
}
|
||||
|
||||
-- if script.active_mods['redmew-data'] then
|
||||
-- local PATH_MODULES_MOD = '__redmew-data__/'
|
||||
-- table.insert(modules, PATH_MODULES_MOD .. 'name_of_the_module')
|
||||
-- end
|
||||
|
||||
-- Activate module events
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.on_init then
|
||||
Event.on_init(mod.on_init)
|
||||
end
|
||||
|
||||
if mod.on_load then
|
||||
Event.on_load(mod.on_load)
|
||||
end
|
||||
|
||||
if mod.on_configuration_changed then
|
||||
Event.on_configuration_changed(mod.on_configuration_changed)
|
||||
end
|
||||
|
||||
if mod.events then
|
||||
for id_event, callback in pairs(mod.events) do
|
||||
Event.add(id_event, callback)
|
||||
end
|
||||
end
|
||||
|
||||
if mod.on_nth_tick then
|
||||
for nth_tick, callback in pairs(mod.on_nth_tick) do
|
||||
Event.on_nth_tick(nth_tick, callback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- == CONTROLLER ==============================================================
|
||||
|
||||
local Toast = require 'features.gui.toast'
|
||||
|
||||
local ICEBERG_ENABLE_PERCENTAGE = 0.50
|
||||
local TOAST_DURATION = 10
|
||||
|
||||
local function draw_random_effect(max_share)
|
||||
local mod_index = math.random(1, #modules)
|
||||
local mod = modules[mod_index]
|
||||
|
||||
if mod == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local old_level, new_level, max_level = 0, 0, 0
|
||||
|
||||
if mod.level_get then
|
||||
old_level = mod.level_get()
|
||||
end
|
||||
if mod.max_get then
|
||||
max_level = mod.max_get()
|
||||
end
|
||||
|
||||
if old_level < (max_level * max_share) then
|
||||
if mod.level_increase then
|
||||
mod.level_increase()
|
||||
end
|
||||
end
|
||||
|
||||
if mod.level_get then
|
||||
new_level = mod.level_get()
|
||||
end
|
||||
|
||||
if new_level == old_level then
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
else
|
||||
if new_level == 1 then
|
||||
Toast.toast_all_players(TOAST_DURATION, 'More snow has fallen! A new layer has been added to the iceberg!')
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'The iceberg shifts, but you don\'t notice anything new.')
|
||||
end
|
||||
game.print(mod.name .. ' level: ' .. tostring(new_level))
|
||||
end
|
||||
end
|
||||
|
||||
-- Features can be incremented up to 50% of max level with research
|
||||
local function on_research_finished()
|
||||
if math.random(100) <= 100 * ICEBERG_ENABLE_PERCENTAGE then
|
||||
draw_random_effect(0.5)
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
end
|
||||
end
|
||||
|
||||
-- Features can be incremented up to 100% of max level with rocket launches
|
||||
local function on_rocket_launched()
|
||||
if math.random(100) <= 100 * 2 * ICEBERG_ENABLE_PERCENTAGE then
|
||||
draw_random_effect(1)
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
||||
require 'map_gen.maps.april_fools.scenario.rocket_launched'
|
||||
|
||||
-- == COMMANDS ================================================================
|
||||
|
||||
local Command = require 'utils.command'
|
||||
local Ranks = require 'resources.ranks'
|
||||
local Color = require 'resources.color_presets'
|
||||
|
||||
---Use "/af-reset" to reset all features's levels (admin/server only)
|
||||
Command.add(
|
||||
'af-reset',
|
||||
{
|
||||
description = [[Reset all features]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function()
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.level_reset then
|
||||
mod.level_reset()
|
||||
end
|
||||
end
|
||||
game.print('Scenario reset!', Color.success)
|
||||
end
|
||||
)
|
||||
|
||||
---Use "/af-debug" to print all feature's levels, only to admin (admin/server only)
|
||||
Command.add(
|
||||
'af-debug',
|
||||
{
|
||||
description = [[Prints all features's current levels]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function(_, player)
|
||||
for _, mod in pairs(modules) do
|
||||
local msg = ''
|
||||
if mod.level_get and mod.max_get then
|
||||
msg = msg .. 'Lvl. ' ..tostring(mod.level_get()) .. '/' .. tostring(mod.max_get())
|
||||
end
|
||||
if mod.name then
|
||||
msg = msg .. ' - ' .. mod.name
|
||||
end
|
||||
if player and player.valid then
|
||||
player.print(msg, Color.info)
|
||||
else
|
||||
game.print(msg, Color.info)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
---Use "/af-max" to set all features to their max level (admin/server only)
|
||||
Command.add(
|
||||
'af-max',
|
||||
{
|
||||
description = [[Sets all features to according max level]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function()
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.level_set and mod.max_get then
|
||||
mod.level_set(mod.max_get())
|
||||
end
|
||||
end
|
||||
game.print('Scenario maxed out!', Color.warning)
|
||||
end
|
||||
)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
return map
|
322
map_gen/maps/april_fools/2024.lua
Normal file
322
map_gen/maps/april_fools/2024.lua
Normal file
@ -0,0 +1,322 @@
|
||||
--[[
|
||||
Scenario info: Double Trouble
|
||||
2024 revamped version of "Pinguin" scenario from 2019 with several addons.
|
||||
|
||||
Required mods:
|
||||
- Alien Biomes v0.6.8
|
||||
- RedMew Data v0.2.4
|
||||
]]
|
||||
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
ScenarioInfo.set_map_name('Double Trouble')
|
||||
ScenarioInfo.set_map_description('You are Pinguins in Antarctica and Miners underground!')
|
||||
ScenarioInfo.set_map_extra_info('Watch out for Icebergs!')
|
||||
|
||||
--- Config
|
||||
local Config = global.config
|
||||
Config.redmew_surface.enabled = false
|
||||
Config.currency = 'coin'
|
||||
Config.market.enabled = false
|
||||
Config.player_rewards.enabled = true
|
||||
Config.redmew_qol.set_alt_on_create = false
|
||||
|
||||
local restart_command = require 'map_gen.maps.april_fools.scenario.restart_command'
|
||||
restart_command({scenario_name = 'april-fools-2024', mod_pack = 'april_fools_2024'})
|
||||
|
||||
if _DEBUG then
|
||||
Config.player_create.starting_items = {
|
||||
{name = 'tunnel', count = 10},
|
||||
{name = 'iron-plate', count = 26 },
|
||||
{name = 'steel-chest', count = 12},
|
||||
{name = 'power-armor-mk2', count = 1},
|
||||
{name = 'fusion-reactor-equipment', count = 4},
|
||||
{name = 'personal-roboport-mk2-equipment', count = 4},
|
||||
{name = 'battery-mk2-equipment', count = 4},
|
||||
{name = 'construction-robot', count = 50},
|
||||
{name = 'rocket-launcher', count = 1},
|
||||
{name = 'explosive-rocket', count = 200},
|
||||
{name = 'green-wire', count = 200},
|
||||
{name = 'red-wire', count = 200},
|
||||
}
|
||||
else
|
||||
Config.player_create.starting_items = {
|
||||
{name = 'burner-mining-drill', count = 4 },
|
||||
{name = 'stone-furnace', count = 2},
|
||||
{name = 'iron-gear-wheel', count = 3},
|
||||
{name = 'electronic-circuit', count = 5},
|
||||
{name = 'pistol', count = 1},
|
||||
{name = 'firearm-magazine', count = 20},
|
||||
{name = 'coal', count = 34},
|
||||
}
|
||||
end
|
||||
|
||||
-- == MAP GEN =================================================================
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local ABS = require 'resources.alien_biomes.biomes_settings'
|
||||
local Biomes = require 'resources.alien_biomes.biomes'
|
||||
local mgs = Biomes.preset_to_mgs
|
||||
|
||||
local function on_init()
|
||||
local spawn = {0, 0}
|
||||
|
||||
-- Above ground
|
||||
local islands_preset = Biomes.presets.ice
|
||||
islands_preset.water = ABS.water.max
|
||||
islands_preset.enemy = ABS.enemy.high
|
||||
local islands_mgs = mgs(islands_preset)
|
||||
for _, resource in pairs({'iron-ore', 'copper-ore', 'stone', 'coal', 'uranium-ore', 'crude-oil'}) do
|
||||
islands_mgs.autoplace_controls[resource] = { frequency = 1, richness = 1, size = 0 }
|
||||
end
|
||||
local islands = game.create_surface('islands', islands_mgs)
|
||||
islands.request_to_generate_chunks(spawn, 5)
|
||||
islands.force_generate_chunk_requests()
|
||||
islands.ticks_per_day = 72000
|
||||
|
||||
-- Under ground
|
||||
local mines_preset = Biomes.presets.volcano
|
||||
mines_preset.water = ABS.water.none
|
||||
local mines_mgs = mgs(mines_preset)
|
||||
mines_mgs.seed = _DEBUG and 309111855 or nil
|
||||
mines_mgs.autoplace_settings = {
|
||||
tile = {}
|
||||
}
|
||||
for _, tile in pairs({'deepwater', 'deepwater-green', 'water', 'water-green', 'water-mud', 'water-shallow'}) do
|
||||
mines_mgs.autoplace_settings.tile[tile] = { frequency = 1, size = 0, richness = 1 }
|
||||
end
|
||||
for _, resource in pairs({'iron-ore', 'copper-ore', 'stone', 'coal', 'uranium-ore', 'crude-oil'}) do
|
||||
mines_mgs.autoplace_controls[resource] = { frequency = 12.0, size = 0.5, richness = 0.08 }
|
||||
end
|
||||
local mines = game.create_surface('mines', mines_mgs)
|
||||
mines.request_to_generate_chunks(spawn, 2)
|
||||
mines.force_generate_chunk_requests()
|
||||
mines.solar_power_multiplier = 0
|
||||
mines.min_brightness = 0.11
|
||||
mines.ticks_per_day = 72000
|
||||
mines.daytime = 0.42
|
||||
mines.freeze_daytime = true
|
||||
mines.show_clouds = false
|
||||
mines.brightness_visual_weights = {1/0.85, 1/0.85, 1/0.85}
|
||||
|
||||
game.forces.player.set_spawn_position(spawn, 'islands')
|
||||
game.forces.player.manual_mining_speed_modifier = _DEBUG and 20 or 1.2
|
||||
game.difficulty_settings.technology_price_multiplier = game.difficulty_settings.technology_price_multiplier * 2
|
||||
end
|
||||
|
||||
local function on_player_created(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
player.teleport({0,0}, 'islands')
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_player_created, on_player_created)
|
||||
require 'map_gen.maps.april_fools.scenario.camera'
|
||||
require 'map_gen.maps.april_fools.scenario.entity-restrictions'
|
||||
require 'map_gen.maps.april_fools.scenario.evolution_control'
|
||||
require 'map_gen.maps.april_fools.scenario.market'
|
||||
require 'map_gen.maps.april_fools.scenario.mines'
|
||||
|
||||
-- == MODULES IMPORT ==========================================================
|
||||
|
||||
local modules = {
|
||||
require 'map_gen.maps.april_fools.modules.alternative_biters', -- Spawns a random biters on every player that has alt-mode turned on
|
||||
require 'map_gen.maps.april_fools.modules.auto_build', -- Randomly selected players will have their cursor items automatically built nearby for a time, before changing targets
|
||||
require 'map_gen.maps.april_fools.modules.biter_ores', -- Biters spawn ores on death, level determines amount
|
||||
require 'map_gen.maps.april_fools.modules.crazy_chat_colors', -- Chance to change player's color every time they send a message in chat
|
||||
require 'map_gen.maps.april_fools.modules.crazy_toolbar', -- Randomly replaces quickbar slots with new items
|
||||
require 'map_gen.maps.april_fools.modules.enemy_turrets', -- Chance to change turret to enemy force, and give it ammo/fuel/power
|
||||
require 'map_gen.maps.april_fools.modules.explosion_scare', -- Spawns random non-damaging explosions on random players as a jump-scare
|
||||
require 'map_gen.maps.april_fools.modules.floor_is_lava', -- Does minor damage to a player when afk for a few second
|
||||
require 'map_gen.maps.april_fools.modules.golden_goose', -- Randomly selected players will drop coins for a time, before changing targets
|
||||
require 'map_gen.maps.april_fools.modules.marathon_mode', -- Enables expensive recipes and increases technology multiplier
|
||||
require 'map_gen.maps.april_fools.modules.meteOres', -- Meteors fall from the sky, generating ores, and biters
|
||||
require 'map_gen.maps.april_fools.modules.orphan_crafting', -- Chance to give the player an additional single underground belt or pipe-to-ground
|
||||
require 'map_gen.maps.april_fools.modules.permanent_factory', -- Chance to make an entity indestructable
|
||||
require 'map_gen.maps.april_fools.modules.random_ores', -- Chance to change an ore to a random ore when a mining drill is placed
|
||||
require 'map_gen.maps.april_fools.modules.rotate_entities', -- Chance to randomly rotate an entity when rotated by a player
|
||||
require 'map_gen.maps.april_fools.modules.rotate_inserters', -- Chance to randomly rotate an inserter when built
|
||||
require 'map_gen.maps.april_fools.modules.rotten_egg', -- Randomly selected players will produce pollution for a time, before changing targets
|
||||
require 'map_gen.maps.april_fools.modules.unorganized_recipes', -- Randomly selected players will have their recipe groups and subgroups disabled, unorganizing their crafting menu
|
||||
}
|
||||
|
||||
-- if script.active_mods['redmew-data'] then
|
||||
-- local PATH_MODULES_MOD = '__redmew-data__/'
|
||||
-- table.insert(modules, PATH_MODULES_MOD .. 'name_of_the_module')
|
||||
-- end
|
||||
|
||||
-- Activate module events
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.on_init then
|
||||
Event.on_init(mod.on_init)
|
||||
end
|
||||
|
||||
if mod.on_load then
|
||||
Event.on_load(mod.on_load)
|
||||
end
|
||||
|
||||
if mod.on_configuration_changed then
|
||||
Event.on_configuration_changed(mod.on_configuration_changed)
|
||||
end
|
||||
|
||||
if mod.events then
|
||||
for id_event, callback in pairs(mod.events) do
|
||||
Event.add(id_event, callback)
|
||||
end
|
||||
end
|
||||
|
||||
if mod.on_nth_tick then
|
||||
for nth_tick, callback in pairs(mod.on_nth_tick) do
|
||||
Event.on_nth_tick(nth_tick, callback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- == CONTROLLER ==============================================================
|
||||
|
||||
local Toast = require 'features.gui.toast'
|
||||
|
||||
local ICEBERG_ENABLE_PERCENTAGE = _DEBUG and 1 or 0.50
|
||||
local TOAST_DURATION = 10
|
||||
|
||||
local function draw_random_effect(max_share)
|
||||
local mod_index = math.random(1, #modules)
|
||||
local mod = modules[mod_index]
|
||||
|
||||
if mod == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local old_level, new_level, max_level = 0, 0, 0
|
||||
|
||||
if mod.level_get then
|
||||
old_level = mod.level_get()
|
||||
end
|
||||
if mod.max_get then
|
||||
max_level = mod.max_get()
|
||||
end
|
||||
|
||||
if old_level < (max_level * max_share) then
|
||||
if mod.level_increase then
|
||||
mod.level_increase()
|
||||
end
|
||||
end
|
||||
|
||||
if mod.level_get then
|
||||
new_level = mod.level_get()
|
||||
end
|
||||
|
||||
if new_level == old_level then
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
else
|
||||
if new_level == 1 then
|
||||
Toast.toast_all_players(TOAST_DURATION, 'More snow has fallen! A new layer has been added to the iceberg!')
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'The iceberg shifts, but you don\'t notice anything new.')
|
||||
end
|
||||
game.print(mod.name .. ' level: ' .. tostring(new_level))
|
||||
end
|
||||
end
|
||||
|
||||
-- Features can be incremented up to 50% of max level with research
|
||||
local function on_research_finished()
|
||||
if math.random(100) <= 100 * ICEBERG_ENABLE_PERCENTAGE then
|
||||
draw_random_effect(0.5)
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
end
|
||||
end
|
||||
|
||||
-- Features can be incremented up to 100% of max level with rocket launches
|
||||
local function on_rocket_launched()
|
||||
if math.random(100) <= 100 * 2 * ICEBERG_ENABLE_PERCENTAGE then
|
||||
draw_random_effect(1)
|
||||
else
|
||||
Toast.toast_all_players(TOAST_DURATION, 'Everything seems normal... for now.')
|
||||
game.print('There appears to be no change to the iceberg, lucky Pinguins.')
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
||||
require 'map_gen.maps.april_fools.scenario.rocket_launched'
|
||||
|
||||
-- == COMMANDS ================================================================
|
||||
|
||||
local Command = require 'utils.command'
|
||||
local Ranks = require 'resources.ranks'
|
||||
local Color = require 'resources.color_presets'
|
||||
|
||||
---Use "/af-reset" to reset all features's levels (admin/server only)
|
||||
Command.add(
|
||||
'af-reset',
|
||||
{
|
||||
description = [[Reset all features]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function()
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.level_reset then
|
||||
mod.level_reset()
|
||||
end
|
||||
end
|
||||
game.print('Scenario reset!', Color.success)
|
||||
end
|
||||
)
|
||||
|
||||
---Use "/af-debug" to print all feature's levels, only to admin (admin/server only)
|
||||
Command.add(
|
||||
'af-debug',
|
||||
{
|
||||
description = [[Prints all features's current levels]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function(_, player)
|
||||
for _, mod in pairs(modules) do
|
||||
local msg = ''
|
||||
if mod.level_get and mod.max_get then
|
||||
msg = msg .. 'Lvl. ' ..tostring(mod.level_get()) .. '/' .. tostring(mod.max_get())
|
||||
end
|
||||
if mod.name then
|
||||
msg = msg .. ' - ' .. mod.name
|
||||
end
|
||||
if player and player.valid then
|
||||
player.print(msg, Color.info)
|
||||
else
|
||||
game.print(msg, Color.info)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
---Use "/af-max" to set all features to their max level (admin/server only)
|
||||
Command.add(
|
||||
'af-max',
|
||||
{
|
||||
description = [[Sets all features to according max level]],
|
||||
arguments = {},
|
||||
required_rank = Ranks.admin,
|
||||
allowed_by_server = true
|
||||
},
|
||||
function()
|
||||
for _, mod in pairs(modules) do
|
||||
if mod.level_set and mod.max_get then
|
||||
mod.level_set(mod.max_get())
|
||||
end
|
||||
end
|
||||
game.print('Scenario maxed out!', Color.warning)
|
||||
end
|
||||
)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
--return map
|
126
map_gen/maps/april_fools/modules/alternative_biters.lua
Normal file
126
map_gen/maps/april_fools/modules/alternative_biters.lua
Normal file
@ -0,0 +1,126 @@
|
||||
-- Spawns biters of a level scaling with _global.level on every player that has alt_mode toggled ON
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local math = require 'utils.math'
|
||||
|
||||
local SPAWN_INTERVAL = 60 * 60 -- 60sec
|
||||
local UNIT_COUNT = 1 -- Number of units spawned per enemy listed in each ENEMY_GROUP
|
||||
|
||||
local _global = {
|
||||
level = 0, --1 to enabled by defualt
|
||||
max_level = 10,
|
||||
alt_biters_players = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local ENEMY_GROUPS = {
|
||||
{ 'small-biter', 'small-spitter' },
|
||||
{ 'small-biter', 'small-spitter', 'small-worm-turret' },
|
||||
{ 'medium-biter', 'medium-spitter' },
|
||||
{ 'medium-biter', 'medium-spitter', 'medium-worm-turret' },
|
||||
{ 'big-biter', 'big-spitter' },
|
||||
{ 'big-biter', 'big-spitter', 'big-worm-turret' },
|
||||
{ 'behemoth-biter', 'behemoth-spitter' },
|
||||
{ 'behemoth-biter', 'behemoth-spitter', 'behemoth-worm-turret' },
|
||||
{ 'behemoth-biter', 'behemoth-spitter', 'behemoth-worm-turret', 'biter-spawner' },
|
||||
{ 'behemoth-biter', 'behemoth-spitter', 'behemoth-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
}
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function spawn_biters_nearby_players()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local index_from_level = math.clamp(_global.level, 1, #ENEMY_GROUPS)
|
||||
local biters = ENEMY_GROUPS[index_from_level]
|
||||
|
||||
for _, player in pairs(game.players) do
|
||||
if (player and player.valid and _global.alt_biters_players[player.name]) then
|
||||
local position = player.position
|
||||
|
||||
for i=1, UNIT_COUNT do
|
||||
local unit_index = math.random(1, #biters)
|
||||
player.surface.create_entity{
|
||||
name = biters[unit_index],
|
||||
position = position,
|
||||
force = 'enemy',
|
||||
target = player.character,
|
||||
move_stuck_players = true,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- toggle alt-biters for the player when alt-mode is toggled
|
||||
local function on_player_toggled_alt_mode(event)
|
||||
local player_index = event.player_index
|
||||
if player_index == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(player_index)
|
||||
if (player and player.valid and player.name) then
|
||||
_global.alt_biters_players[player.name] = event.alt_mode or false
|
||||
end
|
||||
end
|
||||
|
||||
-- turn off alt-mode on game join, and set alt-biters to off
|
||||
local function on_player_joined_game(event)
|
||||
local player_index = event.player_index
|
||||
if player_index == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(player_index)
|
||||
if (player and player.valid and player.name) then
|
||||
player.game_view_settings.show_entity_info = false
|
||||
_global.alt_biters_players[player.name] = false
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Alternative biters'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_player_toggled_alt_mode] = on_player_toggled_alt_mode,
|
||||
[defines.events.on_player_joined_game] = on_player_joined_game,
|
||||
}
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[SPAWN_INTERVAL] = spawn_biters_nearby_players,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
129
map_gen/maps/april_fools/modules/auto_build.lua
Normal file
129
map_gen/maps/april_fools/modules/auto_build.lua
Normal file
@ -0,0 +1,129 @@
|
||||
-- auto-builds the item in a random players cursor if possible
|
||||
-- WIP
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_TARGETS = 1 -- how many targets per level
|
||||
local BUILD_INTERVAL = 60 * 5 -- 5sec
|
||||
local CHANGE_TARGET_INTERVAL = _DEBUG and 60 * 1 or 60 * 100 -- 100sec
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
rand_targets = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function clear_targets()
|
||||
for j=1, #_global.rand_targets do
|
||||
_global.rand_targets[j] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function change_targets()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local num_targets = math.min(#game.connected_players, _global.level * BASE_TARGETS)
|
||||
|
||||
for j=1, num_targets do
|
||||
_global.rand_targets[j] = nil
|
||||
end
|
||||
|
||||
if #game.connected_players > 0 then
|
||||
for j=1, num_targets do
|
||||
local player_index = math.random(1, #game.connected_players)
|
||||
_global.rand_targets[j] = game.connected_players[player_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function try_auto_build()
|
||||
if not (_global and _global.rand_targets and (#_global.rand_targets > 0)) then
|
||||
-- No targets
|
||||
return
|
||||
end
|
||||
-- useful functions:
|
||||
-- surface.find_non_colliding_position, surface.find_non_colliding_position_in_box
|
||||
-- player.can_build_from_cursor, player.build_from_cursor
|
||||
--
|
||||
local cursor_item
|
||||
local surface
|
||||
local build_position
|
||||
for _, player in pairs(_global.rand_targets) do
|
||||
if not (player and player.valid) then
|
||||
goto skip
|
||||
end
|
||||
|
||||
surface = player.surface
|
||||
if player.cursor_stack.valid_for_read then
|
||||
cursor_item = player.cursor_stack.name
|
||||
else
|
||||
goto skip --cursor not valud to read, i.e. just before spawning
|
||||
end
|
||||
if cursor_item == nil then
|
||||
goto skip -- no item in cursor
|
||||
end
|
||||
|
||||
-- randomly pick a position near the player, check for a valid nearby location
|
||||
build_position = {player.position.x + math.random(-5,5),player.position.y + math.random(-5,5)}
|
||||
build_position = surface.find_non_colliding_position(cursor_item,build_position, 5, .1)
|
||||
if build_position == nil then
|
||||
goto skip -- no valud build position
|
||||
end
|
||||
|
||||
-- must be extra cautious with surface & players as they may be teleported across temporary surfaces
|
||||
if (surface and surface.valid and build_position) then
|
||||
if player.can_build_from_cursor{position = build_position} then
|
||||
player.build_from_cursor{position = build_position}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
::skip::
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Auto Build'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_TARGET_INTERVAL] = change_targets,
|
||||
[BUILD_INTERVAL] = try_auto_build,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.rand_targets[_global.level] = nil
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
clear_targets()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
clear_targets()
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
115
map_gen/maps/april_fools/modules/biter_ores.lua
Normal file
115
map_gen/maps/april_fools/modules/biter_ores.lua
Normal file
@ -0,0 +1,115 @@
|
||||
-- Spawns ores on biter death
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local math = require 'utils.math'
|
||||
|
||||
local RANDOM_ORES = false
|
||||
local BASE_ORE_AMOUNT = 5 -- ore spawned per small biter, per level
|
||||
local BASIC_ORES = {'coal','stone','iron-ore','copper-ore'}
|
||||
local URANIUM_CHANCE = 5 -- chance for uranium ore. All others will share the remaining chance
|
||||
local ORE_SEARCH_RADIUS = RANDOM_ORES and 1 or 20 -- how far away do we look for ores before spawning a new one
|
||||
|
||||
local _global = {
|
||||
level = 0, --1 to enabled by defualt
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local ENEMY_ORE_MULTIPLIER = { -- roughly in order of evolution percentage required to see these biters
|
||||
['small-biter'] = 1,
|
||||
['small-spitter'] = 2,
|
||||
['small-worm-turret'] = 5,
|
||||
['medium-biter'] = 2,
|
||||
['medium-spitter'] = 4,
|
||||
['medium-worm-turret'] = 10,
|
||||
['big-biter'] = 5,
|
||||
['big-spitter'] = 10,
|
||||
['big-worm-turret'] = 25,
|
||||
['behemoth-biter'] = 10,
|
||||
['behemoth-spitter'] = 20,
|
||||
['behemoth-worm-turret'] = 50,
|
||||
['biter-spawner'] = 10,
|
||||
['spitter-spawner'] = 20
|
||||
}
|
||||
|
||||
-- ============================================================================
|
||||
local function spawn_ores_on_death(event)
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
-- check if entity is biter, worm, or spawner
|
||||
local entity = event.entity
|
||||
if entity.type ~= 'unit' and entity.type ~= 'turret' and entity.type ~= 'unit-spawner' then
|
||||
return
|
||||
end
|
||||
local ore_amount_to_add = _global.level * ENEMY_ORE_MULTIPLIER[entity.name] * BASE_ORE_AMOUNT
|
||||
local position = entity.position
|
||||
local surface = entity.surface
|
||||
local ore_type
|
||||
|
||||
--first, look for ores on the tile the biter died, and add ores to that ore if possible
|
||||
local found_ores = surface.find_entities_filtered{position = position, radius = .1, type = 'resource'}
|
||||
if #found_ores == 0 then
|
||||
--no ore found on biter tile
|
||||
found_ores = surface.find_entities_filtered{position = position, radius = ORE_SEARCH_RADIUS, type = 'resource'}
|
||||
if #found_ores == 0 then
|
||||
--no ore found nearby, decide on a new ore to spawn
|
||||
if math.random(1,100) < URANIUM_CHANCE then
|
||||
ore_type = 'uranium-ore'
|
||||
else
|
||||
ore_type = BASIC_ORES[math.random(1,#BASIC_ORES)]
|
||||
end
|
||||
else
|
||||
-- found nearby ore, use that one
|
||||
ore_type = found_ores[math.random(1,#found_ores)].name
|
||||
end
|
||||
|
||||
if surface.get_tile(position).collides_with("ground-tile") then
|
||||
surface.create_entity{name = ore_type, position = position, amount = ore_amount_to_add}
|
||||
end
|
||||
--return since we might have changed found_ores
|
||||
return
|
||||
else
|
||||
-- ore on biters tile, add to that ore instead
|
||||
found_ores[1].amount = found_ores[1].amount + ore_amount_to_add
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Biter Ores'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_entity_died] = spawn_ores_on_death
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
75
map_gen/maps/april_fools/modules/crazy_chat_colors.lua
Normal file
75
map_gen/maps/april_fools/modules/crazy_chat_colors.lua
Normal file
@ -0,0 +1,75 @@
|
||||
-- Changes player color with every message
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local Colors = require 'resources.color_presets'
|
||||
|
||||
local COLORS = {}
|
||||
for _, color in pairs(Colors) do
|
||||
table.insert(COLORS, color)
|
||||
end
|
||||
|
||||
local BASE_PERCENT = 0.1
|
||||
local MAX_RAND = 100
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function on_console_chat(event)
|
||||
local index = event.player_index
|
||||
if index == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local change_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand >= MAX_RAND*(1 - change_percent) then
|
||||
local color = COLORS[math.random(1, #COLORS)]
|
||||
local player = game.get_player(index)
|
||||
player.color = color
|
||||
player.chat_color = color
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Disco players'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_console_chat] = on_console_chat,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
83
map_gen/maps/april_fools/modules/crazy_toolbar.lua
Normal file
83
map_gen/maps/april_fools/modules/crazy_toolbar.lua
Normal file
@ -0,0 +1,83 @@
|
||||
-- Randmly changes shortcut items in player's quickbar
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local Item_list = require 'resources.item_list'
|
||||
|
||||
local BASE_PERCENT = 0.05
|
||||
local MAX_RAND = 100
|
||||
local CHANGE_INTERVAL = 60 * 12 --12sec
|
||||
local SEARCHED_QUICKBAR_SLOTS = 100
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function change_quickbar_item()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local crazy_percent = _global.level * BASE_PERCENT
|
||||
|
||||
for _, player in pairs(game.players) do
|
||||
if (player and player.valid) then
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
if rand >= MAX_RAND*(1 - crazy_percent) then
|
||||
local valid_item, rand_item = false, false
|
||||
local max_attempts = 10
|
||||
while ((max_attempts > 0) and (not valid_item)) do
|
||||
rand_item = Item_list[math.random(1, #Item_list)]
|
||||
valid_item = (game.item_prototypes[rand_item] ~= nil)
|
||||
max_attempts = max_attempts - 1
|
||||
end
|
||||
if valid_item then
|
||||
local rand_position = math.random(1, SEARCHED_QUICKBAR_SLOTS)
|
||||
player.set_quick_bar_slot(rand_position, rand_item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Fuzzy quickbar'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_INTERVAL] = change_quickbar_item,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
147
map_gen/maps/april_fools/modules/enemy_turrets.lua
Normal file
147
map_gen/maps/april_fools/modules/enemy_turrets.lua
Normal file
@ -0,0 +1,147 @@
|
||||
-- turrets have a 90% chance of being on player force when placed
|
||||
-- Be sure to adjust ammo count/amount on the enemy turrets below as needed
|
||||
-- Completed
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_PERCENT = 0.05
|
||||
local MAX_RAND = 100
|
||||
local LASER_SHOTS_PER_LEVEL = 10 -- No idea what a good number is here balance wise.
|
||||
local ENERGY_PER_SHOT = 800000 -- 1 shot of the laser turret
|
||||
|
||||
local _global = { level = 0, max_level = 10 }
|
||||
|
||||
Global.register(_global, function(tbl)
|
||||
_global = tbl
|
||||
end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local TURRET_ACTIONS = {
|
||||
['gun-turret'] = function(entity)
|
||||
entity.insert{ name = 'firearm-magazine', count = 2 * (_global.level or 1) }
|
||||
end,
|
||||
['flamethrower-turret'] = function(entity)
|
||||
entity.insert_fluid{ name = 'crude-oil', amount = 6 * (_global.level or 1) }
|
||||
end,
|
||||
['artillery-turret'] = function(entity)
|
||||
entity.insert{ name = 'artillery-shell', count = _global.level or 1 }
|
||||
end,
|
||||
['laser-turret'] = function(entity)
|
||||
-- TODO: change e-interface to accumulator with power
|
||||
if entity.surface then
|
||||
entity.surface.create_entity{
|
||||
name = 'hidden-electric-energy-interface',
|
||||
force = 'enemy',
|
||||
position = entity.position,
|
||||
raise_built = false,
|
||||
move_stuck_players = true
|
||||
}
|
||||
-- find that interface we just made
|
||||
local entities = entity.surface.find_entities_filtered{ name = 'hidden-electric-energy-interface', position = entity.position, radius = 2 }
|
||||
-- Set energy interface
|
||||
local total_power = ENERGY_PER_SHOT * LASER_SHOTS_PER_LEVEL * (_global.level or 1)
|
||||
for i = 1, #entities do
|
||||
if (entities[i] and entities[i].valid) then
|
||||
entities[i].electric_buffer_size = total_power
|
||||
entities[i].power_production = 0
|
||||
entities[i].power_usage = 0
|
||||
entities[i].energy = total_power
|
||||
end
|
||||
end
|
||||
entity.surface.create_entity{
|
||||
name = 'small-electric-pole',
|
||||
force = 'enemy',
|
||||
position = entity.position,
|
||||
raise_built = false,
|
||||
move_stuck_players = true
|
||||
}
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
local function on_built_turret(event)
|
||||
local entity = event.created_entity
|
||||
if not (entity and entity.valid and entity.name) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
local fill_entity = TURRET_ACTIONS[entity.name]
|
||||
if not fill_entity then
|
||||
-- Turret not whitelisted
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local change_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand >= MAX_RAND * (1 - change_percent) then
|
||||
fill_entity(entity)
|
||||
entity.clone({ position = entity.position, force = 'enemy' })
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_enemy_power_on_death(event)
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
if not (entity.name == 'laser-turret' and entity.force == 'enemy') then
|
||||
-- Wrong entity
|
||||
return
|
||||
end
|
||||
|
||||
local entities = entity.surface.find_entities_filtered{ name = 'hidden-electric-energy-interface', position = entity.position, radius = 2 }
|
||||
for i = 1, #entities do
|
||||
if (entities[i] and entities[i].valid) then
|
||||
entities[i].destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Rogue turrets'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_robot_built_entity] = on_built_turret,
|
||||
[defines.events.on_built_entity] = on_built_turret,
|
||||
[defines.events.on_entity_died] = remove_enemy_power_on_death
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
120
map_gen/maps/april_fools/modules/explosion_scare.lua
Normal file
120
map_gen/maps/april_fools/modules/explosion_scare.lua
Normal file
@ -0,0 +1,120 @@
|
||||
-- Spawns random non-damaging explosions on random players as a jump-scare
|
||||
-- WIP
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_TARGETS = 1 -- how many targets per level
|
||||
local EXPLOSION_INTERVAL = _DEBUG and 60 * 5 or 60 * 60 -- 60sec
|
||||
local CHANGE_TARGET_INTERVAL = _DEBUG and 60 * 10 or 60 * 180 -- 180 seconds
|
||||
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
rand_target = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local EXPLOSION_GROUPS = {
|
||||
{ 'water-splash' },
|
||||
{ 'water-splash', 'explosion' },
|
||||
{ 'water-splash', 'explosion', 'land-mine-explosion' },
|
||||
{ 'explosion', 'land-mine-explosion', 'grenade-explosion' },
|
||||
{ 'land-mine-explosion', 'grenade-explosion', 'medium-explosion' },
|
||||
{ 'grenade-explosion', 'medium-explosion' },
|
||||
{ 'medium-explosion', 'big-explosion' },
|
||||
{ 'big-explosion', 'massive-explosion', 'big-artillery-explosion' },
|
||||
{ 'massive-explosion', 'big-artillery-explosion' },
|
||||
{ 'massive-explosion', 'big-artillery-explosion', 'nuke-explosion' },
|
||||
}
|
||||
-- ============================================================================
|
||||
|
||||
local function clear_targets()
|
||||
for j=1, #_global.rand_target do
|
||||
_global.rand_target[j] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function change_targets()
|
||||
if not (_global and (_global.level > 0)) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
-- without taking the min of connected players, and the desired targets, it's possible for 1 player to get ALL the explosions
|
||||
-- The code would then randomly choose an explosion for each target, so you might get a water splash and a normal explosion at the same time.
|
||||
local num_targets = math.min(_global.level * BASE_TARGETS, #game.connected_players)
|
||||
|
||||
for j=1, num_targets do
|
||||
_global.rand_target[j] = nil
|
||||
end
|
||||
|
||||
if #game.connected_players > 0 then
|
||||
for j=1, num_targets do
|
||||
local player_index = math.random(1, #game.connected_players)
|
||||
_global.rand_target[j] = game.connected_players[player_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function explode_targets()
|
||||
if not (_global and _global.rand_target and (#_global.rand_target > 0)) then
|
||||
-- No targets
|
||||
return
|
||||
end
|
||||
local index_from_level = math.clamp(_global.level, 1, #EXPLOSION_GROUPS) --luacheck: ignore 143 math.clamp does in fact exist
|
||||
local explosions = EXPLOSION_GROUPS[index_from_level]
|
||||
|
||||
for _, player in pairs(_global.rand_target) do
|
||||
if (player and player.valid) then
|
||||
local surface = player.surface
|
||||
local position = player.position
|
||||
local explosion_index = math.random(1, #explosions)
|
||||
-- must be extra cautious with surface & players as they may be teleported across temporary surfaces
|
||||
if (surface and surface.valid and position) then
|
||||
surface.create_entity{
|
||||
name = explosions[explosion_index],
|
||||
position = position,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
Public.name = 'Explosion Scare'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_TARGET_INTERVAL] = change_targets,
|
||||
[EXPLOSION_INTERVAL] = explode_targets,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.rand_target[_global.level] = nil
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
clear_targets()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
clear_targets()
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
71
map_gen/maps/april_fools/modules/floor_is_lava.lua
Normal file
71
map_gen/maps/april_fools/modules/floor_is_lava.lua
Normal file
@ -0,0 +1,71 @@
|
||||
-- Floor is lava, a player that is AFK for ALLOWED_AFK_TIME ticks will be damaged every DAMAGE_INTERVAL ticks
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local DAMAGE_INTERVAL = 60 * 5 -- 5sec
|
||||
local ALLOWED_AFK_TIME = 60 * 7 -- 7sec
|
||||
local BASE_DAMAGE = 1
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function damage_afk_players()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
for _, player in pairs(game.players) do
|
||||
if (player and player.valid and player.character and player.character.valid) then
|
||||
if player.afk_time > ALLOWED_AFK_TIME then
|
||||
player.character.damage(BASE_DAMAGE * _global.level, 'enemy')
|
||||
if _global.level >= _global.max_level/2 then
|
||||
player.surface.create_entity({name = 'fire-flame', position = player.position})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'The floor is lava'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[DAMAGE_INTERVAL] = damage_afk_players,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
106
map_gen/maps/april_fools/modules/golden_goose.lua
Normal file
106
map_gen/maps/april_fools/modules/golden_goose.lua
Normal file
@ -0,0 +1,106 @@
|
||||
-- golden goose
|
||||
-- SPAWN_INTERVAL and CHANGE_GEESE_INTERVAL should be set to the number of ticks between the event triggering
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_GEESE = 1 -- how many geese per level
|
||||
local SPAWN_INTERVAL = 60 * 5 -- 5sec
|
||||
local CHANGE_GEESE_INTERVAL = 60 * 100 -- 100sec
|
||||
local DROP_AMOUNT = 1
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
rand_geese = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function clear_geese()
|
||||
for j=1, #_global.rand_geese do
|
||||
_global.rand_geese[j] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function change_geese()
|
||||
if not (_global and (_global.level > 0)) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local num_geese = _global.level * BASE_GEESE
|
||||
|
||||
for j=1, num_geese do
|
||||
_global.rand_geese[j] = nil
|
||||
end
|
||||
|
||||
if #game.connected_players > 0 then
|
||||
for j=1, num_geese do
|
||||
local player_index = math.random(1, #game.connected_players)
|
||||
_global.rand_geese[j] = game.connected_players[player_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function geese_spawn_coin()
|
||||
if not (_global and _global.rand_geese and (#_global.rand_geese > 0)) then
|
||||
-- No geese
|
||||
return
|
||||
end
|
||||
|
||||
for _, player in pairs(_global.rand_geese) do
|
||||
if (player and player.valid) then
|
||||
local surface = player.surface
|
||||
local position = player.position
|
||||
-- must be extra cautious with surface & players as they may be teleported across temporary surfaces
|
||||
if (surface and surface.valid and position) then
|
||||
surface.create_entity{
|
||||
name = 'item-on-ground',
|
||||
position = position,
|
||||
stack = {name = 'coin', count = DROP_AMOUNT},
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
Public.name = 'Golden goose'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_GEESE_INTERVAL] = change_geese,
|
||||
[SPAWN_INTERVAL] = geese_spawn_coin,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.rand_geese[_global.level] = nil
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
clear_geese()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
clear_geese()
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
62
map_gen/maps/april_fools/modules/marathon_mode.lua
Normal file
62
map_gen/maps/april_fools/modules/marathon_mode.lua
Normal file
@ -0,0 +1,62 @@
|
||||
-- Increases research costs and enables marathon mode
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local COST_STEP = 1.0
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 9,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function update_price_multiplier()
|
||||
local level = math.max(0, _global.level)
|
||||
|
||||
-- Enable expensive recipes after lvl.3
|
||||
game.difficulty_settings.recipe_difficulty = (level > 3) and 1 or 0
|
||||
|
||||
-- Apply expensive tech cost above lvl.0
|
||||
game.difficulty_settings.technology_difficulty = (level > 0) and 1 or 0
|
||||
game.difficulty_settings.technology_price_multiplier = (level + 1) * COST_STEP
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Marathon'
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
update_price_multiplier()
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
update_price_multiplier()
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
update_price_multiplier()
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
update_price_multiplier()
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
176
map_gen/maps/april_fools/modules/meteOres.lua
Normal file
176
map_gen/maps/april_fools/modules/meteOres.lua
Normal file
@ -0,0 +1,176 @@
|
||||
-- Spawns "meteors" that spawn a boulder, and dense random ores, and biters, and maybe nests
|
||||
-- WIP
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local math = require 'utils.math'
|
||||
|
||||
local SPAWN_INTERVAL = _DEBUG and 60 * 1 or 60 * 60 * 8 -- 8 mins
|
||||
local UNIT_COUNT = 10 -- Balance Number of units spawned per enemy listed in each ENEMY_GROUP
|
||||
local METEOR_COUNT = 1 -- meteors per spawn interval
|
||||
local METEOR_SIZE = 7 -- radius, Balance
|
||||
local METEOR_DAMAGE = 50 -- Balance
|
||||
local ORE_DENSITY = 10 -- Balance, Must be at least 8?
|
||||
local ORE_COMPLEXITY = 5 -- Percent chance for each of the 5 ore types to spawn, otherwise mixed ores without uranium will spawn.
|
||||
|
||||
local _global = {
|
||||
level = 0, --1 to enabled by defualt
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local ENEMY_GROUPS = {
|
||||
{ 'small-biter'},
|
||||
{ 'small-biter', 'small-spitter', 'small-worm-turret', 'biter-spawner'},
|
||||
{ 'small-biter', 'small-spitter','medium-biter','small-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'small-biter', 'small-spitter','medium-biter', 'medium-spitter','small-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'medium-biter', 'medium-spitter', 'big-biter', 'big-spitter','small-worm-turret','medium-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'medium-biter', 'medium-spitter', 'big-biter', 'big-spitter', 'big-worm-turret','medium-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'big-biter', 'big-spitter','behemoth-biter', 'behemoth-spitter', 'medium-worm-turret','big-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'big-biter', 'big-spitter','behemoth-biter', 'behemoth-spitter', 'medium-worm-turret', 'big-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'big-biter', 'big-spitter','behemoth-biter', 'behemoth-spitter', 'big-worm-turret','behemoth-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
{ 'behemoth-biter', 'behemoth-spitter', 'behemoth-worm-turret', 'biter-spawner', 'spitter-spawner' },
|
||||
}
|
||||
local BASIC_ORES = {'coal','stone','iron-ore','copper-ore'}
|
||||
local ALL_ORES = {'coal','stone','iron-ore','copper-ore','uranium-ore'}
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function drop_meteors()
|
||||
--[[ Large function, lots of steps. May want to split out into several functions later
|
||||
[X] Find a player to use their surface
|
||||
[X] Generate a random position on the map
|
||||
[X] Spawn a rock
|
||||
[X] Damage Nearby Entities
|
||||
[X] Spawn Ores
|
||||
[X] Spawn Biters
|
||||
--]]
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
local player
|
||||
local surface
|
||||
for _ = 1, METEOR_COUNT do
|
||||
-- find a random player so we can use their surface
|
||||
if #game.connected_players > 0 then
|
||||
player = game.connected_players[math.random(1, #game.connected_players)]
|
||||
surface = player.surface
|
||||
else
|
||||
return -- no connected players
|
||||
end
|
||||
|
||||
-- generate a random position in a random chunk
|
||||
local chunk_position = surface.get_random_chunk()
|
||||
local rand_x = math.random(0, 31)
|
||||
local rand_y = math.random(0, 31)
|
||||
local map_position = {x = chunk_position.x * 32 + rand_x, y = chunk_position.y * 32 + rand_y}
|
||||
|
||||
-- Spawn Rock
|
||||
if surface.get_tile(map_position).collides_with('ground-tile') then
|
||||
surface.create_entity({name = 'rock-huge', position = map_position, move_stuck_players = true,})
|
||||
surface.create_entity({name = 'massive-explosion', position = map_position,})
|
||||
end
|
||||
|
||||
-- Find nearby entities
|
||||
local damaged_entities = surface.find_entities_filtered{position = map_position, radius = METEOR_SIZE}
|
||||
-- Damage nearby entities
|
||||
if damaged_entities == nil then
|
||||
return
|
||||
else
|
||||
for _, entity in ipairs(damaged_entities) do
|
||||
if entity.is_entity_with_health then
|
||||
entity.damage(METEOR_DAMAGE,'enemy','impact')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Select ores to spawn
|
||||
local ore_selector = math.random(1,100)
|
||||
local ores
|
||||
local ore_type
|
||||
local ore_amount
|
||||
if ore_selector > 100 - 5 * ORE_COMPLEXITY then
|
||||
ores = 'individual'
|
||||
ore_type = ALL_ORES[math.random(1, #ALL_ORES)]
|
||||
else
|
||||
ores = 'mixed'
|
||||
end
|
||||
-- Spawn ores
|
||||
-- Loop over x, y, check in the circle, and spawn ores in a natural density
|
||||
-- aka code adapted from wube wiki console page for spawning a resource patch
|
||||
for y = -METEOR_SIZE, METEOR_SIZE do
|
||||
for x = -METEOR_SIZE, METEOR_SIZE do
|
||||
if (x * x + y * y < METEOR_SIZE * METEOR_SIZE) then
|
||||
local a = (METEOR_SIZE + 1 - math.abs(x)) * 10
|
||||
local b = (METEOR_SIZE + 1 - math.abs(y)) * 10
|
||||
if a < b then
|
||||
ore_amount = math.random(a * ORE_DENSITY - a * (ORE_DENSITY - 8), a * ORE_DENSITY + a * (ORE_DENSITY - 8))
|
||||
end
|
||||
if b < a then
|
||||
ore_amount = math.random(b * ORE_DENSITY - b * (ORE_DENSITY - 8), b * ORE_DENSITY + b * (ORE_DENSITY - 8))
|
||||
end
|
||||
if surface.get_tile(map_position.x + x, map_position.y + y).collides_with('ground-tile') then
|
||||
if ores == 'mixed' then
|
||||
ore_type = BASIC_ORES[math.random(1, #BASIC_ORES)]
|
||||
end
|
||||
surface.create_entity({name=ore_type, amount=ore_amount, position={map_position.x + x, map_position.y + y}})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- spawn biters
|
||||
local index_from_level = math.clamp(_global.level, 1, #ENEMY_GROUPS)
|
||||
local biters = ENEMY_GROUPS[index_from_level]
|
||||
for i=1, UNIT_COUNT do
|
||||
local unit_index = math.random(1, #biters)
|
||||
local biter_position = {
|
||||
map_position.x + math.random(-METEOR_SIZE, METEOR_SIZE),
|
||||
map_position.y + math.random(-METEOR_SIZE, METEOR_SIZE)}
|
||||
if surface.get_tile(biter_position).collides_with('ground-tile') then
|
||||
surface.create_entity{
|
||||
name = biters[unit_index],
|
||||
position = biter_position,
|
||||
force = 'enemy',
|
||||
-- target = player.character, -- try without player target? Will they behave normally?
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'MeteOres'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[SPAWN_INTERVAL] = drop_meteors,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
90
map_gen/maps/april_fools/modules/orphan_crafting.lua
Normal file
90
map_gen/maps/april_fools/modules/orphan_crafting.lua
Normal file
@ -0,0 +1,90 @@
|
||||
-- crafting underground belt/pipes will no longer give an even number
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_PERCENT = 0.01
|
||||
local MAX_RAND = 100
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local PAIR_NAMES = {
|
||||
['underground-belt'] = true,
|
||||
['fast-underground-belt'] = true,
|
||||
['express-underground-belt'] = true,
|
||||
['pipe-to-ground'] = true,
|
||||
}
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function on_player_crafted_item(event)
|
||||
local name = event.item_stack and event.item_stack.name
|
||||
if not (name and PAIR_NAMES[name]) then
|
||||
-- Invalid item
|
||||
return
|
||||
end
|
||||
|
||||
local index = event.player_index
|
||||
if not index then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(index)
|
||||
if not (player and player.valid) then
|
||||
-- Invalid player
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local extra_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand >= MAX_RAND*(1 - extra_percent) then
|
||||
player.insert({ name = event.item_stack.name, count = 1 })
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Orphan crafting'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_player_crafted_item] = on_player_crafted_item,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
77
map_gen/maps/april_fools/modules/permanent_factory.lua
Normal file
77
map_gen/maps/april_fools/modules/permanent_factory.lua
Normal file
@ -0,0 +1,77 @@
|
||||
-- Any placed entity has a chance to become permanent
|
||||
-- WIP
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_PERCENT = 0.01
|
||||
local MAX_RAND = 100
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function on_built_entity(event)
|
||||
local entity = event.created_entity
|
||||
if not (entity and entity.valid) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local permanent_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand <= MAX_RAND*(1 - permanent_percent) then
|
||||
-- Normal construction
|
||||
return
|
||||
else
|
||||
entity.destructible = false
|
||||
entity.minable = false
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Permanent Structures'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_robot_built_entity] = on_built_entity,
|
||||
[defines.events.on_built_entity] = on_built_entity,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
118
map_gen/maps/april_fools/modules/random_ores.lua
Normal file
118
map_gen/maps/april_fools/modules/random_ores.lua
Normal file
@ -0,0 +1,118 @@
|
||||
-- Each ore tile has 1% chance to mutate into another ore (every patch becomes a mixed ore patch)
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local table = require 'utils.table'
|
||||
|
||||
local BASE_PERCENT = 0.01
|
||||
local MAX_RAND = 100
|
||||
|
||||
local _global = {
|
||||
level = 0, --1 to enabled by defualt
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local ORES = {
|
||||
{'iron-ore', 10},
|
||||
{'copper-ore', 7},
|
||||
{'stone', 5},
|
||||
{'coal', 3},
|
||||
{'uranium-ore', 1},
|
||||
}
|
||||
|
||||
local ALLOWED_DRILLS = {
|
||||
['burner-mining-drill'] = true,
|
||||
['electric-mining-drill'] = true,
|
||||
}
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function on_built_miner(event)
|
||||
local entity = event.created_entity
|
||||
if not (entity and entity.valid and entity.name and ALLOWED_DRILLS[entity.name]) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local radius = entity.prototype.mining_drill_radius
|
||||
|
||||
if not (surface and surface.valid) then
|
||||
-- Invalid surface
|
||||
return
|
||||
end
|
||||
|
||||
local ore_tiles = surface.find_entities_filtered{
|
||||
position = position,
|
||||
radius = radius or 1.5,
|
||||
type = 'resource',
|
||||
}
|
||||
|
||||
for _, ore in pairs(ore_tiles) do
|
||||
if (ore and ore.valid) then
|
||||
local extra_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand >= MAX_RAND*(1 - extra_percent) then
|
||||
local rand_ore = table.get_random_weighted(ORES)
|
||||
|
||||
if (rand_ore ~= ore.name) and surface.get_tile(ore.position.x, ore.position.y).collides_with('ground-tile') then
|
||||
local amount = ore.amount
|
||||
local ore_position = ore.position
|
||||
ore.destroy()
|
||||
surface.create_entity{
|
||||
name = rand_ore,
|
||||
amount = amount,
|
||||
position = ore_position,
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Magic drills'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_robot_built_entity] = on_built_miner,
|
||||
[defines.events.on_built_entity] = on_built_miner,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
83
map_gen/maps/april_fools/modules/rotate_entities.lua
Normal file
83
map_gen/maps/april_fools/modules/rotate_entities.lua
Normal file
@ -0,0 +1,83 @@
|
||||
-- when the player rotates an object it is sometimes rotated to a random direction instead.
|
||||
-- Complete
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local ROTATE_BASE_PERCENT = 0.05
|
||||
local MAX_RAND = 100 * 3
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
local function on_player_rotated_entity(event)
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local rotate_percent = _global.level * ROTATE_BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand <= MAX_RAND*(1 - rotate_percent) then
|
||||
-- No Rotation
|
||||
return
|
||||
elseif rand <= MAX_RAND*(1 - rotate_percent * 2/3) then
|
||||
-- Single Rotation
|
||||
entity.rotate()
|
||||
return
|
||||
elseif rand <= MAX_RAND*(1 - rotate_percent * 1/3) then
|
||||
-- Double Rotation
|
||||
entity.rotate()
|
||||
entity.rotate()
|
||||
return
|
||||
elseif rand <= MAX_RAND then
|
||||
-- Reverse Rotation
|
||||
entity.rotate({reverse = true})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Spinning world'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_player_rotated_entity] = on_player_rotated_entity,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
92
map_gen/maps/april_fools/modules/rotate_inserters.lua
Normal file
92
map_gen/maps/april_fools/modules/rotate_inserters.lua
Normal file
@ -0,0 +1,92 @@
|
||||
-- Inserters are sometimes randomly rotated when placed by player or bots
|
||||
-- Complete
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_PERCENT = 0.05
|
||||
local MAX_RAND = 100 * 3
|
||||
|
||||
local _global = {
|
||||
level = 0,
|
||||
max_level = 10,
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function on_built_inserter(event)
|
||||
local entity = event.created_entity
|
||||
if not (entity and entity.valid) then
|
||||
-- Invalid entity
|
||||
return
|
||||
end
|
||||
|
||||
if not (entity.prototype and entity.prototype.type == 'inserter') then
|
||||
-- Wrong entity type
|
||||
return
|
||||
end
|
||||
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local rotate_percent = _global.level * BASE_PERCENT
|
||||
local rand = math.random(0, MAX_RAND)
|
||||
|
||||
if rand <= MAX_RAND*(1 - rotate_percent) then
|
||||
-- No Rotation
|
||||
return
|
||||
elseif rand <= MAX_RAND*(1 - rotate_percent * 2/3) then
|
||||
-- Single Rotation
|
||||
entity.rotate()
|
||||
return
|
||||
elseif rand <= MAX_RAND*(1 - rotate_percent * 1/3) then
|
||||
-- Double Rotation
|
||||
entity.rotate()
|
||||
entity.rotate()
|
||||
return
|
||||
elseif rand <= MAX_RAND then
|
||||
-- Reverse Rotation
|
||||
entity.rotate({reverse = true})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Dancing inserters'
|
||||
|
||||
Public.events = {
|
||||
[defines.events.on_robot_built_entity] = on_built_inserter,
|
||||
[defines.events.on_built_entity] = on_built_inserter,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
104
map_gen/maps/april_fools/modules/rotten_egg.lua
Normal file
104
map_gen/maps/april_fools/modules/rotten_egg.lua
Normal file
@ -0,0 +1,104 @@
|
||||
-- rotten egg, produces pollution. Similar to golden goose
|
||||
-- SPAWN_INTERVAL and CHANGE_EGGS_INTERVAL should be set to the number of ticks between the event triggering
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_EGGS = 1 -- how many eggs per level
|
||||
local SPAWN_INTERVAL = 60 * 5 -- 5sec
|
||||
local CHANGE_EGGS_INTERVAL = 60 * 101 -- 100sec
|
||||
local DROP_AMOUNT = 1 -- 60/m ~ 6x mining drills
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
rand_eggs = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function clear_eggs()
|
||||
for j=1, #_global.rand_eggs do
|
||||
_global.rand_eggs[j] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function change_eggs()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local num_eggs = _global.level * BASE_EGGS
|
||||
|
||||
for j=1, num_eggs do
|
||||
_global.rand_eggs[j] = nil
|
||||
end
|
||||
|
||||
if #game.connected_players > 0 then
|
||||
for j=1, num_eggs do
|
||||
local player_index = math.random(1, #game.connected_players)
|
||||
_global.rand_eggs[j] = game.connected_players[player_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function eggs_spawn_pollution()
|
||||
if not (_global and _global.rand_eggs and (#_global.rand_eggs > 0)) then
|
||||
-- No eggs
|
||||
return
|
||||
end
|
||||
|
||||
for _, player in pairs(_global.rand_eggs) do
|
||||
if (player and player.valid) then
|
||||
local surface = player.surface
|
||||
local position = player.position
|
||||
local amount = (_global.level or 1) * DROP_AMOUNT
|
||||
-- must be extra cautious with surface & players as they may be teleported across temporary surfaces
|
||||
if (surface and surface.valid and position) then
|
||||
surface.pollute(position, amount)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Rotten egg'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_EGGS_INTERVAL] = change_eggs,
|
||||
[SPAWN_INTERVAL] = eggs_spawn_pollution,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.rand_eggs[_global.level] = nil
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
clear_eggs()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
clear_eggs()
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
95
map_gen/maps/april_fools/modules/unorganized_recipes.lua
Normal file
95
map_gen/maps/april_fools/modules/unorganized_recipes.lua
Normal file
@ -0,0 +1,95 @@
|
||||
-- hides recipe groups from random players. If a player is targeted again, it will revert back to normal
|
||||
-- only works with vanilla item-groups.
|
||||
-- in future possible change to on_init to populate item_groups with all detected item groups?
|
||||
-- WIP
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local BASE_TARGETS = 1 -- how many targets per level
|
||||
local CHANGE_TARGET_INTERVAL = _DEBUG and 60 * 10 or 60 * 180 -- 180sec
|
||||
|
||||
local _global = {
|
||||
level = 0, -- 1 to enabled by defualt
|
||||
max_level = 10,
|
||||
rand_targets = {},
|
||||
}
|
||||
|
||||
Global.register(_global, function(tbl) _global = tbl end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local function clear_targets()
|
||||
for j=1, #_global.rand_targets do
|
||||
_global.rand_targets[j] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function change_targets()
|
||||
if not (_global and _global.level > 0) then
|
||||
-- Level not enabled
|
||||
return
|
||||
end
|
||||
|
||||
local num_targets = math.min(#game.connected_players, _global.level * BASE_TARGETS)
|
||||
|
||||
if #game.connected_players > 0 then
|
||||
for j=1, num_targets do
|
||||
local player_index = math.random(1, #game.connected_players)
|
||||
local duplicate = false
|
||||
--check that randomly selected player is not in old list
|
||||
for k=1, #_global.rand_targets do
|
||||
if game.connected_players[player_index].name == _global.rand_targets[k].name then
|
||||
duplicate = true -- target was previously targeted, so enable them and take them off the list
|
||||
_global.rand_targets[k].enable_recipe_groups()
|
||||
_global.rand_targets[k].enable_recipe_subgroups()
|
||||
_global.rand_targets[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if duplicate == false then -- this is a new target
|
||||
_global.rand_targets[j] = game.connected_players[player_index]
|
||||
_global.rand_targets[j].disable_recipe_groups()
|
||||
_global.rand_targets[j].disable_recipe_subgroups()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
local Public = {}
|
||||
|
||||
Public.name = 'Unorganized Recipes'
|
||||
|
||||
Public.on_nth_tick = {
|
||||
[CHANGE_TARGET_INTERVAL] = change_targets,
|
||||
}
|
||||
|
||||
Public.level_increase = function()
|
||||
_global.level = math.min(_global.level + 1, _global.max_level)
|
||||
end
|
||||
|
||||
Public.level_decrease = function()
|
||||
_global.rand_targets[_global.level] = nil
|
||||
_global.level = math.max(_global.level - 1, 0)
|
||||
end
|
||||
|
||||
Public.level_reset = function()
|
||||
clear_targets()
|
||||
_global.level = 0
|
||||
end
|
||||
|
||||
Public.level_set = function(val)
|
||||
clear_targets()
|
||||
_global.level = val
|
||||
end
|
||||
|
||||
Public.level_get = function()
|
||||
return _global.level
|
||||
end
|
||||
|
||||
Public.max_get = function()
|
||||
return _global.max_level
|
||||
end
|
||||
|
||||
return Public
|
215
map_gen/maps/april_fools/scenario/camera.lua
Normal file
215
map_gen/maps/april_fools/scenario/camera.lua
Normal file
@ -0,0 +1,215 @@
|
||||
-- from features/gui/camera
|
||||
-- edited to support "opposite surface"
|
||||
local Event = require 'utils.event'
|
||||
local mod_gui = require 'mod-gui'
|
||||
local Gui = require 'utils.gui'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local main_button_name = Gui.uid_name()
|
||||
|
||||
local camera_users = {}
|
||||
Global.register({ camera_users = camera_users }, function(tbl)
|
||||
camera_users = tbl.camera_users
|
||||
end)
|
||||
|
||||
local camera_prototype = 'camera'
|
||||
local zoomlevels = { 1.00, 0.75, 0.50, 0.40, 0.30, 0.25, 0.20, 0.15, 0.10, 0.05 }
|
||||
local zoomlevellabels = { '100%', '75%', '50%', '40%', '30%', '25%', '20%', '15%', '10%', '5%' }
|
||||
local sizelevels = { 0, 100, 200, 250, 300, 350, 400, 450, 500 }
|
||||
local sizelevellabels = { 'hide', '100x100', '200x200', '250x250', '300x300', '350x350', '400x400', '450x450', '500x500' }
|
||||
|
||||
---@param surface SurfaceIdentification union LuaSurface|string
|
||||
local function get_opposite_surface(surface)
|
||||
local src = game.get_surface(type(surface) == 'table' and surface.name or surface)
|
||||
local mines = game.get_surface('mines')
|
||||
local islands = game.get_surface('islands')
|
||||
|
||||
if not islands or not mines or not src then
|
||||
return
|
||||
end
|
||||
|
||||
if src.name == mines.name then
|
||||
return islands
|
||||
end
|
||||
if src.name == islands.name then
|
||||
return mines
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
--- Takes args and a LuaPlayer and creates a camera GUI element
|
||||
local function create_camera(args, player)
|
||||
local player_index = player.index
|
||||
local mainframeflow = mod_gui.get_frame_flow(player)
|
||||
local mainframeid = 'mainframe_' .. player_index
|
||||
local mainframe = mainframeflow[mainframeid]
|
||||
|
||||
local target = game.get_player(args.target)
|
||||
if not target then
|
||||
player.print('Not a valid target')
|
||||
return
|
||||
end
|
||||
|
||||
if not mainframe then
|
||||
mainframe = mainframeflow.add { type = 'frame', name = mainframeid, direction = 'vertical', style = 'captionless_frame' }
|
||||
mainframe.visible = true
|
||||
player.set_shortcut_toggled(camera_prototype, true)
|
||||
end
|
||||
|
||||
local headerframe = mainframe.headerframe
|
||||
if not headerframe then
|
||||
mainframe.add { type = 'frame', name = 'headerframe', direction = 'horizontal', style = 'captionless_frame' }
|
||||
end
|
||||
|
||||
local cameraframe = mainframe.cameraframe
|
||||
if not cameraframe then
|
||||
mainframe.add { type = 'frame', name = 'cameraframe', style = 'captionless_frame' }
|
||||
end
|
||||
|
||||
mainframe.add { type = 'label', caption = 'Following: ' .. target.name .. '\'s steps on other surface' }
|
||||
Gui.make_close_button(mainframe, main_button_name)
|
||||
local target_index = target.index
|
||||
camera_users[player_index] = target_index
|
||||
end
|
||||
|
||||
--- Takes table with a LuaPlayer under key player and destroys the camera of the associated player
|
||||
local function destroy_camera(data)
|
||||
local player = data.player
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local player_index = player.index
|
||||
local mainframeflow = mod_gui.get_frame_flow(player)
|
||||
local mainframeid = 'mainframe_' .. player_index
|
||||
local mainframe = mainframeflow[mainframeid]
|
||||
|
||||
if mainframe then
|
||||
mainframe.destroy()
|
||||
player.set_shortcut_toggled(camera_prototype, false)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--- Destroys existing camera and, if applicable, creates a new one for the new target.
|
||||
local function camera_command(args, player)
|
||||
destroy_camera({ player = player })
|
||||
-- Once the old camera is destroyed, check to see if we need to make a new one
|
||||
if global.config.camera_disabled then
|
||||
player.print('The watch/camera function has been disabled for performance reasons.')
|
||||
return
|
||||
end
|
||||
if args and args.target and player then
|
||||
create_camera(args, player)
|
||||
end
|
||||
end
|
||||
|
||||
local function update_camera_render(target, targetframe, zoom, size, visible)
|
||||
local position = { x = target.position.x, y = target.position.y - 0.5 }
|
||||
local surface_index = target.surface.index
|
||||
local preview_size = size
|
||||
local camera = targetframe.camera
|
||||
|
||||
if not camera then
|
||||
camera = targetframe.add { type = 'camera', name = 'camera', position = position, surface_index = surface_index, zoom = zoom }
|
||||
end
|
||||
|
||||
camera.position = position
|
||||
camera.surface_index = get_opposite_surface(surface_index).index
|
||||
camera.zoom = zoom
|
||||
camera.visible = visible
|
||||
camera.style.minimal_width = preview_size
|
||||
camera.style.minimal_height = preview_size
|
||||
camera.style.maximal_width = preview_size
|
||||
camera.style.maximal_height = preview_size
|
||||
end
|
||||
|
||||
local function update_camera_zoom(targetframe)
|
||||
local zoomselection = targetframe.zoomselection
|
||||
local zoomlabels = {}
|
||||
|
||||
for i = 1, #zoomlevellabels do
|
||||
zoomlabels[i] = { '', '' .. zoomlevellabels[i] }
|
||||
end
|
||||
if zoomselection then
|
||||
zoomselection.items = zoomlabels
|
||||
else
|
||||
zoomselection = targetframe.add { type = 'drop-down', name = 'zoomselection', items = zoomlabels, selected_index = 3 }
|
||||
end
|
||||
|
||||
local zoom = zoomlevels[zoomselection.selected_index]
|
||||
return zoom
|
||||
end
|
||||
|
||||
local function update_camera_size(targetframe)
|
||||
local sizeselection = targetframe.sizeselection
|
||||
local sizelabels = {}
|
||||
|
||||
for i = 1, #sizelevellabels do
|
||||
sizelabels[i] = { '', '' .. sizelevellabels[i] }
|
||||
end
|
||||
if sizeselection then
|
||||
sizeselection.items = sizelabels
|
||||
else
|
||||
sizeselection = targetframe.add { type = 'drop-down', name = 'sizeselection', items = sizelabels, selected_index = 4 }
|
||||
end
|
||||
|
||||
local size = sizelevels[sizeselection.selected_index]
|
||||
local visible = (size ~= 0)
|
||||
return size, visible
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if global.config.camera_disabled then
|
||||
return
|
||||
end
|
||||
for table_key, camera_table in pairs(camera_users) do
|
||||
local player = game.get_player(table_key)
|
||||
local target = game.get_player(camera_table)
|
||||
if not target.connected then
|
||||
destroy_camera({ player = player })
|
||||
player.print('Target is offline, camera closed')
|
||||
camera_users[player.index] = nil
|
||||
return
|
||||
end
|
||||
local mainframeflow = mod_gui.get_frame_flow(player)
|
||||
local mainframeid = 'mainframe_' .. table_key
|
||||
local mainframe = mainframeflow[mainframeid]
|
||||
if mainframe then
|
||||
local headerframe = mainframe.headerframe
|
||||
local cameraframe = mainframe.cameraframe
|
||||
local zoom = update_camera_zoom(headerframe)
|
||||
local size, visible = update_camera_size(headerframe)
|
||||
update_camera_render(target, cameraframe, zoom, size, visible)
|
||||
player.set_shortcut_toggled(camera_prototype, visible)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_lua_shortcut(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local shortcut = event.prototype_name or event.input_name
|
||||
if shortcut ~= camera_prototype then
|
||||
return
|
||||
end
|
||||
|
||||
local toggled = player.is_shortcut_toggled(camera_prototype)
|
||||
player.set_shortcut_toggled(camera_prototype, not toggled)
|
||||
|
||||
if toggled then
|
||||
destroy_camera({ player = player })
|
||||
else
|
||||
camera_command({ target = player.name }, player)
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_nth_tick(61, on_tick)
|
||||
Gui.on_click(main_button_name, destroy_camera)
|
||||
|
||||
Event.add(defines.events.on_lua_shortcut, on_lua_shortcut)
|
||||
-- luacheck: ignore script
|
||||
script.on_event(camera_prototype, on_lua_shortcut)
|
51
map_gen/maps/april_fools/scenario/entity-restrictions.lua
Normal file
51
map_gen/maps/april_fools/scenario/entity-restrictions.lua
Normal file
@ -0,0 +1,51 @@
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local alert_message = '[color=yellow]Cannot build here![/color]'
|
||||
local banned_per_surface = {
|
||||
islands = {
|
||||
['furnace'] = true,
|
||||
},
|
||||
mines = {
|
||||
['assembling-machine'] = true,
|
||||
['solar-panel'] = true,
|
||||
['rocket-silo'] = true,
|
||||
}
|
||||
}
|
||||
|
||||
local function on_built(event)
|
||||
local entity = event.created_entity
|
||||
if not (entity and entity.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = entity.surface.name
|
||||
local entity_type = entity.prototype.type
|
||||
if not (banned_per_surface[surface] and banned_per_surface[surface][entity_type]) then
|
||||
return
|
||||
end
|
||||
|
||||
local ghost = false
|
||||
if entity.name == 'entity-ghost' then
|
||||
ghost = true
|
||||
end
|
||||
|
||||
entity.destroy()
|
||||
|
||||
local stack = event.stack
|
||||
local player = game.get_player(event.player_index or 'none')
|
||||
local robot = event.robot
|
||||
if player and player.valid and not ghost and stack.valid then
|
||||
if player.can_insert(stack) then
|
||||
player.insert(stack)
|
||||
player.print(alert_message)
|
||||
end
|
||||
elseif robot and robot.valid and not ghost and stack.valid then
|
||||
-- FIXME: currenlty not refunding anything when using robots...
|
||||
if robot.can_insert(stack) then
|
||||
robot.insert(stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_built_entity, on_built)
|
||||
Event.add(defines.events.on_robot_built_entity, on_built)
|
22
map_gen/maps/april_fools/scenario/evolution_control.lua
Normal file
22
map_gen/maps/april_fools/scenario/evolution_control.lua
Normal file
@ -0,0 +1,22 @@
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local relations = {
|
||||
['logistic-science-pack'] = 10,
|
||||
['military-science-pack'] = 20,
|
||||
['chemical-science-pack'] = 40,
|
||||
['production-science-pack'] = 50,
|
||||
['utility-science-pack'] = 90,
|
||||
}
|
||||
|
||||
Event.on_nth_tick(103, function()
|
||||
local max = 0
|
||||
local tech = game.forces.player.technologies
|
||||
for name, evo in pairs(relations) do
|
||||
if tech[name] and tech[name].researched then
|
||||
max = math.max(max, evo)
|
||||
end
|
||||
end
|
||||
if game.forces.enemy.evolution_factor > 10 and max > 2 then
|
||||
game.forces.enemy.evolution_factor = math.min(game.forces.enemy.evolution_factor, max - 1)
|
||||
end
|
||||
end)
|
312
map_gen/maps/april_fools/scenario/market.lua
Normal file
312
map_gen/maps/april_fools/scenario/market.lua
Normal file
@ -0,0 +1,312 @@
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local Global = require 'utils.global'
|
||||
local Retailer = require 'features.retailer'
|
||||
local market_items = require 'map_gen.maps.april_fools.scenario.market_items'
|
||||
local fish_market_bonus_message = require 'resources.fish_messages'
|
||||
local ScoreTracker = require 'utils.score_tracker'
|
||||
local Color = require 'resources.color_presets'
|
||||
local change_for_player = ScoreTracker.change_for_player
|
||||
local get_for_player = ScoreTracker.get_for_player
|
||||
local coins_earned_name = 'coins-earned'
|
||||
|
||||
-- localized functions
|
||||
local pairs = pairs
|
||||
local round = math.round
|
||||
local random = math.random
|
||||
local format = string.format
|
||||
local market_config = global.config.market
|
||||
local currency = market_config.currency
|
||||
local entity_drop_amount = market_config.entity_drop_amount
|
||||
local max_coins_earned = 5
|
||||
|
||||
-- local vars
|
||||
|
||||
local nth_tick_token
|
||||
local running_speed_boost_messages = {
|
||||
'%s found the lost Dragon Scroll and got a lv.1 speed boost!',
|
||||
'Guided by Master Oogway, %s got a lv.2 speed boost!',
|
||||
'Kung Fu Master %s defended the village and was awarded a lv.3 speed boost!',
|
||||
'Travelled at the speed of light. %s saw a black hole. Oops.',
|
||||
}
|
||||
|
||||
local mining_speed_boost_messages = {
|
||||
'%s is going on a tree harvest!',
|
||||
'In search of a sharper axe, %s got a lv.2 mining boost!',
|
||||
'Wood fiend, %s, has picked up a massive chain saw and is awarded a lv.3 mining boost!',
|
||||
'Better learn to control that saw, %s, chopped off their legs. Oops.',
|
||||
}
|
||||
|
||||
-- Global registered local vars
|
||||
local primitives = { event_registered = nil }
|
||||
local markets = {}
|
||||
local speed_records = {}
|
||||
local mining_records = {}
|
||||
|
||||
Global.register({ markets = markets, speed_records = speed_records, mining_records = mining_records, primitives = primitives }, function(tbl)
|
||||
markets = tbl.markets
|
||||
speed_records = tbl.speed_records
|
||||
mining_records = tbl.mining_records
|
||||
primitives = tbl.primitives
|
||||
end)
|
||||
|
||||
-- local functions
|
||||
|
||||
local function register_event()
|
||||
if not primitives.event_registered then
|
||||
Event.add_removable_nth_tick(907, nth_tick_token)
|
||||
primitives.event_registered = true
|
||||
end
|
||||
end
|
||||
|
||||
local function unregister_event()
|
||||
if primitives.event_registered then
|
||||
Event.remove_removable_nth_tick(907, nth_tick_token)
|
||||
primitives.event_registered = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_market(args, player)
|
||||
if args and args.removeall == 'removeall' then
|
||||
local count = 0
|
||||
for _, market in pairs(markets) do
|
||||
if market.valid then
|
||||
count = count + 1
|
||||
market.destroy()
|
||||
end
|
||||
end
|
||||
player.print(count .. ' markets removed')
|
||||
return
|
||||
end
|
||||
local surface = game.get_surface('mines')
|
||||
local force = game.forces.player
|
||||
local maket_spawn_pos = market_config.standard_market_location
|
||||
|
||||
if args and args.surface then
|
||||
surface = game.get_surface(type(args.surface) == 'table' and args.surface.name or args.surface)
|
||||
end
|
||||
|
||||
if player then -- If we have a player, this is coming from a player running the command
|
||||
surface = player.surface
|
||||
force = player.force
|
||||
maket_spawn_pos = player.position
|
||||
maket_spawn_pos.y = round(maket_spawn_pos.y - 4)
|
||||
maket_spawn_pos.x = round(maket_spawn_pos.x)
|
||||
player.print('Market added. To remove it, highlight it with your cursor and use the /destroy command, or use /market removeall to remove all markets placed.')
|
||||
end
|
||||
|
||||
local market = surface.create_entity({ name = 'market', position = maket_spawn_pos, force = 'neutral' })
|
||||
markets[#markets + 1] = market
|
||||
market.destructible = false
|
||||
|
||||
Retailer.add_market('fish_market', market)
|
||||
|
||||
if table.size(Retailer.get_items('fish_market')) == 0 then
|
||||
for _, prototype in pairs(market_items) do
|
||||
Retailer.set_item('fish_market', prototype)
|
||||
end
|
||||
end
|
||||
|
||||
force.add_chart_tag(surface, { icon = { type = 'item', name = currency }, position = maket_spawn_pos, text = 'Market' })
|
||||
end
|
||||
|
||||
local function fish_earned(event, amount)
|
||||
amount = math.random(math.min(amount, max_coins_earned))
|
||||
local player_index = event.player_index
|
||||
local player = game.get_player(player_index)
|
||||
|
||||
local stack = { name = currency, count = amount }
|
||||
local inserted = player.insert(stack)
|
||||
if amount > 0 then
|
||||
player.surface.create_entity {
|
||||
name = 'flying-text',
|
||||
position = { player.position.x - 1, player.position.y },
|
||||
text = '+' .. amount .. ' [img=item.coin]',
|
||||
color = Color.gold,
|
||||
render_player_index = player.index,
|
||||
}
|
||||
end
|
||||
|
||||
local diff = amount - inserted
|
||||
if diff > 0 then
|
||||
stack.count = diff
|
||||
player.surface.spill_item_stack(player.position, stack, true)
|
||||
end
|
||||
|
||||
change_for_player(player_index, coins_earned_name, amount)
|
||||
if get_for_player(player_index, coins_earned_name) % 70 == 0 and player and player.valid then
|
||||
local message = fish_market_bonus_message[random(#fish_market_bonus_message)]
|
||||
player.print(message)
|
||||
end
|
||||
end
|
||||
|
||||
local function pre_player_mined_item(event)
|
||||
local type = event.entity.type
|
||||
if type == 'simple-entity' then -- Cheap check for rock, may have other side effects
|
||||
fish_earned(event, 10)
|
||||
return
|
||||
end
|
||||
|
||||
if type == 'tree' and random(1, 4) == 1 then
|
||||
fish_earned(event, 4)
|
||||
end
|
||||
end
|
||||
|
||||
local spill_items = Token.register(function(data)
|
||||
data.surface.spill_item_stack(data.position, { name = currency, count = data.count }, true)
|
||||
end)
|
||||
|
||||
-- Determines how many coins to drop when enemy entity dies based upon the entity_drop_amount table in config.lua
|
||||
local function fish_drop_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local bounds = entity_drop_amount[entity.name]
|
||||
if not bounds then
|
||||
return
|
||||
end
|
||||
|
||||
local chance = bounds.chance
|
||||
|
||||
if chance == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if chance == 1 or random() <= chance then
|
||||
local count = random(bounds.low, bounds.high)
|
||||
if count > 0 then
|
||||
Task.set_timeout_in_ticks(1, spill_items, { count = count, surface = entity.surface, position = entity.position })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function reset_player_running_speed(player)
|
||||
local index = player.index
|
||||
player.character_running_speed_modifier = speed_records[index].pre_boost_modifier
|
||||
speed_records[index] = nil
|
||||
end
|
||||
|
||||
local function reset_player_mining_speed(player)
|
||||
local index = player.index
|
||||
player.character_mining_speed_modifier = mining_records[index].pre_mining_boost_modifier
|
||||
mining_records[index] = nil
|
||||
end
|
||||
|
||||
local function boost_player_running_speed(player)
|
||||
local index = player.index
|
||||
local p_name = player.name
|
||||
if not speed_records[index] then
|
||||
speed_records[index] = { start_tick = game.tick, pre_boost_modifier = player.character_running_speed_modifier, boost_lvl = 0 }
|
||||
end
|
||||
speed_records[index].boost_lvl = 1 + speed_records[index].boost_lvl
|
||||
|
||||
player.character_running_speed_modifier = 1 + player.character_running_speed_modifier
|
||||
|
||||
if speed_records[index].boost_lvl >= 4 then
|
||||
game.print(format(running_speed_boost_messages[speed_records[index].boost_lvl], p_name))
|
||||
reset_player_running_speed(player)
|
||||
player.character.die(player.force, player.character)
|
||||
return
|
||||
end
|
||||
|
||||
player.print(format(running_speed_boost_messages[speed_records[index].boost_lvl], p_name))
|
||||
register_event()
|
||||
end
|
||||
|
||||
local function boost_player_mining_speed(player)
|
||||
local index = player.index
|
||||
local p_name = player.name
|
||||
if not mining_records[index] then
|
||||
mining_records[index] = { start_tick = game.tick, pre_mining_boost_modifier = player.character_mining_speed_modifier, boost_lvl = 0 }
|
||||
end
|
||||
mining_records[index].boost_lvl = 1 + mining_records[index].boost_lvl
|
||||
|
||||
player.character_mining_speed_modifier = 1 + player.character_mining_speed_modifier
|
||||
|
||||
if mining_records[index].boost_lvl >= 4 then
|
||||
game.print(format(mining_speed_boost_messages[mining_records[index].boost_lvl], p_name))
|
||||
reset_player_mining_speed(player)
|
||||
player.character.die(player.force, player.character)
|
||||
return
|
||||
end
|
||||
|
||||
player.print(format(mining_speed_boost_messages[mining_records[index].boost_lvl], p_name))
|
||||
register_event()
|
||||
end
|
||||
|
||||
local function market_item_purchased(event)
|
||||
local item_name = event.item.name
|
||||
if item_name == 'temporary-running-speed-bonus' then
|
||||
boost_player_running_speed(event.player)
|
||||
return
|
||||
end
|
||||
|
||||
if item_name == 'temporary-mining-speed-bonus' then
|
||||
boost_player_mining_speed(event.player)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
nth_tick_token = Token.register(function()
|
||||
local tick = game.tick
|
||||
for k, v in pairs(speed_records) do
|
||||
if tick - v.start_tick > 3000 then
|
||||
local player = game.get_player(k)
|
||||
if player and player.valid and player.connected and player.character then
|
||||
reset_player_running_speed(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(mining_records) do
|
||||
if tick - v.start_tick > 6000 then
|
||||
local player = game.get_player(k)
|
||||
if player and player.valid and player.connected and player.character then
|
||||
reset_player_mining_speed(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not next(speed_records) and not next(mining_records) then
|
||||
unregister_event()
|
||||
end
|
||||
end)
|
||||
|
||||
local function fish_player_crafted_item(event)
|
||||
if random(1, 50) == 1 then
|
||||
fish_earned(event, 1)
|
||||
end
|
||||
end
|
||||
|
||||
local function player_created(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local count = global.config.player_rewards.info_player_reward and 1 or 10
|
||||
player.insert { name = currency, count = count }
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_pre_player_mined_item, pre_player_mined_item)
|
||||
Event.add(defines.events.on_entity_died, fish_drop_entity_died)
|
||||
Event.add(Retailer.events.on_market_purchase, market_item_purchased)
|
||||
Event.add(defines.events.on_player_crafted_item, fish_player_crafted_item)
|
||||
Event.add(defines.events.on_player_created, player_created)
|
||||
|
||||
if market_config.create_standard_market then
|
||||
local delay = market_config.delay or 30
|
||||
if delay then
|
||||
local spawn_market_token = Token.register(spawn_market)
|
||||
Event.on_init(function()
|
||||
Task.set_timeout_in_ticks(delay, spawn_market_token)
|
||||
end)
|
||||
else
|
||||
Event.on_init(spawn_market)
|
||||
end
|
||||
end
|
66
map_gen/maps/april_fools/scenario/market_items.lua
Normal file
66
map_gen/maps/april_fools/scenario/market_items.lua
Normal file
@ -0,0 +1,66 @@
|
||||
return {
|
||||
{
|
||||
name = 'temporary-running-speed-bonus',
|
||||
name_label = {'market_items.running_speed_bonus_name_label'},
|
||||
type = 'temporary-buff',
|
||||
description = {'market_items.running_speed_bonus_description'},
|
||||
sprite = 'technology/exoskeleton-equipment',
|
||||
stack_limit = 1,
|
||||
price = 10,
|
||||
},
|
||||
{
|
||||
name = 'temporary-mining-speed-bonus',
|
||||
name_label = {'market_items.mining_speed_bonus_name_label'},
|
||||
type = 'temporary-buff',
|
||||
description = {'market_items.mining_speed_bonus_description'},
|
||||
sprite = 'technology/mining-productivity-1',
|
||||
stack_limit = 1,
|
||||
price = 10,
|
||||
},
|
||||
{price = 1, name = 'firearm-magazine'},
|
||||
{price = 1, name = 'land-mine'},
|
||||
{price = 1, name = 'wood'},
|
||||
{price = 2, name = 'rocket'},
|
||||
{price = 2, name = 'shotgun-shell'},
|
||||
{price = 3, name = 'cannon-shell'},
|
||||
{price = 4, name = 'defender-capsule'},
|
||||
{price = 4, name = 'piercing-rounds-magazine'},
|
||||
{price = 5, name = 'raw-fish'},
|
||||
{price = 6, name = 'piercing-shotgun-shell'},
|
||||
{price = 7, name = 'explosive-cannon-shell'},
|
||||
{price = 7, name = 'explosive-rocket'},
|
||||
{price = 8, name = 'grenade'},
|
||||
{price = 10, name = 'artillery-shell'},
|
||||
{price = 10, name = 'light-armor'},
|
||||
{price = 25, name = 'artillery-targeting-remote'},
|
||||
{price = 25, name = 'cliff-explosives'},
|
||||
{price = 25, name = 'flamethrower-ammo'},
|
||||
{price = 30, name = 'submachine-gun'},
|
||||
{price = 32, name = 'cluster-grenade'},
|
||||
{price = 35, name = 'construction-robot'},
|
||||
{price = 40, name = 'poison-capsule'},
|
||||
{price = 50, name = 'gun-turret'},
|
||||
{price = 50, name = 'solar-panel-equipment'},
|
||||
{price = 80, name = 'car'},
|
||||
{price = 100, name = 'battery-equipment'},
|
||||
{price = 125, name = 'heavy-armor'},
|
||||
{price = 125, name = 'night-vision-equipment'},
|
||||
{price = 125, name = 'rocket-launcher'},
|
||||
{price = 175, name = 'exoskeleton-equipment'},
|
||||
{price = 200, name = 'belt-immunity-equipment'},
|
||||
{price = 200, name = 'energy-shield-equipment'},
|
||||
{price = 250, name = 'combat-shotgun'},
|
||||
{price = 250, name = 'personal-roboport-equipment'},
|
||||
{price = 300, name = 'laser-turret'},
|
||||
{price = 350, name = 'modular-armor'},
|
||||
{price = 450, name = 'artillery-turret'},
|
||||
{price = 450, name = 'flamethrower'},
|
||||
{price = 625, name = 'battery-mk2-equipment'},
|
||||
{price = 850, name = 'personal-laser-defense-equipment'},
|
||||
{price = 1000, name = 'tunnel'},
|
||||
{price = 1200, name = 'tank'},
|
||||
{price = 1500, name = 'power-armor'},
|
||||
{price = 2250, name = 'fusion-reactor-equipment'},
|
||||
{price = 7500, name = 'atomic-bomb'},
|
||||
{price = 12000, name = 'power-armor-mk2'},
|
||||
}
|
159
map_gen/maps/april_fools/scenario/mines.lua
Normal file
159
map_gen/maps/april_fools/scenario/mines.lua
Normal file
@ -0,0 +1,159 @@
|
||||
local Event = require 'utils.event'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local AlienEvolutionProgress = require 'utils.alien_evolution_progress'
|
||||
|
||||
local rock_list = {
|
||||
'rock-huge-volcanic',
|
||||
'rock-big-volcanic',
|
||||
'rock-huge-black',
|
||||
'rock-big-black',
|
||||
'rock-huge-grey',
|
||||
'rock-big-grey',
|
||||
'rock-huge-red',
|
||||
'rock-big-red',
|
||||
'rock-huge-white',
|
||||
'rock-big-white',
|
||||
'rock-huge-brown',
|
||||
'rock-big-brown',
|
||||
'rock-huge-dustyrose',
|
||||
'rock-big-dustyrose',
|
||||
}
|
||||
local rocks = #rock_list
|
||||
local rock_map = util.list_to_map(rock_list)
|
||||
|
||||
-- == MAP GEN =================================================================
|
||||
|
||||
local starting_radius = 64
|
||||
local biter_radius = 144
|
||||
local PRECISION = 10e8
|
||||
|
||||
local function inside_radius(x, y, radius)
|
||||
return x*x + y*y < radius*radius + 3600 * Perlin.noise(x, y)
|
||||
end
|
||||
|
||||
local function worm_by_distance(x, y)
|
||||
local evo = game.forces.enemy.evolution_factor or 0
|
||||
local radius = math.sqrt(x*x + y*y)
|
||||
local weighted_distance = radius * (evo + 0.45)
|
||||
|
||||
if weighted_distance < 1000 then
|
||||
return 'small-worm-turret'
|
||||
elseif weighted_distance < 1800 then
|
||||
return 'medium-worm-turret'
|
||||
elseif weighted_distance < 2600 then
|
||||
return 'big-worm-turret'
|
||||
else
|
||||
return 'behemoth-worm-turret'
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_chunk_generated, function(event)
|
||||
local surface = event.surface
|
||||
if not (surface and surface.valid and surface.name == 'mines') then
|
||||
return
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
|
||||
-- remove water
|
||||
local tiles = surface.find_tiles_filtered { area = area, name = { 'deepwater', 'deepwater-green', 'water', 'water-green', 'water-mud', 'water-shallow' } }
|
||||
local new_tiles = {}
|
||||
for _, tile in pairs(tiles) do
|
||||
table.insert(new_tiles, { name = 'volcanic-orange-heat-4', position = tile.position })
|
||||
end
|
||||
surface.set_tiles(new_tiles)
|
||||
|
||||
-- place rocks
|
||||
local tx, ty = area.left_top.x, area.left_top.y
|
||||
local bx, by = area.right_bottom.x, area.right_bottom.y
|
||||
for x = tx, bx do
|
||||
for y = ty, by do
|
||||
local c = math.random(PRECISION)
|
||||
if not inside_radius(x, y, starting_radius) and c > (0.55 * PRECISION) then
|
||||
surface.create_entity { name = rock_list[math.random(rocks)], position = { x, y }, raise_built = false, move_stuck_players = true, force = 'neutral'}
|
||||
else
|
||||
if not inside_radius(x, y, biter_radius) and c < (0.000125 * PRECISION) then
|
||||
surface.create_entity { name = worm_by_distance(x, y), position = {x, y}, move_stuck_players = true }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- == SPAWNERS ================================================================
|
||||
|
||||
Event.add(defines.events.on_player_mined_entity, function(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
local entity = event.entity
|
||||
if not (entity and entity.valid) then
|
||||
return
|
||||
end
|
||||
|
||||
if not rock_map[entity.name] then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = entity.position
|
||||
|
||||
local c = math.random(PRECISION)
|
||||
if c < (0.005 * PRECISION) and not inside_radius(pos.x, pos.y, biter_radius) then
|
||||
entity.surface.create_entity {
|
||||
name = math.random() > 0.40 and 'biter-spawner' or 'spitter-spawner',
|
||||
position = entity.position,
|
||||
force = 'enemy',
|
||||
target = player.character,
|
||||
move_stuck_players = true,
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
local function give_command(group, target)
|
||||
if target and target.valid then
|
||||
local command = { type = defines.command.attack, target = target, distraction = defines.distraction.by_damage }
|
||||
group.set_command(command)
|
||||
group.start_moving()
|
||||
else
|
||||
local command = { type = defines.command.attack_area, destination = {0, 0}, radius = 32, distraction = defines.distraction.by_damage }
|
||||
|
||||
local members = group.members
|
||||
for i = 1, #members do
|
||||
local entitiy = members[i]
|
||||
entitiy.set_command(command)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_died, function(event)
|
||||
local entity = event.entity
|
||||
if not entity or not (entity.name == 'biter-spawner' or entity.name == 'spitter-spawner') then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local spawn = entity.surface.create_entity
|
||||
local evo = game.forces.enemy.evolution_factor
|
||||
|
||||
local spawner = AlienEvolutionProgress.create_spawner_request(math.ceil(evo * 100 / 4))
|
||||
local aliens = AlienEvolutionProgress.get_aliens(spawner, evo)
|
||||
|
||||
local group = surface.create_unit_group { position = position }
|
||||
local add_member = group.add_member
|
||||
|
||||
for name, count in pairs(aliens) do
|
||||
for i = 1, count do
|
||||
local ent = spawn{ name = name, position = position, force = 'enemy', move_stuck_players = true, }
|
||||
if ent then
|
||||
add_member(ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
give_command(group, event.cause)
|
||||
end)
|
||||
|
||||
-- ============================================================================
|
194
map_gen/maps/april_fools/scenario/restart_command.lua
Normal file
194
map_gen/maps/april_fools/scenario/restart_command.lua
Normal file
@ -0,0 +1,194 @@
|
||||
local Discord = require 'resources.discord'
|
||||
local Server = require 'features.server'
|
||||
local Core = require 'utils.core'
|
||||
local Restart = require 'features.restart_command'
|
||||
local ShareGlobals = require 'map_gen.maps.april_fools.scenario.shared_globals'
|
||||
local ScoreTracker = require 'utils.score_tracker'
|
||||
local PlayerStats = require 'features.player_stats'
|
||||
local format_number = require 'util'.format_number
|
||||
|
||||
return function(config)
|
||||
local map_promotion_channel = Discord.channel_names.map_promotion
|
||||
local events_channel = Discord.channel_names.events
|
||||
local map_update_role_mention = Discord.role_mentions.map_update
|
||||
-- Use these settings for testing
|
||||
--local map_promotion_channel = Discord.channel_names.bot_playground
|
||||
--local events_channel = Discord.channel_names.bot_playground
|
||||
--local map_update_role_mention = Discord.role_mentions.test
|
||||
|
||||
Restart.set_start_game_data({type = Restart.game_types.scenario, name = config.scenario_name or 'April Fools', mod_pack = config.mod_pack})
|
||||
|
||||
local function can_restart(player)
|
||||
if player.admin then
|
||||
return true
|
||||
end
|
||||
|
||||
if not ShareGlobals.data.map_won then
|
||||
player.print({'command_description.danger_ore_restart_condition_not_met'})
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function restart_callback()
|
||||
local start_game_data = Restart.get_start_game_data()
|
||||
local new_map_name = start_game_data.name
|
||||
|
||||
local time_string = Core.format_time(game.ticks_played)
|
||||
|
||||
local end_epoch = Server.get_current_time()
|
||||
if end_epoch == nil then
|
||||
end_epoch = -1 -- end_epoch is nil if the restart command is used locally rather than on the server
|
||||
end
|
||||
|
||||
local player_data = {}
|
||||
for _, p in pairs(game.players) do
|
||||
player_data[p.index] = {
|
||||
name = p.name,
|
||||
total_kills = ScoreTracker.get_for_player(p.index, PlayerStats.player_total_kills_name),
|
||||
spawners_killed = ScoreTracker.get_for_player(p.index, PlayerStats.player_spawners_killed_name),
|
||||
worms_killed = ScoreTracker.get_for_player(p.index, PlayerStats.player_worms_killed_name),
|
||||
units_killed = ScoreTracker.get_for_player(p.index, PlayerStats.player_units_killed_name),
|
||||
turrets_killed = ScoreTracker.get_for_player(p.index, PlayerStats.player_turrets_killed_name),
|
||||
distance_walked = ScoreTracker.get_for_player(p.index, PlayerStats.player_distance_walked_name),
|
||||
player_deaths = ScoreTracker.get_for_player(p.index, PlayerStats.player_deaths_name),
|
||||
entities_built = ScoreTracker.get_for_player(p.index, PlayerStats.player_entities_built_name),
|
||||
entities_crafted = ScoreTracker.get_for_player(p.index, PlayerStats.player_items_crafted_name),
|
||||
resources_hand_mined = ScoreTracker.get_for_player(p.index, PlayerStats.player_resources_hand_mined_name),
|
||||
time_played = p.online_time
|
||||
}
|
||||
end
|
||||
|
||||
local statistics = {
|
||||
scenario = config.scenario_name or 'April Fools',
|
||||
start_epoch = Server.get_start_time(),
|
||||
end_epoch = end_epoch, -- stored as key already, useful to have it as part of same structure
|
||||
game_ticks = game.ticks_played,
|
||||
biters_killed = ScoreTracker.get_for_global(PlayerStats.aliens_killed_name),
|
||||
total_players = #game.players,
|
||||
entities_built = ScoreTracker.get_for_global(PlayerStats.built_by_players_name),
|
||||
resources_exhausted = ScoreTracker.get_for_global(PlayerStats.resources_exhausted_name),
|
||||
resources_hand_mined = ScoreTracker.get_for_global(PlayerStats.resources_hand_mined_name),
|
||||
player_data = player_data
|
||||
}
|
||||
|
||||
local awards = {
|
||||
['total_kills'] = {value = 0, player = ""},
|
||||
['units_killed'] = {value = 0, player = ""},
|
||||
['spawners_killed'] = {value = 0, player = ""},
|
||||
['worms_killed'] = {value = 0, player = ""},
|
||||
['player_deaths'] = {value = 0, player = ""},
|
||||
['time_played'] = {value = 0, player = ""},
|
||||
['entities_built'] = {value = 0, player = ""},
|
||||
['entities_crafted'] = {value = 0, player = ""},
|
||||
['distance_walked'] = {value = 0, player = ""},
|
||||
['resources_hand_mined'] = {value = 0, player = ""}
|
||||
}
|
||||
|
||||
for _, v in pairs(statistics.player_data) do
|
||||
if v.total_kills > awards.total_kills.value then
|
||||
awards.total_kills.value = v.total_kills
|
||||
awards.total_kills.player = v.name
|
||||
end
|
||||
if v.units_killed > awards.units_killed.value then
|
||||
awards.units_killed.value = v.units_killed
|
||||
awards.units_killed.player = v.name
|
||||
end
|
||||
if v.spawners_killed > awards.spawners_killed.value then
|
||||
awards.spawners_killed.value = v.spawners_killed
|
||||
awards.spawners_killed.player = v.name
|
||||
end
|
||||
if v.worms_killed > awards.worms_killed.value then
|
||||
awards.worms_killed.value = v.worms_killed
|
||||
awards.worms_killed.player = v.name
|
||||
end
|
||||
if v.player_deaths > awards.player_deaths.value then
|
||||
awards.player_deaths.value = v.player_deaths
|
||||
awards.player_deaths.player = v.name
|
||||
end
|
||||
if v.time_played > awards.time_played.value then
|
||||
awards.time_played.value = v.time_played
|
||||
awards.time_played.player = v.name
|
||||
end
|
||||
if v.entities_built > awards.entities_built.value then
|
||||
awards.entities_built.value = v.entities_built
|
||||
awards.entities_built.player = v.name
|
||||
end
|
||||
if v.entities_crafted > awards.entities_crafted.value then
|
||||
awards.entities_crafted.value = v.entities_crafted
|
||||
awards.entities_crafted.player = v.name
|
||||
end
|
||||
if v.distance_walked > awards.distance_walked.value then
|
||||
awards.distance_walked.value = v.distance_walked
|
||||
awards.distance_walked.player = v.name
|
||||
end
|
||||
if v.resources_hand_mined > awards.resources_hand_mined.value then
|
||||
awards.resources_hand_mined.value = v.resources_hand_mined
|
||||
awards.resources_hand_mined.player = v.name
|
||||
end
|
||||
end
|
||||
|
||||
local resource_prototypes = game.get_filtered_entity_prototypes({{filter = "type", type = "resource"}})
|
||||
local ore_products = {}
|
||||
for _, ore_prototype in pairs(resource_prototypes) do
|
||||
local mineable_properties = ore_prototype.mineable_properties
|
||||
if mineable_properties.minable and ore_prototype.resource_category == 'basic-solid' then
|
||||
for _, product in pairs(mineable_properties.products) do
|
||||
ore_products[product.name] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local total_ore = 0
|
||||
local ore_totals_message = '('
|
||||
for ore_name in pairs(ore_products) do
|
||||
local count = game.forces["player"].item_production_statistics.get_input_count(ore_name)
|
||||
total_ore = total_ore + count
|
||||
ore_totals_message = ore_totals_message..ore_name:gsub( "-ore", "")..": "..format_number(count, true)..", "
|
||||
end
|
||||
ore_totals_message = ore_totals_message:sub(1, -3)..')' -- remove the last ", " and add a bracket
|
||||
ore_totals_message = "Total ore mined: "..format_number(total_ore, true).. "\\n"..ore_totals_message
|
||||
|
||||
local statistics_message = statistics.scenario..' completed!\\n\\n'..
|
||||
'Statistics:\\n'..
|
||||
'Map time: '..time_string..'\\n'..
|
||||
'Total entities built: '..statistics.entities_built..'\\n'..
|
||||
'Total ore mined:'..ore_totals_message..'\\n'..
|
||||
'Total ore resources exhausted: '..statistics.resources_exhausted..'\\n'..
|
||||
'Total ore hand mined: '..statistics.resources_hand_mined..'\\n'..
|
||||
'Players: '..statistics.total_players..'\\n'..
|
||||
'Enemies killed: '..statistics.biters_killed..'\\n\\n'..
|
||||
'Awards:\\n'..
|
||||
'Most ore hand mined:'..awards.resources_hand_mined.player..' ('..awards.resources_hand_mined.value..')\\n'..
|
||||
'Most items crafted: '..awards.entities_crafted.player..' ('..awards.entities_crafted.value..')\\n'..
|
||||
'Most entities built: '..awards.entities_built.player..' ('..awards.entities_built.value..')\\n'..
|
||||
'Most time played: '..awards.time_played.player..' ('..Core.format_time(awards.time_played.value)..')\\n'..
|
||||
'Furthest walked: '..awards.distance_walked.player..' ('..math.floor(awards.distance_walked.value)..')\\n'..
|
||||
'Most deaths: '..awards.player_deaths.player..' ('..awards.player_deaths.value..')\\n'..
|
||||
'Most kills overall: '..awards.total_kills.player..' ('..awards.total_kills.value..')\\n'..
|
||||
'Most biters/spitters killed: '..awards.units_killed.player..' ('..awards.units_killed.value..')\\n'..
|
||||
'Most spawners killed: '..awards.spawners_killed.player..' ('..awards.spawners_killed.value..')\\n'..
|
||||
'Most worms killed: '..awards.worms_killed.player..' ('..awards.worms_killed.value..')\\n'
|
||||
|
||||
Server.to_discord_named_embed(map_promotion_channel, statistics_message)
|
||||
Server.to_discord_named_embed(events_channel, statistics_message)
|
||||
|
||||
Server.set_data('danger_ores_data', tostring(end_epoch), statistics)
|
||||
|
||||
local message = {
|
||||
map_update_role_mention,
|
||||
' **April Fools has just restarted! Previous map lasted: ',
|
||||
time_string,
|
||||
'!\\n',
|
||||
'Next map: ',
|
||||
new_map_name,
|
||||
'**'
|
||||
}
|
||||
message = table.concat(message)
|
||||
|
||||
Server.to_discord_named_raw(map_promotion_channel, message)
|
||||
end
|
||||
|
||||
Restart.register(can_restart, restart_callback, nil)
|
||||
end
|
80
map_gen/maps/april_fools/scenario/rocket_launched.lua
Normal file
80
map_gen/maps/april_fools/scenario/rocket_launched.lua
Normal file
@ -0,0 +1,80 @@
|
||||
local Event = require 'utils.event'
|
||||
local Server = require 'features.server'
|
||||
local ShareGlobals = require 'map_gen.maps.april_fools.scenario.shared_globals'
|
||||
|
||||
ShareGlobals.data.map_won = false
|
||||
|
||||
local win_satellite_count = 1000
|
||||
|
||||
_G.rocket_launched_win_data = {
|
||||
extra_rockets = win_satellite_count
|
||||
}
|
||||
|
||||
local function disable_biters()
|
||||
game.forces.enemy.kill_all_units()
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
for _, enemy_entity in pairs(surface.find_entities_filtered({ force = 'enemy' })) do
|
||||
enemy_entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local message = 'Launching the last satellite has killed all the biters!'
|
||||
game.print(message)
|
||||
Server.to_discord_bold(message)
|
||||
end
|
||||
|
||||
local function win()
|
||||
if ShareGlobals.data.map_won then
|
||||
return
|
||||
end
|
||||
|
||||
ShareGlobals.data.map_won = true
|
||||
local message = 'Congratulations! The map has been won. Restart the map with /restart'
|
||||
game.print(message)
|
||||
Server.to_discord_bold(message)
|
||||
end
|
||||
|
||||
local function print_satellite_message(count)
|
||||
local remaining_count = win_satellite_count - count
|
||||
if remaining_count <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local message = table.concat { 'Launch another ', remaining_count, ' satellites to win the map.' }
|
||||
game.print(message)
|
||||
Server.to_discord_bold(message)
|
||||
end
|
||||
|
||||
local function rocket_launched(event)
|
||||
if ShareGlobals.data.map_won then
|
||||
return
|
||||
end
|
||||
|
||||
local entity = event.rocket
|
||||
if not entity or not entity.valid or not entity.force == 'player' then
|
||||
return
|
||||
end
|
||||
|
||||
local inventory = entity.get_inventory(defines.inventory.rocket)
|
||||
if not inventory or not inventory.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local satellite_count = game.forces.player.get_item_launched('satellite')
|
||||
if satellite_count == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if satellite_count == win_satellite_count then
|
||||
disable_biters()
|
||||
win()
|
||||
return
|
||||
end
|
||||
|
||||
if (satellite_count % 50) == 0 then
|
||||
print_satellite_message(satellite_count)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_rocket_launched, rocket_launched)
|
||||
|
228
map_gen/maps/april_fools/scenario/rocket_waves.lua
Normal file
228
map_gen/maps/april_fools/scenario/rocket_waves.lua
Normal file
@ -0,0 +1,228 @@
|
||||
local Event = require 'utils.event'
|
||||
local Generate = require 'map_gen.shared.generate'
|
||||
local Global = require 'utils.global'
|
||||
local Queue = require 'utils.queue'
|
||||
local AlienEvolutionProgress = require 'utils.alien_evolution_progress'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local Server = require 'features.server'
|
||||
local ShareGlobals = require 'map_gen.maps.april_fools.scenario.shared_globals'
|
||||
|
||||
ShareGlobals.data.map_won = false
|
||||
|
||||
local config = {
|
||||
recent_chunks_max = 20,
|
||||
ticks_between_waves = 60 * 30,
|
||||
enemy_factor = 5,
|
||||
max_enemies_per_wave_per_chunk = 60,
|
||||
extra_rockets = 33
|
||||
}
|
||||
|
||||
local recent_chunks = Queue.new() -- Keeps track of recently revealed chunks
|
||||
local recent_chunks_max = config.recent_chunks_max or 10 -- Maximum number of chunks to track
|
||||
local ticks_between_waves = config.ticks_between_waves or (60 * 30)
|
||||
local enemy_factor = config.enemy_factor or 5
|
||||
local max_enemies_per_wave_per_chunk = config.max_enemies_per_wave_per_chunk or 60
|
||||
|
||||
local win_data = { evolution_rocket_maxed = -1, extra_rockets = config.extra_rockets or 100 }
|
||||
|
||||
_G.rocket_launched_win_data = win_data
|
||||
|
||||
Global.register({ recent_chunks = recent_chunks, win_data = win_data }, function(tbl)
|
||||
recent_chunks = tbl.recent_chunks
|
||||
win_data = tbl.win_data
|
||||
end)
|
||||
|
||||
local function give_command(group, data)
|
||||
local target = data.target
|
||||
|
||||
if target and target.valid then
|
||||
local command = { type = defines.command.attack, target = target, distraction = defines.distraction.by_damage }
|
||||
group.set_command(command)
|
||||
group.start_moving()
|
||||
else
|
||||
local command = { type = defines.command.attack_area, destination = data.position, radius = 32, distraction = defines.distraction.by_damage }
|
||||
|
||||
local members = group.members
|
||||
for i = 1, #members do
|
||||
local entitiy = members[i]
|
||||
entitiy.set_command(command)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local do_waves
|
||||
local do_wave
|
||||
|
||||
do_waves = Token.register(function(data)
|
||||
Task.queue_task(do_wave, data, 10)
|
||||
end)
|
||||
|
||||
do_wave = Token.register(function(data)
|
||||
local wave = data.wave
|
||||
local last_wave = data.last_wave
|
||||
-- game.print('wave: ' .. wave .. '/' .. last_wave)
|
||||
|
||||
local chunk_index = data.chunk_index
|
||||
local chunk = data.chunks[chunk_index]
|
||||
|
||||
if not chunk then
|
||||
data.wave = wave + 1
|
||||
data.chunk_index = 1
|
||||
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
|
||||
return false
|
||||
end
|
||||
|
||||
local spawner = data.spawner
|
||||
|
||||
local aliens = AlienEvolutionProgress.get_aliens(spawner, game.forces.enemy.evolution_factor)
|
||||
|
||||
local left_top = chunk.area.left_top
|
||||
local center = { left_top.x + 16, left_top.y + 16 }
|
||||
local surface = chunk.surface
|
||||
local find_non_colliding_position = surface.find_non_colliding_position
|
||||
local create_entity = surface.create_entity
|
||||
|
||||
local group = surface.create_unit_group { position = center }
|
||||
local add_member = group.add_member
|
||||
|
||||
for name, count in pairs(aliens) do
|
||||
for i = 1, count do
|
||||
local pos = find_non_colliding_position(name, center, 32, 1)
|
||||
if pos then
|
||||
local e = { name = name, position = pos, force = 'enemy', center = center, radius = 16, 1 }
|
||||
local ent = create_entity(e)
|
||||
|
||||
add_member(ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
give_command(group, data)
|
||||
|
||||
if chunk_index < recent_chunks_max then
|
||||
data.chunk_index = chunk_index + 1
|
||||
return true
|
||||
end
|
||||
|
||||
if wave < last_wave then
|
||||
data.wave = wave + 1
|
||||
data.chunk_index = 1
|
||||
Task.set_timeout_in_ticks(ticks_between_waves, do_waves, data)
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
|
||||
local function start_waves(event)
|
||||
local num_enemies = enemy_factor * game.forces.player.get_item_launched('satellite')
|
||||
local number_of_waves = math.ceil(num_enemies / max_enemies_per_wave_per_chunk)
|
||||
local num_enemies_per_wave_per_chunk = math.ceil(num_enemies / number_of_waves)
|
||||
|
||||
local target = event.rocket_silo
|
||||
local position
|
||||
if target and target.valid then
|
||||
position = target.position
|
||||
else
|
||||
position = { 0, 0 }
|
||||
end
|
||||
|
||||
local data = {
|
||||
spawner = AlienEvolutionProgress.create_spawner_request(num_enemies_per_wave_per_chunk),
|
||||
wave = 1,
|
||||
last_wave = number_of_waves,
|
||||
chunk_index = 1,
|
||||
chunks = Queue.to_array(recent_chunks),
|
||||
target = target,
|
||||
position = position,
|
||||
}
|
||||
|
||||
Task.set_timeout_in_ticks(1, do_waves, data)
|
||||
|
||||
game.print('Warning incomming biter attack! Number of waves: ' .. number_of_waves)
|
||||
end
|
||||
|
||||
local function rocket_launched(event)
|
||||
local entity = event.rocket
|
||||
|
||||
if not entity or not entity.valid or not entity.force == 'player' then
|
||||
return
|
||||
end
|
||||
|
||||
local inventory = entity.get_inventory(defines.inventory.rocket)
|
||||
if not inventory or not inventory.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local satellite_count = game.forces.player.get_item_launched('satellite')
|
||||
if satellite_count == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
-- Increase enemy_evolution
|
||||
local current_evolution = game.forces.enemy.evolution_factor
|
||||
|
||||
if (satellite_count % 5) == 0 and win_data.evolution_rocket_maxed == -1 then
|
||||
local message = 'Continued launching of satellites has angered the local biter population, evolution increasing...'
|
||||
game.print(message)
|
||||
Server.to_discord_bold(message)
|
||||
|
||||
current_evolution = current_evolution + 0.05
|
||||
game.forces.enemy.evolution_factor = current_evolution
|
||||
end
|
||||
|
||||
if current_evolution < 1 then
|
||||
start_waves(event)
|
||||
return
|
||||
end
|
||||
|
||||
if win_data.evolution_rocket_maxed == -1 then
|
||||
win_data.evolution_rocket_maxed = satellite_count
|
||||
end
|
||||
|
||||
local remaining_satellites = win_data.evolution_rocket_maxed + win_data.extra_rockets - satellite_count
|
||||
if remaining_satellites > 0 then
|
||||
local message = 'Biters at maximum evolution! Protect the base for an additional ' .. remaining_satellites .. ' rockets to wipe them out forever.'
|
||||
game.print(message)
|
||||
Server.to_discord_bold(message)
|
||||
|
||||
start_waves(event)
|
||||
return
|
||||
end
|
||||
|
||||
local win_message = 'Congratulations! Biters have been wiped from the map!'
|
||||
game.print(win_message)
|
||||
Server.to_discord_bold(win_message)
|
||||
ShareGlobals.data.map_won = true
|
||||
|
||||
game.forces.enemy.kill_all_units()
|
||||
for _, surface in pairs(game.surfaces) do
|
||||
for _, enemy_entity in pairs(surface.find_entities_filtered({ force = 'enemy' })) do
|
||||
enemy_entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local bad_tiles = { 'deepwater-green', 'deepwater', 'out-of-map', 'water-green', 'water' }
|
||||
|
||||
local function chunk_unlocked(chunk)
|
||||
if chunk.surface and chunk.surface.name == 'islands' then
|
||||
-- Dont need to rule out chunks with water if biters can walk on water (Walkable Water mod)
|
||||
if not script.active_mods['walkable-water'] then
|
||||
local count = chunk.surface.count_tiles_filtered({ area = chunk.area, name = bad_tiles, limit = 1 })
|
||||
if count > 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Queue.push(recent_chunks, chunk)
|
||||
|
||||
while Queue.size(recent_chunks) > recent_chunks_max do
|
||||
Queue.pop(recent_chunks)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_rocket_launched, rocket_launched)
|
||||
Event.add(Generate.events.on_chunk_generated, chunk_unlocked)
|
17
map_gen/maps/april_fools/scenario/shared_globals.lua
Normal file
17
map_gen/maps/april_fools/scenario/shared_globals.lua
Normal file
@ -0,0 +1,17 @@
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local Public = {
|
||||
data = {}
|
||||
}
|
||||
|
||||
_G.april_fools_shared_globals = Public.data
|
||||
|
||||
Global.register(
|
||||
Public.data,
|
||||
function(tbl)
|
||||
Public.data = tbl
|
||||
_G.april_fools_shared_globals = tbl
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
217
map_gen/shared/alien_biomes.lua
Normal file
217
map_gen/shared/alien_biomes.lua
Normal file
@ -0,0 +1,217 @@
|
||||
--[[
|
||||
Map gen settings generator supporting Alien Biome's noise levels & autoplace settings
|
||||
|
||||
=== Preset Library ===
|
||||
|
||||
A MGS preset is a dictionary of autoplace controls for:
|
||||
- aux (Alien Biomes)
|
||||
- moisture (Alien Biomes)
|
||||
- temperature (Alien Biomes)
|
||||
- enemy
|
||||
- trees
|
||||
- water
|
||||
full updated list available at: resources/alien_biomes/biomes.lua
|
||||
|
||||
** AB.set_preset(data), AB.remove_preset(name), AB.clear_presets()
|
||||
|
||||
=== Param Customization ===
|
||||
|
||||
** AB.override_vanilla_mgs(MapGenSettings)
|
||||
Adds aux and moisture parameters to neg generated maps.
|
||||
@usage
|
||||
local AB = require 'map_gen.shared.alien_biomes'
|
||||
AB.override_vanilla_mgs(game.surfaces.redmew.map_gen_settings)
|
||||
|
||||
=== Map Gen Settings ===
|
||||
|
||||
** AB.new_from_existent(config)
|
||||
1. Generate a new random MGS based off default preset
|
||||
@usage
|
||||
local AB = require 'map_gen.shared.alien_biomes'
|
||||
local new_mgs = AB.new_from_existent()
|
||||
2. Generate a new random MGS based on current surface
|
||||
@usage
|
||||
local AB = require 'map_gen.shared.alien_biomes'
|
||||
local new_mgs = AB.new_from_existent({map_gen_settings = game.surfaces.redmew})
|
||||
|
||||
** AB.new_from_preset(config)
|
||||
1. Generate a new random MGS based off a random preset from the AB library
|
||||
@usage
|
||||
local AB = require 'map_gen.shared.alien_biomes'
|
||||
local new_mgs = AB.new_from_preset()
|
||||
2. Generate a new random MGS based on a specific preset from the AB library
|
||||
@usage
|
||||
local AB = require 'map_gen.shared.alien_biomes'
|
||||
local new_mgs = AB.new_from_preset({preset_name = 'volcano'})
|
||||
]]
|
||||
|
||||
require 'util'
|
||||
require 'utils.table'
|
||||
local Global = require 'utils.global'
|
||||
local Biomes = require 'resources.alien_biomes.biomes'
|
||||
|
||||
local Public = {}
|
||||
local _this = {
|
||||
presets = Biomes.presets
|
||||
}
|
||||
|
||||
Global.register(_this, function(tbl) _this = tbl end)
|
||||
|
||||
-- === PRESET LIBRARY MANIPULATION ============================================
|
||||
|
||||
--- Adds a new preset to the global table
|
||||
---@param data table<{ name: tostringing, preset: table }>
|
||||
---@return bool
|
||||
function Public.set_preset(data)
|
||||
if not (data and data.name and data.preset) then
|
||||
return false
|
||||
end
|
||||
|
||||
_this.presets[data.name] = data.preset
|
||||
return _this.presets[data.name] ~= nil
|
||||
end
|
||||
|
||||
--- Remove target preset from the global presets list
|
||||
---@param name tostringing
|
||||
---@return bool
|
||||
function Public.remove_preset(name)
|
||||
if not (name and type(name) == 'tostringing') then
|
||||
return false
|
||||
end
|
||||
|
||||
_this.presets[name] = nil
|
||||
return _this.presets[name] ~= nil
|
||||
end
|
||||
|
||||
--- Clears the global table from all presets
|
||||
---@return bool
|
||||
function Public.clear_presets()
|
||||
for key, _ in pairs(_this.presets) do
|
||||
_this.presets[key] = nil
|
||||
end
|
||||
return table_size(_this.presets) == 0
|
||||
end
|
||||
|
||||
-- === PARAM CUSTOMIZATION ====================================================
|
||||
|
||||
local function apply_temperature(mgs)
|
||||
local hf, hs = 1, 1
|
||||
local cf, cs = 1, 1
|
||||
|
||||
if _LIFECYCLE == _STAGE.init or _LIFECYCLE == _STAGE.runtime then
|
||||
hf = hf + 0.5*(math.random()-0.5)
|
||||
hs = hs + 0.2*(math.random()-0.5)
|
||||
|
||||
cf = cf + 0.5*(math.random()-0.5)
|
||||
cs = cs + 0.2*(math.random()-0.5)
|
||||
end
|
||||
|
||||
mgs.autoplace_controls = mgs.autoplace_controls or {}
|
||||
mgs.autoplace_controls.hot = { frequency = hf, size = hs }
|
||||
mgs.autoplace_controls.cold = { frequency = cf, size = cs }
|
||||
end
|
||||
|
||||
--- Adds +-25% freq and +-10% bias to Aux autoplace
|
||||
---@param mgs MapGenSettings
|
||||
local function apply_aux(mgs)
|
||||
local freq, bias = 1, 0
|
||||
|
||||
if _LIFECYCLE == _STAGE.init or _LIFECYCLE == _STAGE.runtime then
|
||||
freq = freq + 0.5*(math.random()-0.5)
|
||||
bias = bias + 0.2*(math.random()-0.5)
|
||||
end
|
||||
|
||||
mgs.property_expression_names = mgs.property_expression_names or {}
|
||||
mgs.property_expression_names['control-setting:aux:bias'] = tostring(bias)
|
||||
mgs.property_expression_names['control-setting:aux:frequency'] = tostring(freq)
|
||||
end
|
||||
|
||||
--- Adds +-25% freq and +-10% bias to Moisture autoplace
|
||||
---@param mgs MapGenSettings
|
||||
local function apply_moisture(mgs)
|
||||
local freq, bias = 1, 0
|
||||
|
||||
if _LIFECYCLE == _STAGE.init or _LIFECYCLE == _STAGE.runtime then
|
||||
freq = freq + 0.5*(math.random()-0.5)
|
||||
bias = bias + 0.2*(math.random()-0.5)
|
||||
end
|
||||
|
||||
mgs.property_expression_names = mgs.property_expression_names or {}
|
||||
mgs.property_expression_names['control-setting:moisture:bias'] = tostring(bias)
|
||||
mgs.property_expression_names['control-setting:moisture:frequency'] = tostring(freq)
|
||||
end
|
||||
|
||||
|
||||
--- Adds random aux and moisture to default vanilla MapGenSettings
|
||||
--- Is safe to call even for vanilla scenarios
|
||||
---@param mgs MapGenSettings
|
||||
function Public.override_vanilla_mgs(mgs)
|
||||
if not script.active_mods['alien-biomes'] then
|
||||
return
|
||||
end
|
||||
|
||||
apply_aux(mgs)
|
||||
apply_moisture(mgs)
|
||||
apply_temperature(mgs)
|
||||
end
|
||||
|
||||
-- === MAP GEN SETTINGS =======================================================
|
||||
|
||||
--- Generates a new random map_gen_setting from a given preset. If none is passed, the default one is used instead
|
||||
--- Is safe to call even for vanilla scenarios
|
||||
---@param config table
|
||||
---@field seed? number
|
||||
---@field map_gen_settings? MapGenSettings
|
||||
---@return MapGenSettings
|
||||
function Public.new_from_existent(config)
|
||||
config = config or {}
|
||||
local mgs = game.default_map_gen_settings
|
||||
|
||||
if config.map_gen_settings then
|
||||
mgs = config.map_gen_settings
|
||||
end
|
||||
|
||||
if _LIFECYCLE == _STAGE.init or _LIFECYCLE == _STAGE.runtime then
|
||||
mgs.seed = config.seed or math.random(4294967295)
|
||||
end
|
||||
|
||||
Public.override_vanilla(mgs)
|
||||
|
||||
return mgs
|
||||
end
|
||||
|
||||
--- Generates a random map_gen_setting from the available presets
|
||||
---- Is safe to call even for vanilla scenarios
|
||||
--@param config table
|
||||
---@field seed? number
|
||||
---@field preset_name? tostringing
|
||||
---@field map_gen_settings? MapGenSetting
|
||||
---@return MapGenSettings
|
||||
function Public.new_from_preset(config)
|
||||
config = config or {}
|
||||
local mgs = game.default_map_gen_settings
|
||||
mgs.seed = config.seed or mgs.seed or 4294967295
|
||||
local n_presets = table_size(_this.presets)
|
||||
local index = mgs.seed % n_presets + 1
|
||||
|
||||
if config.map_gen_settings then
|
||||
mgs = util.merge{mgs, config.map_gen_settings}
|
||||
end
|
||||
|
||||
if _LIFECYCLE == _STAGE.init or _LIFECYCLE == _STAGE.runtime then
|
||||
mgs.seed = config.seed or math.random(4294967295)
|
||||
index = math.random(n_presets)
|
||||
end
|
||||
|
||||
if script.active_mods['alien-biomes'] and n_presets > 0 then
|
||||
local preset_name = config.preset_name or table.keys(_this.presets)[index]
|
||||
local preset = Biomes.preset_to_mgs(_this.presets[preset_name])
|
||||
mgs = util.merge{mgs, preset}
|
||||
end
|
||||
|
||||
return mgs
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
return Public
|
133
resources/alien_biomes/biomes.lua
Normal file
133
resources/alien_biomes/biomes.lua
Normal file
@ -0,0 +1,133 @@
|
||||
local b = require 'resources.alien_biomes.biomes_settings'
|
||||
local str = tostring
|
||||
|
||||
local Public = {}
|
||||
|
||||
-- Converts a table of settings from resources/alien_biomes/biome_settings into a valid MapGenSettings
|
||||
function Public.preset_to_mgs(preset)
|
||||
local mgs = {
|
||||
autoplace_controls = {},
|
||||
property_expression_names = {},
|
||||
cliff_settings = {},
|
||||
}
|
||||
|
||||
if preset.aux then
|
||||
mgs.property_expression_names['control-setting:aux:bias'] = str(preset.aux.aux.bias or 0)
|
||||
mgs.property_expression_names['control-setting:aux:frequency'] = str(preset.aux.aux.frequency or 1)
|
||||
end
|
||||
|
||||
if preset.moisture then
|
||||
mgs.property_expression_names['control-setting:moisture:bias'] = str(preset.moisture.moisture.bias or 0)
|
||||
mgs.property_expression_names['control-setting:moisture:frequency'] = str(preset.moisture.moisture.frequency or 1)
|
||||
end
|
||||
|
||||
if preset.enemy then
|
||||
mgs.autoplace_controls['enemy-base'] = preset.enemy['enemy-base']
|
||||
end
|
||||
|
||||
if preset.temperature then
|
||||
local t = preset.temperature
|
||||
if t.cold then
|
||||
mgs.autoplace_controls.cold = t.cold
|
||||
end
|
||||
if t.hot then
|
||||
mgs.autoplace_controls.hot = t.hot
|
||||
end
|
||||
end
|
||||
|
||||
if preset.water then
|
||||
mgs.water = preset.water.water.size
|
||||
if preset.water.water.frequency and preset.water.water.frequency > 0 then
|
||||
mgs.terrain_segmentation = 1 / preset.water.water.frequency
|
||||
end
|
||||
end
|
||||
|
||||
if preset.trees then
|
||||
mgs.autoplace_controls.trees = preset.trees.trees
|
||||
end
|
||||
|
||||
for _, k in pairs({'autoplace_controls', 'property_expression_names', 'cliff_settings'}) do
|
||||
if table_size(mgs[k]) == 0 then
|
||||
mgs[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return mgs
|
||||
end
|
||||
|
||||
Public.presets = {
|
||||
default = {
|
||||
aux = b.aux.med,
|
||||
enemy = b.enemy.high,
|
||||
moisture = b.moisture.med,
|
||||
temperature = b.temperature.balanced,
|
||||
trees = b.trees.high,
|
||||
water = b.water.med,
|
||||
},
|
||||
cloud = {
|
||||
aux = b.aux.very_low,
|
||||
enemy = b.enemy.none,
|
||||
moisture = b.moisture.high,
|
||||
temperature = b.temperature.cool,
|
||||
trees = b.trees.med,
|
||||
water = b.water.high,
|
||||
},
|
||||
ice = {
|
||||
aux = b.aux.med,
|
||||
enemy = b.enemy.none,
|
||||
moisture = b.moisture.med,
|
||||
temperature = b.temperature.frozen,
|
||||
trees = b.trees.none,
|
||||
water = b.water.low,
|
||||
},
|
||||
volcano = {
|
||||
aux = b.aux.very_low,
|
||||
enemy = b.enemy.none,
|
||||
moisture = b.moisture.none,
|
||||
temperature = b.temperature.volcanic,
|
||||
trees = b.trees.none,
|
||||
water = b.water.none,
|
||||
},
|
||||
mountain = {
|
||||
aux = b.aux.low,
|
||||
enemy = b.enemy.low,
|
||||
moisture = b.moisture.low,
|
||||
temperature = b.temperature.wild,
|
||||
trees = b.trees.none,
|
||||
water = b.water.low,
|
||||
},
|
||||
neptune = {
|
||||
aux = b.aux.very_high,
|
||||
enemy = b.enemy.none,
|
||||
moisture = b.moisture.high,
|
||||
temperature = b.temperature.bland,
|
||||
trees = b.trees.med,
|
||||
water = b.water.max,
|
||||
},
|
||||
jungle = {
|
||||
aux = b.aux.very_low,
|
||||
enemy = b.enemy.med,
|
||||
moisture = b.moisture.high,
|
||||
temperature = b.temperature.bland,
|
||||
trees = b.trees.high,
|
||||
water = b.water.med,
|
||||
},
|
||||
canyon = {
|
||||
aux = b.aux.low,
|
||||
enemy = b.enemy.med,
|
||||
moisture = b.moisture.high,
|
||||
temperature = b.temperature.hot,
|
||||
trees = b.trees.low,
|
||||
water = b.water.none,
|
||||
},
|
||||
desert = {
|
||||
aux = b.aux.low,
|
||||
enemy = b.enemy.med,
|
||||
moisture = b.moisture.low,
|
||||
temperature = b.temperature.warm,
|
||||
trees = b.trees.low,
|
||||
water = b.water.low,
|
||||
},
|
||||
}
|
||||
|
||||
return Public
|
71
resources/alien_biomes/biomes_settings.lua
Normal file
71
resources/alien_biomes/biomes_settings.lua
Normal file
@ -0,0 +1,71 @@
|
||||
return {
|
||||
-- AUX
|
||||
-- range: [0, 1]
|
||||
-- determines whether low-moisture tiles become sand or red desert
|
||||
aux = {
|
||||
very_low = { aux = { frequency = 1, bias = -0.5 } },
|
||||
low = { aux = { frequency = 1, bias = -0.3 } },
|
||||
med = { aux = { frequency = 1, bias = -0.1 } },
|
||||
high = { aux = { frequency = 1, bias = 0.2 } },
|
||||
very_high = { aux = { frequency = 1, bias = 0.5 } },
|
||||
},
|
||||
-- MOISTURE
|
||||
-- range: [0, 1]
|
||||
-- determines whether a tile becomes sandy (low moisture) or grassy (high moisture).
|
||||
moisture = {
|
||||
none = { moisture = { frequency = 2, bias = -1 } },
|
||||
low = { moisture = { frequency = 1, bias = -0.15 } },
|
||||
med = { moisture = { frequency = 1, bias = 0 } },
|
||||
high = { moisture = { frequency = 1, bias = 0.15 } },
|
||||
max = { moisture = { frequency = 2, bias = 0.5 } },
|
||||
},
|
||||
temperature = {
|
||||
-- mixed
|
||||
bland = { hot = { frequency = 0.5, size = 0 }, cold = { frequency = 0.5, size = 0 } },
|
||||
temperate = { hot = { frequency = 1, size = 0.25 }, cold = { frequency = 1, size = 0.25 } },
|
||||
midrange = { hot = { frequency = 1, size = 0.65 }, cold = { frequency = 1, size = 0.65 } },
|
||||
balanced = { hot = { frequency = 1, size = 1 }, cold = { frequency = 1, size = 1 } },
|
||||
wild = { hot = { frequency = 1, size = 3 }, cold = { frequency = 1, size = 3 } },
|
||||
extreme = { hot = { frequency = 1, size = 6 }, cold = { frequency = 1, size = 6 } },
|
||||
-- cold
|
||||
cool = { hot = { frequency = 0.75, size = 0 }, cold = { frequency = 0.75, size = 0.5 } },
|
||||
cold = { hot = { frequency = 0.75, size = 0 }, cold = { frequency = 0.75, size = 1 } },
|
||||
very_cold = { hot = { frequency = 0.75, size = 0 }, cold = { frequency = 0.75, size = 2.2 } },
|
||||
frozen = { hot = { frequency = 0.75, size = 0 }, cold = { frequency = 0.75, size = 6 } },
|
||||
-- hot
|
||||
warm = { hot = { frequency = 0.75, size = 0.5 }, cold = { frequency = 0.75, size = 0 } },
|
||||
hot = { hot = { frequency = 0.75, size = 1 }, cold = { frequency = 0.75, size = 0 } },
|
||||
very_hot = { hot = { frequency = 0.75, size = 2.2 }, cold = { frequency = 0.75, size = 0 } },
|
||||
volcanic = { hot = { frequency = 0.75, size = 6 }, cold = { frequency = 0.75, size = 0 } },
|
||||
},
|
||||
trees = {
|
||||
none = { trees = { frequency = 0.25, size = 0, richness = 0 } },
|
||||
low = { trees = { frequency = 0.6, size = 0.35, richness = 0.8 } },
|
||||
med = { trees = { frequency = 0.8, size = 0.66, richness = 1 } },
|
||||
high = { trees = { frequency = 1, size = 1, richness = 1 } },
|
||||
max = { trees = { frequency = 3, size = 1, richness = 1 } },
|
||||
},
|
||||
cliff = {
|
||||
none = { cliff = { frequency = 0.01, richness = 0 } },
|
||||
low = { cliff = { frequency = 0.3, richness = 0.3 } },
|
||||
med = { cliff = { frequency = 1, richness = 1 } },
|
||||
high = { cliff = { frequency = 2, richness = 2 } },
|
||||
max = { cliff = { frequency = 6, richness = 2 } },
|
||||
},
|
||||
water = {
|
||||
none = { water = { frequancy = 1, size = 0 } },
|
||||
low = { water = { frequency = 0.5, size = 0.3 } },
|
||||
med = { water = { frequency = 1, size = 1 } },
|
||||
high = { water = { frequency = 1, size = 4 } },
|
||||
max = { water = { frequency = 0.5, size = 10 } },
|
||||
},
|
||||
enemy = {
|
||||
none = { ['enemy-base'] = { frequency = 1e-6, size = -1, richness = -1 } },
|
||||
very_low = { ['enemy-base'] = { frequency = 0.1, size = 0.1, richness = 0.1 } },
|
||||
low = { ['enemy-base'] = { frequency = 0.2, size = 0.2, richness = 0.2 } },
|
||||
med = { ['enemy-base'] = { frequency = 0.5, size = 0.5, richness = 0.5 } },
|
||||
high = { ['enemy-base'] = { frequency = 1, size = 1, richness = 1 } },
|
||||
very_high = { ['enemy-base'] = { frequency = 1.5, size = 2, richness = 1.5 } },
|
||||
max = { ['enemy-base'] = { frequency = 2, size = 6, richness = 2 } },
|
||||
},
|
||||
}
|
49
resources/alien_biomes/tile_names.lua
Normal file
49
resources/alien_biomes/tile_names.lua
Normal file
@ -0,0 +1,49 @@
|
||||
local function make_variations(name, min, max)
|
||||
local tiles = {}
|
||||
for i=min, max do
|
||||
table.insert(tiles, name .. '-' .. tostring(i))
|
||||
end
|
||||
return tiles
|
||||
end
|
||||
|
||||
return {
|
||||
['frozen-snow'] = make_variations('frozen-snow', 0, 9),
|
||||
['mineral-aubergine-dirt'] = make_variations('mineral-aubergine-dirt', 1, 6),
|
||||
['mineral-aubergine-sand'] = make_variations('mineral-aubergine-sand', 1, 3),
|
||||
['mineral-beige-dirt'] = make_variations('mineral-beige-dirt', 1, 6),
|
||||
['mineral-beige-sand'] = make_variations('mineral-beige-sand', 1, 3),
|
||||
['mineral-black-dirt'] = make_variations('mineral-black-dirt', 1, 6),
|
||||
['mineral-black-sand'] = make_variations('mineral-black-sand', 1, 3),
|
||||
['mineral-brown-dirt'] = make_variations('mineral-brown-dirt', 1, 6),
|
||||
['mineral-brown-sand'] = make_variations('mineral-brown-sand', 1, 3),
|
||||
['mineral-cream-dirt'] = make_variations('mineral-cream-dirt', 1, 6),
|
||||
['mineral-cream-sand'] = make_variations('mineral-cream-sand', 1, 3),
|
||||
['mineral-dustyrose-dirt'] = make_variations('mineral-dustyrose-dirt', 1, 6),
|
||||
['mineral-dustyrose-sand'] = make_variations('mineral-dustyrose-sand', 1, 3),
|
||||
['mineral-grey-dirt'] = make_variations('mineral-grey-dirt', 1, 6),
|
||||
['mineral-grey-sand'] = make_variations('mineral-grey-sand', 1, 3),
|
||||
['mineral-purple-dirt'] = make_variations('mineral-purple-dirt', 1, 6),
|
||||
['mineral-purple-sand'] = make_variations('mineral-purple-sand', 1, 3),
|
||||
['mineral-red-dirt'] = make_variations('mineral-red-dirt', 1, 6),
|
||||
['mineral-red-sand'] = make_variations('mineral-red-sand', 1, 3),
|
||||
['mineral-tan-dirt'] = make_variations('mineral-tan-dirt', 1, 6),
|
||||
['mineral-tan-sand'] = make_variations('mineral-tan-sand', 1, 3),
|
||||
['mineral-violet-dirt'] = make_variations('mineral-violet-dirt', 1, 6),
|
||||
['mineral-violet-sand'] = make_variations('mineral-violet-sand', 1, 3),
|
||||
['mineral-white-dirt'] = make_variations('mineral-white-dirt', 1, 6),
|
||||
['mineral-white-sand'] = make_variations('mineral-white-sand', 1, 3),
|
||||
['vegetation-blue-grass'] = make_variations('vegetation-blue-grass', 1, 2),
|
||||
['vegetation-green-grass'] = make_variations('vegetation-green-grass', 1, 4),
|
||||
['vegetation-mauve-grass'] = make_variations('vegetation-mauve-grass', 1, 2),
|
||||
['vegetation-olive-grass'] = make_variations('vegetation-olive-grass', 1, 2),
|
||||
['vegetation-orange-grass'] = make_variations('vegetation-orange-grass', 1, 2),
|
||||
['vegetation-purple-grass'] = make_variations('vegetation-purple-grass', 1, 2),
|
||||
['vegetation-red-grass'] = make_variations('vegetation-red-grass', 1, 2),
|
||||
['vegetation-turquoise-grass'] = make_variations('vegetation-turquoise-grass', 1, 2),
|
||||
['vegetation-violet-grass'] = make_variations('vegetation-violet-grass', 1, 2),
|
||||
['vegetation-yellow-grass'] = make_variations('vegetation-yellow-grass', 1, 2),
|
||||
['volcanic-blue-heat'] = make_variations('volcanic-blue-heat', 1, 4),
|
||||
['volcanic-green-heat'] = make_variations('volcanic-green-heat', 1, 4),
|
||||
['volcanic-orange-heat'] = make_variations('volcanic-orange-heat', 1, 4),
|
||||
['volcanic-purple-heat'] = make_variations('volcanic-purple-heat', 1, 4),
|
||||
}
|
262
resources/alien_biomes/tile_presets.lua
Normal file
262
resources/alien_biomes/tile_presets.lua
Normal file
@ -0,0 +1,262 @@
|
||||
--[[
|
||||
Each preset will be similar to:
|
||||
|
||||
grass = autoplace_settings = {
|
||||
tile = {
|
||||
treat_missing_as_default = false,
|
||||
settings = {
|
||||
['grass-1'] = {frequency = 1, size = 1, richness = 1},
|
||||
['grass-2'] = {frequency = 1, size = 1, richness = 1},
|
||||
['grass-3'] = {frequency = 1, size = 1, richness = 1},
|
||||
['grass-4'] = {frequency = 1, size = 1, richness = 1},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- no water, you will need to add it if wanted
|
||||
- tiles not listed tiles will not be placed
|
||||
]]
|
||||
|
||||
local Table = require 'utils.table'
|
||||
local ab_tiles = require 'resources.alien_biomes.tile_names'
|
||||
|
||||
local function make_default_autoplace_settings(tile_table)
|
||||
local autoplace_settings = {
|
||||
tile = {
|
||||
treat_missing_as_default = false,
|
||||
settings = {}
|
||||
}
|
||||
}
|
||||
for _, tile_name in pairs(Table.concat_tables(tile_table)) do
|
||||
autoplace_settings.tile.settings[tile_name] = {frequency = 1, size = 1, richness = 1}
|
||||
end
|
||||
return autoplace_settings
|
||||
end
|
||||
|
||||
return {
|
||||
-- Color subsets
|
||||
green = make_default_autoplace_settings{
|
||||
ab_tiles['vegetation-green-grass'],
|
||||
ab_tiles['vegetation-olive-grass'],
|
||||
ab_tiles['vegetation-turquioise-grass']
|
||||
},
|
||||
white = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-white-dirt'],
|
||||
ab_tiles['mineral-white-sand'],
|
||||
},
|
||||
grey = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-grey-dirt'],
|
||||
ab_tiles['mineral-grey-sand'],
|
||||
},
|
||||
black = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-black-dirt'],
|
||||
ab_tiles['mineral-black-sand'],
|
||||
},
|
||||
aubergine = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-aubergine-dirt'],
|
||||
ab_tiles['mineral-aubergine-sand'],
|
||||
},
|
||||
purple = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-purple-dirt'],
|
||||
ab_tiles['mineral-purple-sand'],
|
||||
},
|
||||
red = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-red-dirt'],
|
||||
ab_tiles['mineral-red-sand'],
|
||||
},
|
||||
beige = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-beige-dirt'],
|
||||
ab_tiles['mineral-beige-sand'],
|
||||
},
|
||||
brown = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-brown-sand'],
|
||||
},
|
||||
cream = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
ab_tiles['mineral-cream-sand'],
|
||||
},
|
||||
dustyrose = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
ab_tiles['mineral-dustyrose-sand'],
|
||||
},
|
||||
tan = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
ab_tiles['mineral-tan-sand'],
|
||||
},
|
||||
violet = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-violet-dirt'],
|
||||
ab_tiles['mineral-violet-sand'],
|
||||
},
|
||||
|
||||
-- Texture subsets
|
||||
grass = make_default_autoplace_settings{
|
||||
ab_tiles['vegetation-green-grass'],
|
||||
ab_tiles['vegetation-olive-grass'],
|
||||
ab_tiles['vegetation-turquioise-grass'],
|
||||
},
|
||||
snow = make_default_autoplace_settings{
|
||||
ab_tiles['frozen-snow'],
|
||||
},
|
||||
light_sand = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-tan-sand'],
|
||||
ab_tiles['mineral-beige-sand'],
|
||||
ab_tiles['mineral-cream-sand'],
|
||||
},
|
||||
dark_sand = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-black-sand'],
|
||||
ab_tiles['mineral-grey-sand'],
|
||||
},
|
||||
colorful_sand = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-brown-sand'],
|
||||
ab_tiles['mineral-aubergine-sand'],
|
||||
ab_tiles['mineral-purple-sand'],
|
||||
ab_tiles['mineral-dustyrose-sand'],
|
||||
ab_tiles['mineral-red-sand'],
|
||||
ab_tiles['mineral-violet-sand'],
|
||||
},
|
||||
sand_only = make_default_autoplace_settings{
|
||||
-- light sand
|
||||
ab_tiles['mineral-tan-sand'],
|
||||
ab_tiles['mineral-beige-sand'],
|
||||
ab_tiles['mineral-cream-sand'],
|
||||
-- dark sand
|
||||
ab_tiles['mineral-black-sand'],
|
||||
ab_tiles['mineral-grey-sand'],
|
||||
-- purple/red sand
|
||||
ab_tiles['mineral-brown-sand'],
|
||||
ab_tiles['mineral-aubergine-sand'],
|
||||
ab_tiles['mineral-purple-sand'],
|
||||
ab_tiles['mineral-dustyrose-sand'],
|
||||
ab_tiles['mineral-red-sand'],
|
||||
ab_tiles['mineral-violet-sand'],
|
||||
},
|
||||
brown_light_dirt = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-beige-dirt'],
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
},
|
||||
brown_dark_dirt = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
},
|
||||
brown_dirt = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-beige-dirt'],
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
},
|
||||
light_grey_dirt = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-grey-dirt'],
|
||||
ab_tiles['mineral-white-dirt'],
|
||||
},
|
||||
colorful_dirt = {
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-aubergine-dirt'],
|
||||
ab_tiles['mineral-purple-dirt'],
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
ab_tiles['mineral-red-dirt'],
|
||||
ab_tiles['mineral-violet-dirt'],
|
||||
},
|
||||
dirt_only = make_default_autoplace_settings{
|
||||
-- light dirt
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
ab_tiles['mineral-beige-dirt'],
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
-- dark dirt
|
||||
ab_tiles['mineral-black-dirt'],
|
||||
ab_tiles['mineral-grey-dirt'],
|
||||
-- purple/red dirt
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-aubergine-dirt'],
|
||||
ab_tiles['mineral-purple-dirt'],
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
ab_tiles['mineral-red-dirt'],
|
||||
ab_tiles['mineral-violet-dirt'],
|
||||
},
|
||||
heat_blue = make_default_autoplace_settings{
|
||||
ab_tiles['volcaninc-blue-heat'],
|
||||
},
|
||||
heat_green = make_default_autoplace_settings{
|
||||
ab_tiles['volcaninc-green-heat'],
|
||||
},
|
||||
heat_orange = make_default_autoplace_settings{
|
||||
ab_tiles['volcaninc-orange-heat'],
|
||||
},
|
||||
heat_purple = make_default_autoplace_settings{
|
||||
ab_tiles['volcaninc-purple-heat'],
|
||||
},
|
||||
|
||||
-- Full biomes
|
||||
cold = make_default_autoplace_settings{
|
||||
ab_tiles['frozen-snow'],
|
||||
ab_tiles['mineral-white-dirt'],
|
||||
ab_tiles['mineral-white-sand'],
|
||||
ab_tiles['volcaninc-blue-heat'],
|
||||
},
|
||||
hot = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-red-dirt'],
|
||||
ab_tiles['mineral-red-sand'],
|
||||
ab_tiles['vegetation-red-grass'],
|
||||
ab_tiles['volcaninc-orange-heat'],
|
||||
},
|
||||
pale = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-beige-dirt'],
|
||||
ab_tiles['mineral-beige-sand'],
|
||||
ab_tiles['mineral-grey-dirt'],
|
||||
ab_tiles['mineral-grey-sand'],
|
||||
ab_tiles['mineral-white-dirt'],
|
||||
ab_tiles['mineral-white-sand'],
|
||||
},
|
||||
temperate = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
ab_tiles['mineral-tan-sand'],
|
||||
ab_tiles['mineral-brown-dirt'],
|
||||
ab_tiles['mineral-brown-sand'],
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
ab_tiles['mineral-cream-sand'],
|
||||
ab_tiles['mineral-dustyrose-dirt'],
|
||||
ab_tiles['mineral-dustyrose-sand'],
|
||||
ab_tiles['vegetation-green-grass'],
|
||||
ab_tiles['vegetation-olive-grass'],
|
||||
ab_tiles['vegetation-orange-grass'],
|
||||
ab_tiles['vegetation-turquoise-grass'],
|
||||
ab_tiles['vegetation-yellow-grass'],
|
||||
},
|
||||
vegetation = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-cream-dirt'],
|
||||
ab_tiles['mineral-cream-sand'],
|
||||
ab_tiles['mineral-tan-dirt'],
|
||||
ab_tiles['mineral-tan-sand'],
|
||||
ab_tiles['vegetation-green-grass'],
|
||||
ab_tiles['vegetation-olive-grass'],
|
||||
ab_tiles['vegetation-orange-grass'],
|
||||
ab_tiles['vegetation-turquoise-grass'],
|
||||
ab_tiles['vegetation-yellow-grass'],
|
||||
ab_tiles['volcanic-green-heat'],
|
||||
},
|
||||
volcano = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-black-dirt'],
|
||||
ab_tiles['mineral-black-sand'],
|
||||
ab_tiles['mineral-red-dirt'],
|
||||
ab_tiles['mineral-red-sand'],
|
||||
ab_tiles['vegetation-red-grass'],
|
||||
ab_tiles['volcaninc-orange-heat'],
|
||||
},
|
||||
mystic_purple = make_default_autoplace_settings{
|
||||
ab_tiles['mineral-aubergine-dirt'],
|
||||
ab_tiles['mineral-aubergine-sand'],
|
||||
ab_tiles['mineral-purple-dirt'],
|
||||
ab_tiles['mineral-purple-sand'],
|
||||
ab_tiles['mineral-violet-dirt'],
|
||||
ab_tiles['mineral-violet-sand'],
|
||||
ab_tiles['vegetation-blue-grass'],
|
||||
ab_tiles['vegetation-mauve-grass'],
|
||||
ab_tiles['vegetation-purple-grass'],
|
||||
ab_tiles['vegetation-violet-grass'],
|
||||
ab_tiles['volcanic-blue-heat'],
|
||||
ab_tiles['volcanic-purple-heat'],
|
||||
},
|
||||
}
|
@ -8,7 +8,8 @@ return {
|
||||
moderation_log = 'moderation-log',
|
||||
helpdesk = 'helpdesk',
|
||||
danger_ores = 'danger-ores',
|
||||
crash_site = 'crash-site'
|
||||
crash_site = 'crash-site',
|
||||
events = 'events',
|
||||
},
|
||||
--- The strings that mention the discord role.
|
||||
-- Has to be used with features.server.to_discord_raw variants else the mention is sanitized server side.
|
||||
@ -17,6 +18,7 @@ return {
|
||||
crash_site = '<@&762441731194748958>',
|
||||
danger_ore = '<@&793231011144007730>',
|
||||
moderator = '<@&454192594633883658>',
|
||||
diggy = '<@&921476458076061718>'
|
||||
diggy = '<@&921476458076061718>',
|
||||
map_update = '<@486532533220147203>',
|
||||
}
|
||||
}
|
||||
|
146
resources/item_list.lua
Normal file
146
resources/item_list.lua
Normal file
@ -0,0 +1,146 @@
|
||||
return {
|
||||
'accumulator',
|
||||
'advanced-circuit',
|
||||
'arithmetic-combinator',
|
||||
'artillery-turret',
|
||||
'assembling-machine-1',
|
||||
'assembling-machine-2',
|
||||
'assembling-machine-3',
|
||||
'battery',
|
||||
'battery-equipment',
|
||||
'battery-mk2-equipment',
|
||||
'beacon',
|
||||
'belt-immunity-equipment',
|
||||
'big-electric-pole',
|
||||
'boiler',
|
||||
'burner-inserter',
|
||||
'burner-mining-drill',
|
||||
'centrifuge',
|
||||
'chemical-plant',
|
||||
'coal',
|
||||
'coin',
|
||||
'concrete',
|
||||
'constant-combinator',
|
||||
'construction-robot',
|
||||
'copper-cable',
|
||||
'copper-ore',
|
||||
'copper-plate',
|
||||
'crude-oil-barrel',
|
||||
'decider-combinator',
|
||||
'discharge-defense-equipment',
|
||||
'electric-engine-unit',
|
||||
'electric-furnace',
|
||||
'electric-mining-drill',
|
||||
'electronic-circuit',
|
||||
'empty-barrel',
|
||||
'energy-shield-equipment',
|
||||
'energy-shield-mk2-equipment',
|
||||
'engine-unit',
|
||||
'exoskeleton-equipment',
|
||||
'explosives',
|
||||
'express-loader',
|
||||
'express-splitter',
|
||||
'express-transport-belt',
|
||||
'express-underground-belt',
|
||||
'fast-inserter',
|
||||
'fast-loader',
|
||||
'fast-splitter',
|
||||
'fast-transport-belt',
|
||||
'fast-underground-belt',
|
||||
'filter-inserter',
|
||||
'flamethrower-turret',
|
||||
'flying-robot-frame',
|
||||
'fusion-reactor-equipment',
|
||||
'gate',
|
||||
'green-wire',
|
||||
'gun-turret',
|
||||
'hazard-concrete',
|
||||
'heat-exchanger',
|
||||
'heat-interface',
|
||||
'heat-pipe',
|
||||
'heavy-oil-barrel',
|
||||
'inserter',
|
||||
'iron-chest',
|
||||
'iron-gear-wheel',
|
||||
'iron-ore',
|
||||
'iron-plate',
|
||||
'iron-stick',
|
||||
'lab',
|
||||
'land-mine',
|
||||
'landfill',
|
||||
'laser-turret',
|
||||
'light-oil-barrel',
|
||||
'loader',
|
||||
'logistic-chest-active-provider',
|
||||
'logistic-chest-buffer',
|
||||
'logistic-chest-passive-provider',
|
||||
'logistic-chest-requester',
|
||||
'logistic-chest-storage',
|
||||
'logistic-robot',
|
||||
'long-handed-inserter',
|
||||
'low-density-structure',
|
||||
'lubricant-barrel',
|
||||
'medium-electric-pole',
|
||||
'night-vision-equipment',
|
||||
'nuclear-fuel',
|
||||
'nuclear-reactor',
|
||||
'offshore-pump',
|
||||
'oil-refinery',
|
||||
'personal-laser-defense-equipment',
|
||||
'personal-roboport-equipment',
|
||||
'personal-roboport-mk2-equipment',
|
||||
'petroleum-gas-barrel',
|
||||
'pipe',
|
||||
'pipe-to-ground',
|
||||
'plastic-bar',
|
||||
'player-port',
|
||||
'power-switch',
|
||||
'processing-unit',
|
||||
'programmable-speaker',
|
||||
'pump',
|
||||
'pumpjack',
|
||||
'radar',
|
||||
'rail-chain-signal',
|
||||
'rail-signal',
|
||||
'red-wire',
|
||||
'refined-concrete',
|
||||
'refined-hazard-concrete',
|
||||
'roboport',
|
||||
'rocket-control-unit',
|
||||
'rocket-fuel',
|
||||
'rocket-part',
|
||||
'rocket-silo',
|
||||
'satellite',
|
||||
'small-electric-pole',
|
||||
'small-lamp',
|
||||
'solar-panel',
|
||||
'solar-panel-equipment',
|
||||
'solid-fuel',
|
||||
'splitter',
|
||||
'stack-filter-inserter',
|
||||
'stack-inserter',
|
||||
'steam-engine',
|
||||
'steam-turbine',
|
||||
'steel-chest',
|
||||
'steel-furnace',
|
||||
'steel-plate',
|
||||
'stone',
|
||||
'stone-brick',
|
||||
'stone-furnace',
|
||||
'stone-wall',
|
||||
'storage-tank',
|
||||
'substation',
|
||||
'sulfur',
|
||||
'sulfuric-acid-barrel',
|
||||
'train-stop',
|
||||
'transport-belt',
|
||||
'underground-belt',
|
||||
'uranium-235',
|
||||
'uranium-238',
|
||||
'uranium-fuel-cell',
|
||||
'uranium-ore',
|
||||
'used-up-uranium-fuel-cell',
|
||||
'water-barrel',
|
||||
'wood',
|
||||
'wooden-chest',
|
||||
}
|
1
scenario_templates/april-fools-2019/map_selection.lua
Normal file
1
scenario_templates/april-fools-2019/map_selection.lua
Normal file
@ -0,0 +1 @@
|
||||
return require 'map_gen.maps.april_fools.2019'
|
1
scenario_templates/april-fools-2024/map_selection.lua
Normal file
1
scenario_templates/april-fools-2024/map_selection.lua
Normal file
@ -0,0 +1 @@
|
||||
return require 'map_gen.maps.april_fools.2024'
|
@ -10,7 +10,7 @@ Declare.module({'utils', 'Gui'}, function()
|
||||
end
|
||||
|
||||
for _, name in pairs(Gui._top_elements) do
|
||||
Declare.test(Gui.names[name] or name, function(context)
|
||||
Declare.test(Gui.names and Gui.names[name] or name, function(context)
|
||||
local player = context.player
|
||||
local element = player.gui.top[name]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user