mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 03:25:49 +01:00
Deadchat Plays SS13: Ghost Control of Mobs (#20600)
* Add dchat control * adds human support, cleans other things up * Bit of cleanup * actually use the item * minor proc ref mistake, laugh at this user * evil tg strings * Renames defines, adds vv menu item for it * Improve anarchy message formatting * don't go to_chatting tesla energy balls * aa review * Minor cleanups, replace some emotes * Addressing some reviews * Incorporate some checks for deadchat mutes/prefs
This commit is contained in:
@@ -216,6 +216,8 @@
|
||||
|
||||
if(GLOB.configuration.general.enable_auto_mute && !check_rights(R_ADMIN, 0) && last_message == message)
|
||||
last_message_count++
|
||||
if(SEND_SIGNAL(mob, COMSIG_MOB_AUTOMUTE_CHECK, src, last_message, mute_type) & WAIVE_AUTOMUTE_CHECK)
|
||||
return FALSE
|
||||
if(last_message_count >= SPAM_TRIGGER_AUTOMUTE)
|
||||
to_chat(src, "<span class='danger'>You have exceeded the spam filter limit for identical messages. An auto-mute was applied.</span>")
|
||||
cmd_admin_mute(mob, mute_type, 1)
|
||||
|
||||
@@ -102,3 +102,16 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
T.ex_act(EXPLODE_HEAVY)
|
||||
if(loc == destination)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/immovablerod/deadchat_plays(mode = DEADCHAT_DEMOCRACY_MODE, cooldown = 6 SECONDS)
|
||||
return AddComponent(/datum/component/deadchat_control/immovable_rod, mode, list(), cooldown)
|
||||
|
||||
/**
|
||||
* Rod will walk towards edge turf in the specified direction.
|
||||
*
|
||||
* Arguments:
|
||||
* * direction - The direction to walk the rod towards: NORTH, SOUTH, EAST, WEST.
|
||||
*/
|
||||
/obj/effect/immovablerod/proc/walk_in_direction(direction)
|
||||
destination = get_edge_target_turf(src, direction)
|
||||
walk_towards(src, destination)
|
||||
|
||||
@@ -2065,3 +2065,83 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
|
||||
set category = "IC"
|
||||
|
||||
update_flavor_text()
|
||||
|
||||
// Behavior for deadchat control
|
||||
|
||||
/mob/living/carbon/human/proc/dchat_emote()
|
||||
var/list/possible_emotes = list("scream", "clap", "snap", "crack", "dap", "burp")
|
||||
emote(pick(possible_emotes))
|
||||
|
||||
/mob/living/carbon/human/proc/dchat_attack()
|
||||
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)
|
||||
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)
|
||||
return
|
||||
|
||||
visible_message("<span class='warning'>[src] swings [isnull(in_hand) ? "[p_their()] fists" : in_hand] wildly!")
|
||||
|
||||
/mob/living/carbon/human/proc/dchat_pickup()
|
||||
var/turf/ahead = get_step(src, dir)
|
||||
var/obj/item/thing = locate(/obj/item) in ahead
|
||||
if(!thing)
|
||||
return
|
||||
|
||||
var/old_loc = thing.loc
|
||||
var/obj/item/in_hand = get_active_hand()
|
||||
|
||||
if(in_hand)
|
||||
visible_message("<span class='notice'>[src] drops [in_hand] and picks up [thing] instead!</span>")
|
||||
unEquip(in_hand)
|
||||
in_hand.forceMove(old_loc)
|
||||
else
|
||||
visible_message("<span class='notice'>[src] picks up [thing]!</span>")
|
||||
put_in_active_hand(thing)
|
||||
|
||||
/mob/living/carbon/human/proc/dchat_throw()
|
||||
var/in_hand = get_active_hand()
|
||||
if(!in_hand)
|
||||
visible_message("<span class='notice'>[src] makes a throwing motion!</span>")
|
||||
return
|
||||
var/atom/possible_target
|
||||
var/cur_turf = get_turf(src)
|
||||
for(var/i in 1 to 5)
|
||||
cur_turf = get_step(cur_turf, dir)
|
||||
possible_target = locate(/mob/living) in cur_turf
|
||||
if(possible_target)
|
||||
break
|
||||
|
||||
possible_target = locate(/obj/structure) in cur_turf
|
||||
if(possible_target)
|
||||
break
|
||||
|
||||
if(!possible_target)
|
||||
throw_item(cur_turf)
|
||||
else
|
||||
throw_item(possible_target)
|
||||
|
||||
/mob/living/carbon/human/proc/dchat_shove()
|
||||
var/turf/ahead = get_turf(get_step(src, dir))
|
||||
var/mob/living/carbon/human/H = locate(/mob/living/carbon/human) in ahead
|
||||
if(!H)
|
||||
visible_message("<span class='notice'>[src] tries to shove something away!</span>")
|
||||
return
|
||||
dna?.species.disarm(src, H)
|
||||
|
||||
|
||||
/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)),
|
||||
"pickup" = CALLBACK(src, PROC_REF(dchat_pickup)),
|
||||
"throw" = CALLBACK(src, PROC_REF(dchat_throw)),
|
||||
"disarm" = CALLBACK(src, PROC_REF(dchat_shove)),
|
||||
)
|
||||
|
||||
AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, inputs, cooldown)
|
||||
|
||||
@@ -105,6 +105,48 @@
|
||||
..(gibbed)
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/deadchat_plays(mode = DEADCHAT_ANARCHY_MODE, cooldown = 12 SECONDS)
|
||||
. = AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, list(
|
||||
"speak" = CALLBACK(src, PROC_REF(handle_automated_speech), TRUE),
|
||||
"wear_hat" = CALLBACK(src, PROC_REF(find_new_hat)),
|
||||
"drop_hat" = CALLBACK(src, PROC_REF(drop_hat)),
|
||||
"spin" = CALLBACK(src, TYPE_PROC_REF(/mob, emote), "spin")), cooldown, CALLBACK(src, PROC_REF(end_dchat_plays)))
|
||||
|
||||
if(. == COMPONENT_INCOMPATIBLE)
|
||||
return
|
||||
|
||||
stop_automated_movement = TRUE
|
||||
|
||||
///Deadchat plays command that picks a new hat for Ian.
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/find_new_hat()
|
||||
if(!isturf(loc))
|
||||
return
|
||||
var/list/possible_headwear = list()
|
||||
for(var/obj/item/item in loc)
|
||||
if(ispath(item.dog_fashion, /datum/dog_fashion/head))
|
||||
possible_headwear += item
|
||||
if(!length(possible_headwear))
|
||||
for(var/obj/item/item in orange(1))
|
||||
if(ispath(item.dog_fashion, /datum/dog_fashion/head) && Adjacent(item))
|
||||
possible_headwear += item
|
||||
if(!length(possible_headwear))
|
||||
return
|
||||
if(inventory_head)
|
||||
inventory_head.forceMove(drop_location())
|
||||
inventory_head = null
|
||||
place_on_head(pick(possible_headwear))
|
||||
visible_message("<span class='notice'>[src] puts [inventory_head] on [p_their()] own head, somehow.</span>")
|
||||
|
||||
///Deadchat plays command that drops the current hat off Ian.
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/drop_hat()
|
||||
if(!inventory_head)
|
||||
return
|
||||
visible_message("<span class='notice'>[src] vigorously shakes [p_their()] head, dropping [inventory_head] to the ground.</span>")
|
||||
inventory_head.forceMove(drop_location())
|
||||
inventory_head = null
|
||||
update_corgi_fluff()
|
||||
regenerate_icons()
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user)
|
||||
if(user.incapacitated() || !Adjacent(user))
|
||||
return
|
||||
|
||||
@@ -635,3 +635,14 @@
|
||||
|
||||
/mob/living/simple_animal/proc/npc_safe(mob/user)
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/deadchat_plays(mode = DEADCHAT_ANARCHY_MODE, cooldown = 12 SECONDS)
|
||||
. = AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, list(), cooldown, CALLBACK(src, PROC_REF(end_dchat_plays)))
|
||||
|
||||
if(. == COMPONENT_INCOMPATIBLE)
|
||||
return
|
||||
|
||||
stop_automated_movement = TRUE
|
||||
|
||||
/mob/living/simple_animal/proc/end_dchat_plays()
|
||||
stop_automated_movement = FALSE
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
if(client.handle_spam_prevention(message, MUTE_DEADCHAT))
|
||||
return
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_DEADSAY, message) & MOB_DEADSAY_SIGNAL_INTERCEPT)
|
||||
return
|
||||
|
||||
if(message in USABLE_DEAD_EMOTES)
|
||||
emote(copytext(message, 2), intentional = TRUE)
|
||||
|
||||
@@ -522,3 +522,20 @@
|
||||
projectile_angle += angle_to_projectile / (distance ** 2)
|
||||
P.damage += 10 / distance
|
||||
P.set_angle(projectile_angle)
|
||||
|
||||
/obj/singularity/proc/end_deadchat_plays()
|
||||
move_self = TRUE
|
||||
|
||||
|
||||
/obj/singularity/deadchat_plays(mode = DEADCHAT_DEMOCRACY_MODE, cooldown = 12 SECONDS)
|
||||
. = AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, list(), cooldown, CALLBACK(src, TYPE_PROC_REF(/atom/movable, stop_deadchat_plays)))
|
||||
|
||||
if(. == COMPONENT_INCOMPATIBLE)
|
||||
return
|
||||
|
||||
move_self = FALSE
|
||||
|
||||
|
||||
/obj/singularity/deadchat_controlled/Initialize(mapload, starting_energy)
|
||||
. = ..()
|
||||
deadchat_plays(mode = DEADCHAT_DEMOCRACY_MODE)
|
||||
|
||||
Reference in New Issue
Block a user