From b4cba9f98144e8affdc06bec7d9fad57229cf159 Mon Sep 17 00:00:00 2001
From: Luc <89928798+lewcc@users.noreply.github.com>
Date: Fri, 2 Jun 2023 12:12:10 -0700
Subject: [PATCH] Minor deadchat control improvements (#21162)
* Add resist, improves attack
* Make emotes intentional too
* fix a qdel loop
* Add "help" command, start deadchat control with existing followers as well
* Minor messaging improvements
---
code/datums/components/deadchat_control.dm | 17 +++++--
code/game/atoms_movable.dm | 3 +-
.../modules/mob/living/carbon/carbon_emote.dm | 2 +-
.../mob/living/carbon/human/human_mob.dm | 48 ++++++++++++++-----
4 files changed, 53 insertions(+), 17 deletions(-)
diff --git a/code/datums/components/deadchat_control.dm b/code/datums/components/deadchat_control.dm
index 8608af566d0..a3a45e9c5f1 100644
--- a/code/datums/components/deadchat_control.dm
+++ b/code/datums/components/deadchat_control.dm
@@ -47,7 +47,12 @@
if(!ismob(parent) && !(parent in GLOB.poi_list))
GLOB.poi_list |= parent
generated_point_of_interest = TRUE
- message_admins("[parent] has been given deadchat control in [deadchat_mode == DEADCHAT_ANARCHY_MODE ? "anarchy" : "democracy"] mode with a cooldown of [input_cooldown SECONDS] second\s.")
+ message_admins("[parent] has been given deadchat control in [deadchat_mode == DEADCHAT_ANARCHY_MODE ? "anarchy" : "democracy"] mode with a cooldown of [input_cooldown] second\s.")
+
+ var/atom/A = parent
+ for(var/mob/dead/observer/ghost in A.get_orbiters())
+ // get started with anyone who's already following
+ orbit_begin(A, ghost)
/datum/component/deadchat_control/Destroy(force, silent)
var/message = "[parent] is no longer controllable."
@@ -145,6 +150,8 @@
to_chat(O, "You have deadchat muted, and as such will not receive messages related to, nor be able to participate in, controlling this object.")
to_chat(O, "If you would like to participate, unmute deadchat and follow this object again.")
return
+ else
+ to_chat(O, "[parent] is deadchat-controllable! Examine [parent] to see possible commands you can use while orbiting [parent.p_them()] to control [parent.p_their()] behavior!")
RegisterSignal(orbiter, COMSIG_MOB_DEADSAY, PROC_REF(deadchat_react))
RegisterSignal(orbiter, COMSIG_MOB_AUTOMUTE_CHECK, PROC_REF(waive_automute))
@@ -190,6 +197,11 @@
examine_list += "As you have deadchat disabled, you will not see vote messages, nor be able to participate in voting."
return
+ if(!(user in orbiters))
+ examine_list += "Orbit [A.p_them()] and examine [A.p_them()] again to see the list of possible commands."
+ return
+
+
if(deadchat_mode & DEADCHAT_DEMOCRACY_MODE)
examine_list += "Type a command into chat to vote on an action. This happens once every [input_cooldown * 0.1] second\s."
else if(deadchat_mode & DEADCHAT_ANARCHY_MODE)
@@ -197,8 +209,7 @@
var/extended_examine = "Command list:"
- for(var/possible_input in inputs)
- extended_examine += " [possible_input]"
+ extended_examine += english_list(inputs)
extended_examine += "."
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 3281abf80ba..77eb99f55fb 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -639,7 +639,8 @@
/// Easy way to remove the component when the fun has been played out
/atom/movable/proc/stop_deadchat_plays()
var/datum/component/deadchat_control/comp = GetComponent(/datum/component/deadchat_control)
- qdel(comp)
+ if(!QDELETED(comp))
+ qdel(comp)
/atom/movable/vv_get_dropdown()
. = ..()
diff --git a/code/modules/mob/living/carbon/carbon_emote.dm b/code/modules/mob/living/carbon/carbon_emote.dm
index bc908ba6a07..0c0f15d7161 100644
--- a/code/modules/mob/living/carbon/carbon_emote.dm
+++ b/code/modules/mob/living/carbon/carbon_emote.dm
@@ -36,7 +36,7 @@
/datum/emote/living/carbon/clap/get_sound(mob/living/user)
if(ishuman(user))
var/mob/living/carbon/human/H = user
- if(!H?.mind.miming)
+ if(!H?.mind?.miming)
return pick(
'sound/misc/clap1.ogg',
'sound/misc/clap2.ogg',
diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm
index dce5539fcd1..9dee51c2561 100644
--- a/code/modules/mob/living/carbon/human/human_mob.dm
+++ b/code/modules/mob/living/carbon/human/human_mob.dm
@@ -2070,22 +2070,44 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/proc/dchat_emote()
var/list/possible_emotes = list("scream", "clap", "snap", "crack", "dap", "burp")
- emote(pick(possible_emotes))
+ emote(pick(possible_emotes), intentional = TRUE)
-/mob/living/carbon/human/proc/dchat_attack()
+/mob/living/carbon/human/proc/dchat_attack(intent)
var/turf/ahead = get_turf(get_step(src, dir))
- var/mob/living/victim = locate(/mob/living) in ahead
- var/in_hand = get_active_hand()
- if(victim)
- victim.attacked_by(in_hand, src, BODY_ZONE_CHEST)
+ var/atom/victim = locate(/mob/living) in ahead
+ var/obj/item/in_hand = get_active_hand()
+ var/implement = "[isnull(in_hand) ? "[p_their()] fists" : in_hand]"
+ if(!victim)
+ victim = locate(/obj/structure) in ahead
+ if(!victim)
+ switch(intent)
+ if(INTENT_HARM)
+ visible_message("[src] swings [implement] wildly!")
+ if(INTENT_HELP)
+ visible_message("[src] seems to take a deep breath.")
return
- var/obj/structure/other_victim = locate(/obj/structure) in ahead
- if(other_victim)
- do_attack_animation(other_victim, used_item = in_hand)
- other_victim.attacked_by(in_hand, src)
+ if(isLivingSSD(victim))
+ visible_message("[src] [intent == INTENT_HARM ? "reluctantly " : ""]lowers [p_their()] [implement].")
return
- visible_message("[src] swings [isnull(in_hand) ? "[p_their()] fists" : in_hand] wildly!")
+ var/original_intent = a_intent
+ a_intent = intent
+ if(in_hand)
+ in_hand.melee_attack_chain(src, victim)
+ else
+ UnarmedAttack(victim, TRUE)
+ a_intent = original_intent
+
+/mob/living/carbon/human/proc/dchat_resist()
+ if(!can_resist())
+ visible_message("[src] seems to be unable to do anything!")
+ return
+ if(!restrained())
+ visible_message("[src] seems to be doing nothing in particular.")
+ return
+
+ visible_message("[src] is trying to break free!")
+ resist()
/mob/living/carbon/human/proc/dchat_pickup()
var/turf/ahead = get_step(src, dir)
@@ -2138,10 +2160,12 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
/mob/living/carbon/human/deadchat_plays(mode = DEADCHAT_DEMOCRACY_MODE, cooldown = 7 SECONDS)
var/list/inputs = list(
"emote" = CALLBACK(src, PROC_REF(dchat_emote)),
- "attack" = CALLBACK(src, PROC_REF(dchat_attack)),
+ "attack" = CALLBACK(src, PROC_REF(dchat_attack), INTENT_HARM),
+ "help" = CALLBACK(src, PROC_REF(dchat_attack), INTENT_HELP),
"pickup" = CALLBACK(src, PROC_REF(dchat_pickup)),
"throw" = CALLBACK(src, PROC_REF(dchat_throw)),
"disarm" = CALLBACK(src, PROC_REF(dchat_shove)),
+ "resist" = CALLBACK(src, PROC_REF(dchat_resist)),
)
AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, inputs, cooldown)