mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-16 03:56:20 +00:00
Done using this command sed -Ei 's/(\s*\S+)\s*\t+/\1 /g' code/**/*.dm We have countless examples in the codebase with this style gone wrong, and defines and such being on hideously different levels of indentation. Fixing this to keep the alignment involves tainting the blames of code your PR doesn't need to be touching at all. And ultimately, it's hideous. There are some files that this sed makes uglier. I can fix these when they are pointed out, but I believe this is ultimately for the greater good of readability. I'm more concerned with if any strings relied on this. Hi codeowners! Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
412 lines
13 KiB
Plaintext
412 lines
13 KiB
Plaintext
#define FILE_ANTAG_REP "data/AntagReputation.json"
|
|
#define FILE_RECENT_MAPS "data/RecentMaps.json"
|
|
|
|
#define KEEP_ROUNDS_MAP 3
|
|
|
|
SUBSYSTEM_DEF(persistence)
|
|
name = "Persistence"
|
|
init_order = INIT_ORDER_PERSISTENCE
|
|
flags = SS_NO_FIRE
|
|
|
|
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_maps = list()
|
|
var/list/blocked_maps = list()
|
|
var/list/saved_trophies = list()
|
|
var/list/antag_rep = list()
|
|
var/list/antag_rep_change = list()
|
|
var/list/picture_logging_information = list()
|
|
var/list/obj/structure/sign/picture_frame/photo_frames
|
|
var/list/obj/item/storage/photo_album/photo_albums
|
|
var/list/obj/structure/sign/painting/painting_frames = list()
|
|
var/list/paintings = list()
|
|
|
|
/datum/controller/subsystem/persistence/Initialize()
|
|
LoadPoly()
|
|
LoadChiselMessages()
|
|
LoadTrophies()
|
|
LoadRecentModes()
|
|
LoadRecentMaps()
|
|
LoadPhotoPersistence()
|
|
if(CONFIG_GET(flag/use_antag_rep))
|
|
LoadAntagReputation()
|
|
LoadRandomizedRecipes()
|
|
LoadPaintings()
|
|
return ..()
|
|
|
|
/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?!
|
|
|
|
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
|
|
var/list/saved_messages = list()
|
|
if(fexists("data/npc_saves/ChiselMessages.sav")) //legacy compatability to convert old format to new
|
|
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
|
var/saved_json
|
|
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
|
|
if(!saved_json)
|
|
return
|
|
saved_messages = json_decode(saved_json)
|
|
fdel("data/npc_saves/ChiselMessages.sav")
|
|
else
|
|
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
|
|
if(!fexists(json_file))
|
|
return
|
|
var/list/json = json_decode(file2text(json_file))
|
|
|
|
if(!json)
|
|
return
|
|
saved_messages = json["data"]
|
|
|
|
for(var/item in saved_messages)
|
|
if(!islist(item))
|
|
continue
|
|
|
|
var/xvar = item["x"]
|
|
var/yvar = item["y"]
|
|
var/zvar = item["z"]
|
|
|
|
if(!xvar || !yvar || !zvar)
|
|
continue
|
|
|
|
var/turf/T = locate(xvar, yvar, zvar)
|
|
if(!isturf(T))
|
|
continue
|
|
|
|
if(locate(/obj/structure/chisel_message) in T)
|
|
continue
|
|
|
|
var/obj/structure/chisel_message/M = new(T)
|
|
|
|
if(!QDELETED(M))
|
|
M.unpack(item)
|
|
|
|
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/LoadRecentMaps()
|
|
var/map_sav = FILE_RECENT_MAPS
|
|
if(!fexists(FILE_RECENT_MAPS))
|
|
return
|
|
var/list/json = json_decode(file2text(map_sav))
|
|
if(!json)
|
|
return
|
|
saved_maps = json["data"]
|
|
|
|
//Convert the mapping data to a shared blocking list, saves us doing this in several places later.
|
|
for(var/map in config.maplist)
|
|
var/datum/map_config/VM = config.maplist[map]
|
|
var/run = 0
|
|
if(VM.map_name == SSmapping.config.map_name)
|
|
run++
|
|
for(var/name in SSpersistence.saved_maps)
|
|
if(VM.map_name == name)
|
|
run++
|
|
if(run >= 2) //If run twice in the last KEEP_ROUNDS_MAP + 1 (including current) rounds, disable map for voting and rotation.
|
|
blocked_maps += VM.map_name
|
|
|
|
/datum/controller/subsystem/persistence/proc/LoadAntagReputation()
|
|
var/json = file2text(FILE_ANTAG_REP)
|
|
if(!json)
|
|
var/json_file = file(FILE_ANTAG_REP)
|
|
if(!fexists(json_file))
|
|
WARNING("Failed to load antag reputation. File likely corrupt.")
|
|
return
|
|
return
|
|
antag_rep = json_decode(json)
|
|
|
|
/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(!length(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()
|
|
CollectTrophies()
|
|
CollectRoundtype()
|
|
CollectMaps()
|
|
SavePhotoPersistence() //THIS IS PERSISTENCE, NOT THE LOGGING PORTION.
|
|
if(CONFIG_GET(flag/use_antag_rep))
|
|
CollectAntagReputation()
|
|
SaveRandomizedRecipes()
|
|
SavePaintings()
|
|
SaveScars()
|
|
|
|
/datum/controller/subsystem/persistence/proc/GetPhotoAlbums()
|
|
var/album_path = file("data/photo_albums.json")
|
|
if(fexists(album_path))
|
|
return json_decode(file2text(album_path))
|
|
|
|
/datum/controller/subsystem/persistence/proc/GetPhotoFrames()
|
|
var/frame_path = file("data/photo_frames.json")
|
|
if(fexists(frame_path))
|
|
return json_decode(file2text(frame_path))
|
|
|
|
/datum/controller/subsystem/persistence/proc/LoadPhotoPersistence()
|
|
var/album_path = file("data/photo_albums.json")
|
|
var/frame_path = file("data/photo_frames.json")
|
|
if(fexists(album_path))
|
|
var/list/json = json_decode(file2text(album_path))
|
|
if(json.len)
|
|
for(var/i in photo_albums)
|
|
var/obj/item/storage/photo_album/A = i
|
|
if(!A.persistence_id)
|
|
continue
|
|
if(json[A.persistence_id])
|
|
A.populate_from_id_list(json[A.persistence_id])
|
|
|
|
if(fexists(frame_path))
|
|
var/list/json = json_decode(file2text(frame_path))
|
|
if(json.len)
|
|
for(var/i in photo_frames)
|
|
var/obj/structure/sign/picture_frame/PF = i
|
|
if(!PF.persistence_id)
|
|
continue
|
|
if(json[PF.persistence_id])
|
|
PF.load_from_id(json[PF.persistence_id])
|
|
|
|
/datum/controller/subsystem/persistence/proc/SavePhotoPersistence()
|
|
var/album_path = file("data/photo_albums.json")
|
|
var/frame_path = file("data/photo_frames.json")
|
|
|
|
var/list/frame_json = list()
|
|
var/list/album_json = list()
|
|
|
|
if(fexists(album_path))
|
|
album_json = json_decode(file2text(album_path))
|
|
fdel(album_path)
|
|
|
|
for(var/i in photo_albums)
|
|
var/obj/item/storage/photo_album/A = i
|
|
if(!istype(A) || !A.persistence_id)
|
|
continue
|
|
var/list/L = A.get_picture_id_list()
|
|
album_json[A.persistence_id] = L
|
|
|
|
album_json = json_encode(album_json)
|
|
|
|
WRITE_FILE(album_path, album_json)
|
|
|
|
if(fexists(frame_path))
|
|
frame_json = json_decode(file2text(frame_path))
|
|
fdel(frame_path)
|
|
|
|
for(var/i in photo_frames)
|
|
var/obj/structure/sign/picture_frame/F = i
|
|
if(!istype(F) || !F.persistence_id)
|
|
continue
|
|
frame_json[F.persistence_id] = F.get_photo_id()
|
|
|
|
frame_json = json_encode(frame_json)
|
|
|
|
WRITE_FILE(frame_path, frame_json)
|
|
|
|
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
|
|
var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json")
|
|
|
|
for(var/obj/structure/chisel_message/M in chisel_messages)
|
|
saved_messages += list(M.pack())
|
|
|
|
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
|
var/list/file_data = list()
|
|
file_data["data"] = saved_messages
|
|
fdel(json_file)
|
|
WRITE_FILE(json_file, json_encode(file_data))
|
|
|
|
/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/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)
|
|
|
|
/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/CollectMaps()
|
|
if(length(saved_maps) > KEEP_ROUNDS_MAP) //Get rid of extras from old configs.
|
|
saved_maps.Cut(KEEP_ROUNDS_MAP+1)
|
|
var/mapstosave = min(length(saved_maps)+1, KEEP_ROUNDS_MAP)
|
|
if(length(saved_maps) < mapstosave) //Add extras if too short, one per round.
|
|
saved_maps += mapstosave
|
|
for(var/i = mapstosave; i > 1; i--)
|
|
saved_maps[i] = saved_maps[i-1]
|
|
saved_maps[1] = SSmapping.config.map_name
|
|
var/json_file = file(FILE_RECENT_MAPS)
|
|
var/list/file_data = list()
|
|
file_data["data"] = 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)
|
|
|
|
for(var/p_ckey in antag_rep_change)
|
|
// var/start = antag_rep[p_ckey]
|
|
antag_rep[p_ckey] = max(0, min(antag_rep[p_ckey]+antag_rep_change[p_ckey], ANTAG_REP_MAXIMUM))
|
|
|
|
// WARNING("AR_DEBUG: [p_ckey]: Committed [antag_rep_change[p_ckey]] reputation, going from [start] to [antag_rep[p_ckey]]")
|
|
|
|
antag_rep_change = list()
|
|
|
|
fdel(FILE_ANTAG_REP)
|
|
text2file(json_encode(antag_rep), FILE_ANTAG_REP)
|
|
|
|
|
|
/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes()
|
|
var/json_file = file("data/RandomizedChemRecipes.json")
|
|
var/json
|
|
if(fexists(json_file))
|
|
json = json_decode(file2text(json_file))
|
|
|
|
for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
|
|
var/datum/chemical_reaction/randomized/R = new randomized_type
|
|
var/loaded = FALSE
|
|
if(R.persistent && json)
|
|
var/list/recipe_data = json["[R.type]"]
|
|
if(recipe_data)
|
|
if(R.LoadOldRecipe(recipe_data) && (daysSince(R.created) <= R.persistence_period))
|
|
loaded = TRUE
|
|
if(!loaded) //We do not have information for whatever reason, just generate new one
|
|
if(R.persistent)
|
|
log_game("Resetting persistent [randomized_type] random recipe.")
|
|
R.GenerateRecipe()
|
|
|
|
if(!R.HasConflicts()) //Might want to try again if conflicts happened in the future.
|
|
add_chemical_reaction(R)
|
|
else
|
|
log_game("Randomized recipe [randomized_type] resulted in conflicting recipes.")
|
|
|
|
/datum/controller/subsystem/persistence/proc/SaveRandomizedRecipes()
|
|
var/json_file = file("data/RandomizedChemRecipes.json")
|
|
var/list/file_data = list()
|
|
|
|
//asert globchems done
|
|
for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized))
|
|
var/datum/chemical_reaction/randomized/R = get_chemical_reaction(randomized_type) //ew, would be nice to add some simple tracking
|
|
if(R?.persistent)
|
|
var/recipe_data = list()
|
|
recipe_data["timestamp"] = R.created
|
|
recipe_data["required_reagents"] = R.required_reagents
|
|
recipe_data["required_catalysts"] = R.required_catalysts
|
|
recipe_data["required_temp"] = R.required_temp
|
|
recipe_data["is_cold_recipe"] = R.is_cold_recipe
|
|
recipe_data["results"] = R.results
|
|
recipe_data["required_container"] = "[R.required_container]"
|
|
file_data["[R.type]"] = recipe_data
|
|
|
|
fdel(json_file)
|
|
WRITE_FILE(json_file, json_encode(file_data))
|
|
|
|
/datum/controller/subsystem/persistence/proc/LoadPaintings()
|
|
var/json_file = file("data/paintings.json")
|
|
if(fexists(json_file))
|
|
paintings = json_decode(file2text(json_file))
|
|
|
|
for(var/obj/structure/sign/painting/P in painting_frames)
|
|
P.load_persistent()
|
|
|
|
/datum/controller/subsystem/persistence/proc/SavePaintings()
|
|
for(var/obj/structure/sign/painting/P in painting_frames)
|
|
P.save_persistent()
|
|
|
|
var/json_file = file("data/paintings.json")
|
|
fdel(json_file)
|
|
WRITE_FILE(json_file, json_encode(paintings))
|
|
|
|
/datum/controller/subsystem/persistence/proc/SaveScars()
|
|
for(var/i in GLOB.joined_player_list)
|
|
var/mob/living/carbon/human/ending_human = get_mob_by_ckey(i)
|
|
if(!istype(ending_human) || !ending_human.mind?.original_character_slot_index || !ending_human.client || !ending_human.client.prefs || !ending_human.client.prefs.persistent_scars)
|
|
continue
|
|
|
|
var/mob/living/carbon/human/original_human = ending_human.mind.original_character
|
|
|
|
if(!original_human)
|
|
continue
|
|
|
|
if(original_human.stat == DEAD || !original_human.all_scars || original_human != ending_human)
|
|
original_human.save_persistent_scars(TRUE)
|
|
else
|
|
original_human.save_persistent_scars()
|