Merge pull request #486 from bbassie/feature/convert-configs

Convert the remaining scenario configs into features
This commit is contained in:
Bastiaan authored and GitHub committed 2026-10-05 00:33:36 +01:00
1 parent b4ee485b13
commit 757a36fc03
44 files changed
+2137 -2033

No files matched your search

-105
View File
@@ -1,105 +0,0 @@
--- Lists all bonuses which can be used, name followed by min max
-- @config Bonuses
return {
--[[
Base point is equal to the amount of standard value in each parameter.
CMMS CRS CCS CISB CHB CRDB PBR
STD 20 60 24 10 12 8 40
= 174
MAX 40 120 48 20 24 16 80
= 348
]]
points = {
base = 174,
increase_percentage_per_role_level = 0.03,
role_name = "Member",
},
periodic_bonus_rate = 300,
player_bonus = {
{
name = "character_mining_speed_modifier",
scale = 1,
cost = 10,
max_value = 4,
value_step = 0.5,
is_percentage = true,
},
{
name = "character_running_speed_modifier",
scale = 1,
cost = 60,
max_value = 2,
value_step = 0.25,
is_percentage = true,
},
{
name = "character_crafting_speed_modifier",
scale = 1,
cost = 4,
max_value = 12,
value_step = 1,
is_percentage = true,
},
{
name = "character_inventory_slots_bonus",
scale = 10,
cost = 2,
max_value = 100,
value_step = 10,
},
{
name = "character_health_bonus",
scale = 50,
cost = 4,
max_value = 300,
value_step = 50,
},
{
name = "character_reach_distance_bonus",
scale = 1,
cost = 1,
max_value = 16,
value_step = 2,
combined_bonus = {
"character_resource_reach_distance_bonus",
"character_build_distance_bonus",
},
},
{
name = "personal_battery_recharge",
scale = 4,
cost = 40,
max_value = 8,
value_step = 1,
is_special = true,
},
},
force_bonus = {
["worker_robots_battery_modifier"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
["worker_robots_storage_bonus"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
["following_robots_lifetime_modifier"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
},
surface_bonus = {
},
}
-26
View File
@@ -1,26 +0,0 @@
--- Config file for the compliatrons including where they spawn and what messages they show
-- @config Compilatron
local config_server_detail = require("modules.exp_legacy.config.server_detail") --- @dep config.server_detail
return {
message_cycle = 60 * 15, --- @setting message_cycle 15 seconds default, how often (in ticks) the messages will cycle
locations = {
["Spawn"] = {
spawn_position = { x = 0, y = 0 },
spawn_surface = "nauvis",
entity_name = "small-biter",
messages = {
{ "info.website", config_server_detail["website"] },
{ "info.read-readme" },
{ "info.discord", config_server_detail["discord"] },
{ "info.softmod" },
{ "info.redmew" },
{ "info.custom-commands" },
{ "info.status", config_server_detail["status"] },
{ "info.lhd" },
{ "info.github", config_server_detail["github"] },
{ "info.patreon", config_server_detail["patreon"] },
},
}
},
}
-11
View File
@@ -1,11 +0,0 @@
--- This config controls whether actions such as deconning by players without sufficient permissions is logged or not
-- @config Deconlog
return {
decon_area = true, --- @setting decon_area whether to log when an area is being deconstructed
built_entity = true, --- @setting built_entity whether to log when an entity is built
mined_entity = true, --- @setting mined_entity whether to log when an entity is mined
fired_rocket = true, --- @setting fired_nuke whether to log when a rocket is fired
fired_explosive_rocket = true, --- @setting fired_nuke whether to log when a explosive rocket is fired
fired_nuke = true, --- @setting fired_nuke whether to log when a nuke is fired
}
-7
View File
@@ -1,7 +0,0 @@
return {
modules = {
["forcestats"] = true,
["logistorage"] = false,
["other"] = true,
},
}
-47
View File
@@ -1,47 +0,0 @@
--- This file controls what will show in each section of the rocket info gui
-- @config Rockets
return {
stats = { --- @setting stats The data that will show in the stats section
show_stats = true, --- @setting show_stats false will hide this section all together
show_first_rocket = true, --- @setting show_first_rocket false will not show when the first rocket was launched
show_last_rocket = true, --- @setting show_last_rocket false will not show when the last rocket was launched
show_fastest_rocket = true, --- @setting show_fastest_rocket false will not show the time taken for the fastest rocket
show_total_rockets = true, --- @setting show_total_rockets false will not show the total number of rockets launched
show_game_avg = true, --- @setting show_game_avg false will hide the avg across the entire map time
rolling_avg = { --- @setting rolling_avg each number will be one statistic; 5 means the avg time taken for the last 5 rockets
5, 10, 25,
},
},
milestones = { --- @setting milestones each number will be one statistic; 5 means the time that the 5th rocket was launched
show_milestones = true, --- @setting show_milestones false will hide this section all together
1,
2,
5,
10,
20,
50,
100,
200,
500,
1000,
1500,
2000,
2500,
3000,
3500,
4000,
4500,
5000,
},
progress = { --- @setting progress The data and buttons in the build progress section
show_progress = true, --- @setting show_progress false will hide this section altogether
allow_zoom_to_map = true, --- @setting allow_zoom_to_map false will disable the zoom to map feature
allow_remote_launch = true, --- @setting allow_remote_launch false removes the remote launch button for all players
remote_launch_admins_only = false, --- @setting remote_launch_admins_only true will remove the remote launch button for all non (game) admins
remote_launch_role_permission = "exp_scenario.gui.rocket_info.remote_launch", --- @setting remote_launch_role_permission value used by custom permission system to allow or disallow the button
allow_toggle_active = true, --- @setting allow_toggle_active false removes the remote toggle auto launch button for all players
toggle_active_admins_only = false, --- @setting toggle_active_admins_only true will remove the toggle auto launch button for all non (game) admins
toggle_active_role_permission = "exp_scenario.gui.rocket_info.toggle_active", --- @setting toggle_active_role_permission value used by custom permission system to allow or disallow the button
},
}
-21
View File
@@ -1,21 +0,0 @@
--- Config file for the science info gui
-- @config Science
return {
-- list of all science packs to be shown in the gui
show_eta = true, --- @setting show_eta when true the eta for research completion will be shown
color_cutoff = 0.8, --- @setting color_cutoff the amount that production can fall before the text changes color
color_flux = 0.1, --- @setting color_flux the amount of fluctuation allowed in production before the icon changes color
"automation-science-pack",
"logistic-science-pack",
"military-science-pack",
"chemical-science-pack",
"production-science-pack",
"utility-science-pack",
"space-science-pack",
"metallurgic-science-pack",
"agricultural-science-pack",
"electromagnetic-science-pack",
"cryogenic-science-pack",
"promethium-science-pack",
}
-13
View File
@@ -1,13 +0,0 @@
--- Config file for the tasks gui
-- @config Tasks
return {
-- Adding tasks
allow_add_task = "all", --- @setting allow_add_task dictates who is allowed to add new tasks; values: all, admin, exp_roles, none
exp_roles_allow_add_task = "exp_scenario.gui.task_list.add", --- @setting exp_roles_allow_add_task if exp_roles is used then this is the required permission
-- Editing tasks
allow_edit_task = "exp_roles", --- @setting allow_edit_task dictates who is allowed to edit existing tasks; values: all, admin, exp_roles, none
exp_roles_allow_edit_task = "exp_scenario.gui.task_list.edit", --- @setting exp_roles_allow_edit_task if exp_roles is used then this is the required permission
user_can_edit_own_tasks = true, --- @settings if true then the user who made the task can edit it regardless of the allow_edit_task setting
}
-52
View File
@@ -1,52 +0,0 @@
--- This file contains all the different settings for the warp system and gui
-- @config Warps
return {
-- General config
update_smoothing = 10, --- @setting update_smoothing the amount of smoothing applied to updates to the cooldown timer, higher is better, max is 60
minimum_distance = 100, --- @setting minimum_distance the minimum distance that is allowed between warps on the same force
default_icon = { type = "item", name = "discharge-defense-equipment" }, --- @setting default_icon the default icon that will be used for warps
-- Warp cooldowns
bypass_warp_cooldown = "exp_roles", --- @setting bypass_warp_cooldown dictates who the warp cooldown is applied to; values: all, admin, exp_roles, none
exp_roles_bypass_warp_cooldown = "exp_scenario.gui.warp_list.bypass_cooldown", --- @setting exp_roles_bypass_warp_cooldown if exp_roles is used then this is the required permission
cooldown_duration = 60, --- @setting cooldown_duration the duration of the warp cooldown in seconds
-- Warp proximity
bypass_warp_proximity = "exp_roles", --- @setting bypass_warp_proximity dictates who the warp proximity is applied to; values: all, admin, exp_roles, none
exp_roles_bypass_warp_proximity = "exp_scenario.gui.warp_list.bypass_proximity", --- @setting exp_roles_bypass_warp_proximity if exp_roles is used then this is the required permission
standard_proximity_radius = 4, --- @setting standard_proximity_radius the minimum distance a player is allowed to be to a warp in order to use it
spawn_proximity_radius = 20, --- @setting spawn_proximity_radius the minimum distance a player is allowed to be from they spawn point to use warps
-- Adding warps
allow_add_warp = "exp_roles", --- @setting allow_add_warp dictates who is allowed to add warps; values: all, admin, exp_roles, none
exp_roles_allow_add_warp = "exp_scenario.gui.warp_list.add", --- @setting exp_roles_allow_add_warp if exp_roles is used then this is the required permission
-- Editing warps
allow_edit_warp = "exp_roles", --- @setting allow_edit_warp dictates who is allowed to edit warps; values: all, admin, exp_roles, none
exp_roles_allow_edit_warp = "exp_scenario.gui.warp_list.edit", --- @setting exp_roles_allow_edit_warp if exp_roles is used then this is the required permission
user_can_edit_own_warps = false, --- @settings user_can_edit_own_warps if true then the user who made the warp can edit it regardless of the allow_edit_warp setting
-- Warp area generation
entities = { --- @setting entities The entities which are created for warp areas
{ "small-lamp", -4, -2 }, { "small-lamp", -2, -4 }, { "medium-electric-pole", -3, -3 }, -- Top left corner
{ "small-lamp", 3, -2 }, { "small-lamp", 1, -4 }, { "medium-electric-pole", 2, -3 }, -- Top right corner
{ "small-lamp", 3, 1 }, { "small-lamp", 1, 3 }, { "medium-electric-pole", 2, 2 }, -- Bottom right corner
{ "small-lamp", -4, 1 }, { "small-lamp", -2, 3 }, { "medium-electric-pole", -3, 2 }, -- Bottom left corner
},
tiles = { --- @setting tiles The tiles which are created for warp areas
{ "black-refined-concrete", -4, -2 }, { "black-refined-concrete", -4, -1 }, { "black-refined-concrete", -4, 0 }, { "black-refined-concrete", -4, 1 },
{ "black-refined-concrete", -3, -3 }, { "purple-refined-concrete", -3, -2 }, { "purple-refined-concrete", -3, -1 }, { "purple-refined-concrete", -3, 0 },
{ "purple-refined-concrete", -3, 1 }, { "black-refined-concrete", -3, 2 }, { "black-refined-concrete", -2, -4 }, { "purple-refined-concrete", -2, -3 },
{ "purple-refined-concrete", -2, -2 }, { "purple-refined-concrete", -2, -1 }, { "purple-refined-concrete", -2, 0 }, { "purple-refined-concrete", -2, 1 },
{ "purple-refined-concrete", -2, 2 }, { "black-refined-concrete", -2, 3 }, { "black-refined-concrete", -1, -4 }, { "purple-refined-concrete", -1, -3 },
{ "purple-refined-concrete", -1, -2 }, { "purple-refined-concrete", -1, -1 }, { "purple-refined-concrete", -1, 0 }, { "purple-refined-concrete", -1, 1 },
{ "purple-refined-concrete", -1, 2 }, { "black-refined-concrete", -1, 3 }, { "black-refined-concrete", 0, -4 }, { "purple-refined-concrete", 0, -3 },
{ "purple-refined-concrete", 0, -2 }, { "purple-refined-concrete", 0, -1 }, { "purple-refined-concrete", 0, 0 }, { "purple-refined-concrete", 0, 1 },
{ "purple-refined-concrete", 0, 2 }, { "black-refined-concrete", 0, 3 }, { "black-refined-concrete", 1, -4 }, { "purple-refined-concrete", 1, -3 },
{ "purple-refined-concrete", 1, -2 }, { "purple-refined-concrete", 1, -1 }, { "purple-refined-concrete", 1, 0 }, { "purple-refined-concrete", 1, 1 },
{ "purple-refined-concrete", 1, 2 }, { "black-refined-concrete", 1, 3 }, { "black-refined-concrete", 2, -3 }, { "purple-refined-concrete", 2, -2 },
{ "purple-refined-concrete", 2, -1 }, { "purple-refined-concrete", 2, 0 }, { "purple-refined-concrete", 2, 1 }, { "black-refined-concrete", 2, 2 },
{ "black-refined-concrete", 3, -2 }, { "black-refined-concrete", 3, -1 }, { "black-refined-concrete", 3, 0 }, { "black-refined-concrete", 3, 1 },
},
}
@@ -1,9 +0,0 @@
--- Config to control when players items are removed, this is a list of event names that will trigger inventory clear
-- @config inventory_clear
local events = defines.events
return {
events.on_player_banned,
events.on_player_kicked,
-- events.on_player_left_game
}
-30
View File
@@ -1,30 +0,0 @@
--- Settings for logging
-- @config logging
return {
file_name = "log/logging.log",
rocket_launch_display = {
[1] = true,
[2] = true,
[5] = true,
[10] = true,
[20] = true,
[50] = true,
[100] = true,
[200] = true,
},
rocket_launch_display_rate = 500,
disconnect_reason = {
[defines.disconnect_reason.quit] = "left the game",
[defines.disconnect_reason.dropped] = "was dropped from the game",
[defines.disconnect_reason.reconnect] = "is reconnecting",
[defines.disconnect_reason.wrong_input] = "was having a wrong input",
[defines.disconnect_reason.desync_limit_reached] = "had desync limit reached",
[defines.disconnect_reason.cannot_keep_up] = "cannot keep up",
[defines.disconnect_reason.afk] = "was afk",
[defines.disconnect_reason.kicked] = "was kicked",
[defines.disconnect_reason.kicked_and_deleted] = "was kicked and deleted",
[defines.disconnect_reason.banned] = "was banned",
[defines.disconnect_reason.switching_servers] = "is switching servers",
},
}
-86
View File
@@ -1,86 +0,0 @@
return {
module_slots_per_row = 4,
module_slot_max = 8,
copy_paste_module = true,
copy_paste_rotation = false,
machines = {
},
machine_sets = {
["base"] = {
["electric-mining-drill"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["pumpjack"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["assembling-machine-2"] = {
["module"] = "productivity-module",
["prod"] = true,
},
["assembling-machine-3"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["electric-furnace"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["beacon"] = {
["module"] = "speed-module-3",
["prod"] = false,
},
["oil-refinery"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["chemical-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["centrifuge"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["lab"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["rocket-silo"] = {
["module"] = "productivity-module-3",
["prod"] = true,
}
},
["space-age"] = {
["big-mining-drill"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["biochamber"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["electromagnetic-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["cryogenic-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["biolab"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["foundry"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["recycler"] = {
["module"] = "quality-module-3",
["prod"] = true,
}
}
}
}
@@ -1,9 +0,0 @@
--- This controls how pollution is viewed on the map
-- @config Pollution-Grading
return {
reference_point = { x = 0, y = 0 }, --- @setting reference_point where pollution is read from
max_scalar = 0.5, --- @setting max_scalar the scale between true max and max
min_scalar = 0.17, --- @setting min_scalar the scale between the lowest max and min
update_delay = 15, --- @setting update_delay time in minutes between view updates
}
-8
View File
@@ -1,8 +0,0 @@
--- Config file for the repair command
-- @config Repair
return {
allow_blueprint_repair = false, --- @setting allow_blueprint_repair when true will allow blueprints (things not destroyed by biters) to be build instantly using the repair command
allow_ghost_revive = true, --- @setting allow_ghost_revive when true will allow ghosts (things destroyed by biters) to be build instantly using the repair command
allow_heal_entities = true, --- @setting allow_heal_entities when true will heal entities to full health that are within range
}
-116
View File
@@ -1,116 +0,0 @@
--- This file controls the placement/degrading of tiles as players build and walk
-- @config Scorched-Earth
return {
weakness_value = 70, --- @setting weakness_value lower value will make tiles more likely to degrade
strengths = { --- @setting strengths this decides how "strong" a tile is, bigger number means less likely to degrade
-- debug: /interface require('modules.addons.worn-paths')(player.name,true)
-- note: tiles are effected by the tiles around them, so player paths will not degrade as fast when made wider
-- note: values are relative to the tile with the highest value, recommended to keep highest tile as a "nice" number
-- note: tiles not in list will never degrade under any conditions (which is why some are omitted such as water)
["refined-concrete"] = 100,
["refined-hazard-concrete-left"] = 100,
["refined-hazard-concrete-right"] = 100,
["concrete"] = 90,
["hazard-concrete-left"] = 90,
["hazard-concrete-right"] = 90,
["stone-path"] = 80,
["red-desert-0"] = 80,
["dry-dirt"] = 50,
-- grass four (main grass tiles)
["grass-1"] = 50,
["grass-2"] = 40,
["grass-3"] = 30,
["grass-4"] = 25,
-- red three (main red tiles)
["red-desert-1"] = 40,
["red-desert-2"] = 30,
["red-desert-3"] = 25,
-- sand three (main sand tiles)
["sand-1"] = 40,
["sand-2"] = 30,
["sand-3"] = 25,
-- dirt 3 (main dirt tiles)
["dirt-1"] = 40,
["dirt-2"] = 30,
["dirt-3"] = 25,
-- last three/four (all sets of three merge here)
["dirt-4"] = 25,
["dirt-5"] = 30,
["dirt-6"] = 40,
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]=50,
-- ["water-shallow"]=90,
-- ["water-mud"]=0, -- last tile, nothing to degrade to
},
degrade_order = { --- @setting degrade_order when a tile degrades it will turn into the next tile given here
["refined-concrete"] = "concrete",
["refined-hazard-concrete-left"] = "hazard-concrete-left",
["refined-hazard-concrete-right"] = "hazard-concrete-right",
["concrete"] = "stone-path",
["hazard-concrete-left"] = "stone-path",
["hazard-concrete-right"] = "stone-path",
["stone-path"] = "dry-dirt",
["red-desert-0"] = "dry-dirt",
["dry-dirt"] = "dirt-4",
-- grass four (main grass tiles)
["grass-1"] = "grass-2",
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
-- red three (main red tiles)
["red-desert-1"] = "red-desert-2",
["red-desert-2"] = "red-desert-3",
["red-desert-3"] = "dirt-4",
-- sand three (main sand tiles)
["sand-1"] = "sand-2",
["sand-2"] = "sand-3",
["sand-3"] = "dirt-4",
-- dirt 3 (main dirt tiles)
["dirt-1"] = "dirt-2",
["dirt-2"] = "dirt-3",
["dirt-3"] = "dirt-4",
-- last three/four (all sets of three merge here)
["dirt-4"] = "dirt-5",
["dirt-5"] = "dirt-6",
["dirt-6"] = "dirt-7",
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]='grass-2', -- 'water-shallow'
-- ["water-shallow"]='water-mud',
-- ["water-mud"]=0, -- last tile, nothing to degrade to
},
entities = { --- @setting entities entities in this list will degrade the tiles under them when they are placed
["stone-furnace"] = true,
["steel-furnace"] = true,
["electric-furnace"] = true,
["assembling-machine-1"] = true,
["assembling-machine-2"] = true,
["assembling-machine-3"] = true,
["beacon"] = true,
["centrifuge"] = true,
["chemical-plant"] = true,
["oil-refinery"] = true,
["storage-tank"] = true,
["nuclear-reactor"] = true,
["steam-engine"] = true,
["steam-turbine"] = true,
["boiler"] = true,
["heat-exchanger"] = true,
["stone-wall"] = true,
["gate"] = true,
["gun-turret"] = true,
["laser-turret"] = true,
["flamethrower-turret"] = true,
["radar"] = true,
["lab"] = true,
["big-electric-pole"] = true,
["substation"] = true,
["rocket-silo"] = true,
["pumpjack"] = true,
["electric-mining-drill"] = true,
["roboport"] = true,
["accumulator"] = true,
},
}
-180
View File
@@ -1,180 +0,0 @@
--- Settings for vlayer including the allowed items, the update frequency, and some cheats
-- @config Vlayer
return {
update_tick_storage = 60, --- @setting update_tick_storage The number of ticks between each update of the storage interfaces
update_tick_energy = 10, --- @setting update_tick_energy The number of ticks between each update of the energy and circuit interfaces
update_tick_gui = 60, --- @setting update_tick_gui The number of ticks between each update of the gui
unlimited_capacity = false, --- @setting unlimited_capacity When true the vlayer has an unlimited energy capacity, accumulators are not required
unlimited_surface_area = false, --- @setting unlimited_surface_area When true the vlayer has an unlimited surface area, landfill is not required
modded_auto_downgrade = false, --- @setting modded_auto_downgrade When true modded items will be converted into their base game equivalent, original items can not be recovered
power_on_space = false, --- @setting power_on_space When true allow on spaceship
power_on_space_research = { --- @setting power_on_space_research the research level needed to use power_on_space
name = "research-productivity",
level = 10
},
mimic_surface = "nauvis", --- @setting mimic_surface Surface name/index the vlayer will copy its settings from, use nil to use the settings below
surface = { --- @setting surface When mimic_surface is nil these settings will be used instead, see LuaSurface for details
always_day = false,
solar_power_multiplier = 1,
min_brightness = 0.15,
ticks_per_day = 25200,
daytime = 0,
dusk = 0.25,
evening = 0.45,
morning = 0.55,
dawn = 0.75,
},
interface_limit = { --- @setting interface_limit Sets the limit for the number of vlayer interfaces that can be created
energy = 1, -- >1 allows for disconnected power networks to receive power
circuit = 20, -- No caveats
storage_input = 20, -- No caveats
storage_output = 1, -- >0 allows for item teleportation (allowed_items only)
},
--- @class Vlayer.ItemProperties
--- @field starting_value number
--- @field required_area number
--- @field production number?
--- @field discharge number?
--- @field capacity number?
--- @field surface_area number?
--- @field fuel_value number?
--- @field power boolean?
--- @field modded boolean? Set when the item is registered from a modded equivalent
--- @field base_game_equivalent string?
--- @field multiplier number?
--- @type table<string, Vlayer.ItemProperties>
allowed_items = { --- @setting allowed_items List of all items allowed in vlayer storage and their properties
--[[
Allowed properties:
starting_value : The amount of the item placed into the vlayer on game start, ignores area requirements
required_area : When greater than 0 the items properties are not applied unless their is sufficient surplus surface area
production : The energy production of the item in MW, used for solar panels
discharge : The energy discharge of the item in MW, used for accumulators
capacity : The energy capacity of the item in MJ, used for accumulators
surface_area : The surface area provided by the item, used for landfill
]]
["solar-panel"] = {
starting_value = 0,
required_area = 9,
production = 0.06, -- MW
},
["accumulator"] = {
starting_value = 0,
required_area = 4,
discharge = 0.3, -- MW
capacity = 5, -- MJ
},
["landfill"] = {
starting_value = 0,
required_area = 0,
surface_area = 20, -- Tiles
},
["wood"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 2, -- MJ
power = true, -- turn all wood to power to reduce trash
},
["coal"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 4, -- MJ
power = false, -- turn all coal to power to reduce trash
},
["solid-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 12, -- MJ
power = false, -- turn all solid fuel to power to reduce trash
},
["rocket-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 100, -- MJ
power = false, -- turn all rocket fuel to power to reduce trash
}
},
modded_items = { --- @setting modded_items List of all modded items allowed in vlayer storage and their base game equivalent
["solar-panel-2"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 4,
},
["solar-panel-3"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 16,
},
["solar-panel-4"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 64,
},
["solar-panel-5"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 256,
},
["solar-panel-6"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 1024,
},
["solar-panel-7"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 4096,
},
["solar-panel-8"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 16384,
},
["accumulator-2"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 4,
},
["accumulator-3"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 16,
},
["accumulator-4"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 64,
},
["accumulator-5"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 256,
},
["accumulator-6"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 1024,
},
["accumulator-7"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 4096,
},
["accumulator-8"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 16384,
},
}
}
+187
View File
@@ -81,6 +81,47 @@ export const features: Feature[] = [
str("command_prefix", "Command prefix", "Prefix for chat commands, and for key words to reply to everyone", "!"),
],
},
{
name: "custom_start",
title: "Custom Start",
description: "Map settings applied when the map is created, and the items new players start with",
fields: [
bool("skip_intro", "Skip intro", "Skip the freeplay intro", true),
bool("skip_victory", "Skip victory", "Skip the victory screen when a rocket is launched", true),
bool("friendly_fire", "Friendly fire", "Players can damage each other", false),
bool("disable_crashsite", "No crash site", "Do not create the crash site", true),
bool("enemy_expansion", "Enemy expansion", "Biters expand, in case the map settings file fails to load", false),
num("chart_radius", "Chart radius", "Tiles charted around spawn when the map starts", 320, 0, "tiles"),
],
},
{
name: "deconstruction_log",
title: "Deconstruction Log",
description: "Write actions of players without the bypass permission to log/deconstruction.log",
fields: [
bool("decon_area", "Deconstructed areas", "Log when an area is deconstructed", true),
bool("built_entity", "Built entities", "Log when an entity is built", true),
bool("mined_entity", "Mined entities", "Log when an entity is mined", true),
bool("fired_rocket", "Rockets", "Log when a rocket is fired", true),
bool("fired_explosive_rocket", "Explosive rockets", "Log when an explosive rocket is fired", true),
bool("fired_nuke", "Nukes", "Log when a nuke is fired", true),
],
},
{
name: "degrading_tiles",
title: "Degrading Tiles",
description: "Tiles wear down as players walk on them and build on them",
fields: [
num("weakness_value", "Weakness", "Lower values make tiles degrade sooner", 70, 1),
list("entities", "Degrading entities", "Entities which degrade the tiles under them when built", [
"stone-furnace", "steel-furnace", "electric-furnace", "assembling-machine-1", "assembling-machine-2", "assembling-machine-3",
"beacon", "centrifuge", "chemical-plant", "oil-refinery", "storage-tank", "nuclear-reactor",
"steam-engine", "steam-turbine", "boiler", "heat-exchanger", "stone-wall", "gate",
"gun-turret", "laser-turret", "flamethrower-turret", "radar", "lab", "big-electric-pole",
"substation", "rocket-silo", "pumpjack", "electric-mining-drill", "roboport", "accumulator",
]),
],
},
{
name: "death_markers",
title: "Death Markers",
@@ -111,6 +152,27 @@ export const features: Feature[] = [
]),
],
},
{
name: "extra_logging",
title: "Extra Logging",
description: "Write rockets, deaths, research, joins, and leaves to a log file",
fields: [
str("file_name", "File name", "Path of the log file within script-output", "log/logging.log"),
num("rocket_launch_display_rate", "Rocket log interval", "After the first few launches, log every this many rockets", 500, 1, "rockets"),
],
},
{
name: "help_bubbles",
title: "Help Bubbles",
description: "A compilatron at spawn which cycles through tips and the community links",
fields: [],
},
{
name: "inventory_clear",
title: "Inventory Clear",
description: "Move the items of banned and kicked players to a chest at spawn",
fields: [],
},
{
name: "lawnmower",
title: "Lawnmower",
@@ -129,6 +191,15 @@ export const features: Feature[] = [
bool("fluid", "Replace with pipes", "Place pipe ghosts where a drill carried fluid", true),
],
},
{
name: "module_inserter",
title: "Module Inserter",
description: "A tool to fill machines with modules by selecting an area",
fields: [
bool("copy_paste_module", "Copy modules", "Copying a machine also copies its modules", true),
bool("copy_paste_rotation", "Copy rotation", "Copying a machine also copies its rotation", false),
],
},
{
name: "nuke_protection",
title: "Nuke Protection",
@@ -137,6 +208,27 @@ export const features: Feature[] = [
list("banned_items", "Banned items", "Items which are moved to a chest at spawn", ["atomic-bomb"]),
],
},
{
name: "player_bonus",
title: "Player Bonus",
description: "Points players spend on personal bonuses, the bonuses live in config/player_bonus.lua",
fields: [
num("points.base", "Base points", "The points of the points role, the standard value of each bonus adds up to this", 174, 0, "points"),
num("points.increase_percentage_per_role_level", "Points per role level", "Extra points as a fraction of the base for each role above the points role", 0.03, 0),
role("points.role_id", "Points role", "The role the base points apply to, without one every player gets the base"),
],
},
{
name: "pollution_grading",
title: "Pollution Grading",
description: "Scale the pollution overlay so it is not one red mess",
fields: [
num("reference_point.x", "Reference X", "Where pollution is read from", 0),
num("reference_point.y", "Reference Y", "Where pollution is read from", 0),
num("max_scalar", "Max scale", "The scale between the true max and the shown max", 0.5, 0),
num("min_scalar", "Min scale", "The scale between the shown max and the shown min", 0.17, 0),
],
},
{
name: "popups",
title: "Popups",
@@ -166,6 +258,63 @@ export const features: Feature[] = [
]),
],
},
{
name: "research",
title: "Research",
description: "Research effects, the per level limits live in config/research_data.lua",
fields: [
bool("pollution_ageing_by_research", "Pollution ageing", "Pollution ages faster with each level of the bonus inventory researches", false),
bool("bonus_inventory.enabled", "Bonus inventory", "Extra inventory slots for each level of the researches below", true),
list("bonus_inventory.res", "Bonus researches", "Researches which grant the extra slots", [
"mining-productivity", "mining-productivity-2", "mining-productivity-3", "mining-productivity-4",
]),
num("bonus_inventory.rate", "Slots per level", "Extra slots for each research level", 5, 0, "slots"),
num("bonus_inventory.limit", "Slot limit", "The most extra slots a force can have", 20, 0, "slots"),
],
},
{
name: "research_milestones",
title: "Research Milestones",
description: "A GUI tracking research against target times, the targets live in config/research_data.lua",
fields: [
str("log_file", "Log file", "Where the milestone times are written within script-output", "log/research.log"),
],
},
{
name: "rocket_info",
title: "Rocket Info",
description: "A GUI with rocket launch statistics, milestones, and build progress",
fields: [
bool("show_stats", "Statistics section", "Show the statistics section", true),
bool("show_first_rocket", "First rocket", "Show when the first rocket was launched", true),
bool("show_last_rocket", "Last rocket", "Show when the last rocket was launched", true),
bool("show_fastest_rocket", "Fastest rocket", "Show the time taken for the fastest rocket", true),
bool("show_total_rockets", "Total rockets", "Show the total number of rockets launched", true),
bool("show_game_avg", "Game average", "Show the average across the entire map time", true),
bool("show_milestones", "Milestones section", "Show when each milestone rocket was launched", true),
bool("show_progress", "Progress section", "Show the build progress of each silo", true),
bool("allow_zoom_to_map", "Zoom to map", "Clicking a silo zooms the map to it", true),
],
},
{
name: "science_production",
title: "Science Production",
description: "A GUI with the production of each science pack",
fields: [
bool("show_eta", "Show ETA", "Show the estimated time until the current research completes", true),
num("color_flux", "Colour threshold", "How much production may fluctuate before the icon changes colour", 0.1, 0),
],
},
{
name: "repair",
title: "Repair",
description: "The /repair command which revives ghosts and heals entities in an area",
fields: [
bool("allow_ghost_revive", "Revive ghosts", "Build ghosts in the area instantly", true),
bool("allow_blueprint_repair", "Revive blueprints", "Also revive ghosts which were never built, not only those left by destroyed entities", false),
bool("allow_heal_entities", "Heal entities", "Heal entities in the area to full health", true),
],
},
{
name: "spawn_area",
title: "Spawn Area",
@@ -202,6 +351,44 @@ export const features: Feature[] = [
str("station_name", "Station name", "Placeholders: __icon__ __item_name__ __backer_name__ __direction__ __x__ __y__", "[L] __icon__"),
],
},
{
name: "task_list",
title: "Task List",
description: "A shared list of tasks, adding and editing need the task list permissions",
fields: [
bool("user_can_edit_own_tasks", "Own tasks editable", "The player who made a task can edit it without the edit permission", true),
],
},
{
name: "warp_list",
title: "Warp List",
description: "Warp points players can travel between, adding, editing, and bypassing limits need the warp list permissions",
fields: [
num("minimum_distance", "Minimum distance", "Warps of a force can not be closer together than this", 100, 1, "tiles"),
num("cooldown_duration", "Cooldown", "Wait between warps", 60, 0, "seconds"),
num("standard_proximity_radius", "Warp radius", "How close a player must stand to a warp to use it", 4, 1, "tiles"),
num("spawn_proximity_radius", "Spawn radius", "How close a player must stand to spawn to use it as a warp", 20, 1, "tiles"),
bool("user_can_edit_own_warps", "Own warps editable", "The player who made a warp can edit it without the edit permission", false),
],
},
{
name: "vlayer",
title: "Virtual Layer",
description: "A shared virtual surface for solar panels, accumulators, and storage, the items live in config/vlayer_items.lua",
fields: [
bool("unlimited_capacity", "Unlimited capacity", "Energy storage without accumulators", false),
bool("unlimited_surface_area", "Unlimited area", "Place items without landfill", false),
bool("modded_auto_downgrade", "Downgrade modded items", "Convert modded items to their base game equivalent, the originals can not be recovered", false),
bool("power_on_space", "Power on platforms", "Energy interfaces can be built on space platforms", false),
str("power_on_space_research.name", "Platform research", "The research needed to build energy interfaces on platforms", "research-productivity"),
num("power_on_space_research.level", "Platform research level", "The level of that research", 10, 0),
str("mimic_surface", "Mimic surface", "The surface the day cycle is copied from, empty for a fixed cycle", "nauvis"),
num("interface_limit.energy", "Energy interfaces", "More than one lets disconnected power networks receive power", 1, 0),
num("interface_limit.circuit", "Circuit interfaces", "How many circuit interfaces can exist", 20, 0),
num("interface_limit.storage_input", "Input interfaces", "How many storage input interfaces can exist", 20, 0),
num("interface_limit.storage_output", "Output interfaces", "More than zero allows item teleportation of the allowed items", 1, 0),
],
},
];
/** Check values against the fields of a feature, returning those which differ from their default */
+10 -3
View File
@@ -4,9 +4,15 @@ Adds a command that allows an admin to repair and revive a large area
local AABB = require("modules/exp_util/aabb")
local Commands = require("modules/exp_commands")
local config = require("modules.exp_legacy.config.repair") --- @dep config.repair
local Feature = require("modules/exp_scenario/features")
local Selection = require("modules/exp_util/selection")
local SelectArea = Selection.connect("ExpCommand_Waterfill")
local SelectArea = Selection.connect("ExpCommand_Repair")
local feature, config = Feature.register("repair", {
allow_blueprint_repair = false, -- revive ghosts which were never built, not only those left by destroyed entities
allow_ghost_revive = true, -- revive ghosts in the area
allow_heal_entities = true, -- heal entities in the area to full health
})
--- @class ExpCommands_Repair.commands
local commands = {}
@@ -14,6 +20,7 @@ local commands = {}
--- Toggle player selection mode
--- @class ExpCommands_Repair.commands.repair: ExpCommand
commands.repair = Commands.new("repair", { "exp-commands_repair.description" })
:add_flags{ feature = feature }
:register(function(player)
if SelectArea:stop(player) then
return Commands.status.success{ "exp_util.selection_exit", { "exp-commands_repair.selection-name" } }
@@ -22,7 +29,7 @@ commands.repair = Commands.new("repair", { "exp-commands_repair.description" })
return Commands.status.success{ "exp_util.selection_enter", { "exp-commands_repair.selection-name" } }
end)
--- When an area is selected to be converted to water
--- When an area is selected to be repaired
SelectArea:on_selection(function(event)
local player = assert(game.get_player(event.player_index))
local area = AABB.expand(event.area)
@@ -3,7 +3,7 @@
local config = {
-- General config
icon = "item/piercing-rounds-magazine", -- @setting icon that will be used for the toolbar
icon = "item/piercing-rounds-magazine", -- that will be used for the toolbar
categories = {
ammo = "ammo",
fuel = "fuel",
@@ -0,0 +1,82 @@
--- The machines the module inserter can fill, and the modules it puts in them, by mod set
-- @config Module-Inserter-Machines
return {
["base"] = {
["electric-mining-drill"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["pumpjack"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["assembling-machine-2"] = {
["module"] = "productivity-module",
["prod"] = true,
},
["assembling-machine-3"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["electric-furnace"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["beacon"] = {
["module"] = "speed-module-3",
["prod"] = false,
},
["oil-refinery"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["chemical-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["centrifuge"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["lab"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["rocket-silo"] = {
["module"] = "productivity-module-3",
["prod"] = true,
}
},
["space-age"] = {
["big-mining-drill"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["biochamber"] = {
["module"] = "efficiency-module",
["prod"] = true,
},
["electromagnetic-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["cryogenic-plant"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["biolab"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["foundry"] = {
["module"] = "productivity-module-3",
["prod"] = true,
},
["recycler"] = {
["module"] = "quality-module-3",
["prod"] = true,
}
}
}
@@ -0,0 +1,63 @@
--- The bonuses players can spend their points on, see gui/player_bonus.lua
-- @config Player-Bonus
return {
{
name = "character_mining_speed_modifier",
scale = 1,
cost = 10,
max_value = 4,
value_step = 0.5,
is_percentage = true,
},
{
name = "character_running_speed_modifier",
scale = 1,
cost = 60,
max_value = 2,
value_step = 0.25,
is_percentage = true,
},
{
name = "character_crafting_speed_modifier",
scale = 1,
cost = 4,
max_value = 12,
value_step = 1,
is_percentage = true,
},
{
name = "character_inventory_slots_bonus",
scale = 10,
cost = 2,
max_value = 100,
value_step = 10,
},
{
name = "character_health_bonus",
scale = 50,
cost = 4,
max_value = 300,
value_step = 50,
},
{
name = "character_reach_distance_bonus",
scale = 1,
cost = 1,
max_value = 16,
value_step = 2,
combined_bonus = {
"character_resource_reach_distance_bonus",
"character_build_distance_bonus",
},
},
{
name = "personal_battery_recharge",
scale = 4,
cost = 40,
max_value = 8,
value_step = 1,
is_special = true,
},
}
@@ -1,40 +1,20 @@
--- Res Settings
-- @config Research
--- Research data by mod set, the first set in mod_set_lookup whose mod is active is used
-- @config Research-Data
return {
enabled = true,
pollution_ageing_by_research = false,
queue_amount = 3,
mod_set = "base",
local data = {
mod_set_lookup = {
"space-age",
},
-- this enable 20 more inventory for each mining productivity level up to 4
bonus_inventory = {
enabled = true,
res = {
-- Mining Productivity
["mining-productivity"] = true,
["mining-productivity-2"] = true,
["mining-productivity-3"] = true,
["mining-productivity-4"] = true,
final_res = {
["base"] = {
["name"] = "mining-productivity-4",
["level"] = 4
},
name = "character_inventory_slots_bonus",
rate = 5,
limit = 20,
},
file = {
name = "log/research.log",
final_res = {
["base"] = {
["name"] = "mining-productivity-4",
["level"] = 4
},
["space-age"] = {
["name"] = "mining-productivity-3",
["level"] = 3
}
["space-age"] = {
["name"] = "mining-productivity-3",
["level"] = 3
}
},
milestone = {
["base"] = {
@@ -177,3 +157,13 @@ return {
-- ["atomic-bomb"] = 1
},
}
data.mod_set = "base"
for _, mod_name in ipairs(data.mod_set_lookup) do
if script.active_mods[mod_name] then
data.mod_set = mod_name
break
end
end
return data
@@ -1,14 +1,12 @@
--- This file is used to setup the map starting settings and the items players will start with
-- @config Advanced-Start
--- The items players start with, and how many depending on what the factory has made
-- @config Starting-Items
--- These are called factories because they return another function
-- use these as a simple methods of adding new items
-- they will do most of the work for you
-- ['item-name'] = factory(params)
-- luacheck:ignore 212/amount_made 212/items_made 212/player
-- Use these to adjust for ticks ie game.tick < 5*minutes
-- luacheck:ignore 211/seconds 211/minutes 211/hours
local seconds, minutes, hours = 60, 3600, 216000
--- Use to make a split point for the number of items given based on time
@@ -72,41 +70,34 @@ end
hours, minutes, seconds are the number of ticks in each unit of time
]]
--- @type table<string, number | fun(amount_made: number, items_made: fun(name: string): number, player: LuaPlayer): number>
return {
skip_intro = true, --- @setting skip_intro skips the intro given in the default factorio free play scenario
skip_victory = true, --- @setting skip_victory will skip the victory screen when a rocket is launched
friendly_fire = false, --- @setting friendly_fire weather players will be able to attack each other on the same force
disable_crashsite = true, --- @setting disable_crashsite weather to disable creation of the crashsite
enemy_expansion = false, --- @setting enemy_expansion a catch all for in case the map settings file fails to load
chart_radius = 10 * 32, --- @setting chart_radius the number of tiles that will be charted when the map starts
items = { --- @setting items items and there condition for being given
-- ['item-name'] = function(amount_made, production_stats, player) return <Number> end -- 0 means no items given
-- Plates
["iron-plate"] = scale_amount_made(100, 10, 10),
["copper-plate"] = scale_amount_made(100, 0, 8),
["steel-plate"] = scale_amount_made(100, 0, 4),
-- Secondary Items
["electronic-circuit"] = scale_amount_made(1000, 0, 6),
["iron-gear-wheel"] = scale_amount_made(1000, 0, 6),
-- Starting Items
["burner-mining-drill"] = cutoff_time(10 * minutes, 4, 0),
["stone-furnace"] = cutoff_time(10 * minutes, 4, 0),
-- Armor
["light-armor"] = cutoff_amount_made_unless(5, 0, 1, "heavy-armor", 5),
["heavy-armor"] = cutoff_amount_made(5, 0, 1),
-- Weapon
["pistol"] = cutoff_amount_made_unless(0, 1, 1, "submachine-gun", 5),
["submachine-gun"] = cutoff_amount_made(5, 0, 1),
-- Ammo
["firearm-magazine"] = cutoff_amount_made_unless(100, 10, 0, "piercing-rounds-magazine", 100),
["piercing-rounds-magazine"] = cutoff_amount_made(100, 0, 10),
--[[
['construction-robot'] = 10,
['modular-armor'] = 1,
['solar-panel-equipment'] = 16,
['belt-immunity-equipment'] = 1,
['battery-equipment'] = 2,
['personal-roboport-equipment'] = 1
]]
}
-- ['item-name'] = function(amount_made, production_stats, player) return <Number> end -- 0 means no items given
-- Plates
["iron-plate"] = scale_amount_made(100, 10, 10),
["copper-plate"] = scale_amount_made(100, 0, 8),
["steel-plate"] = scale_amount_made(100, 0, 4),
-- Secondary Items
["electronic-circuit"] = scale_amount_made(1000, 0, 6),
["iron-gear-wheel"] = scale_amount_made(1000, 0, 6),
-- Starting Items
["burner-mining-drill"] = cutoff_time(10 * minutes, 4, 0),
["stone-furnace"] = cutoff_time(10 * minutes, 4, 0),
-- Armor
["light-armor"] = cutoff_amount_made_unless(5, 0, 1, "heavy-armor", 5),
["heavy-armor"] = cutoff_amount_made(5, 0, 1),
-- Weapon
["pistol"] = cutoff_amount_made_unless(0, 1, 1, "submachine-gun", 5),
["submachine-gun"] = cutoff_amount_made(5, 0, 1),
-- Ammo
["firearm-magazine"] = cutoff_amount_made_unless(100, 10, 0, "piercing-rounds-magazine", 100),
["piercing-rounds-magazine"] = cutoff_amount_made(100, 0, 10),
--[[
['construction-robot'] = 10,
['modular-armor'] = 1,
['solar-panel-equipment'] = 16,
['belt-immunity-equipment'] = 1,
['battery-equipment'] = 2,
['personal-roboport-equipment'] = 1
]]
}
+147
View File
@@ -0,0 +1,147 @@
--- The items the vlayer can hold and what they do, see control/vlayer.lua
-- @config Vlayer-Items
return {
--- @class Vlayer.ItemProperties
--- @field starting_value number
--- @field required_area number
--- @field production number?
--- @field discharge number?
--- @field capacity number?
--- @field surface_area number?
--- @field fuel_value number?
--- @field power boolean?
--- @field modded boolean? Set when the item is registered from a modded equivalent
--- @field base_game_equivalent string?
--- @field multiplier number?
--- @type table<string, Vlayer.ItemProperties>
allowed_items = { -- List of all items allowed in vlayer storage and their properties
--[[
Allowed properties:
starting_value : The amount of the item placed into the vlayer on game start, ignores area requirements
required_area : When greater than 0 the items properties are not applied unless their is sufficient surplus surface area
production : The energy production of the item in MW, used for solar panels
discharge : The energy discharge of the item in MW, used for accumulators
capacity : The energy capacity of the item in MJ, used for accumulators
surface_area : The surface area provided by the item, used for landfill
]]
["solar-panel"] = {
starting_value = 0,
required_area = 9,
production = 0.06, -- MW
},
["accumulator"] = {
starting_value = 0,
required_area = 4,
discharge = 0.3, -- MW
capacity = 5, -- MJ
},
["landfill"] = {
starting_value = 0,
required_area = 0,
surface_area = 20, -- Tiles
},
["wood"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 2, -- MJ
power = true, -- turn all wood to power to reduce trash
},
["coal"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 4, -- MJ
power = false, -- turn all coal to power to reduce trash
},
["solid-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 12, -- MJ
power = false, -- turn all solid fuel to power to reduce trash
},
["rocket-fuel"] = {
starting_value = 0,
required_area = 0,
surface_area = 0,
fuel_value = 100, -- MJ
power = false, -- turn all rocket fuel to power to reduce trash
}
},
modded_items = { -- List of all modded items allowed in vlayer storage and their base game equivalent
["solar-panel-2"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 4,
},
["solar-panel-3"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 16,
},
["solar-panel-4"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 64,
},
["solar-panel-5"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 256,
},
["solar-panel-6"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 1024,
},
["solar-panel-7"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 4096,
},
["solar-panel-8"] = {
starting_value = 0,
base_game_equivalent = "solar-panel",
multiplier = 16384,
},
["accumulator-2"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 4,
},
["accumulator-3"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 16,
},
["accumulator-4"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 64,
},
["accumulator-5"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 256,
},
["accumulator-6"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 1024,
},
["accumulator-7"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 4096,
},
["accumulator-8"] = {
starting_value = 0,
base_game_equivalent = "accumulator",
multiplier = 16384,
},
}
}
+70 -42
View File
@@ -1,42 +1,70 @@
--[[ Control - Bonus
Various bonus related event handlers
TODO Refactor this fully, this is temp to get it out of the player bonus gui file
]]
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/bonus")
--- @param event EventData.on_force_created
local function apply_force_bonus(event)
local force = event.force
for k, v in pairs(config.force_bonus) do
force[k] = math.floor(v.max_value / 2)
end
end
--- @param event EventData.on_surface_created
local function apply_surface_bonus(event)
local surface = assert(game.get_surface(event.surface_index))
for k, v in pairs(config.surface_bonus) do
surface[k] = math.floor(v.max_value / 2)
end
end
--- @param event EventData.on_player_died
local function fast_respawn(event)
local player = assert(game.get_player(event.player_index))
if Roles.player_has_permission(player, "exp_scenario.player.instant_respawn") then
player.ticks_to_respawn = 120
end
end
local e = defines.events
return {
events = {
[e.on_force_created] = apply_force_bonus,
[e.on_surface_created] = apply_surface_bonus,
[e.on_player_died] = fast_respawn,
}
}
--[[ Control - Bonus
Various bonus related event handlers
TODO Refactor this fully, this is temp to get it out of the player bonus gui file
]]
local Roles = require("modules/exp_roles")
--- Force bonuses are started at half their max value
local force_bonus = {
["worker_robots_battery_modifier"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
["worker_robots_storage_bonus"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
["following_robots_lifetime_modifier"] = {
max_value = 1,
value_step = 1,
scale = 1,
cost = 1,
is_percentage = false,
},
}
--- Surface bonuses are started at half their max value
local surface_bonus = {}
--- @param event EventData.on_force_created
local function apply_force_bonus(event)
local force = event.force
for k, v in pairs(force_bonus) do
force[k] = math.floor(v.max_value / 2)
end
end
--- @param event EventData.on_surface_created
local function apply_surface_bonus(event)
local surface = assert(game.get_surface(event.surface_index))
for k, v in pairs(surface_bonus) do
surface[k] = math.floor(v.max_value / 2)
end
end
--- @param event EventData.on_player_died
local function fast_respawn(event)
local player = assert(game.get_player(event.player_index))
if Roles.player_has_permission(player, "exp_scenario.player.instant_respawn") then
player.ticks_to_respawn = 120
end
end
local e = defines.events
return {
events = {
[e.on_force_created] = apply_force_bonus,
[e.on_surface_created] = apply_surface_bonus,
[e.on_player_died] = fast_respawn,
}
}
+14 -3
View File
@@ -2,9 +2,20 @@
Changes the starting script and the items given on first join depending on factory production levels
]]
local config = require("modules.exp_legacy.config.advanced_start")
local Feature = require("modules/exp_scenario/features")
local starting_items = require("modules/exp_scenario/config/starting_items")
local floor = math.floor
--- Applied when the map is created
local feature, config = Feature.register("custom_start", {
skip_intro = true, -- skips the intro given in the default factorio free play scenario
skip_victory = true, -- will skip the victory screen when a rocket is launched
friendly_fire = false, -- weather players will be able to attack each other on the same force
disable_crashsite = true, -- weather to disable creation of the crashsite
enemy_expansion = false, -- a catch all for in case the map settings file fails to load
chart_radius = 320, -- the number of tiles that will be charted when the map starts
})
--- Give a player their starting items
--- @param player LuaPlayer
local function give_starting_items(player)
@@ -12,7 +23,7 @@ local function give_starting_items(player)
local get_input_count = get_prod_stats.get_input_count
local insert_param = { name = "", count = 0 }
local insert = player.insert
for item_name, insert_amount in pairs(config.items) do
for item_name, insert_amount in pairs(starting_items) do
insert_param.name = item_name
if type(insert_amount) == "function" then
local count = insert_amount(get_input_count(item_name), get_input_count, player)
@@ -55,7 +66,7 @@ end
local e = defines.events
return {
return feature:guard{
on_init = on_init,
events = {
[e.on_player_created] = on_player_created,
@@ -5,7 +5,16 @@ Log certain actions into a file when events are triggered
local ExpUtil = require("modules/exp_util")
local Storage = require("modules/exp_util/storage")
local Roles = require("modules/exp_roles")
local config = require("modules.exp_legacy.config.deconlog")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("deconstruction_log", {
decon_area = true, -- log when an area is deconstructed
built_entity = true, -- log when an entity is built
mined_entity = true, -- log when an entity is mined
fired_rocket = true, -- log when a rocket is fired
fired_explosive_rocket = true, -- log when an explosive rocket is fired
fired_nuke = true, -- log when a nuke is fired
})
local seconds_time_format = ExpUtil.format_time_factory{ format = "short", hours = true, minutes = true, seconds = true }
local format_number = require("util").format_number
@@ -90,6 +99,7 @@ end
--- Log when an area is deconstructed
--- @param event EventData.on_player_deconstructed_area
local function on_player_deconstructed_area(event)
if not config.decon_area then return end
local player = get_log_player(event)
if not player then return end
@@ -118,6 +128,7 @@ end
--- Log when an entity is built
--- @param event EventData.on_built_entity
local function on_built_entity(event)
if not config.built_entity then return end
local player = get_log_player(event)
if not player then return end
add_log_line(player, "built_entity", format_entity(event.entity))
@@ -126,16 +137,17 @@ end
--- Log when an entity is mined
--- @param event EventData.on_player_mined_entity
local function on_player_mined_entity(event)
if not config.mined_entity then return end
local player = get_log_player(event)
if not player then return end
add_log_line(player, "mined_entity", format_entity(event.entity))
end
--- Ammo which is logged when fired
local logged_ammo = {
["rocket"] = config.fired_rocket,
["explosive-rocket"] = config.fired_explosive_rocket,
["atomic-bomb"] = config.fired_nuke,
--- The setting which decides if a shot of an ammo is logged
local ammo_settings = {
["rocket"] = "fired_rocket",
["explosive-rocket"] = "fired_explosive_rocket",
["atomic-bomb"] = "fired_nuke",
}
--- @class ExpScenario_DeconstructionLog.AmmoSlot
@@ -186,7 +198,7 @@ local function on_player_ammo_inventory_changed(event)
fired = previous.name
end
if fired and logged_ammo[fired] then
if fired and config[ammo_settings[fired]] then
add_log_line(player, "shot-" .. fired, format_position(player.physical_position), format_position(player.shooting_state.position))
end
end
@@ -206,29 +218,16 @@ local function on_player_left_game(event)
end
local e = defines.events
local events = {
[e.on_multiplayer_init] = clear_log,
}
if config.decon_area then
events[e.on_player_deconstructed_area] = on_player_deconstructed_area
end
if config.built_entity then
events[e.on_built_entity] = on_built_entity
end
if config.mined_entity then
events[e.on_player_mined_entity] = on_player_mined_entity
end
if config.fired_rocket or config.fired_explosive_rocket or config.fired_nuke then
events[e.on_player_ammo_inventory_changed] = on_player_ammo_inventory_changed
events[e.on_player_joined_game] = on_player_character_changed
events[e.on_player_respawned] = on_player_character_changed
events[e.on_player_left_game] = on_player_left_game
end
return {
events = events,
return feature:guard{
events = {
[e.on_multiplayer_init] = clear_log,
[e.on_player_deconstructed_area] = on_player_deconstructed_area,
[e.on_built_entity] = on_built_entity,
[e.on_player_mined_entity] = on_player_mined_entity,
[e.on_player_ammo_inventory_changed] = on_player_ammo_inventory_changed,
[e.on_player_joined_game] = on_player_character_changed,
[e.on_player_respawned] = on_player_character_changed,
[e.on_player_left_game] = on_player_left_game,
},
}
+102 -7
View File
@@ -2,13 +2,108 @@
When a player walks around the tiles under them will degrade over time, the same is true when entites are built
]]
local config = require("modules.exp_legacy.config.scorched_earth")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("degrading_tiles", {
weakness_value = 70, -- lower value will make tiles more likely to degrade
entities = Feature.set{ -- entities which degrade the tiles under them when they are placed
"stone-furnace", "steel-furnace", "electric-furnace", "assembling-machine-1", "assembling-machine-2", "assembling-machine-3",
"beacon", "centrifuge", "chemical-plant", "oil-refinery", "storage-tank", "nuclear-reactor",
"steam-engine", "steam-turbine", "boiler", "heat-exchanger", "stone-wall", "gate",
"gun-turret", "laser-turret", "flamethrower-turret", "radar", "lab", "big-electric-pole",
"substation", "rocket-silo", "pumpjack", "electric-mining-drill", "roboport", "accumulator",
},
})
local random = math.random
--- How "strong" a tile is, bigger number means less likely to degrade
local strengths = {
-- debug: /interface require('modules.addons.worn-paths')(player.name,true)
-- note: tiles are effected by the tiles around them, so player paths will not degrade as fast when made wider
-- note: values are relative to the tile with the highest value, recommended to keep highest tile as a "nice" number
-- note: tiles not in list will never degrade under any conditions (which is why some are omitted such as water)
["refined-concrete"] = 100,
["refined-hazard-concrete-left"] = 100,
["refined-hazard-concrete-right"] = 100,
["concrete"] = 90,
["hazard-concrete-left"] = 90,
["hazard-concrete-right"] = 90,
["stone-path"] = 80,
["red-desert-0"] = 80,
["dry-dirt"] = 50,
-- grass four (main grass tiles)
["grass-1"] = 50,
["grass-2"] = 40,
["grass-3"] = 30,
["grass-4"] = 25,
-- red three (main red tiles)
["red-desert-1"] = 40,
["red-desert-2"] = 30,
["red-desert-3"] = 25,
-- sand three (main sand tiles)
["sand-1"] = 40,
["sand-2"] = 30,
["sand-3"] = 25,
-- dirt 3 (main dirt tiles)
["dirt-1"] = 40,
["dirt-2"] = 30,
["dirt-3"] = 25,
-- last three/four (all sets of three merge here)
["dirt-4"] = 25,
["dirt-5"] = 30,
["dirt-6"] = 40,
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]=50,
-- ["water-shallow"]=90,
-- ["water-mud"]=0, -- last tile, nothing to degrade to
}
--- When a tile degrades it will turn into the next tile given here
local degrade_order = {
["refined-concrete"] = "concrete",
["refined-hazard-concrete-left"] = "hazard-concrete-left",
["refined-hazard-concrete-right"] = "hazard-concrete-right",
["concrete"] = "stone-path",
["hazard-concrete-left"] = "stone-path",
["hazard-concrete-right"] = "stone-path",
["stone-path"] = "dry-dirt",
["red-desert-0"] = "dry-dirt",
["dry-dirt"] = "dirt-4",
-- grass four (main grass tiles)
["grass-1"] = "grass-2",
["grass-2"] = "grass-3",
["grass-3"] = "grass-4",
["grass-4"] = "dirt-4",
-- red three (main red tiles)
["red-desert-1"] = "red-desert-2",
["red-desert-2"] = "red-desert-3",
["red-desert-3"] = "dirt-4",
-- sand three (main sand tiles)
["sand-1"] = "sand-2",
["sand-2"] = "sand-3",
["sand-3"] = "dirt-4",
-- dirt 3 (main dirt tiles)
["dirt-1"] = "dirt-2",
["dirt-2"] = "dirt-3",
["dirt-3"] = "dirt-4",
-- last three/four (all sets of three merge here)
["dirt-4"] = "dirt-5",
["dirt-5"] = "dirt-6",
["dirt-6"] = "dirt-7",
-- ["dirt-7"]=0, -- last tile, nothing to degrade to
-- land fill chain
-- ["landfill"]='grass-2', -- 'water-shallow'
-- ["water-shallow"]='water-mud',
-- ["water-mud"]=0, -- last tile, nothing to degrade to
}
--- Get the max tile strength
local max_strength = 0
for _, strength in pairs(config.strengths) do
for _, strength in pairs(strengths) do
if strength > max_strength then
max_strength = strength
end
@@ -20,7 +115,7 @@ end
local function degrade_tile(surface, position)
local tile = surface.get_tile(position.x, position.y)
local tile_name = tile.name
local degrade_tile_name = config.degrade_order[tile_name]
local degrade_tile_name = degrade_order[tile_name]
if not degrade_tile_name then return end
surface.set_tiles{ { name = degrade_tile_name, position = position } }
end
@@ -39,7 +134,7 @@ local function degrade_entity(entity)
for y = left_top.y, right_bottom.y do
local tile = surface.get_tile(x, y)
local tile_name = tile.name
local degrade_tile_name = config.degrade_order[tile_name]
local degrade_tile_name = degrade_order[tile_name]
if degrade_tile_name then
tiles[#tiles + 1] = { name = degrade_tile_name, position = { x, y } }
end
@@ -63,14 +158,14 @@ end
local function get_tile_strength(surface, position)
local tile = surface.get_tile(position.x, position.y)
local tile_name = tile.name
local strength = config.strengths[tile_name]
local strength = strengths[tile_name]
if not strength then return end
for x = position.x - 1, position.x + 1 do
for y = position.y - 1, position.y + 1 do
local check_tile = surface.get_tile(x, y)
local check_tile_name = check_tile.name
local check_strength = config.strengths[check_tile_name] or 0
local check_strength = strengths[check_tile_name] or 0
strength = strength + check_strength
end
end
@@ -108,7 +203,7 @@ end
local e = defines.events
return {
return feature:guard{
events = {
[e.on_player_changed_position] = on_player_changed_position,
[e.on_robot_built_entity] = on_built_entity,
+38 -7
View File
@@ -2,8 +2,39 @@
Log some extra events to a separate file
]]
local config = require("modules.exp_legacy.config.logging")
local config_res = require("modules.exp_legacy.config.research")
local Feature = require("modules/exp_scenario/features")
local research_data = require("modules/exp_scenario/config/research_data")
local feature, config = Feature.register("extra_logging", {
file_name = "log/logging.log", -- the file the lines are written to
rocket_launch_display_rate = 500, -- after the counts below, log every this many rockets
})
--- Rocket counts which are always logged
local rocket_launch_display = {
[1] = true,
[2] = true,
[5] = true,
[10] = true,
[20] = true,
[50] = true,
[100] = true,
[200] = true,
}
local disconnect_reason = {
[defines.disconnect_reason.quit] = "left the game",
[defines.disconnect_reason.dropped] = "was dropped from the game",
[defines.disconnect_reason.reconnect] = "is reconnecting",
[defines.disconnect_reason.wrong_input] = "was having a wrong input",
[defines.disconnect_reason.desync_limit_reached] = "had desync limit reached",
[defines.disconnect_reason.cannot_keep_up] = "cannot keep up",
[defines.disconnect_reason.afk] = "was afk",
[defines.disconnect_reason.kicked] = "was kicked",
[defines.disconnect_reason.kicked_and_deleted] = "was kicked and deleted",
[defines.disconnect_reason.banned] = "was banned",
[defines.disconnect_reason.switching_servers] = "is switching servers",
}
local concat = table.concat
local write_file = helpers.write_file
@@ -26,7 +57,7 @@ local function on_cargo_pod_finished_ascending(event)
local force = event.cargo_pod.force --[[@as LuaForce]]
if force.rockets_launched >= config.rocket_launch_display_rate and force.rockets_launched % config.rocket_launch_display_rate == 0 then
add_log_line("[ROCKET]", force.rockets_launched, "rockets launched")
elseif config.rocket_launch_display[force.rockets_launched] then
elseif rocket_launch_display[force.rockets_launched] then
add_log_line("[ROCKET]", force.rockets_launched, "rockets launched")
end
end
@@ -53,7 +84,7 @@ local function on_research_finished(event)
return
end
local inf_research_level = config_res.inf_res[config_res.mod_set][event.research.name]
local inf_research_level = research_data.inf_res[research_data.mod_set][event.research.name]
if inf_research_level and event.research.level >= inf_research_level then
add_log_line_locale{ "", "[RES]", event.research.prototype.localised_name, " at level ", event.research.level - 1, " has been researched\n" }
else
@@ -70,17 +101,17 @@ end
--- @param event EventData.on_player_left_game
local function on_player_left_game(event)
local player = assert(game.get_player(event.player_index))
add_log_line("[LEAVE]", player.name, config.disconnect_reason[event.reason])
add_log_line("[LEAVE]", player.name, disconnect_reason[event.reason])
end
local e = defines.events
return {
return feature:guard{
events = {
[e.on_cargo_pod_finished_ascending] = on_cargo_pod_finished_ascending,
[e.on_pre_player_died] = on_pre_player_died,
[e.on_research_finished] = on_research_finished,
[e.on_player_joined_game] = on_player_joined_game,
[e.on_player_left_game] = on_player_left_game,
}
},
}
+32 -5
View File
@@ -4,7 +4,34 @@ Adds friendly biters that walk around and give helpful messages
local Async = require("modules/exp_util/async")
local Storage = require("modules/exp_util/storage")
local config = require("modules.exp_legacy.config.compilatron")
local Feature = require("modules/exp_scenario/features")
local config_server_detail = require("modules.exp_legacy.config.server_detail")
local feature = Feature.register("help_bubbles")
--- Ticks between message changes
local message_cycle = 60 * 15
local locations = {
["Spawn"] = {
spawn_position = { x = 0, y = 0 },
spawn_surface = "nauvis",
entity_name = "small-biter",
messages = {
{ "info.website", config_server_detail["website"] },
{ "info.read-readme" },
{ "info.discord", config_server_detail["discord"] },
{ "info.softmod" },
{ "info.redmew" },
{ "info.custom-commands" },
{ "info.status", config_server_detail["status"] },
{ "info.lhd" },
{ "info.github", config_server_detail["github"] },
{ "info.patreon", config_server_detail["patreon"] },
},
}
}
--- @type table<string, Async.AsyncReturn<any>>
local persistent_locations = {}
@@ -48,7 +75,7 @@ local speech_bubble_task =
task.previous_message = entity.surface.create_entity(speech_bubble_param)
task.current_message_index = index + 1
return Async.status.delay(config.message_cycle, task)
return Async.status.delay(message_cycle, task)
end)
--- Register an entity to start spawning speech bubbles
@@ -66,7 +93,7 @@ end
--- Check all persistent locations from the config are active
local function check_persistent_locations()
for name, location in pairs(config.locations) do
for name, location in pairs(locations) do
local task = persistent_locations[name]
if task and not task.completed then
goto continue
@@ -92,9 +119,9 @@ local function check_persistent_locations()
end
end
return {
return feature:guard{
on_nth_tick = {
[config.message_cycle] = check_persistent_locations,
[message_cycle] = check_persistent_locations,
},
register_entity = register_entity,
}
@@ -6,7 +6,15 @@ on_player_kicked - player_index
]]
local ExpUtil = require("modules/exp_util")
local events = require("modules.exp_legacy.config.inventory_clear")
local Feature = require("modules/exp_scenario/features")
local feature = Feature.register("inventory_clear")
--- The events which clear the inventory of the player
local events = {
defines.events.on_player_banned,
defines.events.on_player_kicked,
}
--- @param event { player_index: number }
local function clear_items(event)
@@ -26,6 +34,6 @@ for _, event_name in ipairs(events) do
event_handlers[event_name] = clear_items
end
return {
return feature:guard{
events = event_handlers,
}
@@ -2,7 +2,16 @@
Makes pollution look much nice of the map, ie not one big red mess
]]
local config = require("modules.exp_legacy.config.pollution_grading")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("pollution_grading", {
reference_point = { -- where pollution is read from
x = 0,
y = 0,
},
max_scalar = 0.5, -- the scale between true max and max
min_scalar = 0.17, -- the scale between the lowest max and min
})
local function check_surfaces()
local max_reference = 0
@@ -20,8 +29,8 @@ local function check_surfaces()
settings.min_to_show_per_chunk = min
end
return {
return feature:guard{
on_nth_tick = {
[config.update_delay * 3600] = check_surfaces,
}
[15 * 3600] = check_surfaces,
},
}
+62 -48
View File
@@ -1,48 +1,62 @@
--[[ Control - Research
Various research related event handlers
TODO Refactor this fully, this is temp to get it out of the research times gui file
]]
local config = require("modules/exp_legacy/config/research")
--- @param event EventData.on_research_finished
local function on_research_finished(event)
local research_name = event.research.name
if config.bonus_inventory.enabled and config.bonus_inventory.res[research_name] then
event.research.force[config.bonus_inventory.name] = math.min((event.research.level - 1) * config.bonus_inventory.rate, config.bonus_inventory.limit)
end
if config.pollution_ageing_by_research and config.bonus_inventory.res[research_name] then
game.map_settings.pollution.ageing = math.min(10, event.research.level / 5)
end
end
--- @param event EventData.on_research_started
local function on_research_started(event)
if config.limit_res[event.research.name] and event.research.level > config.limit_res[event.research.name] then
event.research.enabled = false
event.research.visible_when_disabled = true
local rq = event.research.force.research_queue
for i = #rq, 1, -1 do
if rq[i] == event.research.name then
table.remove(rq, i)
end
end
event.research.force.cancel_current_research()
event.research.force.research_queue = rq
end
end
local e = defines.events
return {
events = {
[e.on_research_finished] = on_research_finished,
[e.on_research_reversed] = on_research_finished,
[e.on_research_started] = on_research_started,
[e.on_research_queued] = on_research_started,
}
}
--[[ Control - Research
Various research related event handlers
TODO Refactor this fully, this is temp to get it out of the research times gui file
]]
local Feature = require("modules/exp_scenario/features")
local research_data = require("modules/exp_scenario/config/research_data")
local feature, config = Feature.register("research", {
pollution_ageing_by_research = false, -- pollution ages faster with each level of the bonus inventory researches
bonus_inventory = { -- extra inventory slots for each level of these researches
enabled = true,
res = Feature.set{ "mining-productivity", "mining-productivity-2", "mining-productivity-3", "mining-productivity-4" },
rate = 5,
limit = 20,
},
})
local bonus_inventory_name = "character_inventory_slots_bonus"
--- @param event EventData.on_research_finished
local function on_research_finished(event)
local research_name = event.research.name
if config.bonus_inventory.enabled and config.bonus_inventory.res[research_name] then
event.research.force[bonus_inventory_name] = math.min((event.research.level - 1) * config.bonus_inventory.rate, config.bonus_inventory.limit)
end
if config.pollution_ageing_by_research and config.bonus_inventory.res[research_name] then
game.map_settings.pollution.ageing = math.min(10, event.research.level / 5)
end
end
--- @param event EventData.on_research_started
local function on_research_started(event)
local limit = research_data.limit_res[event.research.name]
if limit and event.research.level > limit then
event.research.enabled = false
event.research.visible_when_disabled = true
local rq = event.research.force.research_queue
for i = #rq, 1, -1 do
if rq[i] == event.research.name then
table.remove(rq, i)
end
end
event.research.force.cancel_current_research()
event.research.force.research_queue = rq
end
end
local e = defines.events
return feature:guard{
events = {
[e.on_research_finished] = on_research_finished,
[e.on_research_reversed] = on_research_finished,
[e.on_research_started] = on_research_started,
[e.on_research_queued] = on_research_started,
}
}
+56 -12
View File
@@ -4,7 +4,43 @@ Stores solar panels, accumulators and landfill in a virtual layer which produces
local ExpUtil = require("modules/exp_util")
local Storage = require("modules/exp_util/storage")
local config = require("modules.exp_legacy.config.vlayer")
local Feature = require("modules/exp_scenario/features")
local items = require("modules/exp_scenario/config/vlayer_items")
local feature, config = Feature.register("vlayer", {
unlimited_capacity = false, -- an unlimited energy capacity, accumulators are not required
unlimited_surface_area = false, -- an unlimited surface area, landfill is not required
modded_auto_downgrade = false, -- modded items are converted into their base game equivalent, the originals can not be recovered
power_on_space = false, -- energy interfaces can be built on platforms
power_on_space_research = { -- the research level needed to build them there
name = "research-productivity",
level = 10,
},
mimic_surface = "nauvis", -- the surface the day cycle is copied from, empty to use the fixed cycle below
interface_limit = { -- how many of each interface can exist
energy = 1, -- >1 allows for disconnected power networks to receive power
circuit = 20,
storage_input = 20,
storage_output = 1, -- >0 allows for item teleportation of the allowed items
},
})
local update_tick_storage = 60
local update_tick_energy = 10
--- The day cycle used when there is no mimic surface, see LuaSurface for details
local surface_settings = {
always_day = false,
solar_power_multiplier = 1,
min_brightness = 0.15,
ticks_per_day = 25200,
daytime = 0,
dusk = 0.25,
evening = 0.45,
morning = 0.55,
dawn = 0.75,
}
local floor = math.floor
local min = math.min
@@ -58,6 +94,9 @@ local mega = 1000000
--- @class ExpScenario_Vlayer
local Vlayer = {
--- The config of the feature, read only
config = config,
feature = feature,
--- @package
events = {},
--- @package
@@ -66,11 +105,11 @@ local Vlayer = {
--- The properties of every allowed item, modded items are derived from their base game equivalent
local allowed_items = {} --- @type table<string, Vlayer.ItemProperties>
for name, properties in pairs(config.allowed_items) do
for name, properties in pairs(items.allowed_items) do
allowed_items[name] = properties
end
for name, properties in pairs(config.modded_items) do
local base = config.allowed_items[properties.base_game_equivalent]
for name, properties in pairs(items.modded_items) do
local base = items.allowed_items[properties.base_game_equivalent]
local multiplier = properties.multiplier
allowed_items[name] = {
starting_value = properties.starting_value or 0,
@@ -103,7 +142,7 @@ local vlayer_data = {
power_items = {},
energy = 0,
},
surface = table.deep_copy(config.surface),
surface = table.deep_copy(surface_settings),
}
Storage.register(vlayer_data, function(tbl)
@@ -490,7 +529,7 @@ local function handle_input_interfaces()
end
if removed > 0 then
local modded = config.modded_items[name]
local modded = items.modded_items[name]
if modded and config.modded_auto_downgrade then
Vlayer.insert_item(modded.base_game_equivalent, stored * modded.multiplier)
elseif vlayer_data.storage.power_items[name] then
@@ -595,7 +634,7 @@ end
local function handle_energy_interfaces()
local storage = vlayer_data.storage
local properties = vlayer_data.properties
local production = properties.production * mega * (config.update_tick_energy / 60)
local production = properties.production * mega * (update_tick_energy / 60)
storage.energy = storage.energy + floor(production * get_production_multiplier())
local interfaces = vlayer_data.interfaces.energy
@@ -634,7 +673,7 @@ end
--- Take the day cycle from the mimic surface when it exists, otherwise from the config
local function update_surface()
if config.mimic_surface then
if config.mimic_surface ~= "" then
local surface = game.get_surface(config.mimic_surface)
if surface then
vlayer_data.surface = surface
@@ -644,7 +683,7 @@ local function update_surface()
-- The config copy never has an index, so this avoids replacing it every time a surface changes
if not vlayer_data.surface.index then
vlayer_data.surface = table.deep_copy(config.surface)
vlayer_data.surface = table.deep_copy(surface_settings)
end
end
@@ -667,7 +706,12 @@ Vlayer.on_init = update_surface -- The default surface exists before on_surface_
Vlayer.events[e.on_surface_created] = update_surface
Vlayer.events[e.on_surface_renamed] = update_surface
Vlayer.events[e.on_surface_imported] = update_surface
Vlayer.on_nth_tick[config.update_tick_storage] = update_storage
Vlayer.on_nth_tick[config.update_tick_energy] = update_energy
Vlayer.events[Feature.events.on_config_updated] = function(event)
if event.feature_name == feature.name and event.path == "mimic_surface" then
update_surface()
end
end
Vlayer.on_nth_tick[update_tick_storage] = update_storage
Vlayer.on_nth_tick[update_tick_energy] = update_energy
return Vlayer
return feature:guard(Vlayer)
+1 -1
View File
@@ -5,7 +5,7 @@ Adds a config menu for setting autofill of placed entities
local Feature = require("modules/exp_scenario/features")
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local config = require("modules.exp_legacy.config.gui.autofill")
local config = require("modules/exp_scenario/config/autofill")
local feature = Feature.register("autofill")
local FlyingText = require("modules/exp_util/flying_text")
+26 -14
View File
@@ -9,17 +9,29 @@ local Roles = require("modules/exp_roles")
local Selection = require("modules/exp_util/selection")
local SelectArea = Selection.connect("ModuleArea")
local config = require("modules/exp_legacy/config/module")
local Feature = require("modules/exp_scenario/features")
local machine_sets = require("modules/exp_scenario/config/module_inserter_machines")
local feature, config = Feature.register("module_inserter", {
copy_paste_module = true, -- copying a machine also copies its modules
copy_paste_rotation = false, -- copying a machine also copies its rotation
})
local module_slots_per_row = 4
local module_slot_max = 8
--- The machines of the active mod sets
local machines = {}
--- @class ExpGui_ModuleInserter.elements
local Elements = {}
--- Load all the valid machines from the config file
local machine_names = {}
for mod_name, machine_set in pairs(config.machine_sets) do
for mod_name, machine_set in pairs(machine_sets) do
if script.active_mods[mod_name] then
for machine_name, v in pairs(machine_set) do
config.machines[machine_name] = v
machines[machine_name] = v
table.insert(machine_names, machine_name)
end
end
@@ -137,7 +149,7 @@ Elements.module_selector = Gui.define("module_inserter/module_selector")
Elements.module_table = Gui.define("module_inserter/module_table")
:draw(function(def, parent)
--- @cast def ExpGui_ModuleInserter.elements.module_table
local slots_per_row = config.module_slots_per_row + 1
local slots_per_row = module_slots_per_row + 1
return Gui.elements.scroll_table(parent, 280, slots_per_row)
end)
:element_data{} --[[@as any]]
@@ -163,12 +175,12 @@ function Elements.module_table.add_row(module_table)
}
-- Add the module selectors and row separators
local slots_per_row = config.module_slots_per_row + 1
for i = 1, config.module_slot_max do
local slots_per_row = module_slots_per_row + 1
for i = 1, module_slot_max do
if i % slots_per_row == 0 then
row_separators[#row_separators + 1] = module_table.add{ type = "flow", visible = false }
end
module_selectors[i] = Elements.module_selector(module_table, i <= config.module_slots_per_row)
module_selectors[i] = Elements.module_selector(module_table, i <= module_slots_per_row)
end
end
@@ -199,7 +211,7 @@ function Elements.module_table.reset_row(module_table, machine_selector)
separator.visible = false
end
for i, selector in pairs(row.module_selectors) do
selector.visible = i <= config.module_slots_per_row
selector.visible = i <= module_slots_per_row
selector.enabled = false
selector.elem_value = nil
end
@@ -214,16 +226,16 @@ function Elements.module_table.refresh_row(module_table, machine_selector, machi
local row = assert(rows[machine_selector.index])
local active_module_count = assert(prototypes.entity[machine_name].module_inventory_size)
local visible_row_count = math.ceil(active_module_count / config.module_slots_per_row)
local visible_module_count = visible_row_count * config.module_slots_per_row
local module_elem_value = { name = config.machines[machine_name].module }
local visible_row_count = math.ceil(active_module_count / module_slots_per_row)
local visible_module_count = visible_row_count * module_slots_per_row
local module_elem_value = { name = machines[machine_name].module }
for i, separator in pairs(row.row_separators) do
separator.visible = i < visible_row_count
end
for i, selector in pairs(row.module_selectors) do
if i <= active_module_count then
if config.machines[machine_name].prod then
if machines[machine_name].prod then
selector.elem_filters = elem_filter.with_prod
else
selector.elem_filters = elem_filter.no_prod
@@ -259,7 +271,7 @@ Gui.toolbar.create_button{
sprite = "item/productivity-module-3",
tooltip = { "exp-gui_module-inserter.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.module")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.module")
end
}
@@ -499,7 +511,7 @@ end
local e = defines.events
return {
return feature:guard{
elements = Elements,
events = {
[e.on_entity_settings_pasted] = on_entity_settings_pasted,
+52 -21
View File
@@ -4,7 +4,18 @@ Adds a gui that allows players to apply various bonuses
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/bonus")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("player_bonus", {
points = { -- how many points a player can spend on bonuses
base = 174, -- the points of the points role, the standard value of each bonus adds up to this
increase_percentage_per_role_level = 0.03, -- extra points as a fraction of the base for each role above the points role
role_id = Feature.optional("number"), -- the role the base points apply to, without one every player gets the base
},
})
--- Ticks between applications of the periodic bonuses
local periodic_bonus_rate = 300
local Vlayer = require("modules/exp_scenario/control/vlayer")
local format_number = require("util").format_number
@@ -19,11 +30,12 @@ local Elements = {}
--- @field is_percentage boolean
--- @field is_special boolean
--- @field value_step number
--- @field combined_bonus string[]? Bonuses applied together with this one
--- @field _cost_scale number
--- For perf calculate the division of scale against cost ahead of time
--- @type table<string, ExpGui_PlayerBonus.bonus_data>
local player_bonus = config.player_bonus
--- @type ExpGui_PlayerBonus.bonus_data[]
local player_bonus = require("modules/exp_scenario/config/player_bonus")
for _, bonus_data in pairs(player_bonus) do
bonus_data._cost_scale = bonus_data.cost / bonus_data.scale
@@ -71,8 +83,8 @@ do local _points_limit = {} --- @type table<number, number>
local roles = Roles.get_roles()
local positions = {}
for index, role in ipairs(roles) do positions[role.id] = index end
local role = assert(Roles.get_role_by_name(config.points.role_name), "Bonus points role does not exist")
local role_diff = positions[role.id] - positions[Roles.get_player_highest_role(player).id]
local role = config.points.role_id and Roles.get_role(config.points.role_id)
local role_diff = role and positions[role.id] - positions[Roles.get_player_highest_role(player).id] or 0
local points_limit = math.floor(config.points.base * (1 + config.points.increase_percentage_per_role_level * role_diff))
_points_limit[player.index] = points_limit
return points_limit
@@ -375,7 +387,7 @@ Elements.container = Gui.define("player_bonus/container")
Elements.reset_button.link_apply_button(elements.reset_button, elements.apply_button)
Elements.apply_button.link_reset_button(elements.apply_button, elements.reset_button)
for _, bonus_data in pairs(config.player_bonus) do
for _, bonus_data in pairs(player_bonus) do
--- @cast bonus_data ExpGui_PlayerBonus.bonus_data
Elements.bonus_table.add_row(bonus_table, bonus_data, elements)
end
@@ -409,7 +421,7 @@ function Elements.container.clear_player_bonus(player)
if not player.character then
return
end
for _, bonus_data in pairs(config.player_bonus) do
for _, bonus_data in pairs(player_bonus) do
if not bonus_data.is_special then
player[bonus_data.name] = 0
if bonus_data.combined_bonus then
@@ -429,7 +441,7 @@ function Elements.container.apply_player_bonus(player)
end
local player_data = Elements.container.data[player]
for _, bonus_data in pairs(config.player_bonus) do
for _, bonus_data in pairs(player_bonus) do
if not bonus_data.is_special then
local value = player_data[bonus_data.name] or 0
player[bonus_data.name] = value
@@ -462,27 +474,45 @@ Gui.toolbar.create_button{
sprite = "item/exoskeleton-equipment",
tooltip = { "exp-gui_player-bonus.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.bonus")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.bonus")
end
}
--- Recalculate and apply the bonus for a player
--- Recalculate the limit of a player, their bonus is removed when it is exceeded
--- @param player LuaPlayer
--- @return boolean # False when the bonus was removed
local function refresh_points_limit(player)
Elements.bonus_used._clear_points_limit_cache(player)
local bonus_cost = Elements.container.calculate_cost(player)
local within_limit = Elements.bonus_used.refresh_player(player, bonus_cost)
if not within_limit or not Roles.player_has_permission(player, "exp_scenario.gui.bonus") then
Elements.container.clear_player_bonus(player)
return false
end
return true
end
local function recalculate_bonus(event)
local player = Gui.get_player(event)
if event.name == Roles.events.on_player_roles_changed then
-- If the player's roles changed then we will need to recalculate their limit
Elements.bonus_used._clear_points_limit_cache(player)
local bonus_cost = Elements.container.calculate_cost(player)
local within_limit = Elements.bonus_used.refresh_player(player, bonus_cost)
if not within_limit or not Roles.player_has_permission(player, "exp_scenario.gui.bonus") then
Elements.container.clear_player_bonus(player)
return
end
if event.name == Roles.events.on_player_roles_changed and not refresh_points_limit(player) then
return
end
Elements.container.apply_player_bonus(player)
end
--- The points of every player change with the points settings
--- @param event EventData.ExpScenario.on_config_updated
local function on_config_updated(event)
if event.feature_name ~= feature.name then return end
for _, player in pairs(game.connected_players) do
if refresh_points_limit(player) then
Elements.container.apply_player_bonus(player)
end
end
end
--- Apply periodic bonus to a player
--- @param player LuaPlayer
local function apply_personal_battery_recharge(player)
@@ -501,7 +531,7 @@ local function apply_personal_battery_recharge(player)
return -- No grid or already full
end
local recharge_amount = Elements.container.get_player_bonus(player, "personal_battery_recharge") * 100000 * config.periodic_bonus_rate / 6
local recharge_amount = Elements.container.get_player_bonus(player, "personal_battery_recharge") * 100000 * periodic_bonus_rate / 6
for _, equipment in pairs(grid.equipment) do
if equipment.energy < equipment.max_energy then
@@ -524,13 +554,14 @@ end
local e = defines.events
return {
return feature:guard{
elements = Elements,
events = {
[e.on_player_respawned] = recalculate_bonus,
[Roles.events.on_player_roles_changed] = recalculate_bonus,
[Feature.events.on_config_updated] = on_config_updated,
},
on_nth_tick = {
[config.periodic_bonus_rate] = apply_periodic_bonus_online,
[periodic_bonus_rate] = apply_periodic_bonus_online,
}
}
+5 -5
View File
@@ -5,7 +5,7 @@ Adds a player list to show names and play time; also includes action buttons whi
local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/gui/player_list_actions")
local actions = require("modules/exp_scenario/gui/player_list_actions")
--- @class ExpGui_PlayerList.elements
local Elements = {}
@@ -100,7 +100,7 @@ Elements.reason_confirm = Gui.define("player_list/reason_confirm")
}
:on_click(function(_, player, element)
local action_name = Elements.container.get_selected_action(player)
local button_data = action_name and config.buttons[action_name]
local button_data = action_name and actions.buttons[action_name]
if button_data and button_data.reason_callback then
local reason = assert(element.parent).entry.text --[[@as string?]]
if reason == nil or not reason:find("%S") then reason = "no reason given" end
@@ -330,7 +330,7 @@ Elements.action_bar = Gui.define("player_list/action_bar")
action_bar.visible = false
Elements.close_action_bar(action_bar)
for action_name, button_data in pairs(config.buttons) do
for action_name, button_data in pairs(actions.buttons) do
local permission_flow = action_bar.add{ type = "flow", name = action_name }
permission_flow.visible = false
for _, button in ipairs(button_data) do
@@ -356,7 +356,7 @@ function Elements.action_bar.refresh(action_bar, player, selected_player)
end
action_bar.visible = true
for action_name, buttons in pairs(config.buttons) do
for action_name, buttons in pairs(actions.buttons) do
local flow = action_bar[action_name]
if buttons.auth and not buttons.auth(player, selected_player) then
flow.visible = false
@@ -483,7 +483,7 @@ local function select_action(player, selected_action)
Elements.container.set_selected_action(player, selected_action)
Elements.player_table.refresh_player(player)
end
config.set_accessors(Elements.container.get_selected_player, select_action)
actions.set_accessors(Elements.container.get_selected_player, select_action)
--- Add the element to the left flow with a toolbar button
Gui.add_left_element(Elements.container, true)
@@ -1,9 +1,7 @@
--- Config for the different action buttons that show on the player list;
-- each button has the button define(s) given along side an auth function, and optional reason callback;
-- if a reason callback is used then Store.set(action_name_store,player.name,'BUTTON_NAME') should be called during on_click;
-- buttons can be removed from the gui by commenting them out of the config at the bottom of this file;
-- the key used for the name of the button is the permission name used by the role system;
-- @config Player-List
--[[-- Gui - Player List Actions
The action buttons shown on the player list, each with its auth function and optional reason callback.
The key of each button is the permission name used by the role system.
]]
local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_gui")
+12 -15
View File
@@ -5,7 +5,12 @@ Adds a gui for tracking research milestones
local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/research")
local Feature = require("modules/exp_scenario/features")
local research_data = require("modules/exp_scenario/config/research_data")
local feature, config = Feature.register("research_milestones", {
log_file = "log/research.log", -- where the milestone times are written
})
local table_to_json = helpers.table_to_json
local write_file = helpers.write_file
@@ -34,18 +39,10 @@ local research_targets = {
length = 0,
}
--- Select the mod set to be used for milestones
for _, mod_name in ipairs(config.mod_set_lookup) do
if script.active_mods[mod_name] then
config.mod_set = mod_name
break
end
end
do --- Calculate the research targets
local research_index = 1
local total_time = 0
for name, time in pairs(config.milestone[config.mod_set]) do
for name, time in pairs(research_data.milestone[research_data.mod_set]) do
if prototypes.technology[name] and (not prototypes.technology[name].hidden) then
research_targets.index_lookup[name] = research_index
total_time = total_time + time * 60
@@ -328,7 +325,7 @@ function Elements.container.append_log_line(force)
result_data[name] = force_data[research_index]
end
write_file(config.file.name, table_to_json(result_data) .. "\n", true, 0)
write_file(config.log_file, table_to_json(result_data) .. "\n", true, 0)
end
--- Add the element to the left flow with a toolbar button
@@ -339,7 +336,7 @@ Gui.toolbar.create_button{
sprite = "item/space-science-pack",
tooltip = { "exp-gui_research-milestones.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.research")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.research")
end
}
@@ -350,8 +347,8 @@ local function on_research_finished(event)
local force = event.research.force
-- Check if the log should be updated and print a message to chat
if config.inf_res[config.mod_set][research_name] then
local log_requirement = config.file.final_res[config.mod_set]
if research_data.inf_res[research_data.mod_set][research_name] then
local log_requirement = research_data.final_res[research_data.mod_set]
if research_name == log_requirement.name and research_level == log_requirement.level + 1 then
Elements.container.append_log_line(force)
end
@@ -394,7 +391,7 @@ end
local e = defines.events
return {
return feature:guard{
elements = Elements,
events = {
[e.on_research_finished] = on_research_finished,
+35 -17
View File
@@ -5,7 +5,25 @@ Adds a rocket information gui which shows general stats, milestones and build pr
local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/gui/rockets")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("rocket_info", {
show_stats = true, -- the stats section
show_first_rocket = true, -- when the first rocket was launched
show_last_rocket = true, -- when the last rocket was launched
show_fastest_rocket = true, -- the time taken for the fastest rocket
show_total_rockets = true, -- the total number of rockets launched
show_game_avg = true, -- the average across the entire map time
show_milestones = true, -- the milestones section
show_progress = true, -- the build progress section
allow_zoom_to_map = true, -- the zoom to map button
})
--- Each number is one statistic, 5 means the average time taken for the last 5 rockets
local rolling_avg = { 5, 10, 25 }
--- Each number is one statistic, 5 means the time that the 5th rocket was launched
local milestones = { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000 }
--- @class ExpGui_RocketInfo.elements
local Elements = {}
@@ -26,7 +44,7 @@ local font_color = {
-- The largest rolling average is used to know when an old launch time can be discarded
local largest_rolling_avg = 0
for _, avg_over in pairs(config.stats.rolling_avg) do
for _, avg_over in pairs(rolling_avg) do
if avg_over > largest_rolling_avg then
largest_rolling_avg = avg_over
end
@@ -110,7 +128,7 @@ Elements.position_label = Gui.define("rocket_info/position_label")
)
:on_click(function(def, player, element)
--- @cast def ExpGui_RocketInfo.elements.position_label
if not config.progress.allow_zoom_to_map then return end
if not config.allow_zoom_to_map then return end
local entity = def.data[element]
if not entity or not entity.valid then return end
player.set_controller{ type = defines.controllers.remote, position = entity.position, surface = entity.surface }
@@ -142,34 +160,34 @@ function Elements.stats_table.calculate_row_data(force)
local force_rockets = force.rockets_launched
local rows = {}
if config.stats.show_first_rocket then
if config.show_first_rocket then
local value = stats.first_launch or 0
rows[#rows + 1] = { key = "first-launch", name = "first-launch", value = time_formats.caption_hours(value), tooltip = time_formats.tooltip_hours(value) }
end
if config.stats.show_last_rocket then
if config.show_last_rocket then
local value = stats.last_launch or 0
rows[#rows + 1] = { key = "last-launch", name = "last-launch", value = time_formats.caption_hours(value), tooltip = time_formats.tooltip_hours(value) }
end
if config.stats.show_fastest_rocket then
if config.show_fastest_rocket then
local value = stats.fastest_launch or 0
rows[#rows + 1] = { key = "fastest-launch", name = "fastest-launch", value = time_formats.caption_hours(value), tooltip = time_formats.tooltip_hours(value) }
end
if config.stats.show_total_rockets then
if config.show_total_rockets then
local total_rockets = get_game_rocket_count()
if total_rockets == 0 then total_rockets = 1 end
local percentage = math.floor(force_rockets / total_rockets * 1000) / 10
rows[#rows + 1] = { key = "total-rockets", name = "total-rockets", value = tostring(force_rockets), tooltip = { "exp-gui_rocket-info.value-tooltip-total-rockets", percentage } }
end
if config.stats.show_game_avg then
if config.show_game_avg then
local avg = force_rockets > 0 and math.floor(game.tick / force_rockets) or 0
rows[#rows + 1] = { key = "avg-launch", name = "avg-launch", value = time_formats.caption(avg), tooltip = time_formats.tooltip(avg) }
end
for _, avg_over in pairs(config.stats.rolling_avg) do
for _, avg_over in pairs(rolling_avg) do
local avg = get_rolling_average(force, avg_over)
rows[#rows + 1] = { key = "avg-launch-n-" .. avg_over, name = "avg-launch-n", subname = avg_over, value = time_formats.caption(avg), tooltip = time_formats.tooltip(avg) }
end
@@ -258,7 +276,7 @@ function Elements.milestones_table.calculate_row_data(force)
local force_rockets = force.rockets_launched
local rows = {}
for _, milestone in ipairs(config.milestones) do
for _, milestone in ipairs(milestones) do
-- The milestones config mixes the show_milestones flag with the milestone numbers
if type(milestone) == "number" then
if milestone <= force_rockets then
@@ -421,7 +439,7 @@ end
--- @param row_data ExpGui_RocketInfo.elements.progress_table.row_data
function Elements.progress_table.add_row(progress_table, row_data)
local rows = Elements.progress_table.data[progress_table].rows
local zoom_tooltip = config.progress.allow_zoom_to_map and { "exp-gui_rocket-info.progress-label-tooltip" } or nil
local zoom_tooltip = config.allow_zoom_to_map and { "exp-gui_rocket-info.progress-label-tooltip" } or nil
local x = Elements.position_label(progress_table, { caption = row_data.x, tooltip = zoom_tooltip, entity = row_data.entity })
local y = Elements.position_label(progress_table, { caption = row_data.y, tooltip = zoom_tooltip, entity = row_data.entity })
@@ -544,17 +562,17 @@ Elements.container = Gui.define("rocket_info/container")
local force = player.force --[[@as LuaForce]]
local force_data = def._get_force_data(force)
if config.stats.show_stats then
if config.show_stats then
local row_data = Elements.stats_table.calculate_row_data(force)
Elements.stats_table.refresh(def.add_section(container, "stats", Elements.stats_table), row_data)
end
if config.milestones.show_milestones then
if config.show_milestones then
local row_data = Elements.milestones_table.calculate_row_data(force)
Elements.milestones_table.refresh(def.add_section(container, "milestones", Elements.milestones_table), row_data)
end
if config.progress.show_progress then
if config.show_progress then
local row_data = Elements.progress_table.calculate_row_data_all(force_data.silos)
Elements.progress_table.refresh(def.add_section(container, "progress", Elements.progress_table), row_data)
end
@@ -651,7 +669,7 @@ Gui.toolbar.create_button{
sprite = "item/rocket-silo",
tooltip = { "exp-gui_rocket-info.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.rocket_info")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.rocket_info")
end
}
@@ -678,7 +696,7 @@ local function on_cargo_pod_finished_ascending(event)
-- Discard the launch time that is no longer needed by any rolling average unless it is a milestone
local remove_rocket = rockets_launched - largest_rolling_avg
if remove_rocket > 0 and not table.array_contains(config.milestones, remove_rocket) then
if remove_rocket > 0 and not table.array_contains(milestones, remove_rocket) then
times[remove_rocket] = nil
end
@@ -721,7 +739,7 @@ end
local e = defines.events
return {
return feature:guard{
elements = Elements,
events = {
[e.on_cargo_pod_finished_ascending] = on_cargo_pod_finished_ascending,
+30 -9
View File
@@ -6,7 +6,28 @@ local ExpUtil = require("modules/exp_util")
local Gui = require("modules/exp_gui")
local Colors = require("modules/exp_util/include/color")
local Roles = require("modules/exp_roles")
local config = require("modules/exp_legacy/config/gui/science")
local Feature = require("modules/exp_scenario/features")
local feature, config = Feature.register("science_production", {
show_eta = true, -- the eta for research completion
color_flux = 0.1, -- the fluctuation allowed in production before the icon changes color
})
--- The science packs shown, those not in the game are removed below
local science_packs = {
"automation-science-pack",
"logistic-science-pack",
"military-science-pack",
"chemical-science-pack",
"production-science-pack",
"utility-science-pack",
"space-science-pack",
"metallurgic-science-pack",
"agricultural-science-pack",
"electromagnetic-science-pack",
"cryogenic-science-pack",
"promethium-science-pack",
}
local _format_number = require("util").format_number
local clock_time_format = ExpUtil.format_time_factory_locale{ format = "clock", hours = true, minutes = true, seconds = true }
@@ -16,9 +37,9 @@ local clock_time_format_nil = { "exp-gui_science-production.caption-eta-time", c
local long_time_format_nil = long_time_format(nil)
--- Remove invalid science packs, this can result from a certain mod not being loaded
for i = #config, 1, -1 do
if not prototypes.item[config[i]] then
table.remove(config, i)
for i = #science_packs, 1, -1 do
if not prototypes.item[science_packs[i]] then
table.remove(science_packs, i)
end
end
@@ -337,7 +358,7 @@ do local _row_data = {} --- @type table<string, table<number, ExpGui_ScienceProd
if next(force.connected_players) then
local row_data = _row_data[force.name] or {}
_row_data[force.name] = row_data
for i, science_pack in ipairs(config) do
for i, science_pack in ipairs(science_packs) do
--- @cast science_pack any
row_data[i] = Elements.science_table.calculate_row_data(force, science_pack, row_data[i])
end
@@ -448,7 +469,7 @@ Elements.container = Gui.define("science_production/container")
local force = Gui.get_player(parent).force --[[@as LuaForce]]
local science_table = Elements.science_table(container)
for _, science_pack in ipairs(config) do
for _, science_pack in ipairs(science_packs) do
--- @cast science_pack any
local row_data = Elements.science_table.calculate_row_data(force, science_pack)
Elements.science_table.add_row(science_table, row_data)
@@ -522,7 +543,7 @@ do local _production_data = {} --- @type table<string, { [string]: ExpGui_Scienc
end
-- Calculate the production data for each science pack
for _, science_pack in ipairs(config) do
for _, science_pack in ipairs(science_packs) do
--- @cast science_pack any
local made, used = 0, 0
for _, stats in pairs(production_stats) do
@@ -571,7 +592,7 @@ Gui.toolbar.create_button{
sprite = "entity/lab",
tooltip = { "exp-gui_science-production.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.science_info")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.science_info")
end
}
@@ -583,7 +604,7 @@ local function update_gui()
Elements.no_production_label.refresh_online()
end
return {
return feature:guard{
elements = Elements,
on_nth_tick = {
[60] = update_gui,
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -5,8 +5,8 @@ Shows what the virtual layer holds and lets players build and remove its interfa
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local Colors = require("modules/exp_util/include/color")
local config = require("modules.exp_legacy.config.vlayer")
local Vlayer = require("modules/exp_scenario/control/vlayer")
local feature, config = Vlayer.feature, Vlayer.config
local format_number = require("util").format_number
local Selection = require("modules/exp_util/selection")
@@ -444,7 +444,7 @@ Gui.toolbar.create_button{
sprite = "entity/solar-panel",
tooltip = { "exp-gui_vlayer.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.vlayer")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.vlayer")
end
}
@@ -520,12 +520,12 @@ local function refresh_player_permissions(event)
Elements.controls.refresh_permissions(Gui.get_player(event))
end
return {
return feature:guard{
elements = Elements,
events = {
[Roles.events.on_player_roles_changed] = refresh_player_permissions,
},
on_nth_tick = {
[config.update_tick_gui] = Elements.stats_table.refresh_online,
[60] = Elements.stats_table.refresh_online,
}
}
+63 -30
View File
@@ -5,7 +5,7 @@ Adds a list of warp points which players can travel between, add, and edit
local Gui = require("modules/exp_gui")
local Roles = require("modules/exp_roles")
local Colors = require("modules/exp_util/include/color")
local config = require("modules.exp_legacy.config.gui.warps")
local Feature = require("modules/exp_scenario/features")
local ExpUtil = require("modules/exp_util")
local format_time = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true }
@@ -31,18 +31,61 @@ local status_icons = {
different = "[img=utility/warning_white]",
}
local update_interval = floor(60 / config.update_smoothing)
local cooldown_ticks = config.cooldown_duration * 60
local proximity_radius_sq = config.standard_proximity_radius ^ 2
local spawn_radius_sq = config.spawn_proximity_radius ^ 2
local minimum_distance_sq = config.minimum_distance ^ 2
local feature, config = Feature.register("warp_list", {
minimum_distance = 100, -- the minimum distance that is allowed between warps on the same force
cooldown_duration = 60, -- the duration of the warp cooldown in seconds
standard_proximity_radius = 4, -- the minimum distance a player is allowed to be to a warp in order to use it
spawn_proximity_radius = 20, -- the minimum distance a player is allowed to be from their spawn point to use warps
user_can_edit_own_warps = false, -- the player who made a warp can edit it without the edit permission
})
--- Ticks between updates of the cooldown timers
local update_interval = 6
--- The default icon of new warps
local default_icon = { type = "item", name = "discharge-defense-equipment" }
--- The entities which are created for warp areas { name, x, y }
local area_entities = {
{ "small-lamp", -4, -2 }, { "small-lamp", -2, -4 }, { "medium-electric-pole", -3, -3 }, -- Top left corner
{ "small-lamp", 3, -2 }, { "small-lamp", 1, -4 }, { "medium-electric-pole", 2, -3 }, -- Top right corner
{ "small-lamp", 3, 1 }, { "small-lamp", 1, 3 }, { "medium-electric-pole", 2, 2 }, -- Bottom right corner
{ "small-lamp", -4, 1 }, { "small-lamp", -2, 3 }, { "medium-electric-pole", -3, 2 }, -- Bottom left corner
}
--- The tiles which are created for warp areas { name, x, y }
local area_tiles = {
{ "black-refined-concrete", -4, -2 }, { "black-refined-concrete", -4, -1 }, { "black-refined-concrete", -4, 0 }, { "black-refined-concrete", -4, 1 },
{ "black-refined-concrete", -3, -3 }, { "purple-refined-concrete", -3, -2 }, { "purple-refined-concrete", -3, -1 }, { "purple-refined-concrete", -3, 0 },
{ "purple-refined-concrete", -3, 1 }, { "black-refined-concrete", -3, 2 }, { "black-refined-concrete", -2, -4 }, { "purple-refined-concrete", -2, -3 },
{ "purple-refined-concrete", -2, -2 }, { "purple-refined-concrete", -2, -1 }, { "purple-refined-concrete", -2, 0 }, { "purple-refined-concrete", -2, 1 },
{ "purple-refined-concrete", -2, 2 }, { "black-refined-concrete", -2, 3 }, { "black-refined-concrete", -1, -4 }, { "purple-refined-concrete", -1, -3 },
{ "purple-refined-concrete", -1, -2 }, { "purple-refined-concrete", -1, -1 }, { "purple-refined-concrete", -1, 0 }, { "purple-refined-concrete", -1, 1 },
{ "purple-refined-concrete", -1, 2 }, { "black-refined-concrete", -1, 3 }, { "black-refined-concrete", 0, -4 }, { "purple-refined-concrete", 0, -3 },
{ "purple-refined-concrete", 0, -2 }, { "purple-refined-concrete", 0, -1 }, { "purple-refined-concrete", 0, 0 }, { "purple-refined-concrete", 0, 1 },
{ "purple-refined-concrete", 0, 2 }, { "black-refined-concrete", 0, 3 }, { "black-refined-concrete", 1, -4 }, { "purple-refined-concrete", 1, -3 },
{ "purple-refined-concrete", 1, -2 }, { "purple-refined-concrete", 1, -1 }, { "purple-refined-concrete", 1, 0 }, { "purple-refined-concrete", 1, 1 },
{ "purple-refined-concrete", 1, 2 }, { "black-refined-concrete", 1, 3 }, { "black-refined-concrete", 2, -3 }, { "purple-refined-concrete", 2, -2 },
{ "purple-refined-concrete", 2, -1 }, { "purple-refined-concrete", 2, 0 }, { "purple-refined-concrete", 2, 1 }, { "black-refined-concrete", 2, 2 },
{ "black-refined-concrete", 3, -2 }, { "black-refined-concrete", 3, -1 }, { "black-refined-concrete", 3, 0 }, { "black-refined-concrete", 3, 1 },
}
--- Names of the entities which make up a warp area, used to find them when the area is removed
local area_entity_names = {} --- @type string[]
for _, entity in ipairs(config.entities) do
for _, entity in ipairs(area_entities) do
area_entity_names[#area_entity_names + 1] = entity[1]
end
--- The role permission each action needs
local permissions = {
bypass_warp_cooldown = "exp_scenario.gui.warp_list.bypass_cooldown",
bypass_warp_proximity = "exp_scenario.gui.warp_list.bypass_proximity",
allow_add_warp = "exp_scenario.gui.warp_list.add",
allow_edit_warp = "exp_scenario.gui.warp_list.edit",
}
--- @class ExpGui_WarpList.Warp
--- @field id number
--- @field force LuaForce
@@ -63,21 +106,11 @@ end
--- @field on_cooldown boolean
--- @field bypass_proximity boolean
--- Check a permission from the config, which says who an action applies to
--- @param player LuaPlayer
--- @param action "bypass_warp_cooldown" | "bypass_warp_proximity" | "allow_add_warp" | "allow_edit_warp"
--- @return boolean
local function has_config_permission(player, action)
local setting = config[action]
if setting == "all" then
return true
elseif setting == "admin" then
return player.admin
elseif setting == "exp_roles" then
return Roles.player_has_permission(player, config["exp_roles_" .. action])
end
return false
return Roles.player_has_permission(player, permissions[action])
end
--- Check if a player can edit a warp, the spawn warp can never be edited
@@ -694,7 +727,7 @@ Elements.cooldown_bar = Gui.define("warp_list/cooldown_bar")
--- @param cooldown number
function Elements.cooldown_bar.refresh(cooldown_bar, cooldown)
if cooldown > 0 then
cooldown_bar.value = 1 - cooldown / cooldown_ticks
cooldown_bar.value = 1 - cooldown / (config.cooldown_duration * 60)
cooldown_bar.tooltip = { "exp-gui_warp-list.tooltip-cooldown", ceil(cooldown / 60) }
else
cooldown_bar.value = 1
@@ -877,12 +910,12 @@ function Elements.container._make_area(warp)
warp.old_tile = surface.get_tile(position.x, position.y).name
local tiles = {}
for index, tile in ipairs(config.tiles) do
for index, tile in ipairs(area_tiles) do
tiles[index] = { name = tile[1], position = { x = tile[2] + position.x, y = tile[3] + position.y } }
end
surface.set_tiles(tiles)
for _, entity_config in ipairs(config.entities) do
for _, entity_config in ipairs(area_entities) do
local entity = assert(surface.create_entity{
name = entity_config[1],
position = { x = entity_config[2] + position.x, y = entity_config[3] + position.y },
@@ -908,7 +941,7 @@ function Elements.container._remove_area(warp)
local surface = warp.surface
local position = warp.position
local tiles = {}
for index, tile in ipairs(config.tiles) do
for index, tile in ipairs(area_tiles) do
tiles[index] = { name = old_tile, position = { x = tile[2] + position.x, y = tile[3] + position.y } }
end
surface.set_tiles(tiles)
@@ -947,7 +980,7 @@ function Elements.container.add_warp(force, surface, position, player, name)
id = id,
force = force,
name = name or "New warp",
icon = { type = config.default_icon.type, name = config.default_icon.name },
icon = { type = default_icon.type, name = default_icon.name },
surface = surface,
position = { x = floor(position.x), y = floor(position.y) },
last_user = player,
@@ -1054,8 +1087,8 @@ function Elements.container.teleport_player(player, warp)
local player_data = Elements.container._get_player_data(player)
if not has_config_permission(player, "bypass_warp_cooldown") then
player_data.cooldown = cooldown_ticks
Elements.cooldown_bar.refresh_player(player, cooldown_ticks)
player_data.cooldown = config.cooldown_duration * 60
Elements.cooldown_bar.refresh_player(player, player_data.cooldown)
end
player_data.in_range = warp
Elements.warp_table.refresh_status_player(player)
@@ -1109,7 +1142,7 @@ function Elements.container._update_proximity(player, player_data)
end
local in_range = nil --- @type ExpGui_WarpList.Warp?
if closest and closest_distance < (closest == force_data.spawn and spawn_radius_sq or proximity_radius_sq) then
if closest and closest_distance < (closest == force_data.spawn and config.spawn_proximity_radius or config.standard_proximity_radius) ^ 2 then
in_range = closest
end
if in_range ~= player_data.in_range then
@@ -1121,7 +1154,7 @@ function Elements.container._update_proximity(player, player_data)
end
local blocking = nil --- @type ExpGui_WarpList.Warp?
if closest and closest_distance <= minimum_distance_sq then
if closest and closest_distance <= config.minimum_distance ^ 2 then
blocking = closest
end
if blocking ~= player_data.blocking then
@@ -1135,10 +1168,10 @@ Gui.add_left_element(Elements.container, false)
Gui.toolbar.create_button{
name = "toggle_warp_list",
left_element = Elements.container,
sprite = config.default_icon.type .. "/" .. config.default_icon.name,
sprite = default_icon.type .. "/" .. default_icon.name,
tooltip = { "exp-gui_warp-list.tooltip-main" },
visible = function(player, element)
return Roles.player_has_permission(player, "exp_scenario.gui.warp_list")
return feature:is_enabled() and Roles.player_has_permission(player, "exp_scenario.gui.warp_list")
end
}:on_click(function(def, player)
-- A list the player opened themselves stays open when they leave a warp
@@ -1202,7 +1235,7 @@ end
local e = defines.events
return {
return feature:guard{
elements = Elements,
events = {
[e.on_player_created] = on_player_created,