From 435637e2574b79149fb021eb6a9ee86df877d68a Mon Sep 17 00:00:00 2001 From: Charlie Nolan Date: Wed, 30 Jul 2025 23:01:26 -0700 Subject: [PATCH] All Secondary Goals use labels (#29776) * All Secondary Goals use labels * Fixes. * Fixes. * Update code/__DEFINES/dcs/basetype_signals.dm Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Charlie Nolan --------- Signed-off-by: Charlie Nolan Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> --- code/__DEFINES/dcs/basetype_signals.dm | 2 + code/datums/components/label.dm | 51 ++++++++++++------- code/datums/components/shelved.dm | 13 ++++- .../structures/crates_lockers/crates.dm | 10 +++- code/modules/paperwork/handlabeler.dm | 7 ++- code/modules/shuttle/on_move.dm | 1 + code/modules/shuttle/supply.dm | 17 ++++--- .../secondary/botany/kudzu_goal.dm | 4 +- .../secondary/kitchen/random_bulk_food.dm | 4 +- .../secondary/kitchen/variety_food.dm | 4 +- .../secondary/random_bulk_reagent.dm | 4 +- .../secondary/science/random_ripley.dm | 2 +- .../station_goals/secondary/secondary_goal.dm | 10 ++-- .../secondary/secondary_goal_tracker.dm | 26 ++++++---- .../secondary/supply/random_smithed_item.dm | 4 +- .../secondary/variety_reagent.dm | 4 +- code/modules/virology/virology_goals.dm | 2 + 17 files changed, 107 insertions(+), 58 deletions(-) diff --git a/code/__DEFINES/dcs/basetype_signals.dm b/code/__DEFINES/dcs/basetype_signals.dm index a3f64d41aa3..40635be19ee 100644 --- a/code/__DEFINES/dcs/basetype_signals.dm +++ b/code/__DEFINES/dcs/basetype_signals.dm @@ -31,3 +31,5 @@ #define COMSIG_TURF_ON_SHUTTLE_MOVE "turf_on_shuttle_move" ///from base of turf/proc/get_decals(): (list/datum/element/decal/decals) #define COMSIG_ATOM_GET_DECALS "atom_get_decals" +/// from base of atom/movable/onShuttleMove(): (turf/new_turf) +#define COMSIG_MOVABLE_ON_SHUTTLE_MOVE "movable_on_shuttle_move" diff --git a/code/datums/components/label.dm b/code/datums/components/label.dm index ebe62b668a4..ef48a70759a 100644 --- a/code/datums/components/label.dm +++ b/code/datums/components/label.dm @@ -33,7 +33,7 @@ This proc will fire after the parent is hit by a hand labeler which is trying to apply another label. Since the parent already has a label, it will remove the old one from the parent's name, and apply the new one. */ -/datum/component/label/InheritComponent(datum/component/label/new_comp , i_am_original, _label_name) +/datum/component/label/InheritComponent(datum/component/label/new_comp, i_am_original, _label_name) remove_label() if(new_comp) label_name = new_comp.label_name @@ -79,25 +79,38 @@ /// A verson of the label component specific to labelling goal items. /datum/component/label/goal + var/owner = "Anyone" + var/person + var/department -/datum/component/label/goal/Initialize(_label_name) - if(istype(parent, /obj/item)) - // Can only be attached to things that won't go in a crate. - return COMPONENT_INCOMPATIBLE - return ..() +/datum/component/label/goal/Initialize(who, where, from_cc=FALSE) + person = who + department = where + update_owner_and_label_name(from_cc) + return ..(label_name) + +/datum/component/label/goal/proc/update_owner_and_label_name(from_cc) + if(person) + owner = person + if(department) + owner += " in [department]" + + if(from_cc) + label_name = owner + else + label_name = "Secondary Goal" + +/** + This proc will fire after the parent is hit by a hand labeler which is trying to apply another goal label. + Since the parent already has a goal label, it will remove the old one from the parent's name, and apply the new one. +*/ +/datum/component/label/goal/InheritComponent(datum/component/label/new_comp, i_am_original, who, where, from_cc=FALSE) + remove_label() + person = who + department = where + update_owner_and_label_name(from_cc) + apply_label() /// Adds detailed information to the examine text. /datum/component/label/goal/on_examine(datum/source, mob/user, list/examine_list) - examine_list += "It has a label on it, marking it as part of a secondary goal for [label_name]. Use a hand labeler to remove it." - -/// Applies a static label to the parent's name. -/// We do this instead of using label_name so it's easier to identify goal objects at a glance. -/datum/component/label/goal/apply_label() - var/atom/owner = parent - owner.name += " (Secondary Goal)" - -/// Removes the label from the parent's name -/datum/component/label/goal/remove_label() - var/atom/owner = parent - owner.name = replacetext(owner.name, "(Secondary Goal)", "") // Remove the label text from the parent's name, wherever it's located. - owner.name = trim(owner.name) // Shave off any white space from the beginning or end of the parent's name. + examine_list += "It has a label on it, marking it as part of a secondary goal for [owner]. Use a hand labeler to remove it." diff --git a/code/datums/components/shelved.dm b/code/datums/components/shelved.dm index af0a7a46729..dec7252efe9 100644 --- a/code/datums/components/shelved.dm +++ b/code/datums/components/shelved.dm @@ -226,6 +226,8 @@ var/original_layer /// A copy of the shelved object's original appearance flags, to restore after removing from the shelf. var/original_appearance_flags + /// Are we currently being moved by a shuttle? Prevents us from falling off the shelf in transport. + var/shuttle_moving = FALSE /datum/component/shelved/Initialize(atom/shelf) if(!isobj(parent)) @@ -241,6 +243,7 @@ . = ..() RegisterSignal(parent, COMSIG_ITEM_PICKUP, PROC_REF(on_item_pickup)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_movable_moved)) + RegisterSignal(parent, COMSIG_MOVABLE_ON_SHUTTLE_MOVE, PROC_REF(on_movable_shuttle_moved)) var/obj/shelf = locateUID(shelf_uid) if(shelf) RegisterSignal(shelf, COMSIG_MOVABLE_SHOVE_IMPACT, PROC_REF(on_movable_shove_impact)) @@ -255,10 +258,18 @@ SIGNAL_HANDLER // COMSIG_ITEM_PICKUP qdel(src) +/datum/component/shelved/proc/on_movable_shuttle_moved() + SIGNAL_HANDLER // COMSIG_MOVABLE_ON_SHUTTLE_MOVE, + shuttle_moving = TRUE + /// Generic handler for if anything moves us off our original shelf position, such as atmos pressure. /datum/component/shelved/proc/on_movable_moved() SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED - qdel(src) + if(shuttle_moving) + // Ignore this movement, since we should be moving with the shelf. + shuttle_moving = FALSE + else + qdel(src) /datum/component/shelved/UnregisterFromParent() . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index f0437dd6544..9a5c04b001e 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -281,13 +281,20 @@ /obj/structure/closet/crate/secure/personal name = "personal crate" - desc = "The crate version of Nanotrasen's famous personal locker, ideal for shipping booze, food, or drugs to CC without letting Cargo consume it. This one has not been configured by CC, and the first card swiped gains control." + desc = "The crate version of Nanotrasen's famous personal locker, ideal for shipping booze, food, or drugs to CC without letting Cargo consume it." req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) /// The name of the person this crate is registered to. var/registered_name = null // Unlike most secure crates, personal crates are easily obtained. crate_value = DEFAULT_CRATE_VALUE +/obj/structure/closet/crate/secure/personal/examine(mob/user) + . = ..() + if(registered_name) + . += "Owned by [registered_name]." + else + . += "This crate has no owner, and can be claimed by swiping your ID card." + /obj/structure/closet/crate/secure/personal/allowed(mob/user) if(..()) return TRUE @@ -322,7 +329,6 @@ if(!registered_name) registered_name = id.registered_name - desc = "Owned by [id.registered_name]." to_chat(user, "Crate reserved") return TRUE diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 81ea787089e..01ab09886f2 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -20,6 +20,9 @@ . += "The label is currently set to \"[label]\"." /obj/item/hand_labeler/interact_with_atom(atom/target, mob/living/user, list/modifiers) + if(iseffect(target)) + to_chat(user, "\The [target] doesn't seem solid enough to label!") + return ITEM_INTERACT_COMPLETE if(!mode == LABEL_MODE_OFF) apply_label(target, user) return ITEM_INTERACT_COMPLETE @@ -44,8 +47,8 @@ return if(mode == LABEL_MODE_GOAL) - if(istype(target, /obj/item)) - to_chat(user, "Put it in a personal crate instead!") + if(isturf(target)) + to_chat(user, "You can't just claim a bit of [target] as yours!") return user.visible_message("[user] labels [target] as part of a secondary goal for [label].", \ "You label [target] as part of a secondary goal for [label].") diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index e593f635e30..999ae6a8cf1 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -1,5 +1,6 @@ // Shuttle on-movement // /atom/movable/proc/onShuttleMove(turf/oldT, turf/T1, rotation, mob/calling_mob) + SEND_SIGNAL(src, COMSIG_MOVABLE_ON_SHUTTLE_MOVE, T1) var/turf/newT = get_turf(src) if(newT.z != oldT.z) on_changed_z_level(oldT, newT) diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index fbc3124e8ef..680aaec4acd 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -139,12 +139,9 @@ break var/obj/structure/closet/crate/secure/personal/PC = new(T) - if(SG.requester_name) - PC.name = "goal crate ([SG.requester_name] in [SG.department])" - PC.desc = "This personal crate has been configured by CC for [SG.requester_name]'s use in completing the secondary goal [SG.name]." - PC.registered_name = SG.requester_name - else - PC.name = "goal crate (Unknown in [SG.department])" + PC.name = "goal crate" + PC.registered_name = SG.requester_name + PC.AddComponent(/datum/component/label/goal, SG.requester_name, SG.department, TRUE) PC.locked = FALSE PC.update_icon() @@ -336,7 +333,7 @@ if(department_messages[department][message_piece] > 1) count = " (x[department_messages[department][message_piece]])" rc_message += "[message_piece][count]" - send_requests_console_message(rc_message, "Central Command", department, "Stamped with the Central Command rubber stamp.", "Verified by the Central Command receiving department.", RQ_NORMALPRIORITY) + send_requests_console_message(rc_message, "Procurement Office", department, "Stamped with the Central Command rubber stamp.", "Verified by the Central Command receiving department.", RQ_NORMALPRIORITY) SSeconomy.centcom_message += "[msg]
" manifest = new @@ -852,6 +849,12 @@ SSblackbox.record_feedback("nested tally", "cargo salvage sold", count, list(salvage_name, "count")) SSblackbox.record_feedback("nested tally", "cargo salvage sold", item.credits, list(salvage_name, "credits")) +/datum/economy/simple_seller/shelved_items + +/datum/economy/simple_seller/shelved_items/check_sell(obj/docking_port/mobile/supply/S, atom/movable/AM) + if(AM.GetComponent(/datum/component/shelved)) + return COMSIG_CARGO_IS_SECURED + /datum/economy/cargo_shuttle_manifest var/list/items_to_sell = list() var/list/line_items = list() diff --git a/code/modules/station_goals/secondary/botany/kudzu_goal.dm b/code/modules/station_goals/secondary/botany/kudzu_goal.dm index 2a002dc568a..74d221e6cbc 100644 --- a/code/modules/station_goals/secondary/botany/kudzu_goal.dm +++ b/code/modules/station_goals/secondary/botany/kudzu_goal.dm @@ -51,8 +51,8 @@ /datum/secondary_goal_progress/random_kudzu/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(AM)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(AM)) return if(!istype(AM, /obj/item/seeds/kudzu)) diff --git a/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm index b243fa6a127..8905d48b02e 100644 --- a/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm +++ b/code/modules/station_goals/secondary/kitchen/random_bulk_food.dm @@ -65,8 +65,8 @@ sent_this_shipment = 0 /datum/secondary_goal_progress/random_bulk_food/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(AM)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(AM)) return if(!istype(AM, food_type)) diff --git a/code/modules/station_goals/secondary/kitchen/variety_food.dm b/code/modules/station_goals/secondary/kitchen/variety_food.dm index 32c32380587..067e25af563 100644 --- a/code/modules/station_goals/secondary/kitchen/variety_food.dm +++ b/code/modules/station_goals/secondary/kitchen/variety_food.dm @@ -53,8 +53,8 @@ return copy /datum/secondary_goal_progress/variety_food/update(obj/item/food/food, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(food)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(food)) return // Not food? Ignore. diff --git a/code/modules/station_goals/secondary/random_bulk_reagent.dm b/code/modules/station_goals/secondary/random_bulk_reagent.dm index f1b6e9fc17a..2cd683897ab 100644 --- a/code/modules/station_goals/secondary/random_bulk_reagent.dm +++ b/code/modules/station_goals/secondary/random_bulk_reagent.dm @@ -71,8 +71,8 @@ return copy /datum/secondary_goal_progress/random_bulk_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(AM)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(AM)) return var/amount = AM.reagents?.get_reagent_amount(initial(reagent_type.id)) diff --git a/code/modules/station_goals/secondary/science/random_ripley.dm b/code/modules/station_goals/secondary/science/random_ripley.dm index 136b1d886ca..1516355b2de 100644 --- a/code/modules/station_goals/secondary/science/random_ripley.dm +++ b/code/modules/station_goals/secondary/science/random_ripley.dm @@ -57,7 +57,7 @@ /datum/secondary_goal_progress/random_ripley/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) // Not labelled for this goal? Ignore. - if(!check_personal_crate(AM)) + if(!check_goal_label(AM)) return if(!istype(AM, /obj/mecha/working/ripley)) return diff --git a/code/modules/station_goals/secondary/secondary_goal.dm b/code/modules/station_goals/secondary/secondary_goal.dm index a9643bcee3f..10386eda882 100644 --- a/code/modules/station_goals/secondary/secondary_goal.dm +++ b/code/modules/station_goals/secondary/secondary_goal.dm @@ -45,13 +45,15 @@ message_parts += "Suitable task found. Task details:" message_parts += "" message_parts += report_message + message_parts += "" + message_parts += "All requested materials must be properly labeled for transport, or be inside a properly-labeled container. You can configure a hand labeler to create suitable labels by by swiping your ID card on it." if(should_send_crate) - message_parts += "You must submit this in a locked personal crate. One will be sent to your Cargo department. More can be ordered if needed." - send_requests_console_message(message_parts, "Central Command", department, "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_HIGHPRIORITY) + message_parts += "For your convenience, a pre-labeled personal crate will be sent to your cargo department." + send_requests_console_message(message_parts, "Procurement Office", department, "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_HIGHPRIORITY) if(department != "Captain's Desk") - send_requests_console_message(message_parts, "Central Command", "Captain's Desk", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) + send_requests_console_message(message_parts, "Procurement Office", "Captain's Desk", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) if(department != "Bridge") - send_requests_console_message(message_parts, "Central Command", "Bridge", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) + send_requests_console_message(message_parts, "Procurement Office", "Bridge", "Stamped with the Central Command rubber stamp.", "Verified by A.L.I.C.E (CentCom AI)", RQ_NORMALPRIORITY) /proc/init_secondary_goal_grab_bags() SSticker.mode.secondary_goal_grab_bags = list() diff --git a/code/modules/station_goals/secondary/secondary_goal_tracker.dm b/code/modules/station_goals/secondary/secondary_goal_tracker.dm index edee8140029..14607d94c4e 100644 --- a/code/modules/station_goals/secondary/secondary_goal_tracker.dm +++ b/code/modules/station_goals/secondary/secondary_goal_tracker.dm @@ -97,17 +97,23 @@ /datum/secondary_goal_progress/proc/check_complete(datum/economy/cargo_shuttle_manifest/manifest) return FALSE -/datum/secondary_goal_progress/proc/check_personal_crate(atom/movable/AM) - // Accept stuff that is properly labelled with a hand labeller. - var/datum/component/label/goal/label = AM.GetComponent(/datum/component/label/goal) - if(istype(label)) - return !goal_requester || label.label_name == goal_requester +/datum/secondary_goal_progress/proc/check_goal_label(atom/movable/AM) + // Look for a secondary goal label on this atom or anything it's inside. + var/atom/current_layer = AM + while(current_layer && isobj(current_layer)) + // If it has a goal label, check the label's owner. + var/datum/component/label/goal/label = current_layer.GetComponent(/datum/component/label/goal) + if(istype(label)) + return !goal_requester || label.person == goal_requester - // Accept stuff in matching personal crates. - var/obj/structure/closet/crate/secure/personal/PC = get_atom_on_turf(AM, /obj/structure/closet/crate/secure/personal) - if(!istype(PC)) - return FALSE - return !goal_requester || PC.registered_name == goal_requester + // Otherwise, move to whatever's holding us, and check again. + var/datum/component/shelved/shelving = current_layer.GetComponent(/datum/component/shelved) + var/obj/shelf = locateUID(shelving?.shelf_uid) + if(istype(shelf)) + current_layer = shelf + else + current_layer = current_layer.loc + return FALSE /datum/secondary_goal_progress/proc/three_way_reward(datum/economy/cargo_shuttle_manifest/manifest, department, department_account, reward, message) SSblackbox.record_feedback("nested tally", "secondary goals", 1, list(goal_name, "payments made")) diff --git a/code/modules/station_goals/secondary/supply/random_smithed_item.dm b/code/modules/station_goals/secondary/supply/random_smithed_item.dm index e5fc18589b7..c8b64ece504 100644 --- a/code/modules/station_goals/secondary/supply/random_smithed_item.dm +++ b/code/modules/station_goals/secondary/supply/random_smithed_item.dm @@ -113,8 +113,8 @@ return TRUE /datum/secondary_goal_progress/random_smithed_item/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(AM)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(AM)) return if(!istype(AM, /obj/item/smithed_item)) diff --git a/code/modules/station_goals/secondary/variety_reagent.dm b/code/modules/station_goals/secondary/variety_reagent.dm index 14665b20a8c..526efd982e6 100644 --- a/code/modules/station_goals/secondary/variety_reagent.dm +++ b/code/modules/station_goals/secondary/variety_reagent.dm @@ -45,8 +45,8 @@ return copy /datum/secondary_goal_progress/variety_reagent/update(atom/movable/AM, datum/economy/cargo_shuttle_manifest/manifest = null) - // Not in a matching personal crate? Ignore. - if(!check_personal_crate(AM)) + // Not properly labeled for this goal? Ignore. + if(!check_goal_label(AM)) return // No reagents? Ignore. diff --git a/code/modules/virology/virology_goals.dm b/code/modules/virology/virology_goals.dm index 805e1c23296..e95a24da031 100644 --- a/code/modules/virology/virology_goals.dm +++ b/code/modules/virology/virology_goals.dm @@ -24,6 +24,8 @@ GLOBAL_LIST_EMPTY(archived_virology_goals) SIGNAL_HANDLER // COMSIG_CARGO_CHECK_SELL if(istype(thing, /obj/item/reagent_containers)) var/obj/item/reagent_containers/C = thing + if(!thing.reagents?.has_reagent("blood")) + return if(check_viruses(C.reagents.reagent_list)) return COMSIG_CARGO_SELL_PRIORITY return COMSIG_CARGO_SELL_WRONG