Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ stds.creative_mod = {
"creative_lab",
"creative_mode_defines",
"creative_provider_chest",
"creative_thruster",
"duplicating_cargo_wagon",
"duplicating_chest",
"duplicating_chest_util",
Expand Down
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Date: ????
- Add an admin-only Surface tab. Admins can create a new blank surface by typing a name; the surface immediately appears in the Surface Cheats target list for every connected player allowed to see other surfaces.
- Add space-platform creation to the Surface tab (Space Age only). Admins can type a name and pick the planet to orbit; the platform comes up with a hub already placed and its surface immediately appears in the Surface Cheats target list.
- Add planet-surface creation to the Surface tab (Space Age only). Admins can pick a planet and create its surface; if the surface already exists the action is a harmless no-op, and any newly created surface immediately appears in the Surface Cheats target list.
- Add a creative wall: an indestructible red wall. Enemies still target and attack it, but it instantly heals back to full and can never be destroyed. It works on any surface, including space platforms, and is enabled by the normal Creative tools' recipe sweep.
- Add a creative thruster (Space Age only): a thruster that refuels itself every tick, keeping a space platform travelling at vanilla speed with no fuel or oxidizer chain to supply. Place it on a platform, set a route, and it travels with no fuel management.
- Add an "Asteroid spawning rate" input to the Game Settings cheats (Space Age only): a global multiplier for how often asteroids spawn around space platforms. Default is 1 (vanilla); set it to 0 to stop asteroids spawning entirely. Applies game-wide, not per surface.
Changes:
- Move the Surface Cheats menu from the Cheats tab into the Surface tab, grouping it with the surface-creation tools.
Bugfixes:
Expand Down
9 changes: 9 additions & 0 deletions control.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require("scripts.cheats")
require("scripts.configurable-super-boiler")
require("scripts.creative-cargo-wagon")
require("scripts.creative-chest-util")
require("scripts.creative-thruster")
require("scripts.creative-lab")
require("scripts.void-lab")
require("scripts.duplicating-cargo-wagon")
Expand Down Expand Up @@ -55,6 +56,13 @@ script.on_event(defines.events.on_player_main_inventory_changed, events.on_playe
script.on_event(defines.events.on_entity_logistic_slot_changed, events.on_entity_logistic_slot_changed)
script.on_event(defines.events.on_player_trash_inventory_changed, events.on_player_trash_inventory_changed)

-- on_entity_damaged is registered separately with event filters (the creative wall's name), so it
-- must be excluded from the generic filterless loop below - otherwise this loop would re-register
-- it without filters. Phase 3 will OR an impact damage-type filter into this same registration.
script.on_event(defines.events.on_entity_damaged, events.on_entity_damaged, {
{ filter = "name", name = creative_mode_defines.names.entities.creative_wall },
})

-- Other events.
local events_except_on_tick = {}
for _, event in pairs(defines.events) do
Expand All @@ -63,6 +71,7 @@ for _, event in pairs(defines.events) do
and event ~= defines.events.on_player_main_inventory_changed
and event ~= defines.events.on_entity_logistic_slot_changed
and event ~= defines.events.on_player_trash_inventory_changed
and event ~= defines.events.on_entity_damaged
then
table.insert(events_except_on_tick, event)
end
Expand Down
31 changes: 31 additions & 0 deletions data-final-fixes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,34 @@ for _, name in pairs(finite_resource_names) do

data:extend({ resource })
end

--------------------------------------------------------------

-- Creative thruster: a clone of the vanilla Space Age thruster that keeps the normal performance
-- curve (so it produces real thrust at vanilla speed). Its fuel + oxidizer fluidboxes are topped
-- off every tick by scripts/creative-thruster.lua, so the platform travels with no fuel chain to
-- manage. Defined only when Space Age is present (its filtered fluidboxes reference the
-- thruster-fuel / thruster-oxidizer fluids, which only exist in the space-age mod). Done in
-- data-final-fixes so the vanilla "thruster" prototype is guaranteed to exist before we clone it.
if mods["space-age"] and data.raw["thruster"] and data.raw["thruster"]["thruster"] then
local creative_thruster = util.table.deepcopy(data.raw["thruster"]["thruster"])
creative_thruster.name = creative_mode_defines.names.entities.creative_thruster
-- Keep the vanilla thruster's entity flags. ("spawnable" is an *item* flag and lives on the
-- creative thruster item, letting the remote controller hold it for placement in remote view.)
creative_thruster.flags = {
"placeable-neutral",
"placeable-player",
"player-creation",
"not-rotatable",
}
creative_thruster.minable = {
mining_time = 0.1,
result = creative_mode_defines.names.items.creative_thruster,
}
creative_thruster.fast_replaceable_group = nil
-- The placed thruster keeps its vanilla graphics: its detailed animated body doesn't take a flat
-- tint cleanly (only the integration patch picked it up, leaving a patchy half-red look). The
-- creative variant is instead marked by its red item icon (see prototypes/item.lua), matching the
-- convention used for the mod's other creative entities.
data:extend({ creative_thruster })
end
11 changes: 11 additions & 0 deletions defines.lua
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ creative_mode_defines.names.entities = {
alien_attractor_proxy_medium = creative_mode_defines.name_prefix .. "alien-attractor-proxy-medium",
alien_attractor_proxy_large = creative_mode_defines.name_prefix .. "alien-attractor-proxy-large",
super_beacon = creative_mode_defines.name_prefix .. "super-beacon",
creative_wall = creative_mode_defines.name_prefix .. "creative-wall",
creative_thruster = creative_mode_defines.name_prefix .. "creative-thruster",
}
-- Technology names
creative_mode_defines.names.technology = {
Expand Down Expand Up @@ -209,6 +211,8 @@ creative_mode_defines.names.items = {
alien_attractor_medium = creative_mode_defines.name_prefix .. "alien-attractor-medium",
alien_attractor_large = creative_mode_defines.name_prefix .. "alien-attractor-large",
super_beacon = creative_mode_defines.name_prefix .. "super-beacon",
creative_wall = creative_mode_defines.name_prefix .. "creative-wall",
creative_thruster = creative_mode_defines.name_prefix .. "creative-thruster",
super_speed_module = creative_mode_defines.name_prefix .. "super-speed-module",
super_effectivity_module = creative_mode_defines.name_prefix .. "super-effectivity-module",
super_productivity_module = creative_mode_defines.name_prefix .. "super-productivity-module",
Expand Down Expand Up @@ -294,6 +298,8 @@ creative_mode_defines.names.recipes = {
alien_attractor_medium = creative_mode_defines.name_prefix .. "alien-attractor-medium",
alien_attractor_large = creative_mode_defines.name_prefix .. "alien-attractor-large",
super_beacon = creative_mode_defines.name_prefix .. "super-beacon",
creative_wall = creative_mode_defines.name_prefix .. "creative-wall",
creative_thruster = creative_mode_defines.name_prefix .. "creative-thruster",
super_speed_module = creative_mode_defines.name_prefix .. "super-speed-module",
super_effectivity_module = creative_mode_defines.name_prefix .. "super-effectivity-module",
super_productivity_module = creative_mode_defines.name_prefix .. "super-productivity-module",
Expand Down Expand Up @@ -680,6 +686,11 @@ creative_mode_defines.names.gui = {
enemy_expansion_label = creative_mode_defines.name_prefix .. "enemy-expansion-label",
enemy_expansion_on_button = creative_mode_defines.name_prefix .. "enemy-expansion-on-button",
enemy_expansion_off_button = creative_mode_defines.name_prefix .. "enemy-expansion-off-button",
asteroid_spawning_rate_container = creative_mode_defines.name_prefix .. "asteroid-spawning-rate-container",
asteroid_spawning_rate_label = creative_mode_defines.name_prefix .. "asteroid-spawning-rate-label",
asteroid_spawning_rate_textfield = creative_mode_defines.name_prefix .. "asteroid-spawning-rate-textfield",
asteroid_spawning_rate_separator = creative_mode_defines.name_prefix .. "asteroid-spawning-rate-separator",
asteroid_spawning_rate_apply_button = creative_mode_defines.name_prefix .. "asteroid-spawning-rate-apply-button",
enemy_expansion_min_cooldown_container = creative_mode_defines.name_prefix
.. "enemy-expansion-min-cooldown-container",
enemy_expansion_min_cooldown_label = creative_mode_defines.name_prefix .. "enemy-expansion-min-cooldown-label",
Expand Down
7 changes: 7 additions & 0 deletions locale/en/base.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ creative-mod_alien-attractor-proxy-small=Small alien attractor
creative-mod_alien-attractor-proxy-medium=Medium alien attractor
creative-mod_alien-attractor-proxy-large=Large alien attractor
creative-mod_super-beacon=Super beacon
creative-mod_creative-wall=Creative wall
creative-mod_creative-thruster=Creative thruster
creative-mode_enemy-object=__1__ (Creative Mode)
creative-mode_infinite-resource=__1__ (Infinite)

Expand Down Expand Up @@ -99,6 +101,8 @@ creative-mod_passive-energy-void=Constantly absorbs exceeded energy from the net
creative-mod_super-radar=Keeps the large area around it to be always revealed. Doesn't really need energy despite the warning signal.\n(Placing it before the sectors are generated may interrupt the generation process and cause the whole map to be blacked out temporarily.)
creative-mod_super-radar-2=Keeps the extremely large area around it to be always revealed. Doesn't really need energy despite the warning signal.\n(Placing it before the sectors are generated may interrupt the generation process, causing lag and the whole map to be blacked out temporarily.\nUsually it takes a few minutes to generate sections for such a large area.)
creative-mod_super-beacon=Super large effective area. Also accepts productivity modules. Doesn't really need energy despite the warning signal.
creative-mod_creative-wall=An indestructible wall that cannot be damaged or destroyed. Works on any surface, including space platforms.
creative-mod_creative-thruster=A thruster that refuels itself every tick, keeping a space platform travelling at vanilla speed with no fuel or oxidizer chain to supply.

[technology-name]
creative-mod_void-technology=Void Technology
Expand Down Expand Up @@ -310,6 +314,7 @@ creative-mode_enemy-expansion-enabled=__1__ has enabled enemy expansion.
creative-mode_enemy-expansion-disabled=__1__ has disabled enemy expansion.
creative-mode_enemy-expansion-min-cooldown-updated=__1__ has updated the enemies' minimum expansion cooldown to __2__.
creative-mode_enemy-expansion-max-cooldown-updated=__1__ has updated the enemies' maximum expansion cooldown to __2__.
creative-mode_asteroid-spawning-rate-updated=__1__ has set the asteroid spawning rate to __2__.
creative-mode_game-speed-updated=__1__ has updated game speed to __2__.

creative-mode_build-active-enabled-by-admin=__1__ has enabled build options - active for you.
Expand Down Expand Up @@ -547,6 +552,8 @@ creative-mode_enemy-expansion-min-cooldown=Expansion min CD [?]
creative-mode_enemy-expansion-min-cooldown-tooltip=Minimum number of ticks before the enemies expand a base. Default is __1__.\nEffective only when enemy expansion is on.
creative-mode_enemy-expansion-max-cooldown=Expansion max CD [?]
creative-mode_enemy-expansion-max-cooldown-tooltip=Maximum number of ticks before the enemies expand a base. Default is __1__.\nEffective only when enemy expansion is on.
creative-mode_asteroid-spawning-rate=Asteroid spawning rate [?]
creative-mode_asteroid-spawning-rate-tooltip=Multiplier for how often asteroids spawn around space platforms. Default is __1__. Set to 0 to stop asteroids spawning entirely. Applies game-wide, not per surface.
creative-mode_game-speed=Game speed [?]
creative-mode_game-speed-tooltip=Speed to update the map. Default is __2__ (60 UPS). Minimum is __1__.

Expand Down
46 changes: 46 additions & 0 deletions prototypes/entity.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2898,6 +2898,52 @@ data:extend({
},
})

-- Creative wall: a clone of the base stone-wall. It stays a normal *destructible* target so
-- biters path to it and asteroids hit it, but it is healed back to full on every hit by the
-- on_entity_damaged handler in scripts/events.lua, so it can never be destroyed. (Setting
-- destructible = false was rejected: it removes the entity from the targeting system entirely,
-- so nothing ever attacks it.) The very high max_health is defense-in-depth so no single hit
-- one-shots it before the heal fires. It is a general creative building block, usable on any
-- surface (including space platforms via the item's "spawnable" flag). Not Space-Age gated -
-- it has no Space Age data dependency, so it loads and is craftable everywhere.
local creative_wall = table.deepcopy(data.raw["wall"]["stone-wall"])
creative_wall.name = creative_mode_defines.names.entities.creative_wall
creative_wall.flags = { "placeable-player", "player-creation" }
creative_wall.minable = {
mining_time = 0.2,
result = creative_mode_defines.names.items.creative_wall,
}
creative_wall.fast_replaceable_group = nil
creative_wall.se_allow_in_space = true
creative_wall.max_health = 1000000
-- Tint the wall red to match the mod's other creative entities. Walls use a deeply nested
-- WallPictures structure, so recursively tint every non-shadow sprite layer.
local creative_entity_tint = { r = 1, g = 0.3, b = 0.3 }
local function apply_creative_tint(sprite)
if type(sprite) ~= "table" then
return
end
if sprite.layers then
for _, layer in pairs(sprite.layers) do
apply_creative_tint(layer)
end
return
end
if sprite.filename then
-- Leave shadows untinted; only tint the visible sprite layers.
if not sprite.draw_as_shadow then
sprite.tint = table.deepcopy(creative_entity_tint)
sprite.apply_runtime_tint = false
end
return
end
for _, value in pairs(sprite) do
apply_creative_tint(value)
end
end
apply_creative_tint(creative_wall.pictures)
data:extend({ creative_wall })

-- Vanilla infinity chest already exists but has no description, so we add one.
data.raw["infinity-container"]["infinity-chest"].localised_description = { "entity-description.infinity-chest" }
-- It also needs it's gui mode set to match our setting.
Expand Down
55 changes: 55 additions & 0 deletions prototypes/item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,30 @@ data:extend({
place_result = creative_mode_defines.names.entities.super_beacon,
stack_size = 50,
},
{
-- Creative wall
type = "item",
name = creative_mode_defines.names.items.creative_wall,
icon_size = 64,
-- Tinted red to match the mod's other creative entities.
icons = {
{
icon = "__base__/graphics/icons/wall.png",
tint = {
r = 1,
g = 0.3,
b = 0.3,
},
},
},
hidden = hidden,
subgroup = creative_mode_defines.names.item_subgroups.advanced,
order = "g",
place_result = creative_mode_defines.names.entities.creative_wall,
stack_size = 50,
-- "spawnable" lets the remote controller hold the item, so it can be placed in remote view (e.g. on space platforms).
flags = { "spawnable" },
},
{
-- Super speed module.
type = "module",
Expand Down Expand Up @@ -866,3 +890,34 @@ data:extend({
stack_size = 50,
},
})

-- Creative thruster item. Defined only when Space Age is present, since its place_result entity
-- (the creative thruster) only exists with Space Age.
if mods["space-age"] then
data:extend({
{
-- Creative thruster
type = "item",
name = creative_mode_defines.names.items.creative_thruster,
icon_size = 64,
-- Tinted red to match the mod's other creative entities.
icons = {
{
icon = "__space-age__/graphics/icons/thruster.png",
tint = {
r = 1,
g = 0.3,
b = 0.3,
},
},
},
hidden = hidden,
subgroup = creative_mode_defines.names.item_subgroups.advanced,
order = "h",
place_result = creative_mode_defines.names.entities.creative_thruster,
stack_size = 50,
-- "spawnable" lets the remote controller hold the item, so it can be placed in remote view on space platforms.
flags = { "spawnable" },
},
})
end
23 changes: 23 additions & 0 deletions prototypes/recipe.lua
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,14 @@ data:extend({
results = { { type = "item", name = creative_mode_defines.names.items.super_beacon, amount = 1 } },
enabled = false,
},
{
-- Creative wall
type = "recipe",
name = creative_mode_defines.names.recipes.creative_wall,
ingredients = {},
results = { { type = "item", name = creative_mode_defines.names.items.creative_wall, amount = 1 } },
enabled = false,
},
{
-- Super speed module
type = "recipe",
Expand Down Expand Up @@ -544,3 +552,18 @@ data:extend({
enabled = false,
},
})

-- Creative thruster recipe. Defined only when Space Age is present, since its result item only
-- exists with Space Age. It is auto-enabled at runtime by the creative_tools_recipes sweep.
if mods["space-age"] then
data:extend({
{
-- Creative thruster
type = "recipe",
name = creative_mode_defines.names.recipes.creative_thruster,
ingredients = {},
results = { { type = "item", name = creative_mode_defines.names.items.creative_thruster, amount = 1 } },
enabled = false,
},
})
end
22 changes: 22 additions & 0 deletions scripts/cheats.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,28 @@ cheats.global_cheats_data = {
end,
get_player_can_access_function = nil,
},
asteroid_spawning_rate = {
is_default = false,
default_enable_value = 1,
default_disable_value = 1,
get_value_function = function(target)
return game.map_settings.asteroids.spawning_rate
end,
limit_value_before_apply_function = function(value)
-- Rate is a multiplier; clamp to a non-negative, safe range. 0 = no asteroids, 1 = vanilla.
return util.clamp(value, 0, 4294967296)
end,
apply_to_target_function = function(target, value, source_player)
game.map_settings.asteroids.spawning_rate = value
return nil
end,
print_applied_by_admin_message_function = function(source_player, target, value)
game.print({ "message.creative-mode_asteroid-spawning-rate-updated", source_player.name, value })
end,
get_player_can_access_function = function(player)
return script.feature_flags["space_travel"] == true
end,
},
game_speed = {
is_default = false,
default_enable_value = 1,
Expand Down
35 changes: 35 additions & 0 deletions scripts/creative-thruster.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-- This file contains variables or functions that are related to the Creative Thruster in this mod.
if not creative_thruster then
creative_thruster = {}
end

-- The creative thruster is cloned from the vanilla Space Age thruster, which has exactly two
-- filtered fluidboxes: fuel (thruster-fuel) and oxidizer (thruster-oxidizer), each with a volume
-- of 1000. The thruster entity does not expose a writable `fluidbox` property, so we top the two
-- fluids up via insert_fluid every tick (the engine clamps inserts at the per-fluid capacity).
local thruster_fluids = {
{ name = "thruster-fuel", capacity = 1000 },
{ name = "thruster-oxidizer", capacity = 1000 },
}

-- Processes the table of creative_thruster in storage.
function creative_thruster.tick()
-- Loop through the table of creative thrusters and top off fuel + oxidizer to capacity, so the
-- thruster always has fuel and the platform travels with no fuel chain to supply.
-- Iterate backwards so table.remove of invalid entries doesn't skip elements.
for index = #storage.creative_mode.creative_thruster, 1, -1 do
local entity = storage.creative_mode.creative_thruster[index]
if entity.valid then
if not entity.to_be_deconstructed() then
for _, fluid in ipairs(thruster_fluids) do
local missing = fluid.capacity - entity.get_fluid_count(fluid.name)
if missing > 0 then
entity.insert_fluid({ name = fluid.name, amount = missing })
end
end
end
else
table.remove(storage.creative_mode.creative_thruster, index)
end
end
end
Loading
Loading