diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index c387bdbe21c..374d48148cd 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -183,11 +183,6 @@
/obj/item/clothing/under/proc/attach_accessory(obj/item/clothing/accessory/accessory, mob/living/user, attach_message = TRUE)
if(!istype(accessory))
return
- if(length(attached_accessories) >= max_number_of_accessories)
- if(user)
- balloon_alert(user, "too many accessories!")
- return
-
if(!accessory.can_attach_accessory(src, user))
return
if(user && !user.temporarilyRemoveItemFromInventory(accessory))
diff --git a/code/modules/clothing/under/accessories/_accessories.dm b/code/modules/clothing/under/accessories/_accessories.dm
index 89f1008479a..1792bff82bb 100644
--- a/code/modules/clothing/under/accessories/_accessories.dm
+++ b/code/modules/clothing/under/accessories/_accessories.dm
@@ -17,6 +17,7 @@
inhand_icon_state = "" //no inhands
slot_flags = NONE
w_class = WEIGHT_CLASS_SMALL
+ item_flags = NOBLUDGEON
/// Whether or not the accessory displays through suits and the like.
var/above_suit = TRUE
/// TRUE if shown as a small icon in corner, FALSE if overlayed
@@ -46,6 +47,11 @@
attach_to.balloon_alert(user, "can't attach there!")
return FALSE
+ if(length(attach_to.attached_accessories) >= attach_to.max_number_of_accessories)
+ if(user)
+ attach_to.balloon_alert(user, "too many accessories!")
+ return FALSE
+
return TRUE
/**
diff --git a/code/modules/clothing/under/accessories/medals.dm b/code/modules/clothing/under/accessories/medals.dm
index 150fa45968a..90db5198ee6 100644
--- a/code/modules/clothing/under/accessories/medals.dm
+++ b/code/modules/clothing/under/accessories/medals.dm
@@ -7,48 +7,88 @@
/// Sprite used for medalbox
var/medaltype = "medal"
/// Has this been use for a commendation?
- var/commended = FALSE
+ var/commendation_message
+ /// Who was first given this medal
+ var/awarded_to
+ /// Who gave out this medal
+ var/awarder
-// If someone adds SHOULD_NOT_SLEEP anywhere up the chain, this will need to be reworked
-/obj/item/clothing/accessory/medal/attach(obj/item/clothing/under/attach_to, mob/living/attacher)
- if(isnull(attacher))
- // Do normal attach
- return ..()
+/// Callback for do_after to check if we can still be pinned
+/obj/item/clothing/accessory/medal/proc/pin_checks(mob/living/pinner, mob/living/carbon/human/pinning_on)
+ if(QDELETED(src) || QDELETED(pinner) || QDELETED(pinning_on))
+ return FALSE
+ if(!pinner.is_holding(src) || !pinner.Adjacent(pinning_on))
+ return FALSE
+ var/obj/item/clothing/under/pinning_on_uniform = pinning_on.w_uniform
+ if(!istype(pinning_on_uniform) || !can_attach_accessory(pinning_on_uniform, pinner))
+ return FALSE
+ return TRUE
- var/mob/living/distinguished = attach_to.loc
- if(!istype(distinguished) || distinguished == attacher)
- // Do normal attach
- return ..()
+/obj/item/clothing/accessory/medal/pre_attack(atom/target, mob/living/user, params)
+ . = ..()
+ if(.)
+ return
+ if(!ishuman(target) || target == user)
+ return
- // Do a do_after before we attach, and allow us to include a commendation message.
- attacher.visible_message(
- span_notice("[attacher] is trying to pin [src] on [distinguished]'s chest."),
+ . = TRUE // no attack chain please
+
+ var/mob/living/carbon/human/distinguished = target
+ var/obj/item/clothing/under/distinguished_uniform = distinguished.w_uniform
+ if(!istype(distinguished_uniform))
+ distinguished.balloon_alert(user, "no uniform to pin on!")
+ return .
+ if(!can_attach_accessory(distinguished_uniform, user))
+ // Check handles feedback messages and etc
+ return .
+
+ user.visible_message(
+ span_notice("[user] tries to pin [src] on [distinguished]'s chest."),
span_notice("You try to pin [src] on [distinguished]'s chest."),
)
- var/input
- if(!commended)
- input = tgui_input_text(attacher, "Reason for this commendation? It will be recorded by Nanotrasen.", "Commendation", max_length = 140)
+ commendation_message = tgui_input_text(user, "Reason for this commendation? It will be recorded by Nanotrasen.", "Commendation", max_length = 140)
+ if(!commendation_message || !pin_checks(user, distinguished))
+ return .
+ if(!do_after(user, 2 SECONDS, distinguished, extra_checks = CALLBACK(src, PROC_REF(pin_checks), user, distinguished)))
+ return .
- if(!do_after(attacher, 2 SECONDS, distinguished))
- return FALSE
+ if(distinguished_uniform.attach_accessory(src, user))
+ user.visible_message(
+ span_notice("[user] pins [src] on [distinguished]'s chest."),
+ span_notice("You pin [src] on [distinguished]'s chest."),
+ )
+ else
+ user.visible_message(
+ span_warning("[user] fails to pin [src] on [distinguished]'s chest, seemingly unable to part with it."),
+ span_warning("You fail to pin [src] on [distinguished]'s chest."),
+ )
- attacher.visible_message(
- span_notice("[attacher] pins [src] on [distinguished]'s chest."),
- span_notice("You pin [src] on [distinguished]'s chest."),
- )
- if(!input)
- return FALSE
+ return .
+
+/obj/item/clothing/accessory/medal/attach(obj/item/clothing/under/attach_to, mob/living/attacher)
+ var/mob/living/distinguished = attach_to.loc
+ if(isnull(attacher) || !istype(distinguished) || distinguished == attacher || awarded_to)
+ // You can't be awarded by nothing, you can't award yourself, and you can't be awarded someone else's medal
+ return ..()
+
+ awarder = attacher.real_name
+ awarded_to = distinguished.real_name
+
+ update_appearance(UPDATE_DESC)
+ add_memory_in_range(distinguished, 7, /datum/memory/received_medal, protagonist = distinguished, deuteragonist = attacher, medal_type = src, medal_text = commendation_message)
+ distinguished.log_message("was given the following commendation by [key_name(attacher)]: [commendation_message]", LOG_GAME, color = "green")
+ message_admins("[key_name_admin(distinguished)] was given the following commendation by [key_name_admin(attacher)]: [commendation_message]")
+ GLOB.commendations += "[awarder] awarded [awarded_to] the [name]! \n- [commendation_message]"
+ SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[awarder]", "commendee" = "[awarded_to]", "medal" = "[src]", "reason" = commendation_message))
- commended = TRUE
- SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[attacher.real_name]", "commendee" = "[distinguished.real_name]", "medal" = "[src]", "reason" = input))
- GLOB.commendations += "[attacher.real_name] awarded [distinguished.real_name] the [name]! \n- [input]"
- desc += "
The inscription reads: [input] - [attacher.real_name]"
- distinguished.log_message("was given the following commendation by [key_name(attacher)]: [input]", LOG_GAME, color = "green")
- message_admins("[key_name_admin(distinguished)] was given the following commendation by [key_name_admin(attacher)]: [input]")
- add_memory_in_range(distinguished, 7, /datum/memory/received_medal, protagonist = distinguished, deuteragonist = attacher, medal_type = src, medal_text = input)
return ..()
+/obj/item/clothing/accessory/medal/update_desc(updates)
+ . = ..()
+ if(commendation_message && awarded_to && awarder)
+ desc += span_info("
The inscription reads: [commendation_message] - Awarded to [awarded_to] by [awarder]")
+
/obj/item/clothing/accessory/medal/conduct
name = "distinguished conduct medal"
desc = "A bronze medal awarded for distinguished conduct. Whilst a great honor, this is the most basic award given by Nanotrasen. It is often awarded by a captain to a member of his crew."