Files
vgstation13/code/controllers/subsystem/init/persistence_misc.dm
ShiftyRail d79c1fe070 Byond 516 v2.0 (#37553)
* The TGS thing

* Revert the 516 revert

* Further segment the world/New() proc

* Fixes an issue here
2025-05-12 00:50:25 -05:00

403 lines
13 KiB
Plaintext

var/datum/subsystem/persistence_misc/SSpersistence_misc
/datum/subsystem/persistence_misc
name = "Persistence - Misc"
init_order = SS_INIT_PERSISTENCE_MISC
flags = SS_NO_FIRE
var/list/tasks = list()
/datum/subsystem/persistence_misc/New()
NEW_SS_GLOBAL(SSpersistence_misc)
/datum/subsystem/persistence_misc/Recover()
tasks = SSpersistence_misc.tasks
..()
/datum/subsystem/persistence_misc/Initialize(timeofday)
for (var/task_type in subtypesof(/datum/persistence_task))
var/datum/persistence_task/task = task_type
if (!initial(task.execute)) // Deprecated or wip persistence task
continue
task = new task_type()
task.on_init()
tasks["[task.type]"] = task
..()
/datum/subsystem/persistence_misc/Shutdown()
for (var/task_type in tasks)
var/datum/persistence_task/task = tasks[task_type]
task.on_shutdown()
..()
/datum/subsystem/persistence_misc/proc/read_data(var/path)
var/datum/persistence_task/task_to_read = tasks["[path]"]
if (!task_to_read)
return null
return task_to_read.data
// *** PERISTENCE TASKS ***
// -- Abstract
/datum/persistence_task/
var/execute = FALSE // -- Do we execute this task or not ?
var/name = "Abstract persistence task"
var/file_path = "" // -- Where do we read/write our peristance data ?
var/list/data = list() // -- The data we save to file.
// -- Proc to be called when the game starts.
/datum/persistence_task/proc/on_init()
// -- Proc to be called when the game shutdowns.
/datum/persistence_task/proc/on_shutdown()
// -- FILE WRITING/DELETION HELPERS --
/* Get the data in the persistance file. */
/datum/persistence_task/proc/read_file()
if(fexists(file_path))
return json_decode(file2text(file_path))
/* Write some data into our file. */
/datum/persistence_task/proc/write_file(var/to_write)
var/writing = file(file_path)
fdel(writing)
writing << json_encode(to_write)
// -- Round count
/datum/persistence_task/round_count
execute = TRUE
name = "Round count"
file_path = "data/persistence/round_counts_per_year.json"
// We just get the data from the file.
/datum/persistence_task/round_count/on_init()
data = read_file()
// We bump the round round and write it to file.
/datum/persistence_task/round_count/on_shutdown()
var/itsthecurrentyear = time2text(world.realtime,"YY")
if(!(itsthecurrentyear in data))
data[itsthecurrentyear] = "0"
data[itsthecurrentyear] = num2text(text2num(data[itsthecurrentyear]) + 1)
write_file(data)
// -- Vox raiders
/datum/persistence_task/vox_raiders
execute = TRUE
name = "Vox raiders best team"
file_path = "data/persistence/vox_raiders_best_team.json"
/datum/persistence_task/vox_raiders/on_init()
data = read_file()
/datum/persistence_task/vox_raiders/on_shutdown()
var/datum/gamemode/dynamic/dynamic_mode = ticker.mode
if (!istype(dynamic_mode))
return // No dynamic mode = no raiders
if (!locate(/datum/dynamic_ruleset/midround/from_ghosts/faction_based/heist) in dynamic_mode.executed_rules)
return
var/datum/faction/vox_shoal/raiders_of_the_day = find_active_faction_by_type(/datum/faction/vox_shoal)
var/score = text2num(data["best_score"])
if (score > raiders_of_the_day.total_points)
return // They didn't beat the best
else
data["best_score"] = num2text(raiders_of_the_day.total_points)
data["winning_team"] = raiders_of_the_day.generate_string()
data["DD"] = time2text(world.realtime,"DD")
data["MM"] = time2text(world.realtime,"MM")
data["YY"] = time2text(world.realtime,"YY")
write_file(data)
/datum/persistence_task/forwards_fulfilled
execute = TRUE
name = "Cargo forwards fulfilled"
file_path = "data/persistence/fulfilled_cargo_forwards.json"
/datum/persistence_task/forwards_fulfilled/on_init()
data = read_file()
if ("fulfilled_forwards" in data)
var/list/previous_forwards_formatted = data["fulfilled_forwards"]
for(var/list/formatted_vars in previous_forwards_formatted)
var/ourtype = null
if(formatted_vars["type"])
ourtype = text2path(formatted_vars["type"])
var/ourname = null
if(formatted_vars["sender"])
ourname = formatted_vars["sender"]
var/ourstation = null
if(formatted_vars["station"])
ourstation = formatted_vars["station"]
var/oursubtype = null
if(formatted_vars["subtype"])
oursubtype = text2path(formatted_vars["subtype"])
if(ispath(ourtype,/datum/cargo_forwarding))
SSsupply_shuttle.previous_forwards += new ourtype(ourname, ourstation, oursubtype, TRUE)
/datum/persistence_task/forwards_fulfilled/on_shutdown()
var/list/all_forwards = SSsupply_shuttle.previous_forwards.Copy() + SSsupply_shuttle.fulfilled_forwards.Copy()
var/list/all_forwards_formatted = list()
for(var/datum/cargo_forwarding/forward in all_forwards)
all_forwards_formatted += list(list("type" = forward.type, "sender" = forward.origin_sender_name, "station" = forward.origin_station_name, "subtype" = forward.initialised_type))
write_file(list("fulfilled_forwards" = all_forwards_formatted))
/datum/persistence_task/round_end_data
execute = TRUE
name = "Round end information"
file_path = "data/persistence/round_end_info.json"
/datum/persistence_task/round_end_data/on_init()
var/to_read = read_file()
if(!to_read)
log_debug("[name] task found an empty file on [file_path]")
return
last_round_end_info = to_read["round_info"]
for (var/client/C in clients)
winset(C, "rpane.round_end", "is-visible=false")
winset(C, "rpane.last_round_end", "is-visible=true")
/datum/persistence_task/round_end_data/on_shutdown()
if (round_end_info)
data["round_info"] = round_end_info
write_file(data)
/datum/persistence_task/latest_dynamic_rulesets
execute = TRUE
name = "Latest dynamic rulesets"
file_path = "data/persistence/latest_dynamic_rulesets.json"
/datum/persistence_task/latest_dynamic_rulesets/on_init()
data = read_file()
/datum/persistence_task/latest_dynamic_rulesets/on_shutdown()
var/datum/gamemode/dynamic/dynamic_mode = ticker.mode
if (!istype(dynamic_mode))
stack_trace("we shut down the persistence - Misc subsystem and ticker.mode is not Dynamic.")
return
data = list(
"one_round_ago" = list(),
"two_rounds_ago" = dynamic_mode.previously_executed_rules["one_round_ago"],
"three_rounds_ago" = dynamic_mode.previously_executed_rules["two_rounds_ago"]
)
for(var/datum/dynamic_ruleset/some_ruleset in dynamic_mode.executed_rules)
if(some_ruleset.calledBy)//forced by an admin
continue
if(some_ruleset.stillborn)//executed near the end of the round
continue
data["one_round_ago"] |= "[some_ruleset.type]"
write_file(data)
/datum/persistence_task/dynamic_ruleset_weights
execute = TRUE
name = "Dynamic ruleset weights"
file_path = "data/persistence/dynamic_ruleset_weights.json"
/datum/persistence_task/dynamic_ruleset_weights/on_init()
data = read_file()
/datum/persistence_task/dynamic_ruleset_weights/on_shutdown()
var/datum/gamemode/dynamic/dynamic_mode = ticker.mode
if (!istype(dynamic_mode))
stack_trace("we shut down the persistence - Misc subsystem and ticker.mode is not Dynamic.")
return
data = list()
for (var/category in dynamic_mode.ruleset_category_weights)
data[category] = dynamic_mode.ruleset_category_weights[category]
if (dynamic_mode.executed_rules.len <= 0)
data["Extended"] = 0
else
for (var/datum/dynamic_ruleset/DR in dynamic_mode.executed_rules)
data[DR.weight_category] = 0
write_file(data)
// This task has a unit test on code/modules/unit_tests/highscores.dm
/datum/persistence_task/highscores
execute = TRUE
name = "Money highscores"
file_path = "data/persistence/money_highscores.json"
/datum/persistence_task/highscores/on_init()
var/to_read = read_file()
if(!to_read)
log_debug("[name] task found an empty file on [file_path]")
return
for(var/list/L in to_read)
var/datum/data/record/money/record = new(L["ckey"], L["role"], L["cash"], L["shift_duration"], L["date"])
data += record
/datum/persistence_task/highscores/on_shutdown()
var/list/L = list()
for(var/datum/data/record/money/record in data)
L += list(record.vars)
write_file(L)
/datum/persistence_task/highscores/proc/insert_records(list/records)
data += records
global.cmp_field = "cash"
sortTim(data, /proc/cmp_records_numerically)
if (data.len > 5)
data.Cut(6) // we only store the top 5
for(var/datum/data/record/money/record in data)
if(record in records)
if(data[1] == record)
announce_new_highest_record(record)
else
announce_new_record(record)
/datum/persistence_task/highscores/proc/announce_new_highest_record(var/datum/data/record/money/record)
var/name = "Richest escape ever"
var/desc = "You broke the record of the richest escape! $[record.fields["cash"]] chips accumulated."
give_award(record.fields["ckey"], /obj/item/weapon/reagent_containers/food/drinks/golden_cup, name, desc)
/datum/persistence_task/highscores/proc/announce_new_record(var/datum/data/record/money/record)
var/name = "Good rich escape"
var/desc = "You made it to the top 5! You accumulated $[record.fields["cash"]]."
give_award(record.fields["ckey"], /obj/item/clothing/accessory/medal/gold, name, desc, FALSE)
/datum/persistence_task/highscores/proc/clear_records()
data = list()
fdel(file(file_path))
/datum/persistence_task/highscores/trader
execute = TRUE
name = "Trader shoal highscores"
file_path = "data/persistence/trader_highscores.json"
/datum/persistence_task/highscores/trader/announce_new_highest_record(var/datum/data/record/money/record)
var/name = "Richest shoal haul ever"
var/desc = "You broke the record of the richest shoal haul! $[record.fields["cash"]] chips accumulated."
give_award(record.fields["ckey"], /obj/item/weapon/reagent_containers/food/drinks/golden_cup, name, desc)
/datum/persistence_task/highscores/trader/announce_new_record(var/datum/data/record/money/record)
var/name = "Good rich shoal haul"
var/desc = "You made it to the top 5! You accumulated $[record.fields["cash"]]."
give_award(record.fields["ckey"], /obj/item/clothing/accessory/medal/gold, name, desc, FALSE)
//stores map votes for code/modules/html_interface/voting/voting.dm
/datum/persistence_task/vote
execute = TRUE
name = "Persistent votes"
file_path = "data/persistence/votes.json"
/datum/persistence_task/vote/on_init()
var/list/to_read = read_file()
if(!to_read)
log_debug("[name] task found an empty file on [file_path]")
return
for(var/i = 1; i <= to_read.len; i++)
data[to_read[i]] = to_read[to_read[i]]
/datum/persistence_task/vote/on_shutdown()
write_file(data)
/datum/persistence_task/vote/proc/insert_counts(var/list/tally)
sortTim(tally, /proc/cmp_numeric_dsc,1)
//reset the winner
data[tally[1]] = 0
for(var/i = 2; i <= tally.len; i++)
data[tally[i]] = tally[tally[i]]
/datum/persistence_task/vote/proc/clear_counts()
data = list()
fdel(file(file_path))
//Ape-related
/datum/persistence_task/ape_mode
execute = TRUE
name = "Ape mode"
file_path = "data/persistence/ape_mode.json"
/datum/persistence_task/ape_mode/on_init()
data = read_file()
if(length(data))
ape_mode = data["ape_mode"]
/datum/persistence_task/ape_mode/on_shutdown()
write_file(list("ape_mode" = ape_mode))
//Lotto
/datum/persistence_task/lotto_jackpot
execute = TRUE
name = "Lotto jackpot"
file_path = "data/persistence/lotto_jackpot.json"
/datum/persistence_task/lotto_jackpot/on_init()
data = read_file()
if(length(data))
station_jackpot = max(1000000,min(200000000, data["station_jackpot"])) //1 - 200 mil
/datum/persistence_task/lotto_jackpot/on_shutdown()
write_file(list("station_jackpot" = max(1000000,station_jackpot)))
// Hub Settings
/datum/persistence_task/hub_settings
execute = TRUE
name = "Hub Settings"
file_path = "data/persistence/hub_settings.json"
/datum/persistence_task/hub_settings/on_init()
data = read_file()
if(length(data))
byond_server_name = data["server_name"]
byond_server_desc = data["server_desc"]
byond_hub_playercount = data["hub_playercount"]
byond_hub_open = data["byond_hub_open"]
/datum/persistence_task/hub_settings/on_shutdown()
var/list/L = list(
"server_name" = byond_server_name,
"server_desc" = byond_server_desc,
"hub_playercount" = byond_hub_playercount,
"byond_hub_open" = byond_hub_open,
)
data = L
write_file(data)
//Research Archive
/datum/persistence_task/researcharchive
execute = TRUE
name = "Research Archive"
file_path = "data/persistence/researcharchive.json"
/datum/persistence_task/researcharchive/on_init()
if(!research_archive_datum)
research_archive_datum = new /datum/research()
var/list/techs = read_file()
//world.log << "DEBUG ARCHIVE: [json_encode(techs)]"
var/skip_reporting = TRUE
for(var/obj/machinery/computer/rdconsole/C in machines)
for(var/element in techs)
var/datum/tech/T = C.files.known_tech[element]
if(!T)
continue
T.level = text2num(techs[element])
if(skip_reporting && (T.level>1))
skip_reporting = FALSE //If any level was increased, we want to report
if(!skip_reporting)
for(var/obj/machinery/computer/rdconsole/S in machines)
var/obj/item/weapon/paper/P = new (S.loc)
P.info = "Your station has benefitted from the research archive project."
P.update_icon()
/datum/persistence_task/researcharchive/on_shutdown()
var/list/to_archive = list()
for(var/datum/tech/T in get_list_of_elements(research_archive_datum.known_tech))
if(T.id in list("syndicate", "Nanotrasen", "anomaly"))
continue
to_archive[T.id] = T.level
write_file(to_archive)