From c05c57acf97bfd798dfa8c2a679d16484dc36679 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 25 Dec 2020 15:49:55 -0800
Subject: [PATCH 01/31] persistent module
---
.../_persistence.dm} | 329 +++---------------
.../subsystem/persistence/panic_bunker.dm | 26 ++
.../subsystem/persistence/poly_parrot.dm | 11 +
.../subsystem/persistence/recent_votes_etc.dm | 107 ++++++
.../subsystem/persistence/secret_satchels.dm | 79 +++++
.../subsystem/persistence/trophies.dm | 84 +++++
tgstation.dme | 7 +-
7 files changed, 370 insertions(+), 273 deletions(-)
rename code/controllers/subsystem/{persistence.dm => persistence/_persistence.dm} (51%)
create mode 100644 code/controllers/subsystem/persistence/panic_bunker.dm
create mode 100644 code/controllers/subsystem/persistence/poly_parrot.dm
create mode 100644 code/controllers/subsystem/persistence/recent_votes_etc.dm
create mode 100644 code/controllers/subsystem/persistence/secret_satchels.dm
create mode 100644 code/controllers/subsystem/persistence/trophies.dm
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
similarity index 51%
rename from code/controllers/subsystem/persistence.dm
rename to code/controllers/subsystem/persistence/_persistence.dm
index e39242aac3..edecba311b 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -5,18 +5,9 @@ SUBSYSTEM_DEF(persistence)
name = "Persistence"
init_order = INIT_ORDER_PERSISTENCE
flags = SS_NO_FIRE
- var/list/satchel_blacklist = list() //this is a typecache
- var/list/new_secret_satchels = list() //these are objects
- var/list/old_secret_satchels = list()
var/list/obj/structure/chisel_message/chisel_messages = list()
var/list/saved_messages = list()
- var/list/saved_modes = list(1,2,3)
- var/list/saved_dynamic_rules = list(list(),list(),list())
- var/list/saved_storytellers = list("foo","bar","baz")
- var/list/average_dynamic_threat = 50
- var/list/saved_maps
- var/list/saved_trophies = list()
var/list/spawned_objects = list()
var/list/antag_rep = list()
var/list/antag_rep_change = list()
@@ -28,62 +19,71 @@ SUBSYSTEM_DEF(persistence)
var/list/paintings = list()
/datum/controller/subsystem/persistence/Initialize()
- LoadSatchels()
- LoadPoly()
- LoadChiselMessages()
- LoadTrophies()
- LoadRecentModes()
- LoadRecentStorytellers()
- LoadRecentRulesets()
- LoadRecentMaps()
- LoadPhotoPersistence()
+ LoadServerPersistence()
+ LoadGamePersistence()
+ LoadMapPersistence()
+ return ..()
+
+/datum/controller/subsystem/persistence/proc/CollectData()
+ SaveServerPersistence()
+ SaveGamePersistence()
+ SaveMapPersistence()
+
+/**
+ * Loads persistent data relevant to the server: Configurations, past gamemodes, votes, etc
+ */
+/datum/controller/subsystem/persistence/proc/LoadServerPersistence()
for(var/client/C in GLOB.clients)
LoadSavedVote(C.ckey)
if(CONFIG_GET(flag/use_antag_rep))
LoadAntagReputation()
+
+/**
+ * Saves persistent data relevant to the server: Configurations, past gamemodes, votes, etc
+ */
+/datum/controller/subsystem/persistence/proc/SaveServerPersistence()
+ if(CONFIG_GET(flag/use_antag_rep))
+ CollectAntagReputation()
+
+/**
+ * Loads persistent data relevant to the game in general: Trophies, antag reputation, etc
+ *
+ * Legacy map persistence systems also use this.
+ */
+/datum/controller/subsystem/persistence/proc/LoadGamePersistence()
+ LoadChiselMessages()
+ LoadPhotoPersistence()
LoadRandomizedRecipes()
- LoadPanicBunker()
- return ..()
-/datum/controller/subsystem/persistence/proc/LoadSatchels()
- var/placed_satchel = 0
- var/path
+/**
+ * Saves persistent data relevant to the game in general: Trophies, antag reputation, etc
+ *
+ * Legacy map persistence systems also use this.
+ */
+/datum/controller/subsystem/persistence/proc/SaveGamePersistence()
+ SaveRandomizedRecipes()
+ CollectChiselMessages()
+ SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
+ SavePaintings()
+ SaveScars()
- var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
- var/list/json = list()
- if(fexists(json_file))
- json = json_decode(file2text(json_file))
+/**
+ * Loads persistent data relevant to the current map: Objects, etc.
+ *
+ * @params
+ * data_directory - The data directory to use. Each map with a persistence key has its own, and this is based on the persistence key.
+ */
+/datum/controller/subsystem/persistence/proc/LoadMapPersistence(data_directory)
+ return
- old_secret_satchels = json["data"]
- var/obj/item/storage/backpack/satchel/flat/F
- if(old_secret_satchels && old_secret_satchels.len >= 10) //guards against low drop pools assuring that one player cannot reliably find his own gear.
- var/pos = rand(1, old_secret_satchels.len)
- F = new()
- old_secret_satchels.Cut(pos, pos+1 % old_secret_satchels.len)
- F.x = old_secret_satchels[pos]["x"]
- F.y = old_secret_satchels[pos]["y"]
- F.z = SSmapping.station_start
- path = text2path(old_secret_satchels[pos]["saved_obj"])
-
- if(F)
- if(isfloorturf(F.loc) && !isplatingturf(F.loc))
- F.hide(1)
- if(ispath(path))
- var/spawned_item = new path(F)
- spawned_objects[spawned_item] = TRUE
- placed_satchel++
- var/free_satchels = 0
- for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,SSmapping.station_start), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,SSmapping.station_start)))) //Nontrivially expensive but it's roundstart only
- if(isfloorturf(T) && !isplatingturf(T))
- new /obj/item/storage/backpack/satchel/flat/secret(T)
- free_satchels++
- if((free_satchels + placed_satchel) == 10) //ten tiles, more than enough to kill anything that moves
- break
-
-/datum/controller/subsystem/persistence/proc/LoadPoly()
- for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list)
- twitterize(P.speech_buffer, "polytalk")
- break //Who's been duping the bird?!
+/**
+ * Saves persistent data relevant to the current map: Objects, etc.
+ *
+ * @params
+ * data_directory - The data directory to use. Each map with a persistence key has its own, and this is based on the persistence key.
+ */
+/datum/controller/subsystem/persistence/proc/SaveMapPersistence(data_directory)
+ return
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
var/list/saved_messages = list()
@@ -130,63 +130,6 @@ SUBSYSTEM_DEF(persistence)
log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
-/datum/controller/subsystem/persistence/proc/LoadTrophies()
- if(fexists("data/npc_saves/TrophyItems.sav")) //legacy compatability to convert old format to new
- var/savefile/S = new /savefile("data/npc_saves/TrophyItems.sav")
- var/saved_json
- S >> saved_json
- if(!saved_json)
- return
- saved_trophies = json_decode(saved_json)
- fdel("data/npc_saves/TrophyItems.sav")
- else
- var/json_file = file("data/npc_saves/TrophyItems.json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- if(!json)
- return
- saved_trophies = json["data"]
- SetUpTrophies(saved_trophies.Copy())
-
-/datum/controller/subsystem/persistence/proc/LoadRecentModes()
- var/json_file = file("data/RecentModes.json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- if(!json)
- return
- saved_modes = json["data"]
-
-/datum/controller/subsystem/persistence/proc/LoadRecentRulesets()
- var/json_file = file("data/RecentRulesets.json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- if(!json)
- return
- saved_dynamic_rules = json["data"]
-
-/datum/controller/subsystem/persistence/proc/LoadRecentStorytellers()
- var/json_file = file("data/RecentStorytellers.json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- if(!json)
- return
- saved_storytellers = json["data"]
- if(saved_storytellers.len > 3)
- average_dynamic_threat = saved_storytellers[4]
- saved_storytellers.len = 3
-
-/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
- var/json_file = file("data/RecentMaps.json")
- if(!fexists(json_file))
- return
- var/list/json = json_decode(file2text(json_file))
- if(!json)
- return
- saved_maps = json["maps"]
/datum/controller/subsystem/persistence/proc/LoadAntagReputation()
var/json = file2text(FILE_ANTAG_REP)
@@ -207,59 +150,6 @@ SUBSYSTEM_DEF(persistence)
return
saved_votes[ckey] = json["data"]
-/datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items)
- for(var/A in GLOB.trophy_cases)
- var/obj/structure/displaycase/trophy/T = A
- if (T.showpiece)
- continue
- T.added_roundstart = TRUE
-
- var/trophy_data = pick_n_take(trophy_items)
-
- if(!islist(trophy_data))
- continue
-
- var/list/chosen_trophy = trophy_data
-
- if(!chosen_trophy || isemptylist(chosen_trophy)) //Malformed
- continue
-
- var/path = text2path(chosen_trophy["path"]) //If the item no longer exist, this returns null
- if(!path)
- continue
-
- T.showpiece = new /obj/item/showpiece_dummy(T, path)
- T.trophy_message = chosen_trophy["message"]
- T.placer_key = chosen_trophy["placer_key"]
- T.update_icon()
-
-/datum/controller/subsystem/persistence/proc/CollectData()
- CollectChiselMessages()
- CollectSecretSatchels()
- CollectTrophies()
- CollectRoundtype()
- if(istype(SSticker.mode, /datum/game_mode/dynamic))
- var/datum/game_mode/dynamic/mode = SSticker.mode
- CollectStoryteller(mode)
- CollectRulesets(mode)
- RecordMaps()
- SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
- if(CONFIG_GET(flag/use_antag_rep))
- CollectAntagReputation()
- SaveRandomizedRecipes()
- SavePanicBunker()
- SavePaintings()
- SaveScars()
-
-/datum/controller/subsystem/persistence/proc/LoadPanicBunker()
- var/bunker_path = file("data/bunker_passthrough.json")
- if(fexists(bunker_path))
- var/list/json = json_decode(file2text(bunker_path))
- GLOB.bunker_passthrough = json["data"]
- for(var/ckey in GLOB.bunker_passthrough)
- if(daysSince(GLOB.bunker_passthrough[ckey]) >= CONFIG_GET(number/max_bunker_days))
- GLOB.bunker_passthrough -= ckey
-
/datum/controller/subsystem/persistence/proc/GetPhotoAlbums()
var/album_path = file("data/photo_albums.json")
if(fexists(album_path))
@@ -329,35 +219,6 @@ SUBSYSTEM_DEF(persistence)
WRITE_FILE(frame_path, frame_json)
-/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
- satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
- var/list/satchels_to_add = list()
- for(var/A in new_secret_satchels)
- var/obj/item/storage/backpack/satchel/flat/F = A
- if(QDELETED(F) || F.z != SSmapping.station_start || F.invisibility != INVISIBILITY_MAXIMUM)
- continue
- var/list/savable_obj = list()
- for(var/obj/O in F)
- if(is_type_in_typecache(O, satchel_blacklist) || (O.flags_1 & ADMIN_SPAWNED_1))
- continue
- if(O.persistence_replacement)
- savable_obj += O.persistence_replacement
- else
- savable_obj += O.type
- if(isemptylist(savable_obj))
- continue
- var/list/data = list()
- data["x"] = F.x
- data["y"] = F.y
- data["saved_obj"] = pick(savable_obj)
- satchels_to_add += list(data)
-
- var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
- var/list/file_data = list()
- fdel(json_file)
- file_data["data"] = old_secret_satchels + satchels_to_add
- WRITE_FILE(json_file, json_encode(file_data))
-
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
@@ -374,82 +235,6 @@ SUBSYSTEM_DEF(persistence)
saved_messages += list(M.pack()) // dm eats one list
-/datum/controller/subsystem/persistence/proc/CollectTrophies()
- var/json_file = file("data/npc_saves/TrophyItems.json")
- var/list/file_data = list()
- file_data["data"] = remove_duplicate_trophies(saved_trophies)
- fdel(json_file)
- WRITE_FILE(json_file, json_encode(file_data))
-
-/datum/controller/subsystem/persistence/proc/SavePanicBunker()
- var/json_file = file("data/bunker_passthrough.json")
- var/list/file_data = list()
- file_data["data"] = GLOB.bunker_passthrough
- fdel(json_file)
- WRITE_FILE(json_file,json_encode(file_data))
-
-/datum/controller/subsystem/persistence/proc/remove_duplicate_trophies(list/trophies)
- var/list/ukeys = list()
- . = list()
- for(var/trophy in trophies)
- var/tkey = "[trophy["path"]]-[trophy["message"]]"
- if(ukeys[tkey])
- continue
- else
- . += list(trophy)
- ukeys[tkey] = TRUE
-
-/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
- if(!T.added_roundstart && T.showpiece)
- var/list/data = list()
- data["path"] = T.showpiece.type
- data["message"] = T.trophy_message
- data["placer_key"] = T.placer_key
- saved_trophies += list(data)
-
-/datum/controller/subsystem/persistence/proc/CollectRoundtype()
- saved_modes[3] = saved_modes[2]
- saved_modes[2] = saved_modes[1]
- saved_modes[1] = SSticker.mode.config_tag
- var/json_file = file("data/RecentModes.json")
- var/list/file_data = list()
- file_data["data"] = saved_modes
- fdel(json_file)
- WRITE_FILE(json_file, json_encode(file_data))
-
-/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode)
- saved_storytellers.len = 3
- saved_storytellers[3] = saved_storytellers[2]
- saved_storytellers[2] = saved_storytellers[1]
- saved_storytellers[1] = mode.storyteller.name
- average_dynamic_threat = (mode.max_threat + average_dynamic_threat) / 2
- var/json_file = file("data/RecentStorytellers.json")
- var/list/file_data = list()
- file_data["data"] = saved_storytellers + average_dynamic_threat
- fdel(json_file)
- WRITE_FILE(json_file, json_encode(file_data))
-
-/datum/controller/subsystem/persistence/proc/CollectRulesets(var/datum/game_mode/dynamic/mode)
- saved_dynamic_rules[3] = saved_dynamic_rules[2]
- saved_dynamic_rules[2] = saved_dynamic_rules[1]
- saved_dynamic_rules[1] = list()
- for(var/r in mode.executed_rules)
- var/datum/dynamic_ruleset/rule = r
- saved_dynamic_rules[1] += rule.config_tag
- var/json_file = file("data/RecentRulesets.json")
- var/list/file_data = list()
- file_data["data"] = saved_dynamic_rules
- fdel(json_file)
- WRITE_FILE(json_file, json_encode(file_data))
-
-/datum/controller/subsystem/persistence/proc/RecordMaps()
- saved_maps = saved_maps?.len ? list("[SSmapping.config.map_name]") | saved_maps : list("[SSmapping.config.map_name]")
- var/json_file = file("data/RecentMaps.json")
- var/list/file_data = list()
- file_data["maps"] = saved_maps
- fdel(json_file)
- WRITE_FILE(json_file, json_encode(file_data))
-
/datum/controller/subsystem/persistence/proc/CollectAntagReputation()
var/ANTAG_REP_MAXIMUM = CONFIG_GET(number/antag_rep_maximum)
diff --git a/code/controllers/subsystem/persistence/panic_bunker.dm b/code/controllers/subsystem/persistence/panic_bunker.dm
new file mode 100644
index 0000000000..93ada2835c
--- /dev/null
+++ b/code/controllers/subsystem/persistence/panic_bunker.dm
@@ -0,0 +1,26 @@
+/**
+ * Persists panic bunker whitelisting for a configured period of time
+ */
+/datum/controller/subsystem/persistence/LoadServerPersistence()
+ . = ..()
+ LoadPanicBunker()
+
+/datum/controller/subsystem/persistence/SaveServerPersistence()
+ . = ..()
+ SavePanicBunker()
+
+/datum/controller/subsystem/persistence/proc/LoadPanicBunker()
+ var/bunker_path = file("data/bunker_passthrough.json")
+ if(fexists(bunker_path))
+ var/list/json = json_decode(file2text(bunker_path))
+ GLOB.bunker_passthrough = json["data"]
+ for(var/ckey in GLOB.bunker_passthrough)
+ if(daysSince(GLOB.bunker_passthrough[ckey]) >= CONFIG_GET(number/max_bunker_days))
+ GLOB.bunker_passthrough -= ckey
+
+/datum/controller/subsystem/persistence/proc/SavePanicBunker()
+ var/json_file = file("data/bunker_passthrough.json")
+ var/list/file_data = list()
+ file_data["data"] = GLOB.bunker_passthrough
+ fdel(json_file)
+ WRITE_FILE(json_file,json_encode(file_data))
diff --git a/code/controllers/subsystem/persistence/poly_parrot.dm b/code/controllers/subsystem/persistence/poly_parrot.dm
new file mode 100644
index 0000000000..64743e9623
--- /dev/null
+++ b/code/controllers/subsystem/persistence/poly_parrot.dm
@@ -0,0 +1,11 @@
+/**
+ * Persists poly messages across rounds
+ */
+/datum/controller/subsystem/persistence/LoadGamePersistence()
+ . = ..()
+ LoadPoly()
+
+/datum/controller/subsystem/persistence/proc/LoadPoly()
+ for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list)
+ twitterize(P.speech_buffer, "polytalk")
+ break //Who's been duping the bird?!
diff --git a/code/controllers/subsystem/persistence/recent_votes_etc.dm b/code/controllers/subsystem/persistence/recent_votes_etc.dm
new file mode 100644
index 0000000000..f1b902d6ab
--- /dev/null
+++ b/code/controllers/subsystem/persistence/recent_votes_etc.dm
@@ -0,0 +1,107 @@
+/**
+ * Stores recently played gamemodes, maps, etc.
+ */
+/datum/controller/subsystem/persistence
+ var/list/saved_modes = list(1,2,3)
+ var/list/saved_dynamic_rules = list(list(),list(),list())
+ var/list/saved_storytellers = list("foo","bar","baz")
+ var/list/average_dynamic_threat = 50
+ var/list/saved_maps
+
+/datum/controller/subsystem/persistence/SaveServerPersistence()
+ . = ..()
+ CollectRoundtype()
+ if(istype(SSticker.mode, /datum/game_mode/dynamic))
+ var/datum/game_mode/dynamic/mode = SSticker.mode
+ CollectStoryteller(mode)
+ CollectRulesets(mode)
+ RecordMaps()
+
+/datum/controller/subsystem/persistence/LoadServerPersistence()
+ . = ..()
+ LoadRecentModes()
+ LoadRecentStorytellers()
+ LoadRecentRulesets()
+ LoadRecentMaps()
+
+/datum/controller/subsystem/persistence/proc/CollectRoundtype()
+ saved_modes[3] = saved_modes[2]
+ saved_modes[2] = saved_modes[1]
+ saved_modes[1] = SSticker.mode.config_tag
+ var/json_file = file("data/RecentModes.json")
+ var/list/file_data = list()
+ file_data["data"] = saved_modes
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
+
+/datum/controller/subsystem/persistence/proc/CollectStoryteller(var/datum/game_mode/dynamic/mode)
+ saved_storytellers.len = 3
+ saved_storytellers[3] = saved_storytellers[2]
+ saved_storytellers[2] = saved_storytellers[1]
+ saved_storytellers[1] = mode.storyteller.name
+ average_dynamic_threat = (mode.max_threat + average_dynamic_threat) / 2
+ var/json_file = file("data/RecentStorytellers.json")
+ var/list/file_data = list()
+ file_data["data"] = saved_storytellers + average_dynamic_threat
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
+
+/datum/controller/subsystem/persistence/proc/CollectRulesets(var/datum/game_mode/dynamic/mode)
+ saved_dynamic_rules[3] = saved_dynamic_rules[2]
+ saved_dynamic_rules[2] = saved_dynamic_rules[1]
+ saved_dynamic_rules[1] = list()
+ for(var/r in mode.executed_rules)
+ var/datum/dynamic_ruleset/rule = r
+ saved_dynamic_rules[1] += rule.config_tag
+ var/json_file = file("data/RecentRulesets.json")
+ var/list/file_data = list()
+ file_data["data"] = saved_dynamic_rules
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
+
+/datum/controller/subsystem/persistence/proc/RecordMaps()
+ saved_maps = saved_maps?.len ? list("[SSmapping.config.map_name]") | saved_maps : list("[SSmapping.config.map_name]")
+ var/json_file = file("data/RecentMaps.json")
+ var/list/file_data = list()
+ file_data["maps"] = saved_maps
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
+
+/datum/controller/subsystem/persistence/proc/LoadRecentModes()
+ var/json_file = file("data/RecentModes.json")
+ if(!fexists(json_file))
+ return
+ var/list/json = json_decode(file2text(json_file))
+ if(!json)
+ return
+ saved_modes = json["data"]
+
+/datum/controller/subsystem/persistence/proc/LoadRecentRulesets()
+ var/json_file = file("data/RecentRulesets.json")
+ if(!fexists(json_file))
+ return
+ var/list/json = json_decode(file2text(json_file))
+ if(!json)
+ return
+ saved_dynamic_rules = json["data"]
+
+/datum/controller/subsystem/persistence/proc/LoadRecentStorytellers()
+ var/json_file = file("data/RecentStorytellers.json")
+ if(!fexists(json_file))
+ return
+ var/list/json = json_decode(file2text(json_file))
+ if(!json)
+ return
+ saved_storytellers = json["data"]
+ if(saved_storytellers.len > 3)
+ average_dynamic_threat = saved_storytellers[4]
+ saved_storytellers.len = 3
+
+/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
+ var/json_file = file("data/RecentMaps.json")
+ if(!fexists(json_file))
+ return
+ var/list/json = json_decode(file2text(json_file))
+ if(!json)
+ return
+ saved_maps = json["maps"]
diff --git a/code/controllers/subsystem/persistence/secret_satchels.dm b/code/controllers/subsystem/persistence/secret_satchels.dm
new file mode 100644
index 0000000000..fa2a445317
--- /dev/null
+++ b/code/controllers/subsystem/persistence/secret_satchels.dm
@@ -0,0 +1,79 @@
+/**
+ * Secret satchel persistence - allows storing of items in underfloor satchels that's loaded later.
+ */
+/datum/controller/subsystem/persistence
+ var/list/satchel_blacklist = list() //this is a typecache
+ var/list/new_secret_satchels = list() //these are objects
+ var/list/old_secret_satchels = list()
+
+/datum/controller/subsystem/persistence/LoadGamePersistence()
+ . = ..()
+ LoadSatchels()
+
+/datum/controller/subsystem/persistence/SaveGamePersistence()
+ . = ..()
+ CollectSecretSatchels()
+
+/datum/controller/subsystem/persistence/proc/LoadSatchels()
+ var/placed_satchel = 0
+ var/path
+
+ var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
+ var/list/json = list()
+ if(fexists(json_file))
+ json = json_decode(file2text(json_file))
+
+ old_secret_satchels = json["data"]
+ var/obj/item/storage/backpack/satchel/flat/F
+ if(old_secret_satchels && old_secret_satchels.len >= 10) //guards against low drop pools assuring that one player cannot reliably find his own gear.
+ var/pos = rand(1, old_secret_satchels.len)
+ F = new()
+ old_secret_satchels.Cut(pos, pos+1 % old_secret_satchels.len)
+ F.x = old_secret_satchels[pos]["x"]
+ F.y = old_secret_satchels[pos]["y"]
+ F.z = SSmapping.station_start
+ path = text2path(old_secret_satchels[pos]["saved_obj"])
+
+ if(F)
+ if(isfloorturf(F.loc) && !isplatingturf(F.loc))
+ F.hide(1)
+ if(ispath(path))
+ var/spawned_item = new path(F)
+ spawned_objects[spawned_item] = TRUE
+ placed_satchel++
+ var/free_satchels = 0
+ for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,SSmapping.station_start), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,SSmapping.station_start)))) //Nontrivially expensive but it's roundstart only
+ if(isfloorturf(T) && !isplatingturf(T))
+ new /obj/item/storage/backpack/satchel/flat/secret(T)
+ free_satchels++
+ if((free_satchels + placed_satchel) == 10) //ten tiles, more than enough to kill anything that moves
+ break
+
+/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
+ satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar))
+ var/list/satchels_to_add = list()
+ for(var/A in new_secret_satchels)
+ var/obj/item/storage/backpack/satchel/flat/F = A
+ if(QDELETED(F) || F.z != SSmapping.station_start || F.invisibility != INVISIBILITY_MAXIMUM)
+ continue
+ var/list/savable_obj = list()
+ for(var/obj/O in F)
+ if(is_type_in_typecache(O, satchel_blacklist) || (O.flags_1 & ADMIN_SPAWNED_1))
+ continue
+ if(O.persistence_replacement)
+ savable_obj += O.persistence_replacement
+ else
+ savable_obj += O.type
+ if(isemptylist(savable_obj))
+ continue
+ var/list/data = list()
+ data["x"] = F.x
+ data["y"] = F.y
+ data["saved_obj"] = pick(savable_obj)
+ satchels_to_add += list(data)
+
+ var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json")
+ var/list/file_data = list()
+ fdel(json_file)
+ file_data["data"] = old_secret_satchels + satchels_to_add
+ WRITE_FILE(json_file, json_encode(file_data))
diff --git a/code/controllers/subsystem/persistence/trophies.dm b/code/controllers/subsystem/persistence/trophies.dm
new file mode 100644
index 0000000000..770ca99125
--- /dev/null
+++ b/code/controllers/subsystem/persistence/trophies.dm
@@ -0,0 +1,84 @@
+/**
+ * Stores trophies in curator display cases
+ */
+/datum/controller/subsystem/persistence
+ var/list/saved_trophies = list()
+
+/datum/controller/subsystem/persistence/LoadGamePersistence()
+ . = ..()
+ LoadTrophies()
+
+/datum/controller/subsystem/persistence/SaveGamePersistence()
+ . = ..()
+ CollectTrophies()
+
+/datum/controller/subsystem/persistence/proc/LoadTrophies()
+ if(fexists("data/npc_saves/TrophyItems.sav")) //legacy compatability to convert old format to new
+ var/savefile/S = new /savefile("data/npc_saves/TrophyItems.sav")
+ var/saved_json
+ S >> saved_json
+ if(!saved_json)
+ return
+ saved_trophies = json_decode(saved_json)
+ fdel("data/npc_saves/TrophyItems.sav")
+ else
+ var/json_file = file("data/npc_saves/TrophyItems.json")
+ if(!fexists(json_file))
+ return
+ var/list/json = json_decode(file2text(json_file))
+ if(!json)
+ return
+ saved_trophies = json["data"]
+ SetUpTrophies(saved_trophies.Copy())
+
+/datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items)
+ for(var/A in GLOB.trophy_cases)
+ var/obj/structure/displaycase/trophy/T = A
+ if (T.showpiece)
+ continue
+ T.added_roundstart = TRUE
+
+ var/trophy_data = pick_n_take(trophy_items)
+
+ if(!islist(trophy_data))
+ continue
+
+ var/list/chosen_trophy = trophy_data
+
+ if(!chosen_trophy || isemptylist(chosen_trophy)) //Malformed
+ continue
+
+ var/path = text2path(chosen_trophy["path"]) //If the item no longer exist, this returns null
+ if(!path)
+ continue
+
+ T.showpiece = new /obj/item/showpiece_dummy(T, path)
+ T.trophy_message = chosen_trophy["message"]
+ T.placer_key = chosen_trophy["placer_key"]
+ T.update_icon()
+
+/datum/controller/subsystem/persistence/proc/CollectTrophies()
+ var/json_file = file("data/npc_saves/TrophyItems.json")
+ var/list/file_data = list()
+ file_data["data"] = remove_duplicate_trophies(saved_trophies)
+ fdel(json_file)
+ WRITE_FILE(json_file, json_encode(file_data))
+
+/datum/controller/subsystem/persistence/proc/remove_duplicate_trophies(list/trophies)
+ var/list/ukeys = list()
+ . = list()
+ for(var/trophy in trophies)
+ var/tkey = "[trophy["path"]]-[trophy["message"]]"
+ if(ukeys[tkey])
+ continue
+ else
+ . += list(trophy)
+ ukeys[tkey] = TRUE
+
+/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
+ if(!T.added_roundstart && T.showpiece)
+ var/list/data = list()
+ data["path"] = T.showpiece.type
+ data["message"] = T.trophy_message
+ data["placer_key"] = T.placer_key
+ saved_trophies += list(data)
diff --git a/tgstation.dme b/tgstation.dme
index 07eefc79ef..a5cad8bc0a 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -340,7 +340,6 @@
#include "code\controllers\subsystem\pai.dm"
#include "code\controllers\subsystem\parallax.dm"
#include "code\controllers\subsystem\pathfinder.dm"
-#include "code\controllers\subsystem\persistence.dm"
#include "code\controllers\subsystem\profiler.dm"
#include "code\controllers\subsystem\radiation.dm"
#include "code\controllers\subsystem\radio.dm"
@@ -363,6 +362,12 @@
#include "code\controllers\subsystem\vis_overlays.dm"
#include "code\controllers\subsystem\vore.dm"
#include "code\controllers\subsystem\vote.dm"
+#include "code\controllers\subsystem\persistence\_persistence.dm"
+#include "code\controllers\subsystem\persistence\panic_bunker.dm"
+#include "code\controllers\subsystem\persistence\poly_parrot.dm"
+#include "code\controllers\subsystem\persistence\recent_votes_etc.dm"
+#include "code\controllers\subsystem\persistence\secret_satchels.dm"
+#include "code\controllers\subsystem\persistence\trophies.dm"
#include "code\controllers\subsystem\processing\chemistry.dm"
#include "code\controllers\subsystem\processing\circuit.dm"
#include "code\controllers\subsystem\processing\fastprocess.dm"
From 999262665b5e152d05e920bccc6c366684e74c5f Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 25 Dec 2020 15:54:28 -0800
Subject: [PATCH 02/31] map keys
---
.../subsystem/persistence/_persistence.dm | 17 +++++++++++++++--
code/modules/mapping/map_config.dm | 11 +++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
index edecba311b..6cf9f84b91 100644
--- a/code/controllers/subsystem/persistence/_persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -21,13 +21,26 @@ SUBSYSTEM_DEF(persistence)
/datum/controller/subsystem/persistence/Initialize()
LoadServerPersistence()
LoadGamePersistence()
- LoadMapPersistence()
+ var/map_persistence_path = get_map_persistence_path()
+ if(map_persistence_path)
+ LoadMapPersistence(map_persistence_path)
return ..()
+/**
+ * Gets the persistence path of the current map.
+ */
+/datum/controller/subsystem/persistence/proc/get_map_persistence_path()
+ ASSERT(SSmapping.config)
+ if(SSmapping.config.persistence_key == "NO_PERSIST")
+ return null
+ return "data/persistence/[ckey(SSmapping.config.persistence_key)]"
+
/datum/controller/subsystem/persistence/proc/CollectData()
SaveServerPersistence()
SaveGamePersistence()
- SaveMapPersistence()
+ var/map_persistence_path = get_map_persistence_path()
+ if(map_persistence_path)
+ SaveMapPersistence(map_persistence_path)
/**
* Loads persistent data relevant to the server: Configurations, past gamemodes, votes, etc
diff --git a/code/modules/mapping/map_config.dm b/code/modules/mapping/map_config.dm
index d18ca1e1e3..83418462f1 100644
--- a/code/modules/mapping/map_config.dm
+++ b/code/modules/mapping/map_config.dm
@@ -18,6 +18,8 @@
var/map_name = "Box Station"
var/map_path = "map_files/BoxStation"
var/map_file = "BoxStation.dmm"
+ /// Persistence key: Defaults to ckey(map_name). If set to "NO_PERSIST", this map will have NO persistence.
+ var/persistence_key
var/traits = null
var/space_ruin_levels = 4
@@ -99,6 +101,15 @@
map_path = json["map_path"]
map_file = json["map_file"]
+
+ persistence_key = ckey(map_name)
+
+ var/json_persistence_key = json["persistence_key"]
+ if(json_persistence_key == "NO_PERSIST")
+ persistence_key = null
+ else
+ persistence_key = json_persistence_key
+
// "map_file": "BoxStation.dmm"
if (istext(map_file))
if (!fexists("_maps/[map_path]/[map_file]"))
From 5e66e4509f88c1310f7776bba5f2ea60e84b292c Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 25 Dec 2020 16:07:17 -0800
Subject: [PATCH 03/31] wew
---
.../configuration/entries/persistence.dm | 17 +++++++++++++++++
.../subsystem/persistence/_persistence.dm | 3 +--
.../subsystem/persistence/cleanable_debris.dm | 3 +++
code/game/objects/effects/decals/cleanable.dm | 17 +++++++++++++++++
4 files changed, 38 insertions(+), 2 deletions(-)
create mode 100644 code/controllers/configuration/entries/persistence.dm
create mode 100644 code/controllers/subsystem/persistence/cleanable_debris.dm
diff --git a/code/controllers/configuration/entries/persistence.dm b/code/controllers/configuration/entries/persistence.dm
new file mode 100644
index 0000000000..cf7b23bef3
--- /dev/null
+++ b/code/controllers/configuration/entries/persistence.dm
@@ -0,0 +1,17 @@
+/// Whether or not to use the persistence system for cleanable objects
+/datum/config_entry/flag/persistent_debris
+ config_entry_value = FALSE
+
+/// Whether or not to nuke all roundstart debris that isn't due to persistence if the above is true
+/datum/config_entry/flag/persistent_debris_only
+ config_entry_value = TRUE
+
+/// Max amount of objects to store, total
+/datum/config_entry/number/persistent_debris_global_max
+ config_entry_value = 10000
+ integer = TRUE
+
+/// Max amount of objects to store per type
+/datum/config_entry/number/persistent_debris_type_max
+ config_entry_value = 2000
+ integer = TRUE
diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
index 6cf9f84b91..a950a78f2b 100644
--- a/code/controllers/subsystem/persistence/_persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -67,6 +67,7 @@ SUBSYSTEM_DEF(persistence)
LoadChiselMessages()
LoadPhotoPersistence()
LoadRandomizedRecipes()
+ LoadPaintings()
/**
* Saves persistent data relevant to the game in general: Trophies, antag reputation, etc
@@ -247,8 +248,6 @@ SUBSYSTEM_DEF(persistence)
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
saved_messages += list(M.pack()) // dm eats one list
-
-
/datum/controller/subsystem/persistence/proc/CollectAntagReputation()
var/ANTAG_REP_MAXIMUM = CONFIG_GET(number/antag_rep_maximum)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
new file mode 100644
index 0000000000..1e3390357b
--- /dev/null
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -0,0 +1,3 @@
+/**
+ * Persistence for cleanable debris.
+ */
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 34996177af..cadda8da00 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,6 +1,9 @@
/obj/effect/decal/cleanable
gender = PLURAL
layer = ABOVE_NORMAL_TURF_LAYER
+ /// Is this kind of cleanable decal persistent
+ var/persistent = FALSE
+
var/list/random_icon_states = null
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
@@ -9,6 +12,8 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
+ if(mapload && persistent && CONFIG_GET(flag/persistent_debris_only))
+ return INITIALIZE_HINT_QDEL
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
@@ -29,6 +34,18 @@
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, beauty)), 0)
+/**
+ * Returns a list of data
+ */
+/obj/effect/decal/cleanable/proc/PersistenceSave()
+ return null
+
+/**
+ * Laods from a data list.
+ */
+/obj/effect/decal/cleanable/proc/PersistenceLoad(list/data)
+ return
+
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
qdel(C)
From d5ab4b79dcda45ee422a53243cf0e5a7afac2d78 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 25 Dec 2020 16:07:29 -0800
Subject: [PATCH 04/31] dme
---
tgstation.dme | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tgstation.dme b/tgstation.dme
index a5cad8bc0a..4fca500006 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -292,6 +292,7 @@
#include "code\controllers\configuration\entries\fail2topic.dm"
#include "code\controllers\configuration\entries\game_options.dm"
#include "code\controllers\configuration\entries\general.dm"
+#include "code\controllers\configuration\entries\persistence.dm"
#include "code\controllers\configuration\entries\plushies.dm"
#include "code\controllers\configuration\entries\policy.dm"
#include "code\controllers\configuration\entries\resources.dm"
@@ -363,6 +364,7 @@
#include "code\controllers\subsystem\vore.dm"
#include "code\controllers\subsystem\vote.dm"
#include "code\controllers\subsystem\persistence\_persistence.dm"
+#include "code\controllers\subsystem\persistence\cleanable_debris.dm"
#include "code\controllers\subsystem\persistence\panic_bunker.dm"
#include "code\controllers\subsystem\persistence\poly_parrot.dm"
#include "code\controllers\subsystem\persistence\recent_votes_etc.dm"
From 5cf717e75da31bd21bbb5ca8446d414ec65937cd Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 25 Dec 2020 16:10:32 -0800
Subject: [PATCH 05/31] self message
---
code/game/objects/effects/decals/cleanable.dm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index cadda8da00..63f17d61ee 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -12,7 +12,8 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
- if(mapload && persistent && CONFIG_GET(flag/persistent_debris_only))
+ #warn OPTIMIZE THE BELOW LINE, CACHE THINGS, THIS IS INSANELY EXPENSIVE
+ if(mapload && persistent && CONFIG_GET(flag/persistent_debris_only) && (z in SSmapping.levels_by_trait(ZTRAIT_STATION)))
return INITIALIZE_HINT_QDEL
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
From 45af2360addcdd33803a0289e14a7f452da67a4f Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 11:35:47 -0800
Subject: [PATCH 06/31] changes
---
.../subsystem/persistence/_persistence.dm | 14 ++----
.../subsystem/persistence/cleanable_debris.dm | 46 +++++++++++++++++++
code/game/area/Space_Station_13_areas.dm | 1 +
code/game/area/areas.dm | 2 +
code/game/objects/effects/decals/cleanable.dm | 14 +++---
.../objects/effects/decals/cleanable/misc.dm | 29 ++++++++++++
code/game/objects/effects/decals/crayon.dm | 26 +++++++++++
7 files changed, 116 insertions(+), 16 deletions(-)
diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
index a950a78f2b..00135bbcc2 100644
--- a/code/controllers/subsystem/persistence/_persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(persistence)
LoadGamePersistence()
var/map_persistence_path = get_map_persistence_path()
if(map_persistence_path)
- LoadMapPersistence(map_persistence_path)
+ LoadMapPersistence()
return ..()
/**
@@ -40,7 +40,7 @@ SUBSYSTEM_DEF(persistence)
SaveGamePersistence()
var/map_persistence_path = get_map_persistence_path()
if(map_persistence_path)
- SaveMapPersistence(map_persistence_path)
+ SaveMapPersistence()
/**
* Loads persistent data relevant to the server: Configurations, past gamemodes, votes, etc
@@ -83,20 +83,14 @@ SUBSYSTEM_DEF(persistence)
/**
* Loads persistent data relevant to the current map: Objects, etc.
- *
- * @params
- * data_directory - The data directory to use. Each map with a persistence key has its own, and this is based on the persistence key.
*/
-/datum/controller/subsystem/persistence/proc/LoadMapPersistence(data_directory)
+/datum/controller/subsystem/persistence/proc/LoadMapPersistence()
return
/**
* Saves persistent data relevant to the current map: Objects, etc.
- *
- * @params
- * data_directory - The data directory to use. Each map with a persistence key has its own, and this is based on the persistence key.
*/
-/datum/controller/subsystem/persistence/proc/SaveMapPersistence(data_directory)
+/datum/controller/subsystem/persistence/proc/SaveMapPersistence()
return
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 1e3390357b..13c80aee57 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -1,3 +1,49 @@
/**
* Persistence for cleanable debris.
*/
+/datum/controller/subsystem/persistence
+ /// tracks if we already loaded debris. Unlike everything else, this can actually be a major problem if some badmin procs it twice.
+ var/loaded_debris = FALSE
+
+/datum/controller/subsystem/persistence/LoadMapPersistence()
+ . = ..()
+ if(CONFIG_GET(flag/persistent_debris))
+ LoadMapDebris()
+
+/datum/controller/subsystem/persistence/SaveMapPersistence()
+ . = ..()
+ if(CONFIG_GET(flag/persistent_debris))
+ SaveMapDebris()
+
+/datum/controller/subsystem/persistence/proc/LoadMapDebris()
+ if(!fexists("[get_map_persistence_path()]/debris.json"))
+ return
+ if(loaded_debris)
+ return
+ loaded_debris = TRUE
+ var/list/data = json_decode(file2text("[get_map_persistence_path()]/debris.json"))
+
+
+/datum/controller/subsystem/persistence/proc/SaveMapDebris()
+ if(fexists("[get_map_persistence_path()]/debris.json"))
+ fdel("[get_map_persistence_path()]/debris.json")
+ var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
+ var/list/allowed_z_cache = list()
+ for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
+ allowed_z_cache[num2text(z)] = TRUE
+ var/list/data = list()
+
+ WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
+
+
+/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache)
+ if(!allowed_typecache[tile.type])
+ return FALSE
+ if(!tile.loc.persistent_debris_allowed)
+ return FALSE
+ if(!allowed_zcache[num2text(tile.z)])
+ return FALSE
+ for(var/obj/structure/window/W in tile)
+ if(W.fulltile)
+ return FALSE
+ return TRUE
diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm
index 5310b24202..03a2309e8a 100644
--- a/code/game/area/Space_Station_13_areas.dm
+++ b/code/game/area/Space_Station_13_areas.dm
@@ -41,6 +41,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
power_environ = FALSE
valid_territory = FALSE
outdoors = TRUE
+ persistent_debris_allowed = FALSE
ambientsounds = SPACE
blob_allowed = FALSE //Eating up space doesn't count for victory as a blob.
considered_hull_exterior = TRUE
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index b9415f3cf8..fcde2bd1eb 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -24,6 +24,8 @@
var/clockwork_warp_allowed = TRUE
/// Message to display when the clockwork warp fails
var/clockwork_warp_fail = "The structure there is too dense for warping to pierce. (This is normal in high-security areas.)"
+ /// Persistent debris alowed
+ var/persistent_debris_allowed = TRUE
/// If mining tunnel generation is allowed in this area
var/tunnel_allowed = FALSE
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 63f17d61ee..1ad2173f76 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -3,6 +3,8 @@
layer = ABOVE_NORMAL_TURF_LAYER
/// Is this kind of cleanable decal persistent
var/persistent = FALSE
+ /// Can we stack multiple in one tile?
+ var/persistence_allow_stacking = FALSE
var/list/random_icon_states = null
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
@@ -36,20 +38,20 @@
addtimer(CALLBACK(src, /datum.proc/_AddElement, list(/datum/element/beauty, beauty)), 0)
/**
- * Returns a list of data
+ * A data list is passed into this.
+ * This should return null to skip saving, or the type of data to save. Type must be /cleanable.
*/
-/obj/effect/decal/cleanable/proc/PersistenceSave()
- return null
+/obj/effect/decal/cleanable/proc/PersistenceSave(list/data)
+ return type
/**
- * Laods from a data list.
+ * Loads from a data list.
*/
/obj/effect/decal/cleanable/proc/PersistenceLoad(list/data)
return
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
- if(mergeable_decal)
- qdel(C)
+ return mergeable_decal
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 044c5c6e86..9c0fb2eca9 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -12,6 +12,8 @@
icon_state = "ash"
mergeable_decal = FALSE
beauty = -50
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
/obj/effect/decal/cleanable/ash/Initialize()
. = ..()
@@ -38,6 +40,8 @@
icon = 'icons/obj/shards.dmi'
icon_state = "tiny"
beauty = -100
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/glass/Initialize()
. = ..()
@@ -94,6 +98,8 @@
light_color = LIGHT_COLOR_GREEN
icon_state = "greenglow"
beauty = -300
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/greenglow/Initialize(mapload)
. = ..()
@@ -122,6 +128,8 @@
icon_state = "molten"
mergeable_decal = FALSE
beauty = -150
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
@@ -136,6 +144,7 @@
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
beauty = -150
+ persistent = TRUE
/obj/effect/decal/cleanable/vomit/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(ishuman(user))
@@ -151,6 +160,10 @@
reagents.trans_to(H, reagents.total_volume)
qdel(src)
+/obj/effect/decal/cleanable/vomit/PersistenceSave(list/data)
+ . = ..()
+ return /obj/effect/decal/cleanable/vomit/old
+
/obj/effect/decal/cleanable/vomit/old
name = "crusty dried vomit"
desc = "You try not to look at the chunks, and fail."
@@ -166,12 +179,16 @@
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
beauty = -100
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
@@ -179,6 +196,8 @@
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
@@ -186,6 +205,8 @@
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
@@ -193,6 +214,8 @@
gender = NEUTER
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/shreds
name = "shreds"
@@ -200,6 +223,8 @@
icon_state = "shreds"
gender = PLURAL
mergeable_decal = FALSE
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/shreds/ex_act(severity, target)
if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion.
@@ -222,6 +247,8 @@
desc = "The herpes of arts and crafts."
icon = 'icons/effects/atmospherics.dmi'
gender = NEUTER
+ mergeable_decal = TRUE
+ persistent = TRUE
/obj/effect/decal/cleanable/glitter/pink
name = "pink glitter"
@@ -247,3 +274,5 @@
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
+ mergeable_decal = TRUE
+ persistent = TRUE
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index 8cfdad0432..d62f8fccb6 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -5,6 +5,8 @@
icon_state = "rune1"
plane = ABOVE_WALL_PLANE //makes the graffiti visible over a wall.
gender = NEUTER
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
mergeable_decal = FALSE
var/do_icon_rotate = TRUE
var/rotation = 0
@@ -29,3 +31,27 @@
if(main)
paint_colour = main
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
+
+/obj/effect/decal/cleanable/crayon/PersistenceSave(list/data)
+ . = ..()
+ if(icon != initial(icon)) // no support for alticons yet, awful system anyways
+ return null
+ data["icon_state"] = icon_stsate
+ data["paint_color"] = paint_colour
+ if(do_icon_rotate)
+ data["rotation"] = rotation
+ data["name"] = name
+
+/obj/effect/decal/cleanable/crayon/PersistenceLoad(list/data)
+ . = ..()
+ if(data["name"])
+ name = data["name"]
+ if(do_icon_rotate && data["rotation"])
+ var/matrix/M = matrix()
+ M.turn(data["rotation"])
+ transform = M
+ if(data["paint_color"])
+ paint_colour = data["paint_color"])
+ add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
+ if(data["icon_state"])
+ icon_state = data["icon_state"]
From d474643debad991e371a8f7e910e256be2b82b52 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 11:41:25 -0800
Subject: [PATCH 07/31] changes
---
code/controllers/subsystem/mapping.dm | 10 ++++++++++
.../subsystem/persistence/cleanable_debris.dm | 7 ++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 2ea3b29c91..3d45672c3b 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -41,6 +41,8 @@ SUBSYSTEM_DEF(mapping)
var/datum/space_level/transit
var/datum/space_level/empty_space
var/num_of_res_levels = 1
+ /// Lookup for zlevel to station z. text = num.
+ var/list/z_to_station_z_index
var/stat_map_name = "Loading..."
@@ -259,6 +261,12 @@ SUBSYSTEM_DEF(mapping)
INIT_ANNOUNCE("Loaded [name] in [(REALTIMEOFDAY - start_time)/10]s!")
return parsed_maps
+/datum/controller/subsystem/mapping/proc/setup_station_z_index()
+ z_to_station_z_index = list()
+ var/sz = 1
+ for(var/i in station_start to (station_Start + islist(config.map_file)? (length(config.map_file) - 1) : 0))
+ z_to_station_z_index["[i]"] = sz++
+
/datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong
var/list/FailedZs = list()
@@ -271,6 +279,8 @@ SUBSYSTEM_DEF(mapping)
INIT_ANNOUNCE("Loading [config.map_name]...")
LoadGroup(FailedZs, "Station", config.map_path, config.map_file, config.traits, ZTRAITS_STATION, FALSE, config.orientation)
+ setup_station_z_index()
+
if(SSdbcore.Connect())
var/datum/DBQuery/query_round_map_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET map_name = '[config.map_name]' WHERE id = [GLOB.round_id]")
query_round_map_name.Execute()
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 13c80aee57..c4ef98121b 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -22,7 +22,11 @@
return
loaded_debris = TRUE
var/list/data = json_decode(file2text("[get_map_persistence_path()]/debris.json"))
-
+ var/list/z_lookup = list()
+ /// reverse it
+ for(var/z in SSmapping.z_to_station_z_index)
+ var/sz = SSmapping.z_to_station_z_index[z]
+ z_lookup[num2text(sz)] = z
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
@@ -32,6 +36,7 @@
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
allowed_z_cache[num2text(z)] = TRUE
var/list/data = list()
+ var/list/z_lookup = SSmapping.z_to_station_z_index
WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
From 338869f6ad5913d6542c1818e6b07c22e1b00448 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 11:48:28 -0800
Subject: [PATCH 08/31] changes
---
.../subsystem/persistence/cleanable_debris.dm | 29 +++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index c4ef98121b..6f85436df8 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -21,12 +21,31 @@
if(loaded_debris)
return
loaded_debris = TRUE
+ var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
+ var/list/allowed_z_cache = list()
var/list/data = json_decode(file2text("[get_map_persistence_path()]/debris.json"))
var/list/z_lookup = list()
/// reverse it
for(var/z in SSmapping.z_to_station_z_index)
var/sz = SSmapping.z_to_station_z_index[z]
z_lookup[num2text(sz)] = z
+ for(var/z in data)
+ var/actual_z = z_lookup[z]
+ var/list/L1 = data[z]
+ for(var/x in L1)
+ var/list/L2 = data[z][x]
+ for(var/y in L2)
+ var/turf/tile = locate(x, y, z)
+ if(!tile)
+ continue
+ var/list/objects = data[z][x][y]
+ for(var/path in objects)
+ if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
+ continue
+ var/obj/effect/cleanable/instantiated = new path(tile)
+ var/list/data = objects[path]
+ if(data)
+ instantiated.PersistenceLoad(data)
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
@@ -38,16 +57,22 @@
var/list/data = list()
var/list/z_lookup = SSmapping.z_to_station_z_index
+
WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
-
-/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache)
+/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache, type, loading = FALSE)
if(!allowed_typecache[tile.type])
return FALSE
if(!tile.loc.persistent_debris_allowed)
return FALSE
if(!allowed_zcache[num2text(tile.z)])
return FALSE
+ if(loading)
+ if(!initial(type.persistence_allow_stacking))
+ var/obj/effect/cleanable/C = locate(type) in tile
+ if(!QDELETED(C))
+ return FALSE
+ // Saving verifies allow stacking in the save proc.
for(var/obj/structure/window/W in tile)
if(W.fulltile)
return FALSE
From 5c0b4f824f81560fad4f1bf0916890c94969167e Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 12:42:03 -0800
Subject: [PATCH 09/31] hoh boy
---
code/controllers/subsystem/mapping.dm | 2 +-
.../subsystem/persistence/cleanable_debris.dm | 88 +++++++++++++++++--
code/game/objects/effects/decals/cleanable.dm | 3 -
code/game/objects/effects/decals/crayon.dm | 4 +-
4 files changed, 82 insertions(+), 15 deletions(-)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 3d45672c3b..1893e9ccd9 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -264,7 +264,7 @@ SUBSYSTEM_DEF(mapping)
/datum/controller/subsystem/mapping/proc/setup_station_z_index()
z_to_station_z_index = list()
var/sz = 1
- for(var/i in station_start to (station_Start + islist(config.map_file)? (length(config.map_file) - 1) : 0))
+ for(var/i in station_start to (station_start + islist(config.map_file)? (length(config.map_file) - 1) : 0))
z_to_station_z_index["[i]"] = sz++
/datum/controller/subsystem/mapping/proc/loadWorld()
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 6f85436df8..8b8cd55d0d 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -21,8 +21,12 @@
if(loaded_debris)
return
loaded_debris = TRUE
+ if(CONFIG_GET(flag/persistent_debris_only))
+ wipe_existing_debris()
var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
var/list/allowed_z_cache = list()
+ for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
+ allowed_z_cache[num2text(z)] = TRUE
var/list/data = json_decode(file2text("[get_map_persistence_path()]/debris.json"))
var/list/z_lookup = list()
/// reverse it
@@ -39,31 +43,78 @@
if(!tile)
continue
var/list/objects = data[z][x][y]
- for(var/path in objects)
+ for(var/_L in objects)
+ var/list/data
+ var/path
+ if(islist(_L))
+ data = _L
+ path = data["__PATH__"]
+ else
+ path = _L
+ data = objects[_L]
if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
continue
+ var/path = data["__PATH__"]
+ if(!path)
+ continue
var/obj/effect/cleanable/instantiated = new path(tile)
- var/list/data = objects[path]
if(data)
- instantiated.PersistenceLoad(data)
+ instantiated.LoadPersistence(data)
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
fdel("[get_map_persistence_path()]/debris.json")
- var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
- var/list/allowed_z_cache = list()
- for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
- allowed_z_cache[num2text(z)] = TRUE
var/list/data = list()
var/list/z_lookup = SSmapping.z_to_station_z_index
+ var/list/debris = RelevantPersistentDebris()
+ var/obj/effect/cleanable/saving
+ var/global_max = CONFIG_GET(number/persistent_debris_global_max)
+ var/type_max = CONFIG_GET(number/persistent_debris_type_max)
+ var/stored = 0
+ var/list/stored_by_type = list()
+ for(var/i in debris)
+ saving = i
+ var/list/serializing = list()
+ var/path = saving.PersistenceSave(serializing)
+ if(!path)
+ continue
+ if(stored_by_type[path] > type_max)
+ continue
+ var/text_z = num2text(saving.z)
+ var/text_y = num2text(saving.y)
+ var/text_x = num2text(saving.x)
+ LAZYINITLIST(data[text_z])
+ LAZYINITLIST(data[text_z][text_x])
+ LAZYINITLIST(data[text_z][text_x][text_y])
+ if(storing.persistence_allow_stacking)
+ serializing["__PATH__"] = path
+ data[text_z][text_x][text_y] += serializing
+ else
+ data[text_z][text_x][text_y][path] = serializing
+ stored++
+ if(stored > global_max)
+ var/w = "Persistent debris saving globally aborted due to global max >= [global_max]. Either janitors never do their jobs or something is wrong."
+ message_admins(w)
+ subsystem_log(w))
+ return
+ stored_by_type[path] = stored_by_type[path]? stored_by_type[path] + 1 : 1
+ if(stored_by_type[path] > type_max)
+ var/w = "Persistent debris saving aborted for type [path] due to type max >= [global_max]. Either janitors never do their jobs or something is wrong."
+ message_admins(w)
+ subsystem_log(w))
-
+ subsystem_log({"
+ Debris saving completed:
+ Total: [global_max]
+ By type: [english_list(stored_by_type)]
+ "})
WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache, type, loading = FALSE)
if(!allowed_typecache[tile.type])
return FALSE
- if(!tile.loc.persistent_debris_allowed)
+ var/area/A = tile.loc
+ if(!A.persistent_debris_allowed)
return FALSE
if(!allowed_zcache[num2text(tile.z)])
return FALSE
@@ -77,3 +128,22 @@
if(W.fulltile)
return FALSE
return TRUE
+
+/datum/controller/subsystem/persistence/proc/wipe_existing_debris()
+ var/list/existing = RelevantPersistentDebris()
+ QDEL_LIST(existing)
+
+/datum/controller/subsystem/persistence/proc/RelevantPersistentDebris()
+ var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
+ var/list/allowed_z_cache = list()
+ for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
+ allowed_z_cache[num2text(z)] = TRUE
+ . = list()
+ for(var/obj/effect/cleanable/C in world)
+ if(!C.loc || QDELETED(C))
+ continue
+ if(!C.persistent)
+ continue
+ if(!IsValidDebrisLocation(C.loc, allowed_turf_typecache, allowed_z_cache, C.type, FALSE))
+ continue
+ . += C
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 1ad2173f76..11d76d3cdf 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -14,9 +14,6 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
- #warn OPTIMIZE THE BELOW LINE, CACHE THINGS, THIS IS INSANELY EXPENSIVE
- if(mapload && persistent && CONFIG_GET(flag/persistent_debris_only) && (z in SSmapping.levels_by_trait(ZTRAIT_STATION)))
- return INITIALIZE_HINT_QDEL
LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index d62f8fccb6..6ebd798e40 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -36,7 +36,7 @@
. = ..()
if(icon != initial(icon)) // no support for alticons yet, awful system anyways
return null
- data["icon_state"] = icon_stsate
+ data["icon_state"] = icon_state
data["paint_color"] = paint_colour
if(do_icon_rotate)
data["rotation"] = rotation
@@ -51,7 +51,7 @@
M.turn(data["rotation"])
transform = M
if(data["paint_color"])
- paint_colour = data["paint_color"])
+ paint_colour = data["paint_color"]
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
if(data["icon_state"])
icon_state = data["icon_state"]
From a5bcd0457ead82cc7bb02dba3ed20a6ce2318a2b Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 12:48:10 -0800
Subject: [PATCH 10/31] hoh boy
---
.../subsystem/persistence/cleanable_debris.dm | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 8b8cd55d0d..772091529a 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -57,9 +57,9 @@
var/path = data["__PATH__"]
if(!path)
continue
- var/obj/effect/cleanable/instantiated = new path(tile)
+ var/obj/effect/decal/cleanable/instantiated = new path(tile)
if(data)
- instantiated.LoadPersistence(data)
+ instantiated.PersistenceLoad(data)
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
@@ -67,7 +67,7 @@
var/list/data = list()
var/list/z_lookup = SSmapping.z_to_station_z_index
var/list/debris = RelevantPersistentDebris()
- var/obj/effect/cleanable/saving
+ var/obj/effect/decal/cleanable/saving
var/global_max = CONFIG_GET(number/persistent_debris_global_max)
var/type_max = CONFIG_GET(number/persistent_debris_type_max)
var/stored = 0
@@ -95,13 +95,13 @@
if(stored > global_max)
var/w = "Persistent debris saving globally aborted due to global max >= [global_max]. Either janitors never do their jobs or something is wrong."
message_admins(w)
- subsystem_log(w))
+ subsystem_log(w)
return
stored_by_type[path] = stored_by_type[path]? stored_by_type[path] + 1 : 1
if(stored_by_type[path] > type_max)
var/w = "Persistent debris saving aborted for type [path] due to type max >= [global_max]. Either janitors never do their jobs or something is wrong."
message_admins(w)
- subsystem_log(w))
+ subsystem_log(w)
subsystem_log({"
Debris saving completed:
@@ -110,7 +110,7 @@
"})
WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
-/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache, type, loading = FALSE)
+/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache, obj/effect/decal/cleanable/type, loading = FALSE)
if(!allowed_typecache[tile.type])
return FALSE
var/area/A = tile.loc
@@ -120,7 +120,7 @@
return FALSE
if(loading)
if(!initial(type.persistence_allow_stacking))
- var/obj/effect/cleanable/C = locate(type) in tile
+ var/obj/effect/decal/cleanable/C = locate(type) in tile
if(!QDELETED(C))
return FALSE
// Saving verifies allow stacking in the save proc.
@@ -139,7 +139,7 @@
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
allowed_z_cache[num2text(z)] = TRUE
. = list()
- for(var/obj/effect/cleanable/C in world)
+ for(var/obj/effect/decal/cleanable/C in world)
if(!C.loc || QDELETED(C))
continue
if(!C.persistent)
From 9f130e0c5a4bedfd6b6e5d0d3d47b5ddcd1dd80c Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 14:09:10 -0800
Subject: [PATCH 11/31] blood
---
.../objects/effects/decals/cleanable/gibs.dm | 19 +++++++
.../effects/decals/cleanable/humans.dm | 57 ++++++++++++++++++-
.../effects/decals/cleanable/robots.dm | 4 ++
3 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm
index 7df0153ddc..1f9897071c 100644
--- a/code/game/objects/effects/decals/cleanable/gibs.dm
+++ b/code/game/objects/effects/decals/cleanable/gibs.dm
@@ -6,6 +6,7 @@
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
bloodiness = 0 //This isn't supposed to be bloody.
+ persistent = TRUE
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = /datum/reagent/liquidgibs
var/gibs_bloodtype = "A+"
@@ -31,6 +32,10 @@
flesh.color = body_colors
add_overlay(flesh)
+/obj/effect/decal/cleanable/blood/gibs/PersistenceSave(list/data)
+ . = ..()
+ return /obj/effect/decal/cleanable/blood/gibs/old
+
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
@@ -92,6 +97,8 @@
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
@@ -159,6 +166,10 @@
. = ..()
update_icon()
+/obj/effect/decal/cleanable/blood/gibs/slime/PersistenceSave(list/data)
+ . = ..()
+ return type
+
/obj/effect/decal/cleanable/blood/gibs/slime/update_icon()
add_atom_colour(body_colors, FIXED_COLOUR_PRIORITY)
cut_overlays()
@@ -198,6 +209,10 @@
. = ..()
update_icon()
+/obj/effect/decal/cleanable/blood/gibs/synth/PersistenceSave(list/data)
+ . = ..()
+ return type
+
//IPCs
/obj/effect/decal/cleanable/blood/gibs/ipc
desc = "They look sharp yet oozing."
@@ -209,6 +224,10 @@
. = ..()
update_icon()
+/obj/effect/decal/cleanable/blood/gibs/ipc/PersistenceSave(list/data)
+ . = ..()
+ return type
+
/obj/effect/decal/cleanable/blood/gibs/ipc/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index fa16a95faf..5d514bc68f 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -8,6 +8,7 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
beauty = -100
+ persistent = TRUE
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
@@ -24,7 +25,20 @@
update_icon()
/obj/effect/decal/cleanable/blood/update_icon()
- color = blood_DNA_to_color()
+ . = ..()
+ if(!fixed_color)
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+
+/obj/effect/decal/cleanable/blood/PersistenceSave(list/data)
+ . = ..()
+ data["color"] = color
+ return /obj/effect/decal/cleanable/blood/old
+
+/obj/effect/decal/cleanable/blood/PersistenceLoad(list/data)
+ . = ..()
+ if(data["color"])
+ fixed_color = TRUE
+ add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
/obj/effect/decal/cleanable/blood/old
name = "dried blood"
@@ -38,6 +52,7 @@
/obj/effect/decal/cleanable/blood/splats
random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
+ persistence_allow_stacking = TRUE
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("splatter1", "splatter2", "splatter3", "splatter4", "splatter5")
@@ -48,16 +63,43 @@
random_icon_states = null
beauty = -50
+/obj/effect/decal/cleanable/blood/tracks/PersistenceSave(list/data)
+ . = ..()
+ data["dir"] = dir
+
+/obj/effect/decal/cleanable/blood/tracks/PersistenceLoad(list/data)
+ . = ..()
+ if(data["dir"])
+ setDir(data["dir"])
+
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
name = "blood"
icon_state = "ltrails_1"
desc = "Your instincts say you shouldn't be following these."
random_icon_states = null
beauty = -50
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
var/list/existing_dirs = list()
+ var/fixed_color = FALSE
+
+/obj/effect/decal/cleanable/trail_holder/PersistenceSave(list/data)
+ . = ..()
+ data["dir"] = dir
+ data["color"] = color
+
+/obj/effect/decal/cleanable/trail_holder/PersistenceLoad(list/data)
+ . = ..()
+ if(data["dir"])
+ setDir(data["dir"])
+ if(data["color"])
+ fixed_color = TRUE
+ add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
/obj/effect/decal/cleanable/trail_holder/update_icon()
- color = blood_DNA_to_color()
+ . = ..()
+ if(!fixed_color)
+ add_atom_colour(blood_DNA_to_color())
/obj/effect/cleanable/trail_holder/Initialize()
. = ..()
@@ -84,8 +126,19 @@
var/entered_dirs = 0
var/exited_dirs = 0
blood_state = BLOOD_STATE_BLOOD //the icon state to load images from
+ persistent = TRUE
+ persistence_allow_stacking = TRUE
var/list/shoe_types = list()
+/obj/effect/decal/cleanable/blood/footprints/PersistenceSave(list/data)
+ . = ..()
+ data["dir"] = dir
+
+/obj/effect/decal/cleanable/blood/footprints/PersistenceLoad(list/data)
+ . = ..()
+ if(data["dir"])
+ setDir(data["dir"])
+
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
if(ishuman(O))
var/mob/living/carbon/human/H = O
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index 2765330977..8f8f27c3c6 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -11,6 +11,7 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
beauty = -50
+ persistent = TRUE
/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
. = ..()
@@ -52,6 +53,7 @@
blood_state = BLOOD_STATE_OIL
bloodiness = BLOOD_AMOUNT_PER_DECAL
beauty = -100
+ persistent = TRUE
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
@@ -61,8 +63,10 @@
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
beauty = -50
+ persistent = TRUE
/obj/effect/decal/cleanable/oil/slippery
+ persistent = FALSE
/obj/effect/decal/cleanable/oil/slippery/Initialize()
AddComponent(/datum/component/slippery, 80, (NO_SLIP_WHEN_WALKING | SLIDE))
From b7cd14b41e5faa101705e8296c1b0050112cecb8 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:09:24 -0800
Subject: [PATCH 12/31] poggy?
---
code/controllers/subsystem/persistence/cleanable_debris.dm | 2 +-
code/game/objects/effects/decals/cleanable/humans.dm | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 772091529a..dccc609ed3 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -86,7 +86,7 @@
LAZYINITLIST(data[text_z])
LAZYINITLIST(data[text_z][text_x])
LAZYINITLIST(data[text_z][text_x][text_y])
- if(storing.persistence_allow_stacking)
+ if(saving.persistence_allow_stacking)
serializing["__PATH__"] = path
data[text_z][text_x][text_y] += serializing
else
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 5d514bc68f..5206279d42 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -9,6 +9,7 @@
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
beauty = -100
persistent = TRUE
+ var/fixed_color = FALSE
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
From 6044086de034a9aeae81be11f53c39a24a773878 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:29:52 -0800
Subject: [PATCH 13/31] changes
---
code/game/area/areas.dm | 2 ++
.../objects/effects/decals/cleanable/misc.dm | 18 ++++++++++++++++
code/game/turfs/open.dm | 7 +++++++
code/game/turfs/simulated/chasm.dm | 1 +
code/game/turfs/simulated/dirtystation.dm | 5 ++++-
code/game/turfs/simulated/floor.dm | 1 +
code/game/turfs/simulated/lava.dm | 1 +
code/game/turfs/simulated/reebe_void.dm | 1 +
code/game/turfs/space/space.dm | 1 +
code/modules/mob/living/living_defines.dm | 2 ++
code/modules/mob/living/living_movement.dm | 21 +++++++++++++++++++
11 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index fcde2bd1eb..ff177898cb 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -26,6 +26,8 @@
var/clockwork_warp_fail = "The structure there is too dense for warping to pierce. (This is normal in high-security areas.)"
/// Persistent debris alowed
var/persistent_debris_allowed = TRUE
+ /// Dirty flooring allowed
+ var/dirt_buildup_allowed = TRUE
/// If mining tunnel generation is allowed in this area
var/tunnel_allowed = FALSE
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 9c0fb2eca9..e3f223f380 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -57,10 +57,28 @@
name = "dirt"
desc = "Someone should clean that up."
icon_state = "dirt"
+ alpha = 127
canSmoothWith = list(/obj/effect/decal/cleanable/dirt, /turf/closed/wall, /obj/structure/falsewall)
smooth = SMOOTH_FALSE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
beauty = -75
+ mergeable_decal = TRUE
+ persistent = TRUE
+
+/obj/effect/decal/cleanable/dirt/proc/dirty(strength)
+ if(alpha < 255)
+ alpha += strength
+ if(alpha > 255)
+ alpha = 255
+
+/obj/effect/decal/cleanable/dirt/PersistenceSave(list/data)
+ . = ..()
+ data["alpha"] = alpha
+
+/obj/effect/decal/cleanable/dirt/PersistenceLoad(list/data)
+ . = ..()
+ if(data["alpha"])
+ alpha = data["alpha"]
/obj/effect/decal/cleanable/dirt/Initialize()
. = ..()
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 493e88d442..15f5738033 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -1,5 +1,12 @@
/turf/open
plane = FLOOR_PLANE
+ /// Does dirt buildup happen on us?
+ var/dirt_buildup_allowed = FALSE
+ /// Dirt level.
+ var/dirtyness = 0
+ /// Dirt level to spawn dirt.
+ var/dirt_spawn_threshold = 100
+ /// Slowdown applied to mobs on us.
var/slowdown = 0 //negative for faster, positive for slower
var/postdig_icon_change = FALSE
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 5e8f55feed..9490d728fe 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -9,6 +9,7 @@
canSmoothWith = list(/turf/open/floor/fakepit, /turf/open/chasm)
density = TRUE //This will prevent hostile mobs from pathing into chasms, while the canpass override will still let it function like an open turf
bullet_bounce_sound = null //abandon all hope ye who enter
+ dirt_buildup_allowed = FALSE
/turf/open/chasm/Initialize()
. = ..()
diff --git a/code/game/turfs/simulated/dirtystation.dm b/code/game/turfs/simulated/dirtystation.dm
index e29d75a248..add8467ceb 100644
--- a/code/game/turfs/simulated/dirtystation.dm
+++ b/code/game/turfs/simulated/dirtystation.dm
@@ -8,6 +8,9 @@
//Making the station dirty, one tile at a time. Called by master controller's setup_objects
/turf/open/floor/proc/MakeDirty()
+ if(CONFIG_GET(flag/persistent_debris_only))
+ return
+
if(prob(66)) //fastest possible exit 2/3 of the time
return
@@ -38,7 +41,7 @@
return
//Construction zones. Blood, sweat, and oil. Oh, and dirt.
- var/static/list/engine_dirt_areas = typecacheof(list(/area/engine,
+ var/static/list/engine_dirt_areas = typecacheof(list(/area/engine,
/area/crew_quarters/heads/chief,
/area/ruin/space/derelict/assembly_line,
/area/science/robotics,
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index ddec9750d9..6a95a4a95d 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -5,6 +5,7 @@
name = "floor"
icon = 'icons/turf/floors.dmi'
baseturfs = /turf/open/floor/plating
+ dirt_buildup_allowed = TRUE
footstep = FOOTSTEP_FLOOR
barefootstep = FOOTSTEP_HARD_BAREFOOT
diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm
index 2f223f2c40..e7471478fb 100644
--- a/code/game/turfs/simulated/lava.dm
+++ b/code/game/turfs/simulated/lava.dm
@@ -6,6 +6,7 @@
gender = PLURAL //"That's some lava."
baseturfs = /turf/open/lava //lava all the way down
slowdown = 2
+ dirt_buildup_allowed = FALSE
light_range = 2
light_power = 0.75
diff --git a/code/game/turfs/simulated/reebe_void.dm b/code/game/turfs/simulated/reebe_void.dm
index 14aa02065d..3f3bf31f9b 100644
--- a/code/game/turfs/simulated/reebe_void.dm
+++ b/code/game/turfs/simulated/reebe_void.dm
@@ -6,6 +6,7 @@
planetary_atmos = TRUE
bullet_bounce_sound = null //forever falling
tiled_dirt = FALSE
+ dirt_buildup_allowed = FALSE
/turf/open/indestructible/reebe_void/Initialize(mapload)
. = ..()
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index b150d4930e..3cdbe8badb 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -3,6 +3,7 @@
icon_state = "0"
name = "\proper space"
intact = 0
+ dirt_buildup_allowed = FALSE
temperature = TCMB
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index d4ccc63b34..79334e1698 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -63,6 +63,8 @@
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
+ /// Do we make floors dirty as we move?
+ var/causes_dirt_buildup_on_floor = TRUE
var/list/roundstart_quirks = list()
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index 0cdfe9dbf2..e7a5de294d 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -101,7 +101,28 @@
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
makeTrail(newloc, T, old_direction)
+ if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
+ dirt_buildup()
+/**
+ * Attempts to make the floor dirty.
+ */
+/mob/living/proc/dirt_buildup(strength)
+ var/turf/T = loc
+ if(!istype(T) || !T.allow_dirt_buildup)
+ return
+ var/area/A = T.loc
+ if(!A.allow_dirt_buildup)
+ return
+ var/obj/effect/decal/cleanable/dirt/D = locate() in T
+ if(D)
+ D.dirty(strength)
+ else
+ T.dirtyness += strength
+ if(T.dirtyness >= T.dirt_spawn_threshold)
+ D = new /obj/effect/decal/cleanable/dirt(T)
+ D.dirty(T.dirt_spawn_threshold - T.dirtyness)
+ T.dirtyness = 0 // reset.
/mob/living/Move_Pulled(atom/A)
. = ..()
From 952d74437864fe1762c65f5f85d2f51f51686b52 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:31:31 -0800
Subject: [PATCH 14/31] done
---
code/modules/mob/living/living_movement.dm | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index e7a5de294d..2a9e2d2634 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -108,11 +108,11 @@
* Attempts to make the floor dirty.
*/
/mob/living/proc/dirt_buildup(strength)
- var/turf/T = loc
- if(!istype(T) || !T.allow_dirt_buildup)
+ var/turf/open/T = loc
+ if(!istype(T) || !T.dirt_buildup_allowed)
return
var/area/A = T.loc
- if(!A.allow_dirt_buildup)
+ if(!A.dirt_buildup_allowed)
return
var/obj/effect/decal/cleanable/dirt/D = locate() in T
if(D)
From 322843523767669b2074fe6e5f9143168c93e43f Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:33:16 -0800
Subject: [PATCH 15/31] errors
---
.../subsystem/persistence/cleanable_debris.dm | 17 ++++++++---------
code/game/objects/effects/decals/crayon.dm | 2 +-
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index dccc609ed3..a08c4c4964 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -39,27 +39,26 @@
for(var/x in L1)
var/list/L2 = data[z][x]
for(var/y in L2)
- var/turf/tile = locate(x, y, z)
+ var/turf/tile = locate(x, y, actual_z)
if(!tile)
continue
var/list/objects = data[z][x][y]
for(var/_L in objects)
- var/list/data
+ var/list/objdata
var/path
if(islist(_L))
- data = _L
- path = data["__PATH__"]
+ objdata = _L
+ path = objdata["__PATH__"]
else
path = _L
- data = objects[_L]
+ objdata = objects[_L]
if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
continue
- var/path = data["__PATH__"]
if(!path)
continue
var/obj/effect/decal/cleanable/instantiated = new path(tile)
- if(data)
- instantiated.PersistenceLoad(data)
+ if(objdata)
+ instantiated.PersistenceLoad(objdata)
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
@@ -82,7 +81,7 @@
continue
var/text_z = num2text(saving.z)
var/text_y = num2text(saving.y)
- var/text_x = num2text(saving.x)
+ var/text_x = num2text(z_lookup[num2text(saving.x)])
LAZYINITLIST(data[text_z])
LAZYINITLIST(data[text_z][text_x])
LAZYINITLIST(data[text_z][text_x][text_y])
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index 6ebd798e40..ad9abe10b1 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -48,7 +48,7 @@
name = data["name"]
if(do_icon_rotate && data["rotation"])
var/matrix/M = matrix()
- M.turn(data["rotation"])
+ M.Turn(data["rotation"])
transform = M
if(data["paint_color"])
paint_colour = data["paint_color"]
From dafc6bf89fe7816474b5a5fe31d42efecfc1b9a6 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:41:21 -0800
Subject: [PATCH 16/31] fix
---
.../configuration/entries/game_options.dm | 13 +++++++++++++
code/game/objects/effects/decals/cleanable/misc.dm | 6 +++++-
code/game/turfs/open.dm | 4 ++--
code/modules/mob/living/living_movement.dm | 4 ++--
config/game_options.txt | 8 +++++++-
5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index 67e4a97894..dcede1e3e0 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -566,3 +566,16 @@
config_entry_value = 0.333
min_val = 0
integer = FALSE
+
+/// Amount of dirtyness tiles need to spawn dirt.
+/datum/config_entry/number/turf_dirt_threshold
+ config_entry_value = 100
+ min_value = 1
+ integer = TRUE
+
+/// Alpha dirt starts at
+/datum/config_entry/number/dirt_alpha_starting
+ config_entry_value = 127
+ max_val = 255
+ min_val = 0
+ integer = TRUE
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index e3f223f380..b4c3a3acec 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -65,7 +65,11 @@
mergeable_decal = TRUE
persistent = TRUE
-/obj/effect/decal/cleanable/dirt/proc/dirty(strength)
+/obj/effect/decal/cleanable/dirt/Initialize(mapload)
+ . = ..()
+ alpha = CONFIG_GET(number/dirt_alpha_starting)
+
+/obj/effect/decal/cleanable/dirt/proc/dirty(strength = 1)
if(alpha < 255)
alpha += strength
if(alpha > 255)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 15f5738033..7e00b1cf63 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -4,8 +4,8 @@
var/dirt_buildup_allowed = FALSE
/// Dirt level.
var/dirtyness = 0
- /// Dirt level to spawn dirt.
- var/dirt_spawn_threshold = 100
+ /// Dirt level to spawn dirt. Null to use config.
+ var/dirt_spawn_threshold
/// Slowdown applied to mobs on us.
var/slowdown = 0 //negative for faster, positive for slower
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index 2a9e2d2634..d4694a76ea 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -107,7 +107,7 @@
/**
* Attempts to make the floor dirty.
*/
-/mob/living/proc/dirt_buildup(strength)
+/mob/living/proc/dirt_buildup(strength =)
var/turf/open/T = loc
if(!istype(T) || !T.dirt_buildup_allowed)
return
@@ -119,7 +119,7 @@
D.dirty(strength)
else
T.dirtyness += strength
- if(T.dirtyness >= T.dirt_spawn_threshold)
+ if(T.dirtyness >= isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold)
D = new /obj/effect/decal/cleanable/dirt(T)
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
T.dirtyness = 0 // reset.
diff --git a/config/game_options.txt b/config/game_options.txt
index bc5fdf940e..3c53d9fecb 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -668,4 +668,10 @@ ALLOW_CUSTOM_SKINTONES
## Enables the FoV component, which hides objects and mobs behind the parent from their sight, unless they turn around, duh.
## Camera mobs, AIs, ghosts and some other are of course exempt from this. This also doesn't influence simplemob AI, for the best.
-#USE_FIELD_OF_VISION
\ No newline at end of file
+#USE_FIELD_OF_VISION
+
+## Default turf threshold to get dirt
+TURF_DIRT_THRESHOLD 100
+
+## Default alpha of dirt on spawn
+DIRT_ALPHA_STARTING 127
From d3414a4d2387597c95bdfb1e6600d502396a9c9c Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:47:50 -0800
Subject: [PATCH 17/31] ok
---
code/game/objects/effects/decals/cleanable.dm | 2 ++
code/game/objects/effects/decals/cleanable/misc.dm | 1 +
code/game/turfs/simulated/floor.dm | 3 +++
code/game/turfs/simulated/floor/plating.dm | 12 ++++++++++++
code/game/turfs/simulated/floor/reinf_floor.dm | 3 +++
5 files changed, 21 insertions(+)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 11d76d3cdf..b447b46754 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -5,6 +5,8 @@
var/persistent = FALSE
/// Can we stack multiple in one tile?
var/persistence_allow_stacking = FALSE
+ /// Are we deleted by turf changes?
+ var/wiped_by_turf_change = FALSE
var/list/random_icon_states = null
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index b4c3a3acec..e2cd40a1af 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -64,6 +64,7 @@
beauty = -75
mergeable_decal = TRUE
persistent = TRUE
+ wiped_by_turf_change = TRUE
/obj/effect/decal/cleanable/dirt/Initialize(mapload)
. = ..()
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index 6a95a4a95d..6a4ddea63b 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -138,6 +138,9 @@
burnt = 1
/turf/open/floor/proc/make_plating()
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
return ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
/turf/open/floor/ChangeTurf(path, new_baseturf, flags)
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 35ee06a584..539fcb63e0 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -61,6 +61,9 @@
to_chat(user, "You begin reinforcing the floor...")
if(do_after(user, 30, target = src))
if (R.get_amount() >= 2 && !istype(src, /turf/open/floor/engine))
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
PlaceOnTop(/turf/open/floor/engine, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
R.use(2)
@@ -78,6 +81,9 @@
to_chat(user, "You begin adding glass to the floor...")
if(do_after(user, 5, target = src))
if (G.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass))
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
PlaceOnTop(/turf/open/transparent/glass, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
G.use(2)
@@ -95,6 +101,9 @@
to_chat(user, "You begin adding reinforced glass to the floor...")
if(do_after(user, 10, target = src))
if (RG.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass/reinforced))
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
PlaceOnTop(/turf/open/transparent/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
RG.use(2)
@@ -110,6 +119,9 @@
var/obj/item/stack/tile/W = C
if(!W.use(1))
return
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
if(istype(W, /obj/item/stack/tile/material))
var/turf/newturf = PlaceOnTop(/turf/open/floor/material, flags = CHANGETURF_INHERIT_AIR)
newturf.set_custom_materials(W.custom_materials)
diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm
index 42b4707b50..f8c6ff1ce2 100644
--- a/code/game/turfs/simulated/floor/reinf_floor.dm
+++ b/code/game/turfs/simulated/floor/reinf_floor.dm
@@ -43,6 +43,9 @@
return TRUE
if(floor_tile)
new floor_tile(src, 2)
+ for(var/obj/effect/decal/cleanable/C in src)
+ if(C.wiped_by_floor_change)
+ qdel(C)
ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
return TRUE
From bfb3d087c3221ab8a217646d08445241fa8392e6 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:50:28 -0800
Subject: [PATCH 18/31] ok
---
.../configuration/entries/game_options.dm | 2 +-
code/game/objects/effects/decals/cleanable.dm | 2 +-
.../objects/effects/decals/cleanable/misc.dm | 2 +-
code/game/turfs/simulated/floor/plating.dm | 24 +++++++++----------
code/modules/mob/living/living_movement.dm | 2 +-
5 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index dcede1e3e0..ffa73d2c32 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -570,7 +570,7 @@
/// Amount of dirtyness tiles need to spawn dirt.
/datum/config_entry/number/turf_dirt_threshold
config_entry_value = 100
- min_value = 1
+ min_val = 1
integer = TRUE
/// Alpha dirt starts at
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index b447b46754..5a6d5e54e9 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -6,7 +6,7 @@
/// Can we stack multiple in one tile?
var/persistence_allow_stacking = FALSE
/// Are we deleted by turf changes?
- var/wiped_by_turf_change = FALSE
+ var/wiped_by_floor_change = FALSE
var/list/random_icon_states = null
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index e2cd40a1af..2bd79edfb4 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -64,7 +64,7 @@
beauty = -75
mergeable_decal = TRUE
persistent = TRUE
- wiped_by_turf_change = TRUE
+ wiped_by_floor_change = TRUE
/obj/effect/decal/cleanable/dirt/Initialize(mapload)
. = ..()
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 539fcb63e0..1b875a5e69 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -61,9 +61,9 @@
to_chat(user, "You begin reinforcing the floor...")
if(do_after(user, 30, target = src))
if (R.get_amount() >= 2 && !istype(src, /turf/open/floor/engine))
- for(var/obj/effect/decal/cleanable/C in src)
- if(C.wiped_by_floor_change)
- qdel(C)
+ for(var/obj/effect/decal/cleanable/decal in src)
+ if(decal.wiped_by_floor_change)
+ qdel(decal)
PlaceOnTop(/turf/open/floor/engine, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
R.use(2)
@@ -81,9 +81,9 @@
to_chat(user, "You begin adding glass to the floor...")
if(do_after(user, 5, target = src))
if (G.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass))
- for(var/obj/effect/decal/cleanable/C in src)
- if(C.wiped_by_floor_change)
- qdel(C)
+ for(var/obj/effect/decal/cleanable/decal in src)
+ if(decal.wiped_by_floor_change)
+ qdel(decal)
PlaceOnTop(/turf/open/transparent/glass, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
G.use(2)
@@ -101,9 +101,9 @@
to_chat(user, "You begin adding reinforced glass to the floor...")
if(do_after(user, 10, target = src))
if (RG.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass/reinforced))
- for(var/obj/effect/decal/cleanable/C in src)
- if(C.wiped_by_floor_change)
- qdel(C)
+ for(var/obj/effect/decal/cleanable/decal in src)
+ if(decal.wiped_by_floor_change)
+ qdel(decal)
PlaceOnTop(/turf/open/transparent/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
RG.use(2)
@@ -119,9 +119,9 @@
var/obj/item/stack/tile/W = C
if(!W.use(1))
return
- for(var/obj/effect/decal/cleanable/C in src)
- if(C.wiped_by_floor_change)
- qdel(C)
+ for(var/obj/effect/decal/cleanable/decal in src)
+ if(decal.wiped_by_floor_change)
+ qdel(decal)
if(istype(W, /obj/item/stack/tile/material))
var/turf/newturf = PlaceOnTop(/turf/open/floor/material, flags = CHANGETURF_INHERIT_AIR)
newturf.set_custom_materials(W.custom_materials)
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index d4694a76ea..1196bc0252 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -107,7 +107,7 @@
/**
* Attempts to make the floor dirty.
*/
-/mob/living/proc/dirt_buildup(strength =)
+/mob/living/proc/dirt_buildup(strength = 1)
var/turf/open/T = loc
if(!istype(T) || !T.dirt_buildup_allowed)
return
From a6ae0fe5c2a241f52f8628546150664c1851d637 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 20:56:48 -0800
Subject: [PATCH 19/31] ok
---
.../configuration/entries/persistence.dm | 3 +++
.../subsystem/persistence/cleanable_debris.dm | 2 ++
code/game/turfs/simulated/floor/plating.dm | 6 +++---
config/config.txt | 1 +
config/persistence.txt | 14 ++++++++++++++
5 files changed, 23 insertions(+), 3 deletions(-)
create mode 100644 config/persistence.txt
diff --git a/code/controllers/configuration/entries/persistence.dm b/code/controllers/configuration/entries/persistence.dm
index cf7b23bef3..2444034b86 100644
--- a/code/controllers/configuration/entries/persistence.dm
+++ b/code/controllers/configuration/entries/persistence.dm
@@ -15,3 +15,6 @@
/datum/config_entry/number/persistent_debris_type_max
config_entry_value = 2000
integer = TRUE
+
+/// Wipe dirty stuff on nuke
+/datum/config_entry/flag/persistent_debris_wipe_on_nuke
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index a08c4c4964..8c9e7ba5c0 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -63,6 +63,8 @@
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
fdel("[get_map_persistence_path()]/debris.json")
+ if(CONFIG_GET(flag/persistent_debris_wipe_on_nuke) && SSticker?.mode?.station_was_nuked)
+ return // local janitor cheers on nukeop team to save some work
var/list/data = list()
var/list/z_lookup = SSmapping.z_to_station_z_index
var/list/debris = RelevantPersistentDebris()
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index 1b875a5e69..ad3cf86864 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -101,9 +101,9 @@
to_chat(user, "You begin adding reinforced glass to the floor...")
if(do_after(user, 10, target = src))
if (RG.get_amount() >= 2 && !istype(src, /turf/open/transparent/glass/reinforced))
- for(var/obj/effect/decal/cleanable/decal in src)
- if(decal.wiped_by_floor_change)
- qdel(decal)
+ for(var/obj/effect/decal/cleanable/decal in src)
+ if(decal.wiped_by_floor_change)
+ qdel(decal)
PlaceOnTop(/turf/open/transparent/glass/reinforced, flags = CHANGETURF_INHERIT_AIR)
playsound(src, 'sound/items/deconstruct.ogg', 80, 1)
RG.use(2)
diff --git a/config/config.txt b/config/config.txt
index 72df74beb1..c7bb36af0e 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -11,6 +11,7 @@ $include dynamic_config.txt
$include plushies/defines.txt
$include job_threats.txt
$include policy.txt
+$include persistence.txt
$include respawns.txt
# You can use the @ character at the beginning of a config option to lock it from being edited in-game
diff --git a/config/persistence.txt b/config/persistence.txt
new file mode 100644
index 0000000000..7d65a150e2
--- /dev/null
+++ b/config/persistence.txt
@@ -0,0 +1,14 @@
+### Whether or not cleanable object persistence is on
+PERSISTENT_DEBRIS
+
+### Whether or not ONLY persistent cleanable objects should be spawned, for supported objects
+PERSISTENT_DEBRIS_ONLY
+
+### Max objects to store, total
+PERSISTENT_DEBRIS_GLOBAL_MAX 10000
+
+### Max objects to store per type, total
+PERSISTENT_DEBRIS_TYPE_MAX 2000
+
+### Wipe objects on nuke for the above
+PERSISTENT_DEBRIS_WIPE_ON_NUKE
From 46b58fa5ba7193ded5f14f7f3dfc2c43254c8680 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 21:10:12 -0800
Subject: [PATCH 20/31] file ops
---
.../subsystem/persistence/_persistence.dm | 2 +-
.../subsystem/persistence/cleanable_debris.dm | 20 +++++++++++--------
code/modules/mapping/map_config.dm | 9 +++++----
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
index 00135bbcc2..4086fe6408 100644
--- a/code/controllers/subsystem/persistence/_persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(persistence)
*/
/datum/controller/subsystem/persistence/proc/get_map_persistence_path()
ASSERT(SSmapping.config)
- if(SSmapping.config.persistence_key == "NO_PERSIST")
+ if(!SSmapping.config.persistence_key || (SSmapping.config.persistence_key == "NO_PERSIST"))
return null
return "data/persistence/[ckey(SSmapping.config.persistence_key)]"
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 8c9e7ba5c0..430bc871dd 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -16,13 +16,13 @@
SaveMapDebris()
/datum/controller/subsystem/persistence/proc/LoadMapDebris()
+ if(CONFIG_GET(flag/persistent_debris_only))
+ wipe_existing_debris()
if(!fexists("[get_map_persistence_path()]/debris.json"))
return
if(loaded_debris)
return
loaded_debris = TRUE
- if(CONFIG_GET(flag/persistent_debris_only))
- wipe_existing_debris()
var/list/allowed_turf_typecache = typecacheof(/turf/open) - typecacheof(/turf/open/space)
var/list/allowed_z_cache = list()
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
@@ -104,12 +104,16 @@
message_admins(w)
subsystem_log(w)
- subsystem_log({"
- Debris saving completed:
- Total: [global_max]
- By type: [english_list(stored_by_type)]
- "})
- WRITE_FILE("[get_map_persistence_path()]/debris.json", json_encode(data))
+ var/list/bytype = list()
+ for(var/path in stored_by_type)
+ bytype += "[path] - [stored_by_type[path]]"
+ subsystem_log(
+ {"Debris saving completed:
+ Total: [stored]
+ By type:
+ [bytype.Join("\n")]"}
+ )
+ WRITE_FILE(file("[get_map_persistence_path()]/debris.json"), json_encode(data))
/datum/controller/subsystem/persistence/proc/IsValidDebrisLocation(turf/tile, list/allowed_typecache, list/allowed_zcache, obj/effect/decal/cleanable/type, loading = FALSE)
if(!allowed_typecache[tile.type])
diff --git a/code/modules/mapping/map_config.dm b/code/modules/mapping/map_config.dm
index 83418462f1..1f4b558e21 100644
--- a/code/modules/mapping/map_config.dm
+++ b/code/modules/mapping/map_config.dm
@@ -105,10 +105,11 @@
persistence_key = ckey(map_name)
var/json_persistence_key = json["persistence_key"]
- if(json_persistence_key == "NO_PERSIST")
- persistence_key = null
- else
- persistence_key = json_persistence_key
+ if(json_persistence_key)
+ if(json_persistence_key == "NO_PERSIST")
+ persistence_key = null
+ else
+ persistence_key = json_persistence_key
// "map_file": "BoxStation.dmm"
if (istext(map_file))
From 753c1389cc3060299619f35384dcf287029e5058 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 22:04:05 -0800
Subject: [PATCH 21/31] fix
---
.../configuration/entries/game_options.dm | 4 ++++
.../subsystem/persistence/cleanable_debris.dm | 20 +++++++++++++------
.../mob/living/carbon/human/human_defines.dm | 1 +
.../mob/living/carbon/human/human_movement.dm | 5 +++++
code/modules/mob/living/living_defines.dm | 2 +-
code/modules/mob/living/living_movement.dm | 4 +++-
6 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index ffa73d2c32..dc8e9e1859 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -579,3 +579,7 @@
max_val = 255
min_val = 0
integer = TRUE
+
+/// Dirtyness multiplier for making turfs dirty
+/datum/config_entry/number/turf_dirty_multiplier
+ config_entry_value = 1
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 430bc871dd..9f55177cbb 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -34,13 +34,19 @@
var/sz = SSmapping.z_to_station_z_index[z]
z_lookup[num2text(sz)] = z
for(var/z in data)
+ to_chat(world, "DEBUG: looking at z [z]")
var/actual_z = z_lookup[z]
+ to_chat(world, "DEBUG: actual z [actual_z]")
var/list/L1 = data[z]
for(var/x in L1)
+ to_chat(world, "DEBUG: looking at x [x]")
var/list/L2 = data[z][x]
for(var/y in L2)
+ to_chat(world, "DEBUG: looking at y [y]")
var/turf/tile = locate(x, y, actual_z)
+ to_chat(world, "DEBUG: finding turf [x] [y] [z]: [tile]")
if(!tile)
+ to_chat(world, "DEBUG: aborting due to no turf")
continue
var/list/objects = data[z][x][y]
for(var/_L in objects)
@@ -48,13 +54,15 @@
var/path
if(islist(_L))
objdata = _L
- path = objdata["__PATH__"]
+ path = text2path(objdata["__PATH__"])
else
- path = _L
+ path = text2path(_L)
objdata = objects[_L]
- if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
- continue
if(!path)
+ to_chat(world, "DEBUG: Aborting: No path")
+ continue
+ if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
+ to_chat(world, "DEBUG: Aborting: Invalid location")
continue
var/obj/effect/decal/cleanable/instantiated = new path(tile)
if(objdata)
@@ -81,9 +89,9 @@
continue
if(stored_by_type[path] > type_max)
continue
- var/text_z = num2text(saving.z)
+ var/text_z = num2text(z_lookup[num2text(saving.z)])
var/text_y = num2text(saving.y)
- var/text_x = num2text(z_lookup[num2text(saving.x)])
+ var/text_x = num2text(saving.x)
LAZYINITLIST(data[text_z])
LAZYINITLIST(data[text_z][text_x])
LAZYINITLIST(data[text_z][text_x][text_y])
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 2e8641b43e..07d45f966a 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -15,6 +15,7 @@
block_parry_data = /datum/block_parry_data/unarmed/human
default_block_parry_data = /datum/block_parry_data/unarmed/pugilist
+ causes_dirt_buildup_on_floor = TRUE
//Hair colour and style
var/hair_color = "000"
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 509633c0d5..440400f889 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -100,3 +100,8 @@
if(dna.species.space_move(src))
return TRUE
return ..()
+
+/mob/living/carbon/human/dirt_buildup(strength)
+ if(!shoes || !(shoes.body_parts_covered & FEET))
+ return // barefoot advantage
+ return ..()
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 79334e1698..742d4d8624 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -64,7 +64,7 @@
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
/// Do we make floors dirty as we move?
- var/causes_dirt_buildup_on_floor = TRUE
+ var/causes_dirt_buildup_on_floor = FALSE
var/list/roundstart_quirks = list()
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index 1196bc0252..9e093d391e 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -114,12 +114,14 @@
var/area/A = T.loc
if(!A.dirt_buildup_allowed)
return
+ var/multiplier = CONFIG_GET(number/turf_dirty_multiplier)
+ strength *= multiplier
var/obj/effect/decal/cleanable/dirt/D = locate() in T
if(D)
D.dirty(strength)
else
T.dirtyness += strength
- if(T.dirtyness >= isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold)
+ if(T.dirtyness >= (isnull(T.dirt_spawn_threshold)? CONFIG_GET(number/turf_dirt_threshold) : T.dirt_spawn_threshold))
D = new /obj/effect/decal/cleanable/dirt(T)
D.dirty(T.dirt_spawn_threshold - T.dirtyness)
T.dirtyness = 0 // reset.
From 57065d995e49963adb807e0ff49cc5c466bdfa97 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 22:20:04 -0800
Subject: [PATCH 22/31] fix
---
code/controllers/subsystem/mapping.dm | 8 ++++++--
.../subsystem/persistence/cleanable_debris.dm | 15 +++++----------
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm
index 1893e9ccd9..90908bbde0 100644
--- a/code/controllers/subsystem/mapping.dm
+++ b/code/controllers/subsystem/mapping.dm
@@ -264,8 +264,12 @@ SUBSYSTEM_DEF(mapping)
/datum/controller/subsystem/mapping/proc/setup_station_z_index()
z_to_station_z_index = list()
var/sz = 1
- for(var/i in station_start to (station_start + islist(config.map_file)? (length(config.map_file) - 1) : 0))
- z_to_station_z_index["[i]"] = sz++
+ var/cz = station_start
+ if(islist(config.map_file))
+ for(var/map in config.map_file)
+ z_to_station_z_index["[cz++]"] = sz++
+ else
+ z_to_station_z_index["[station_start]"] = 1
/datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 9f55177cbb..e2da6114a6 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -32,21 +32,16 @@
/// reverse it
for(var/z in SSmapping.z_to_station_z_index)
var/sz = SSmapping.z_to_station_z_index[z]
- z_lookup[num2text(sz)] = z
+ z_lookup[num2text(sz)] = text2num(z)
for(var/z in data)
- to_chat(world, "DEBUG: looking at z [z]")
var/actual_z = z_lookup[z]
- to_chat(world, "DEBUG: actual z [actual_z]")
var/list/L1 = data[z]
for(var/x in L1)
- to_chat(world, "DEBUG: looking at x [x]")
var/list/L2 = data[z][x]
for(var/y in L2)
- to_chat(world, "DEBUG: looking at y [y]")
- var/turf/tile = locate(x, y, actual_z)
- to_chat(world, "DEBUG: finding turf [x] [y] [z]: [tile]")
+ var/turf/tile = locate(text2num(x), text2num(y), actual_z)
if(!tile)
- to_chat(world, "DEBUG: aborting due to no turf")
+ to_chat(world, "DEBUG: aborting due to no turf ([x] [y] [actual_z])")
continue
var/list/objects = data[z][x][y]
for(var/_L in objects)
@@ -59,10 +54,10 @@
path = text2path(_L)
objdata = objects[_L]
if(!path)
- to_chat(world, "DEBUG: Aborting: No path")
+ to_chat(world, "DEBUG: Aborting: No path ([x] [y] [actual_z])")
continue
if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
- to_chat(world, "DEBUG: Aborting: Invalid location")
+ to_chat(world, "DEBUG: Aborting: Invalid location ([x] [y] [actual_z])")
continue
var/obj/effect/decal/cleanable/instantiated = new path(tile)
if(objdata)
From 5266ae1437e062384189321b70f247f7f686ea9a Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 22:28:41 -0800
Subject: [PATCH 23/31] okay
---
code/controllers/subsystem/persistence/cleanable_debris.dm | 3 ---
code/game/objects/effects/decals/cleanable/humans.dm | 6 +++---
code/game/objects/effects/decals/cleanable/misc.dm | 2 +-
code/game/objects/effects/decals/crayon.dm | 2 +-
code/game/objects/effects/decals/remains.dm | 1 +
5 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index e2da6114a6..63e7c7a2e8 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -41,7 +41,6 @@
for(var/y in L2)
var/turf/tile = locate(text2num(x), text2num(y), actual_z)
if(!tile)
- to_chat(world, "DEBUG: aborting due to no turf ([x] [y] [actual_z])")
continue
var/list/objects = data[z][x][y]
for(var/_L in objects)
@@ -54,10 +53,8 @@
path = text2path(_L)
objdata = objects[_L]
if(!path)
- to_chat(world, "DEBUG: Aborting: No path ([x] [y] [actual_z])")
continue
if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
- to_chat(world, "DEBUG: Aborting: Invalid location ([x] [y] [actual_z])")
continue
var/obj/effect/decal/cleanable/instantiated = new path(tile)
if(objdata)
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 5206279d42..bec00aa944 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -71,7 +71,7 @@
/obj/effect/decal/cleanable/blood/tracks/PersistenceLoad(list/data)
. = ..()
if(data["dir"])
- setDir(data["dir"])
+ setDir(text2num(data["dir"]))
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
name = "blood"
@@ -92,7 +92,7 @@
/obj/effect/decal/cleanable/trail_holder/PersistenceLoad(list/data)
. = ..()
if(data["dir"])
- setDir(data["dir"])
+ setDir(text2num(data["dir"]))
if(data["color"])
fixed_color = TRUE
add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
@@ -138,7 +138,7 @@
/obj/effect/decal/cleanable/blood/footprints/PersistenceLoad(list/data)
. = ..()
if(data["dir"])
- setDir(data["dir"])
+ setDir(text2num(data["dir"]))
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
if(ishuman(O))
diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm
index 2bd79edfb4..0f7d7c185d 100644
--- a/code/game/objects/effects/decals/cleanable/misc.dm
+++ b/code/game/objects/effects/decals/cleanable/misc.dm
@@ -83,7 +83,7 @@
/obj/effect/decal/cleanable/dirt/PersistenceLoad(list/data)
. = ..()
if(data["alpha"])
- alpha = data["alpha"]
+ alpha = text2num(data["alpha"])
/obj/effect/decal/cleanable/dirt/Initialize()
. = ..()
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index ad9abe10b1..a0590b7180 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -48,7 +48,7 @@
name = data["name"]
if(do_icon_rotate && data["rotation"])
var/matrix/M = matrix()
- M.Turn(data["rotation"])
+ M.Turn(text2num(data["rotation"]))
transform = M
if(data["paint_color"])
paint_colour = data["paint_color"]
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index 87337a526c..34019ba897 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -2,6 +2,7 @@
name = "remains"
gender = PLURAL
icon = 'icons/effects/blood.dmi'
+ persistent = TRUE
/obj/effect/decal/remains/acid_act()
visible_message("[src] dissolve[gender==PLURAL?"":"s"] into a puddle of sizzling goop!")
From a42fa987ba38b427be7f2ec4d68f7145d058f49a Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sat, 26 Dec 2020 22:43:25 -0800
Subject: [PATCH 24/31] ok
---
code/game/objects/effects/decals/remains.dm | 1 -
1 file changed, 1 deletion(-)
diff --git a/code/game/objects/effects/decals/remains.dm b/code/game/objects/effects/decals/remains.dm
index 34019ba897..87337a526c 100644
--- a/code/game/objects/effects/decals/remains.dm
+++ b/code/game/objects/effects/decals/remains.dm
@@ -2,7 +2,6 @@
name = "remains"
gender = PLURAL
icon = 'icons/effects/blood.dmi'
- persistent = TRUE
/obj/effect/decal/remains/acid_act()
visible_message("[src] dissolve[gender==PLURAL?"":"s"] into a puddle of sizzling goop!")
From 57d85f7e86cd2d8ed056bb1ffaf55ddef9f69dc0 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Sun, 27 Dec 2020 05:20:29 -0800
Subject: [PATCH 25/31] okay
---
.../subsystem/persistence/cleanable_debris.dm | 25 ++++++++++++++++++-
.../effects/decals/cleanable/humans.dm | 4 ++-
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 63e7c7a2e8..80d10027a0 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -29,6 +29,11 @@
allowed_z_cache[num2text(z)] = TRUE
var/list/data = json_decode(file2text("[get_map_persistence_path()]/debris.json"))
var/list/z_lookup = list()
+ var/loaded = 0
+ var/list/loaded_by_type = list()
+ var/nopath = 0
+ var/badloc = 0
+ var/noturf = 0
/// reverse it
for(var/z in SSmapping.z_to_station_z_index)
var/sz = SSmapping.z_to_station_z_index[z]
@@ -41,6 +46,7 @@
for(var/y in L2)
var/turf/tile = locate(text2num(x), text2num(y), actual_z)
if(!tile)
+ noturf++
continue
var/list/objects = data[z][x][y]
for(var/_L in objects)
@@ -53,12 +59,29 @@
path = text2path(_L)
objdata = objects[_L]
if(!path)
+ nopath++
continue
if(!IsValidDebrisLocation(tile, allowed_turf_typecache, allowed_z_cache, path, TRUE))
+ badloc++
continue
var/obj/effect/decal/cleanable/instantiated = new path(tile)
+ loaded_by_type[path] += 1
+ loaded++
if(objdata)
instantiated.PersistenceLoad(objdata)
+ var/list/bytype = list()
+ for(var/path in loaded_by_type)
+ bytype += "[path] - [loaded_by_type[path]]"
+ subsystem_log(
+ {"Debris loading completed:
+ Errors:
+ No path: [nopath]
+ Invalid location: [badloc]
+ No turf on map: [noturf]
+ Total loaded: [loaded]
+ By type:
+ [bytype.Join("\n")]"}
+ )
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
@@ -89,7 +112,7 @@
LAZYINITLIST(data[text_z][text_x][text_y])
if(saving.persistence_allow_stacking)
serializing["__PATH__"] = path
- data[text_z][text_x][text_y] += serializing
+ data[text_z][text_x][text_y] += list(serializing)
else
data[text_z][text_x][text_y][path] = serializing
stored++
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index bec00aa944..68b13389b9 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -33,13 +33,15 @@
/obj/effect/decal/cleanable/blood/PersistenceSave(list/data)
. = ..()
data["color"] = color
- return /obj/effect/decal/cleanable/blood/old
/obj/effect/decal/cleanable/blood/PersistenceLoad(list/data)
. = ..()
if(data["color"])
fixed_color = TRUE
add_atom_colour(data["color"], FIXED_COLOUR_PRIORITY)
+ name = "dried blood"
+ desc = "Looks like it's been here a while. Eew"
+ bloodiness = 0
/obj/effect/decal/cleanable/blood/old
name = "dried blood"
From 51d1e3a87f44d49c36c705deef1e05628a634348 Mon Sep 17 00:00:00 2001
From: DeltaFire
Date: Mon, 28 Dec 2020 19:41:39 +0100
Subject: [PATCH 26/31] intendation
sigh
---
code/modules/mob/living/carbon/human/human_defines.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index d130b053e2..a82151cc1d 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -14,7 +14,7 @@
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
block_parry_data = /datum/block_parry_data/unarmed/human
- default_block_parry_data = /datum/block_parry_data/unarmed/human
+ default_block_parry_data = /datum/block_parry_data/unarmed/human
causes_dirt_buildup_on_floor = TRUE
//Hair colour and style
From 0c87c3b0e0931e4106ae6bfd0c151749eb711727 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Mon, 28 Dec 2020 12:15:55 -0800
Subject: [PATCH 27/31] fiX
---
code/__HELPERS/roundend.dm | 7 +++++--
.../subsystem/persistence/_persistence.dm | 19 +++++++++++++------
.../subsystem/persistence/cleanable_debris.dm | 2 +-
.../ratvar_the_clockwork_justicar.dm | 1 +
code/modules/power/singularity/narsie.dm | 1 +
5 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index e4a2e6521a..a860a8cd3f 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -238,8 +238,11 @@
CHECK_TICK
SSdbcore.SetRoundEnd()
//Collects persistence features
- if(mode.allow_persistence_save)
- SSpersistence.CollectData()
+ if(mode.station_was_nuked)
+ SSpersistence.station_was_destroyed = TRUE
+ if(!mode.allow_persistence_save)
+ SSpersistence.station_persistence_save_disabled = TRUE
+ SSpersistence.CollectData()
//stop collecting feedback during grifftime
SSblackbox.Seal()
diff --git a/code/controllers/subsystem/persistence/_persistence.dm b/code/controllers/subsystem/persistence/_persistence.dm
index 4086fe6408..741d1dd72a 100644
--- a/code/controllers/subsystem/persistence/_persistence.dm
+++ b/code/controllers/subsystem/persistence/_persistence.dm
@@ -6,6 +6,11 @@ SUBSYSTEM_DEF(persistence)
init_order = INIT_ORDER_PERSISTENCE
flags = SS_NO_FIRE
+ /// Marks if the station got horribly destroyed
+ var/station_was_destroyed = FALSE
+ /// Marks if persistence save should be disabled
+ var/station_persistence_save_disabled = FALSE
+
var/list/obj/structure/chisel_message/chisel_messages = list()
var/list/saved_messages = list()
var/list/spawned_objects = list()
@@ -37,45 +42,47 @@ SUBSYSTEM_DEF(persistence)
/datum/controller/subsystem/persistence/proc/CollectData()
SaveServerPersistence()
+ if(station_persistence_save_disabled)
+ return
SaveGamePersistence()
var/map_persistence_path = get_map_persistence_path()
if(map_persistence_path)
SaveMapPersistence()
/**
- * Loads persistent data relevant to the server: Configurations, past gamemodes, votes, etc
+ * Loads persistent data relevant to the server: Configurations, past gamemodes, votes, antag rep, etc
*/
/datum/controller/subsystem/persistence/proc/LoadServerPersistence()
for(var/client/C in GLOB.clients)
LoadSavedVote(C.ckey)
if(CONFIG_GET(flag/use_antag_rep))
LoadAntagReputation()
+ LoadRandomizedRecipes()
/**
- * Saves persistent data relevant to the server: Configurations, past gamemodes, votes, etc
+ * Saves persistent data relevant to the server: Configurations, past gamemodes, votes, antag rep, etc
*/
/datum/controller/subsystem/persistence/proc/SaveServerPersistence()
if(CONFIG_GET(flag/use_antag_rep))
CollectAntagReputation()
+ SaveRandomizedRecipes()
/**
- * Loads persistent data relevant to the game in general: Trophies, antag reputation, etc
+ * Loads persistent data relevant to the game in general: Photos, etc
*
* Legacy map persistence systems also use this.
*/
/datum/controller/subsystem/persistence/proc/LoadGamePersistence()
LoadChiselMessages()
LoadPhotoPersistence()
- LoadRandomizedRecipes()
LoadPaintings()
/**
- * Saves persistent data relevant to the game in general: Trophies, antag reputation, etc
+ * Saves persistent data relevant to the game in general: Photos, etc
*
* Legacy map persistence systems also use this.
*/
/datum/controller/subsystem/persistence/proc/SaveGamePersistence()
- SaveRandomizedRecipes()
CollectChiselMessages()
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
SavePaintings()
diff --git a/code/controllers/subsystem/persistence/cleanable_debris.dm b/code/controllers/subsystem/persistence/cleanable_debris.dm
index 80d10027a0..a0817c460b 100644
--- a/code/controllers/subsystem/persistence/cleanable_debris.dm
+++ b/code/controllers/subsystem/persistence/cleanable_debris.dm
@@ -86,7 +86,7 @@
/datum/controller/subsystem/persistence/proc/SaveMapDebris()
if(fexists("[get_map_persistence_path()]/debris.json"))
fdel("[get_map_persistence_path()]/debris.json")
- if(CONFIG_GET(flag/persistent_debris_wipe_on_nuke) && SSticker?.mode?.station_was_nuked)
+ if(CONFIG_GET(flag/persistent_debris_wipe_on_nuke) && station_was_destroyed)
return // local janitor cheers on nukeop team to save some work
var/list/data = list()
var/list/z_lookup = SSmapping.z_to_station_z_index
diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
index 73ae89a19b..28901ea0b2 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -30,6 +30,7 @@
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [get_area_name(src)] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 10, null, FALSE, 0)
+ SSpersistence.station_was_destroyed = TRUE
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
GLOB.ratvar_awakens--
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 8bf20fddc6..5b5292a020 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -78,6 +78,7 @@
set_security_level("delta")
SSshuttle.registerHostileEnvironment(src)
SSshuttle.lockdown = TRUE
+ SSpersistence.station_was_destroyed = TRUE
sleep(600)
if(resolved == FALSE)
resolved = TRUE
From e6000ceffa07dcfc9ab12c3416ad0b0400599458 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Tue, 29 Dec 2020 11:12:06 -0800
Subject: [PATCH 28/31] meme
---
code/game/objects/effects/decals/cleanable/humans.dm | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 68b13389b9..cbf9c571e3 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -12,10 +12,14 @@
var/fixed_color = FALSE
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
+ if(C.fixed_color)
+ qdel(C)
+ return FALSE
if (C.blood_DNA)
blood_DNA |= C.blood_DNA
+ qdel(C)
update_icon()
- ..()
+ return FALSE
/obj/effect/decal/cleanable/blood/transfer_blood_dna()
..()
@@ -199,7 +203,7 @@
return
if(color != C.color)
return
- ..()
+ return ..()
/obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
From 34256a61efd05826820deecffe36c77593086f3a Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Wed, 30 Dec 2020 21:06:34 -0800
Subject: [PATCH 29/31] remove drips
---
code/game/objects/effects/decals/cleanable/gibs.dm | 2 --
1 file changed, 2 deletions(-)
diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm
index 1f9897071c..4b63cbecc8 100644
--- a/code/game/objects/effects/decals/cleanable/gibs.dm
+++ b/code/game/objects/effects/decals/cleanable/gibs.dm
@@ -97,8 +97,6 @@
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
- persistent = TRUE
- persistence_allow_stacking = TRUE
var/drips = 1
/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
From 78322199e3bcdc7dcae24c3ee463342fe4490258 Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Fri, 1 Jan 2021 00:38:46 -0800
Subject: [PATCH 30/31] fix
---
code/game/objects/effects/decals/crayon.dm | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index a0590b7180..387b8c167d 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -41,6 +41,10 @@
if(do_icon_rotate)
data["rotation"] = rotation
data["name"] = name
+ if(pixel_x != initial(pixel_x))
+ data["pixel_x"] = pixel_x
+ if(pixel_y != initial(pixel_y))
+ data["pixel_y"] = pixel_y
/obj/effect/decal/cleanable/crayon/PersistenceLoad(list/data)
. = ..()
@@ -55,3 +59,7 @@
add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY)
if(data["icon_state"])
icon_state = data["icon_state"]
+ if(data["pixel_x"])
+ pixel_x = data["pixel_x"]
+ if(data["pixel_y"])
+ pixel_y = data["pixel_y"]
From 407b1fe071548dad8dc7546782c5529ba5b91dbb Mon Sep 17 00:00:00 2001
From: silicons <2003111+silicons@users.noreply.github.com>
Date: Thu, 7 Jan 2021 23:14:59 -0700
Subject: [PATCH 31/31] Update humans.dm
---
code/game/objects/effects/decals/cleanable/humans.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index cbf9c571e3..6d051b6c8c 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -106,7 +106,7 @@
/obj/effect/decal/cleanable/trail_holder/update_icon()
. = ..()
if(!fixed_color)
- add_atom_colour(blood_DNA_to_color())
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
/obj/effect/cleanable/trail_holder/Initialize()
. = ..()