diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index be771e0676..e82976d4a3 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -29,6 +29,7 @@ GLOBAL_LIST_EMPTY(zombie_infection_list) // A list of all zombie_infection org GLOBAL_LIST_EMPTY(meteor_list) // List of all meteors. GLOBAL_LIST_EMPTY(active_jammers) // List of active radio jammers GLOBAL_LIST_EMPTY(ladders) +GLOBAL_LIST_EMPTY(trophy_cases) GLOBAL_LIST_EMPTY(wire_color_directory) GLOBAL_LIST_EMPTY(wire_name_directory) \ No newline at end of file diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index e1cf992e8b..6b3e47054c 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -11,10 +11,14 @@ SUBSYSTEM_DEF(persistence) var/list/saved_messages = list() var/savefile/chisel_messages_sav + var/savefile/trophy_sav + var/list/saved_trophies = list() + /datum/controller/subsystem/persistence/Initialize() LoadSatchels() LoadPoly() LoadChiselMessages() + LoadTrophies() ..() /datum/controller/subsystem/persistence/proc/LoadSatchels() @@ -105,10 +109,49 @@ SUBSYSTEM_DEF(persistence) M.persists = FALSE qdel(M) +/datum/controller/subsystem/persistence/proc/LoadTrophies() + trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav") + var/saved_json + trophy_sav >> saved_json + + var/decoded_json = json_decode(saved_json) + + if(!islist(decoded_json)) + return + + saved_trophies = decoded_json + + 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 + 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() /datum/controller/subsystem/persistence/proc/CollectSecretSatchels() for(var/A in new_secret_satchels) @@ -135,4 +178,16 @@ SUBSYSTEM_DEF(persistence) chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages) /datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M) - saved_messages += list(M.pack()) // dm eats one list. + saved_messages += list(M.pack()) // dm eats one list + + +/datum/controller/subsystem/persistence/proc/CollectTrophies() + trophy_sav << json_encode(saved_trophies) + +/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) \ No newline at end of file diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index be1b49074d..3817a16685 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -16,27 +16,25 @@ var/obj/item/weapon/electronics/airlock/electronics var/start_showpiece_type = null //add type for items on display -/obj/structure/displaycase/New() - ..() +/obj/structure/displaycase/Initialize() + . = ..() if(start_showpiece_type) showpiece = new start_showpiece_type (src) update_icon() /obj/structure/displaycase/Destroy() if(electronics) - qdel(electronics) - electronics = null + QDEL_NULL(electronics) if(showpiece) - qdel(showpiece) - showpiece = null + QDEL_NULL(showpiece) return ..() /obj/structure/displaycase/examine(mob/user) ..() - if(showpiece) - to_chat(user, "There's [showpiece] inside.") if(alert) to_chat(user, "Hooked up with an anti-theft system.") + if(showpiece) + to_chat(user, "There's [showpiece] inside.") /obj/structure/displaycase/proc/dump() @@ -176,8 +174,8 @@ /obj/structure/displaycase/attack_hand(mob/user) user.changeNext_move(CLICK_CD_MELEE) if (showpiece && (broken || open)) - dump() to_chat(user, "You deactivate the hover field built into the case.") + dump() src.add_fingerprint(user) update_icon() return @@ -249,3 +247,96 @@ desc = "A glass lab container for storing interesting creatures." start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr req_access = list(GLOB.access_rd) + + + +/obj/structure/displaycase/trophy + name = "trophy display case" + desc = "Store your trophies of accomplishment in here, and they will stay forever." + var/trophy_message = "" + var/placer_key = "" + var/added_roundstart = TRUE + alert = TRUE + integrity_failure = 0 + +/obj/structure/displaycase/trophy/Initialize() + . = ..() + GLOB.trophy_cases += src + +/obj/structure/displaycase/trophy/Destroy() + GLOB.trophy_cases -= src + return ..() + +/obj/structure/displaycase/trophy/examine(mob/user) + ..() + if(trophy_message) + to_chat(user, "The plaque reads:") + to_chat(user, trophy_message) + +/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params) + + if(!user.Adjacent(src)) //no TK museology + return + + if(!added_roundstart) + to_chat(user, "You've already put something new in this case.") + return + + if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types)) + to_chat(user, "The case rejects the [W].") + return + + for(var/a in W.GetAllContents()) + if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types)) + to_chat(user, "The case rejects the [W].") + return + + if(user.drop_item()) + + if(showpiece) + to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.") + QDEL_NULL(showpiece) + + to_chat(user, "You insert [W] into the case.") + W.forceMove(src) + showpiece = W + added_roundstart = FALSE + update_icon() + + placer_key = user.ckey + + trophy_message = W.desc //default value + + var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque") + if(chosen_plaque) + if(user.Adjacent(src)) + trophy_message = chosen_plaque + to_chat(user, "You set the plaque's text.") + else + to_chat(user, "You are too far to set the plaque's text.") + + SSpersistence.SaveTrophy(src) + + else + to_chat(user, "\The [W] is stuck to your hand, you can't put it in the [src.name]!") + + return + +/obj/structure/displaycase/trophy/dump() + if (showpiece) + if(added_roundstart) + visible_message("The [showpiece] crumbles to dust!") + new /obj/effect/decal/cleanable/ash(loc) + QDEL_NULL(showpiece) + else + ..() + +/obj/item/showpiece_dummy + name = "Cheap replica" + +/obj/item/showpiece_dummy/Initialize(mapload, path) + . = ..() + var/obj/item/I = path + name = initial(I.name) + icon = initial(I.icon) + icon_state = initial(I.icon_state)