diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index a1136929cef..0647e5be12a 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -15,6 +15,9 @@ processing_speed = STATUS_EFFECT_PRIORITY remove_on_fullheal = TRUE heal_flag_necessary = HEAL_CC_STATUS + /// Chance of triggering a force_say + var/force_say_chance = 66 + /// If TRUE we run update_stat on apply/remove var/needs_update_stat = FALSE /// Suffixes attached to the force_say when applied, uses the "hurt" suffixes by default var/list/alter_phrases @@ -39,14 +42,14 @@ if(!.) return - force_say() + try_force_say() -/datum/status_effect/incapacitating/proc/force_say() +/datum/status_effect/incapacitating/proc/try_force_say() SHOULD_CALL_PARENT(TRUE) var/mob/living/carbon/human/human = owner - if(istype(human)) - human.force_say(alter_phrases, immediate = TRUE) + if(istype(human) && prob(force_say_chance) && (duration >= 6 SECONDS || (duration >= 2 SECONDS && prob(66))) ) + human.force_say(alter_phrases, immediate = TRUE, major = (duration >= 30 SECONDS)) //STUN /datum/status_effect/incapacitating/stun @@ -80,6 +83,7 @@ //IMMOBILIZED /datum/status_effect/incapacitating/immobilized id = "immobilized" + force_say_chance = 0 /datum/status_effect/incapacitating/immobilized/on_apply() . = ..() @@ -111,6 +115,7 @@ /// This status effect represents anything that leaves a character unable to perform basic tasks (interrupting do-afters, for example), but doesn't incapacitate them further than that (no stuns etc..) /datum/status_effect/incapacitating/incapacitated id = "incapacitated" + force_say_chance = 0 // What happens when you get the incapacitated status. You get TRAIT_INCAPACITATED added to you for the duration of the status effect. /datum/status_effect/incapacitating/incapacitated/on_apply() @@ -129,6 +134,7 @@ /datum/status_effect/incapacitating/unconscious id = "unconscious" needs_update_stat = TRUE + force_say_chance = 100 /datum/status_effect/incapacitating/unconscious/on_apply() . = ..() @@ -152,6 +158,7 @@ needs_update_stat = TRUE tick_interval = 2 SECONDS alter_phrases = list("Zzz...", "ZZz...", "ZZZ...", "zzZ...", "zZZ...", "ZzZ...", "zzz...", "zZz...", "mimimimimimi...") + force_say_chance = 100 /datum/status_effect/incapacitating/sleeping/on_apply() . = ..() @@ -171,9 +178,9 @@ tick_interval = initial(tick_interval) return ..() -/datum/status_effect/incapacitating/sleeping/force_say() +/datum/status_effect/incapacitating/sleeping/try_force_say() if(!HAS_TRAIT(owner, TRAIT_SLEEPIMMUNE)) - ..() + return ..() ///If the mob is sleeping and gain the TRAIT_SLEEPIMMUNE we remove the TRAIT_KNOCKEDOUT and stop the tick() from happening /datum/status_effect/incapacitating/sleeping/proc/on_owner_insomniac(mob/living/source) diff --git a/code/game/objects/items/cigarettes.dm b/code/game/objects/items/cigarettes.dm index a8eefa88ae6..ca1f04b13b1 100644 --- a/code/game/objects/items/cigarettes.dm +++ b/code/game/objects/items/cigarettes.dm @@ -315,8 +315,11 @@ CIGARETTE PACKETS ARE IN FANCY.DM QDEL_NULL(mob_smoke) how_long_have_we_been_smokin = 0 SECONDS -/obj/item/cigarette/proc/on_forcesay(mob/living/source) +/obj/item/cigarette/proc/on_forcesay(mob/living/source, major) SIGNAL_HANDLER + + if(!major) + return source.apply_status_effect(/datum/status_effect/choke, src, lit, choke_forever ? -1 : rand(25 SECONDS, choke_time_max)) /obj/item/cigarette/proc/on_mob_dir_change(mob/living/source, old_dir, new_dir) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 0c9e8f53aeb..da501b14838 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -893,14 +893,14 @@ GLOBAL_LIST_EMPTY(features_by_species) var/kicking = (atk_effect == ATTACK_EFFECT_KICK) var/final_armor_block = armor_block if(kicking || grappled) //kicks and punches when grappling bypass armor slightly. - if(damage >= 9) + if(damage >= 12 || (damage >= 9 && prob(66))) target.force_say() log_combat(user, target, grappled ? "grapple punched" : "kicked") final_armor_block -= limb_accuracy target.apply_damage(damage, attack_type, affecting, final_armor_block, attack_direction = attack_direction, sharpness = limb_sharpness) else // Normal attacks do not gain the benefit of armor penetration. target.apply_damage(damage, attack_type, affecting, armor_block, attack_direction = attack_direction, sharpness = limb_sharpness) - if(damage >= 9) + if(damage >= 12 || (damage >= 9 && prob(66))) target.force_say() log_combat(user, target, "punched") diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 9552d8f373a..0f5ecfb2073 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) human_heart?.beat = BEAT_NONE human_heart?.Stop() - force_say(immediate = TRUE) + force_say(list(""), immediate = TRUE) . = ..() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 80857085bef..53c3b83c1b1 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -823,6 +823,9 @@ span_userdanger("You[knocked_down ? "'re knocked down" : " resist falling down"] from a shove by [name]!"), span_hear("You hear aggressive shuffling [knocked_down ? "followed by a loud thud!" : ""]"), COMBAT_MESSAGE_RANGE, src) to_chat(src, span_danger("You shove [target.name][knocked_down ? ", knocking [target.p_them()] down" : ""]!")) log_combat(src, target, "shoved", "[knocked_down ? "knocking them down[weapon ? " with [weapon]" : ""]" : ""]") + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + human_target.force_say() return if(shove_flags & SHOVE_CAN_KICK_SIDE) //KICK HIM IN THE NUTS diff --git a/code/modules/tgui_input/say_modal/modal.dm b/code/modules/tgui_input/say_modal/modal.dm index 82e681b6dbd..b4cc549ee8b 100644 --- a/code/modules/tgui_input/say_modal/modal.dm +++ b/code/modules/tgui_input/say_modal/modal.dm @@ -92,6 +92,7 @@ if(!payload?["channel"]) CRASH("No channel provided to an open TGUI-Say") window_open = TRUE + saved_text = "" if(payload["channel"] != OOC_CHANNEL && payload["channel"] != ADMIN_CHANNEL && payload["channel"] != PRAY_CHANNEL) start_thinking() if(!client.typing_indicators) diff --git a/code/modules/tgui_input/say_modal/speech.dm b/code/modules/tgui_input/say_modal/speech.dm index 50d9a5f9265..8c917dadcf2 100644 --- a/code/modules/tgui_input/say_modal/speech.dm +++ b/code/modules/tgui_input/say_modal/speech.dm @@ -87,10 +87,11 @@ /** * Makes the player force say what's in their current input box. * Arguments: - * alter_phrases - Optional list of alternate suffixes to blurt out - * immediate - If [TRUE], the say must be invoked inline due to side effects that may cause the mob to be unable to speak + * * alter_phrases - Optional list of alternate suffixes to blurt out + * * immediate - If [TRUE], the say must be invoked inline due to side effects that may cause the mob to be unable to speak + * * major - If [TRUE], a "major action" triggered the force say, which may have additional side effects */ -/mob/living/carbon/human/proc/force_say(list/alter_phrases = null, immediate = FALSE) +/mob/living/carbon/human/proc/force_say(list/alter_phrases = null, immediate = FALSE, major = TRUE) if(stat != CONSCIOUS || !client?.tgui_say?.window_open) return FALSE client.tgui_say.force_say(alter_phrases, immediate) @@ -98,7 +99,7 @@ log_speech_indicators("[key_name(client)] FORCED to stop typing, indicators enabled.") else log_speech_indicators("[key_name(client)] FORCED to stop typing, indicators DISABLED.") - SEND_SIGNAL(src, COMSIG_HUMAN_FORCESAY) + SEND_SIGNAL(src, COMSIG_HUMAN_FORCESAY, major) /** * Gets whatever text is currently in this mob's say box and returns it.