diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm
index 42146b1a29..e03ba4fcd2 100644
--- a/_maps/map_files/PubbyStation/PubbyStation.dmm
+++ b/_maps/map_files/PubbyStation/PubbyStation.dmm
@@ -17294,7 +17294,7 @@
lootcount = 2;
name = "2maintenance loot spawner"
},
-/obj/item/clothing/gloves/color/random,
+/obj/effect/spawner/lootdrop/gloves,
/turf/open/floor/plating,
/area/maintenance/department/crew_quarters/bar)
"aPD" = (
diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 83b537853a..b04853e576 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -131,6 +131,16 @@
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
+#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list)
+ #define COMPONENT_UPPERCASE_SPEECH 1
+ // used to access COMSIG_MOB_SAY argslist
+ #define SPEECH_MESSAGE 1
+ // #define SPEECH_BUBBLE_TYPE 2
+ #define SPEECH_SPANS 3
+ /* #define SPEECH_SANITIZE 4
+ #define SPEECH_LANGUAGE 5
+ #define SPEECH_IGNORE_SPAM 6
+ #define SPEECH_FORCED 7 */
// /mob/living signals
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 60148e0388..2fe70961f8 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -8,6 +8,7 @@
#define ENABLE_BITFIELD(variable, flag) (variable |= (flag))
#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag))
#define CHECK_BITFIELD(variable, flag) (variable & flag)
+#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag))
GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768))
diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm
index e6d4fd126b..8566571928 100644
--- a/code/__DEFINES/obj_flags.dm
+++ b/code/__DEFINES/obj_flags.dm
@@ -26,6 +26,7 @@
#define NODROP (1<<8) // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted.
#define ABSTRACT (1<<9) // for all things that are technically items but used for various different stuff
#define IMMUTABLE_SLOW (1<<10) //When players should not be able to change the slowdown of the item (Speed potions, ect)
+#define SURGICAL_TOOL (1<<12) //Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
// Flags for the clothing_flags var on /obj/item/clothing
@@ -35,3 +36,5 @@
#define MASKINTERNALS (1<<3) // mask allows internals
#define NOSLIP (1<<4) //prevents from slipping on wet floors, in space etc
#define THICKMATERIAL (1<<5) //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body.
+#define VOICEBOX_TOGGLABLE (1<<6) // The voicebox in this clothing can be toggled.
+#define VOICEBOX_DISABLED (1<<7) // The voicebox is currently turned off.
\ No newline at end of file
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 7363de55ed..f6f0086138 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -114,6 +114,7 @@
#define TRAIT_PARALYSIS_R_ARM "para-r-arm"
#define TRAIT_PARALYSIS_L_LEG "para-l-leg"
#define TRAIT_PARALYSIS_R_LEG "para-r-leg"
+#define TRAIT_UNINTELLIGIBLE_SPEECH "unintelligible-speech"
#define TRAIT_LAW_ENFORCEMENT_METABOLISM "law-enforcement-metabolism"
#define TRAIT_STRONG_GRABBER "strong_grabber"
#define TRAIT_CALCIUM_HEALER "calcium_healer"
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 7d8eb108f3..1ee5ce986f 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -767,3 +767,27 @@ GLOBAL_LIST_INIT(binary, list("0","1"))
return "twelfth"
else
return "[number]\th"
+
+/proc/unintelligize(message)
+ var/prefix=copytext(message,1,2)
+ if(prefix == ";")
+ message = copytext(message,2)
+ else if(prefix in list(":","#"))
+ prefix += copytext(message,2,3)
+ message = copytext(message,3)
+ else
+ prefix=""
+
+ var/list/words = splittext(message," ")
+ var/list/rearranged = list()
+ for(var/i=1;i<=words.len;i++)
+ var/cword = pick(words)
+ words.Remove(cword)
+ var/suffix = copytext(cword,length(cword)-1,length(cword))
+ while(length(cword)>0 && suffix in list(".",",",";","!",":","?"))
+ cword = copytext(cword,1 ,length(cword)-1)
+ suffix = copytext(cword,length(cword)-1,length(cword) )
+ if(length(cword))
+ rearranged += cword
+ message = "[prefix][jointext(rearranged," ")]"
+ . = message
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 6c158f1979..7e078184b7 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1239,19 +1239,21 @@ GLOBAL_REAL_VAR(list/stack_trace_storage)
pixel_x = initialpixelx
pixel_y = initialpixely
-/atom/proc/do_jiggle(targetangle = 45)
+/atom/proc/do_jiggle(targetangle = 45, timer = 20)
var/matrix/OM = matrix(transform)
var/matrix/M = matrix(transform)
+ var/halftime = timer * 0.5
M.Turn(pick(-targetangle, targetangle))
- animate(src, transform = M, time = 10, easing = ELASTIC_EASING)
- animate(src, transform = OM, time = 10, easing = ELASTIC_EASING)
+ animate(src, transform = M, time = halftime, easing = ELASTIC_EASING)
+ animate(src, transform = OM, time = halftime, easing = ELASTIC_EASING)
-/atom/proc/do_squish(squishx = 1.2, squishy = 0.6)
+/atom/proc/do_squish(squishx = 1.2, squishy = 0.6, timer = 20)
var/matrix/OM = matrix(transform)
var/matrix/M = matrix(transform)
+ var/halftime = timer * 0.5
M.Scale(squishx, squishy)
- animate(src, transform = M, time = 10, easing = BOUNCE_EASING)
- animate(src, transform = OM, time = 10, easing = BOUNCE_EASING)
+ animate(src, transform = M, time = halftime, easing = BOUNCE_EASING)
+ animate(src, transform = OM, time = halftime, easing = BOUNCE_EASING)
/proc/weightclass2text(var/w_class)
switch(w_class)
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index c37e6fa531..b861af633d 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -140,6 +140,8 @@ GLOBAL_LIST_INIT(bitfields, list(
"MASKINTERNALS" = MASKINTERNALS,
"NOSLIP" = NOSLIP,
"THICKMATERIAL" = THICKMATERIAL,
+ "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
+ "VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
),
"tesla_flags" = list(
"TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
@@ -171,4 +173,9 @@ GLOBAL_LIST_INIT(bitfields, list(
"RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
"RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
),
- ))
+ "disease_flags" = list(
+ "CURABLE" = CURABLE,
+ "CAN_CARRY" = CAN_CARRY,
+ "CAN_RESIST" = CAN_RESIST
+ ),
+ ))
\ No newline at end of file
diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm
index c444e902fc..4c9815af1c 100644
--- a/code/_globalvars/lists/maintenance_loot.dm
+++ b/code/_globalvars/lists/maintenance_loot.dm
@@ -43,7 +43,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/assembly/timer = 3,
/obj/item/flashlight = 4,
/obj/item/flashlight/pen = 1,
- /obj/item/flashlight/glowstick/random = 4,
+ /obj/effect/spawner/lootdrop/glowstick = 4,
/obj/effect/spawner/lootdrop/mre = 3,
/obj/item/multitool = 2,
/obj/item/radio/off = 2,
@@ -69,7 +69,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/crowbar = 1,
/obj/item/crowbar/red = 1,
/obj/item/extinguisher = 11,
- //obj/item/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
/obj/item/hand_labeler = 1,
/obj/item/paper/crumpled = 1,
/obj/item/pen = 1,
@@ -102,7 +101,7 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
/obj/item/assembly/signaler = 2,
/obj/item/assembly/mousetrap = 2,
/obj/item/reagent_containers/syringe = 2,
- /obj/item/clothing/gloves/color/random = 8,
+ /obj/effect/spawner/lootdrop/gloves = 8,
/obj/item/clothing/shoes/laceup = 1,
/obj/item/storage/secure/briefcase = 3,
/obj/item/storage/toolbox/artistic = 2,
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index 2a14d232aa..3896c3eac3 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -64,7 +64,7 @@
to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto
return // CIT CHANGE - ditto
- if(force && HAS_TRAIT(user, TRAIT_PACIFISM))
+ if(force && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "You don't want to harm other living beings!")
return
diff --git a/code/datums/brain_damage/brain_trauma.dm b/code/datums/brain_damage/brain_trauma.dm
index 3731397170..56a3f3969b 100644
--- a/code/datums/brain_damage/brain_trauma.dm
+++ b/code/datums/brain_damage/brain_trauma.dm
@@ -32,16 +32,18 @@
//Called when given to a mob
/datum/brain_trauma/proc/on_gain()
to_chat(owner, gain_text)
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
//Called when removed from a mob
/datum/brain_trauma/proc/on_lose(silent)
if(!silent)
to_chat(owner, lose_text)
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
//Called when hearing a spoken message
/datum/brain_trauma/proc/on_hear(message, speaker, message_language, raw_message, radio_freq)
return message
//Called when speaking
-/datum/brain_trauma/proc/on_say(message)
- return message
+/datum/brain_trauma/proc/handle_speech(datum/source, list/speech_args)
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm
index f2fec3bb63..c049a7db33 100644
--- a/code/datums/brain_damage/mild.dm
+++ b/code/datums/brain_damage/mild.dm
@@ -68,18 +68,12 @@
lose_text = ""
/datum/brain_trauma/mild/speech_impediment/on_gain()
- owner.dna.add_mutation(UNINTELLIGIBLE)
- ..()
-
-//no fiddling with genetics to get out of this one
-/datum/brain_trauma/mild/speech_impediment/on_life()
- if(!(GLOB.mutations_list[UNINTELLIGIBLE] in owner.dna.mutations))
- on_gain()
- ..()
+ ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT)
+ . = ..()
/datum/brain_trauma/mild/speech_impediment/on_lose()
- owner.dna.remove_mutation(UNINTELLIGIBLE)
- ..()
+ REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, TRAUMA_TRAIT)
+ . = ..()
/datum/brain_trauma/mild/concussion
name = "Concussion"
diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm
index f65344af56..e445787498 100644
--- a/code/datums/brain_damage/phobia.dm
+++ b/code/datums/brain_damage/phobia.dm
@@ -82,16 +82,15 @@
break
return message
-/datum/brain_trauma/mild/phobia/on_say(message)
- if(HAS_TRAIT(owner, TRAIT_FEARLESS))
+/datum/brain_trauma/mild/phobia/handle_speech(datum/source, list/speech_args)
+ if(HAS_TRAIT(owner, TRAIT_FEARLESS))
return message
for(var/word in trigger_words)
var/reg = regex("(\\b|\\A)[REGEX_QUOTE(word)]'?s*(\\b|\\Z)", "i")
- if(findtext(message, reg))
+ if(findtext(speech_args[SPEECH_MESSAGE], reg))
to_chat(owner, "You can't bring yourself to say the word \"[word]\"!")
- return ""
- return message
+ speech_args[SPEECH_MESSAGE] = ""
/datum/brain_trauma/mild/phobia/proc/freak_out(atom/reason, trigger_word)
next_scare = world.time + 120
diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm
index 612af13392..653b8a98c0 100644
--- a/code/datums/brain_damage/split_personality.dm
+++ b/code/datums/brain_damage/split_personality.dm
@@ -199,10 +199,9 @@
addtimer(CALLBACK(src, /datum/brain_trauma/severe/split_personality.proc/switch_personalities), 10)
return message
-/datum/brain_trauma/severe/split_personality/brainwashing/on_say(message)
- if(findtext(message, codeword))
- return "" //oh hey did you want to tell people about the secret word to bring you back?
- return message
+/datum/brain_trauma/severe/split_personality/brainwashing/handle_speech(datum/source, list/speech_args)
+ if(findtext(speech_args[SPEECH_MESSAGE], codeword))
+ speech_args[SPEECH_MESSAGE] = "" //oh hey did you want to tell people about the secret word to bring you back?
/mob/living/split_personality/traitor
name = "split personality"
diff --git a/code/datums/components/bouncy.dm b/code/datums/components/bouncy.dm
new file mode 100644
index 0000000000..f6a2a89195
--- /dev/null
+++ b/code/datums/components/bouncy.dm
@@ -0,0 +1,40 @@
+/datum/component/bouncy
+ dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
+ var/bouncy_mod = 1
+ var/list/bounce_signals = list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_HIT_REACT, COMSIG_ITEM_ATTACK)
+
+/datum/component/bouncy/Initialize(_bouncy_mod, list/_bounce_signals)
+ if(!ismovableatom(parent))
+ return COMPONENT_INCOMPATIBLE
+ if(_bouncy_mod)
+ bouncy_mod = _bouncy_mod
+ if(_bounce_signals)
+ bounce_signals = _bounce_signals
+
+/datum/component/bouncy/InheritComponent(datum/component/bouncy/B, original, _bouncy_mod, list/_bounce_signals)
+ if(_bouncy_mod)
+ bouncy_mod = max(bouncy_mod, _bouncy_mod)
+ if(_bounce_signals)
+ var/list/diff_bounces = difflist(bounce_signals, _bounce_signals, TRUE)
+ for(var/bounce in diff_bounces)
+ bounce_signals += bounce
+ RegisterSignal(parent, bounce, .proc/bounce_up)
+
+/datum/component/bouncy/RegisterWithParent()
+ RegisterSignal(parent, bounce_signals, .proc/bounce_up)
+
+/datum/component/bouncy/UnregisterFromParent()
+ UnregisterSignal(parent, bounce_signals)
+
+/datum/component/bouncy/proc/bounce_up(datum/source)
+ var/atom/movable/A = parent
+ switch(rand(1, 3))
+ if(1)
+ A.do_jiggle(45 + rand(-10, 10) * bouncy_mod, 14)
+ if(2)
+ var/min_b = 0.6/bouncy_mod
+ var/max_b = 1.2 * bouncy_mod
+ A.do_squish(rand(min_b, max_b), rand(min_b, max_b), 14)
+ if(3)
+ var/pixelshift = 8 * bouncy_mod
+ A.Shake(pixelshift, pixelshift, duration = 15)
diff --git a/code/datums/diseases/pierrot_throat.dm b/code/datums/diseases/pierrot_throat.dm
index 64f453cd48..b2241d59ba 100644
--- a/code/datums/diseases/pierrot_throat.dm
+++ b/code/datums/diseases/pierrot_throat.dm
@@ -26,3 +26,30 @@
if(4)
if(prob(5))
affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat")
+
+/datum/disease/pierrot_throat/after_add()
+ RegisterSignal(affected_mob, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/disease/pierrot_throat/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ var/list/split_message = splittext(message, " ") //List each word in the message
+ var/applied = 0
+ for (var/i in 1 to length(split_message))
+ if(prob(3 * stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12%
+ if(findtext(split_message[i], "*") || findtext(split_message[i], ";") || findtext(split_message[i], ":"))
+ continue
+ split_message[i] = "HONK"
+ if (applied++ > stage)
+ break
+ if (applied)
+ speech_args[SPEECH_SPANS] |= SPAN_CLOWN // a little bonus
+ message = jointext(split_message, " ")
+ speech_args[SPEECH_MESSAGE] = message
+
+/datum/disease/pierrot_throat/Destroy()
+ UnregisterSignal(affected_mob, COMSIG_MOB_SAY)
+ return ..()
+
+/datum/disease/pierrot_throat/remove_disease()
+ UnregisterSignal(affected_mob, COMSIG_MOB_SAY)
+ return ..()
\ No newline at end of file
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index 938515625d..33e92e4de5 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -185,25 +185,6 @@
if(DNA_TAUR_BLOCK)
construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len)
-/datum/dna/proc/mutations_say_mods(message)
- if(message)
- for(var/datum/mutation/human/M in mutations)
- message = M.say_mod(message)
- return message
-
-/datum/dna/proc/mutations_get_spans()
- var/list/spans = list()
- for(var/datum/mutation/human/M in mutations)
- spans |= M.get_spans()
- return spans
-
-/datum/dna/proc/species_get_spans()
- var/list/spans = list()
- if(species)
- spans |= species.get_spans()
- return spans
-
-
/datum/dna/proc/is_same_as(datum/dna/D)
if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless && custom_species == D.custom_species)
if(species.type == D.species.type && features == D.features && blood_type == D.blood_type)
diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm
index 7de9ca8b4a..efa248b4f0 100644
--- a/code/datums/mutations.dm
+++ b/code/datums/mutations.dm
@@ -105,13 +105,6 @@ GLOBAL_LIST_EMPTY(mutations_list)
return 0
return 1
-/datum/mutation/human/proc/say_mod(message)
- if(message)
- return message
-
-/datum/mutation/human/proc/get_spans()
- return list()
-
/mob/living/carbon/proc/update_mutations_overlay()
return
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index 0c760f4620..85cecca489 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -15,6 +15,7 @@
ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
owner.update_body_parts()
SEND_SIGNAL(owner, COMSIG_ADD_MOOD_EVENT, "hulk", /datum/mood_event/hulk)
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
if(proximity) //no telekinetic hulk attack
@@ -32,8 +33,11 @@
REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK)
owner.update_body_parts()
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "hulk")
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
-/datum/mutation/human/hulk/say_mod(message)
+/datum/mutation/human/hulk/proc/handle_speech(original_message, wrapped_message)
+ var/message = wrapped_message[1]
if(message)
- message = "[uppertext(replacetext(message, ".", "!"))]!!"
- return message
+ message = "[replacetext(message, ".", "!")]!!"
+ wrapped_message[1] = message
+ return COMPONENT_UPPERCASE_SPEECH
diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm
index d986672924..21adc944f6 100644
--- a/code/datums/mutations/speech.dm
+++ b/code/datums/mutations/speech.dm
@@ -17,9 +17,20 @@
text_gain_indication = "You feel an off sensation in your voicebox."
text_lose_indication = "The off sensation passes."
-/datum/mutation/human/wacky/get_spans()
- return list(SPAN_SANS)
+/datum/mutation/human/wacky/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
+/datum/mutation/human/wacky/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
+
+/datum/mutation/human/wacky/proc/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_SANS
/datum/mutation/human/mute
name = "Mute"
@@ -28,12 +39,14 @@
text_lose_indication = "You feel able to speak freely again."
/datum/mutation/human/mute/on_acquiring(mob/living/carbon/human/owner)
- if(..())
+ . = ..()
+ if(.)
return
ADD_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION)
/datum/mutation/human/mute/on_losing(mob/living/carbon/human/owner)
- if(..())
+ . = ..()
+ if(.)
return
REMOVE_TRAIT(owner, TRAIT_MUTE, GENETIC_MUTATION)
@@ -45,7 +58,20 @@
text_gain_indication = "You feel so happy. Nothing can be wrong with anything. :)"
text_lose_indication = "Everything is terrible again. :("
-/datum/mutation/human/smile/say_mod(message)
+/datum/mutation/human/smile/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/mutation/human/smile/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
+
+/datum/mutation/human/smile/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
if(message)
message = " [message] "
//Time for a friendly game of SS13
@@ -92,7 +118,7 @@
message = replacetext(message," cunt "," privates ")
message = replacetext(message," dick "," jerk ")
message = replacetext(message," vagina "," privates ")
- return trim(message)
+ speech_args[SPEECH_MESSAGE] = trim(message)
/datum/mutation/human/unintelligible
@@ -102,30 +128,17 @@
text_gain_indication = "You can't seem to form any coherent thoughts!"
text_lose_indication = "Your mind feels more clear."
-/datum/mutation/human/unintelligible/say_mod(message)
- if(message)
- var/prefix=copytext(message,1,2)
- if(prefix == ";")
- message = copytext(message,2)
- else if(prefix in list(":","#"))
- prefix += copytext(message,2,3)
- message = copytext(message,3)
- else
- prefix=""
+/datum/mutation/human/unintelligible/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ ADD_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION)
- var/list/words = splittext(message," ")
- var/list/rearranged = list()
- for(var/i=1;i<=words.len;i++)
- var/cword = pick(words)
- words.Remove(cword)
- var/suffix = copytext(cword,length(cword)-1,length(cword))
- while(length(cword)>0 && suffix in list(".",",",";","!",":","?"))
- cword = copytext(cword,1 ,length(cword)-1)
- suffix = copytext(cword,length(cword)-1,length(cword) )
- if(length(cword))
- rearranged += cword
- message ="[prefix][jointext(rearranged," ")]"
- return message
+/datum/mutation/human/unintelligible/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ REMOVE_TRAIT(owner, TRAIT_UNINTELLIGIBLE_SPEECH, GENETIC_MUTATION)
/datum/mutation/human/swedish
@@ -135,7 +148,20 @@
text_gain_indication = "You feel Swedish, however that works."
text_lose_indication = "The feeling of Swedishness passes."
-/datum/mutation/human/swedish/say_mod(message)
+/datum/mutation/human/swedish/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/mutation/human/swedish/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
+
+/datum/mutation/human/swedish/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
if(message)
message = replacetext(message,"w","v")
message = replacetext(message,"j","y")
@@ -144,7 +170,7 @@
message = replacetext(message,"o",pick("�","�","o"))
if(prob(30))
message += " Bork[pick("",", bork",", bork, bork")]!"
- return message
+ speech_args[SPEECH_MESSAGE] = trim(message)
/datum/mutation/human/chav
@@ -154,7 +180,20 @@
text_gain_indication = "Ye feel like a reet prat like, innit?"
text_lose_indication = "You no longer feel like being rude and sassy."
-/datum/mutation/human/chav/say_mod(message)
+/datum/mutation/human/chav/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/mutation/human/chav/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
+
+/datum/mutation/human/chav/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
if(message)
message = " [message] "
message = replacetext(message," looking at "," gawpin' at ")
@@ -178,7 +217,7 @@
message = replacetext(message," break "," do ")
message = replacetext(message," your "," yer ")
message = replacetext(message," security "," coppers ")
- return trim(message)
+ speech_args[SPEECH_MESSAGE] = trim(message)
/datum/mutation/human/elvis
@@ -199,7 +238,20 @@
if(prob(15))
owner.visible_message("[owner] [pick("jiggles their hips", "rotates their hips", "gyrates their hips", "taps their foot", "dances to an imaginary song", "jiggles their legs", "snaps their fingers")]!")
-/datum/mutation/human/elvis/say_mod(message)
+/datum/mutation/human/elvis/on_acquiring(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ RegisterSignal(owner, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/mutation/human/elvis/on_losing(mob/living/carbon/human/owner)
+ . = ..()
+ if(.)
+ return
+ UnregisterSignal(owner, COMSIG_MOB_SAY)
+
+/datum/mutation/human/elvis/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
if(message)
message = " [message] "
message = replacetext(message," i'm not "," I aint ")
@@ -211,7 +263,7 @@
message = replacetext(message," yes ",pick(" sure", "yea "))
message = replacetext(message," faggot "," square ")
message = replacetext(message," muh valids "," getting my kicks ")
- return trim(message)
+ speech_args[SPEECH_MESSAGE] = trim(message)
/datum/mutation/human/stoner
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index f88f4f8e41..83762240bc 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -14,6 +14,7 @@
var/verb_exclaim = "exclaims"
var/verb_whisper = "whispers"
var/verb_yell = "yells"
+ var/speech_span
var/inertia_dir = 0
var/atom/inertia_last_loc
var/inertia_moving = 0
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index a24d846f15..94ca86e0dd 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -275,7 +275,7 @@ Credit where due:
gloves = /obj/item/clothing/gloves/color/yellow
belt = /obj/item/storage/belt/utility/servant
backpack_contents = list(/obj/item/storage/box/engineer = 1, \
- /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1)
+ /obj/item/clockwork/replica_fabricator = 1, /obj/item/stack/tile/brass/fifty = 1, /obj/item/paper/servant_primer = 1, /obj/item/reagent_containers/food/drinks/holyoil = 1)
id = /obj/item/pda
var/plasmaman //We use this to determine if we should activate internals in post_equip()
@@ -338,6 +338,10 @@ Credit where due:
CLOCKCULTCHANGELOG\
\
\
+ Zelus oil: A new reagent. It can be used to heal the faithful to Ratvar, or kill heretics and moreso stun blood cultists,\
+ or splashed onto metal sheets to make brass. This chemical can be found in minimal quantities by grinding brass sheets.\
+ Brass Flasks:Intended to store Zelus Oil in, but can also be used as fragile single use throwing weapons in a pinch! \
+ These are crafted with a single sheet of brass and fit in the Clockwork Cuirass' suit storage.\
Good luck!"
/obj/item/paper/servant_primer/Initialize()
diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm
index 959bcfab4d..884b818f32 100644
--- a/code/game/machinery/announcement_system.dm
+++ b/code/game/machinery/announcement_system.dm
@@ -96,10 +96,10 @@ GLOBAL_LIST_EMPTY(announcement_systems)
message = "The arrivals shuttle has been damaged. Docking for repairs..."
if(channels.len == 0)
- radio.talk_into(src, message, null, list(SPAN_ROBOT), get_default_language())
+ radio.talk_into(src, message, null)
else
for(var/channel in channels)
- radio.talk_into(src, message, channel, list(SPAN_ROBOT), get_default_language())
+ radio.talk_into(src, message, channel)
//config stuff
diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm
index c751ba007a..71dcb89ce7 100644
--- a/code/game/machinery/bank_machine.dm
+++ b/code/game/machinery/bank_machine.dm
@@ -49,12 +49,9 @@
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
- radio.talk_into(src, message, radio_channel, get_spans())
+ radio.talk_into(src, message, radio_channel)
next_warning = world.time + minimum_time_between_warnings
-/obj/machinery/computer/bank_machine/get_spans()
- . = ..() | SPAN_ROBOT
-
/obj/machinery/computer/bank_machine/ui_interact(mob/user)
. = ..()
var/dat = "[station_name()] secure vault. Authorized personnel only.
"
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index 36a5c6ede4..ba9b6fc225 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -6,7 +6,7 @@
#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical
#define MINIMUM_HEAL_LEVEL 40
-#define SPEAK(message) radio.talk_into(src, message, radio_channel, get_spans(), get_default_language())
+#define SPEAK(message) radio.talk_into(src, message, radio_channel)
/obj/machinery/clonepod
name = "cloning pod"
diff --git a/code/game/machinery/computer/arcade/minesweeper.dm b/code/game/machinery/computer/arcade/minesweeper.dm
index fe69860f76..e90e05966c 100644
--- a/code/game/machinery/computer/arcade/minesweeper.dm
+++ b/code/game/machinery/computer/arcade/minesweeper.dm
@@ -250,11 +250,11 @@
itemname = "a syndicate bomb beacon"
new /obj/item/sbeacondrop/bomb(loc)
if(2)
- itemname = "a grenade launcher"
- new /obj/item/gun/ballistic/revolver/grenadelauncher/unrestricted(loc)
- new /obj/item/ammo_casing/a40mm(loc)
- new /obj/item/ammo_casing/a40mm(loc)
- new /obj/item/ammo_casing/a40mm(loc)
+ itemname = "a rocket launcher"
+ new /obj/item/gun/ballistic/rocketlauncher/unrestricted(loc)
+ new /obj/item/ammo_casing/caseless/rocket(loc)
+ new /obj/item/ammo_casing/caseless/rocket(loc)
+ new /obj/item/ammo_casing/caseless/rocket(loc)
if(3)
itemname = "two bags of c4"
new /obj/item/storage/backpack/duffelbag/syndie/c4(loc)
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index f2c216ca98..ad9a846bdc 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -323,7 +323,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
emergency = "Medical"
if(radio_freq)
Radio.set_frequency(radio_freq)
- Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq,get_spans(),get_default_language())
+ Radio.talk_into(src,"[emergency] emergency in [department]!!",radio_freq)
update_icon()
addtimer(CALLBACK(src, .proc/clear_emergency), 3000)
@@ -382,7 +382,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
screen = 6
if(radio_freq)
- Radio.talk_into(src,"[alert]: [message]",radio_freq,get_spans(),get_default_language())
+ Radio.talk_into(src, "[alert]: [message]", radio_freq)
switch(priority)
if(2)
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 93e87a82a4..bdb949a570 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -120,6 +120,33 @@
loot = GLOB.maintenance_loot
. = ..()
+/obj/effect/spawner/lootdrop/glowstick
+ name = "random colored glowstick"
+ icon = 'icons/obj/lighting.dmi'
+ icon_state = "random_glowstick"
+
+/obj/effect/spawner/lootdrop/glowstick/Initialize()
+ loot = typesof(/obj/item/flashlight/glowstick)
+ . = ..()
+
+
+/obj/effect/spawner/lootdrop/gloves
+ name = "random gloves"
+ desc = "These gloves are supposed to be a random color..."
+ icon = 'icons/obj/clothing/gloves.dmi'
+ icon_state = "random_gloves"
+ loot = list(
+ /obj/item/clothing/gloves/color/orange = 1,
+ /obj/item/clothing/gloves/color/red = 1,
+ /obj/item/clothing/gloves/color/blue = 1,
+ /obj/item/clothing/gloves/color/purple = 1,
+ /obj/item/clothing/gloves/color/green = 1,
+ /obj/item/clothing/gloves/color/grey = 1,
+ /obj/item/clothing/gloves/color/light_brown = 1,
+ /obj/item/clothing/gloves/color/brown = 1,
+ /obj/item/clothing/gloves/color/white = 1,
+ /obj/item/clothing/gloves/color/rainbow = 1)
+
/obj/effect/spawner/lootdrop/crate_spawner
name = "lootcrate spawner" //USE PROMO CODE "SELLOUT" FOR 20% OFF!
lootdoubles = FALSE
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 2af7be2564..cb979e8188 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -230,9 +230,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
research_msg += "."
to_chat(user, research_msg.Join())
-/obj/item/proc/speechModification(message) //for message modding by mask slot.
- return message
-
/obj/item/interact(mob/user)
add_fingerprint(user)
ui_interact(user)
@@ -647,11 +644,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
else
. = ""
-
-//when an item modify our speech spans when in our active hand. Override this to modify speech spans.
-/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user)
- return
-
/obj/item/hitby(atom/movable/AM)
return
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index d8b539ac27..722510dccb 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -512,17 +512,6 @@
name = "pink glowstick"
color = LIGHT_COLOR_PINK
-/obj/item/flashlight/glowstick/random
- name = "random colored glowstick"
- icon_state = "random_glowstick"
- color = null
-
-/obj/item/flashlight/glowstick/random/Initialize()
- ..()
- var/T = pick(typesof(/obj/item/flashlight/glowstick) - /obj/item/flashlight/glowstick/random)
- new T(loc)
- return INITIALIZE_HINT_QDEL
-
/obj/item/flashlight/spotlight //invisible lighting source
name = "disco light"
desc = "Groovy..."
diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm
index 661d38ce6b..5894b559ae 100644
--- a/code/game/objects/items/devices/instruments.dm
+++ b/code/game/objects/items/devices/instruments.dm
@@ -234,11 +234,18 @@
w_class = WEIGHT_CLASS_SMALL
actions_types = list(/datum/action/item_action/instrument)
-/obj/item/instrument/harmonica/speechModification(message)
+/obj/item/instrument/harmonica/proc/handle_speech(datum/source, list/speech_args)
if(song.playing && ismob(loc))
to_chat(loc, "You stop playing the harmonica to talk...")
song.playing = FALSE
- return message
+
+/obj/item/instrument/harmonica/equipped(mob/M, slot)
+ . = ..()
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/obj/item/instrument/harmonica/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/instrument/bikehorn
name = "gilded bike horn"
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 4b244e3002..347bb6894d 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -17,13 +17,25 @@
user.say("AAAAAAAAAAAARGHHHHH", forced="megaphone suicide")//he must have died while coding this
return OXYLOSS
-/obj/item/megaphone/get_held_item_speechspans(mob/living/carbon/user)
- if(spamcheck > world.time)
- to_chat(user, "\The [src] needs to recharge!")
+/obj/item/megaphone/equipped(mob/M, slot)
+ . = ..()
+ if (slot == SLOT_HANDS)
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
else
- playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1)
- spamcheck = world.time + 50
- return voicespan
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+
+/obj/item/megaphone/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+
+/obj/item/megaphone/proc/handle_speech(mob/living/carbon/user, list/speech_args)
+ if (user.get_active_held_item() == src)
+ if(spamcheck > world.time)
+ to_chat(user, "\The [src] needs to recharge!")
+ else
+ playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1)
+ spamcheck = world.time + 50
+ speech_args[SPEECH_SPANS] |= voicespan
/obj/item/megaphone/emag_act(mob/user)
if(obj_flags & EMAGGED)
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 2ab365d9f7..1d51aabf86 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -189,7 +189,7 @@
/obj/item/radio/talk_into(atom/movable/M, message, channel, list/spans, datum/language/language)
if(!spans)
- spans = M.get_spans()
+ spans = list(M.speech_span)
if(!language)
language = M.get_default_language()
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans.Copy(), language)
diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index 34ce6bc521..62c41f7155 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -282,9 +282,7 @@
var/obj/item/clothing/mask/horsehead/magichead = new /obj/item/clothing/mask/horsehead
magichead.item_flags |= NODROP //curses!
magichead.flags_inv &= ~HIDEFACE //so you can still see their face
- magichead.voicechange = TRUE //NEEEEIIGHH
- if(!user.dropItemToGround(user.wear_mask))
- qdel(user.wear_mask)
+ user.dropItemToGround(user.wear_mask, TRUE)
user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE)
qdel(src)
else
diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm
index 49a5cfaf35..f9d00b6213 100644
--- a/code/game/objects/items/his_grace.dm
+++ b/code/game/objects/items/his_grace.dm
@@ -8,7 +8,7 @@
name = "artistic toolbox"
desc = "A toolbox painted bright green. Looking at it makes you feel uneasy."
icon_state = "his_grace"
- item_state = "artistic_toolbox"
+ item_state = "toolbox_green"
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
icon = 'icons/obj/items_and_weapons.dmi'
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 44ccd7aad5..7524fc9007 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -15,7 +15,7 @@
var/mopping = 0
var/mopcount = 0
var/mopcap = 5
- var/stamusage = 5
+ var/stamusage = 2
force_string = "robust... against germs"
var/insertable = TRUE
@@ -94,7 +94,7 @@
force = 6
throwforce = 8
throw_range = 4
- stamusage = 2
+ stamusage = 1
var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water.
var/refill_rate = 1 //Rate per process() tick mop refills itself
var/refill_reagent = "water" //Determins what reagent to use for refilling, just in case someone wanted to make a HOLY MOP OF PURGING
diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm
index c93c79a25d..b5bb4fa233 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -578,10 +578,6 @@
icon_state = "vulken"
item_state = "vulken"
-/obj/item/toy/plush/snakeplushie/jecca
- icon_state = "jecca"
- item_state = "jecca"
-
/obj/item/toy/plush/nukeplushie
name = "operative plushie"
desc = "A stuffed toy that resembles a syndicate nuclear operative. The tag claims operatives to be purely fictitious."
@@ -634,13 +630,9 @@
/obj/item/toy/plush/mothplushie
name = "insect plushie"
desc = "An adorable stuffed toy that resembles some kind of insect"
- icon_state = "cydia"
- item_state = "cydia"
- squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1)
-
-/obj/item/toy/plush/mothplushie/bumble
icon_state = "bumble"
item_state = "bumble"
+ squeak_override = list('modular_citadel/sound/voice/mothsqueak.ogg' = 1)
/obj/item/toy/plush/mothplushie/nameko
icon_state = "nameko"
diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm
index a9f0e038df..15127c2e0e 100644
--- a/code/game/objects/items/shields.dm
+++ b/code/game/objects/items/shields.dm
@@ -159,11 +159,13 @@
armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80)
lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi'
- item_state = "makeshift_shield"
+ icon = 'icons/obj/items_and_weapons.dmi'
+ item_state = "metal"
+ icon_state = "makeshift_shield"
materials = list(MAT_METAL = 18000)
slot_flags = null
- block_chance = 25
- force = 5
+ block_chance = 35
+ force = 10
throwforce = 7
/obj/item/shield/riot/tower
@@ -171,8 +173,11 @@
desc = "A massive shield that can block a lot of attacks, can take a lot of abuse before braking."
armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user
item_state = "metal"
+ icon_state = "metal"
+ icon = 'icons/obj/items_and_weapons.dmi'
block_chance = 75 //1/4 shots will hit*
- force = 10
+ force = 16
slowdown = 2
throwforce = 15 //Massive pice of metal
w_class = WEIGHT_CLASS_HUGE
+ item_flags = SLOWS_WHILE_IN_HAND
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index b17bc87ffd..e1ecf6d14d 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -424,6 +424,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("receiver - brass skewer", /obj/structure/destructible/clockwork/trap/brass_skewer, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_ADJACENT), \
new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
+ null,
+ new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/holyoil/null), \
))
@@ -441,7 +443,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
throw_range = 3
turf_type = /turf/open/floor/clockwork
novariants = FALSE
- grind_results = list("iron" = 5, "teslium" = 15)
+ grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1)
merge_type = /obj/item/stack/tile/brass
/obj/item/stack/tile/brass/narsie_act()
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index b2313969f0..5b99bb85bf 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -1,3 +1,5 @@
+GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
+
/obj/item/storage/toolbox
name = "toolbox"
desc = "Danger. Very robust."
@@ -16,21 +18,25 @@
hitsound = 'sound/weapons/smash.ogg'
var/latches = "single_latch"
var/has_latches = TRUE
+ var/can_rubberify = TRUE
-/obj/item/storage/toolbox/Initialize()
+/obj/item/storage/toolbox/Initialize(mapload)
. = ..()
if(has_latches)
if(prob(10))
latches = "double_latch"
if(prob(1))
latches = "triple_latch"
+ if(mapload && can_rubberify && prob(5))
+ rubberify()
update_icon()
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
if(has_latches)
- add_overlay(latches)
+ var/icon/I = icon('icons/obj/storage.dmi', latches)
+ add_overlay(I)
/obj/item/storage/toolbox/suicide_act(mob/user)
@@ -39,8 +45,6 @@
/obj/item/storage/toolbox/emergency
name = "emergency toolbox"
- icon_state = "red"
- item_state = "toolbox_red"
/obj/item/storage/toolbox/emergency/PopulateContents()
new /obj/item/crowbar/red(src)
@@ -59,6 +63,7 @@
name = "rusty red toolbox"
icon_state = "toolbox_red_old"
has_latches = FALSE
+ can_rubberify = FALSE
/obj/item/storage/toolbox/mechanical
name = "mechanical toolbox"
@@ -77,6 +82,7 @@
name = "rusty blue toolbox"
icon_state = "toolbox_blue_old"
has_latches = FALSE
+ can_rubberify = FALSE
/obj/item/storage/toolbox/mechanical/old/heirloom
name = "old, robust toolbox" //this will be named "X family toolbox"
@@ -151,6 +157,7 @@
resistance_flags = FIRE_PROOF | ACID_PROOF
w_class = WEIGHT_CLASS_HUGE
attack_verb = list("robusted", "crushed", "smashed")
+ can_rubberify = FALSE
var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab
/obj/item/storage/toolbox/brass/ComponentInitialize()
@@ -191,6 +198,7 @@
item_state = "toolbox_blue"
w_class = WEIGHT_CLASS_HUGE //heyo no bohing this!
force = 18 //spear damage
+ can_rubberify = FALSE
/obj/item/storage/toolbox/plastitanium/afterattack(atom/A, mob/user, proximity)
. = ..()
@@ -204,7 +212,7 @@
name = "artistic toolbox"
desc = "A toolbox painted bright green. Why anyone would store art supplies in a toolbox is beyond you, but it has plenty of extra space."
icon_state = "green"
- item_state = "artistic_toolbox"
+ item_state = "toolbox_green"
w_class = WEIGHT_CLASS_GIGANTIC //Holds more than a regular toolbox!
/obj/item/storage/toolbox/artistic/ComponentInitialize()
@@ -253,9 +261,55 @@
/obj/item/storage/toolbox/gold_fake // used in crafting
name = "golden toolbox"
- desc = "A gold plated toolbox, fancy and harmless do to the gold plating being on cardboard!"
+ desc = "A gold plated toolbox, fancy and harmless due to the gold plating being on cardboard!"
icon_state = "gold"
item_state = "gold"
has_latches = FALSE
force = 0
throwforce = 0
+ can_rubberify = FALSE
+
+/obj/item/storage/toolbox/proc/rubberify()
+ name = "rubber [name]"
+ desc = replacetext(desc, "Danger", "Bouncy")
+ desc = replacetext(desc, "robust", "safe")
+ desc = replacetext(desc, "heavier", "bouncier")
+ DISABLE_BITFIELD(flags_1, CONDUCT_1)
+ materials = null
+ damtype = STAMINA
+ force += 3 //to compensate the higher stamina K.O. threshold compared to actual health.
+ throwforce += 3
+ attack_verb += "bounced"
+ hitsound = 'sound/effects/clownstep1.ogg'
+ if(!GLOB.rubber_toolbox_icons[icon_state])
+ generate_rubber_toolbox_icon()
+ icon = GLOB.rubber_toolbox_icons[icon_state]
+ AddComponent(/datum/component/bouncy)
+ . = ..()
+
+/obj/item/storage/toolbox/proc/generate_rubber_toolbox_icon()
+ var/icon/new_icon = icon(icon, icon_state)
+ var/icon/smooth = icon('icons/obj/storage.dmi', "rubber_toolbox_blend")
+ new_icon.Blend(smooth, ICON_MULTIPLY)
+ new_icon = fcopy_rsc(new_icon)
+ GLOB.rubber_toolbox_icons[icon_state] = new_icon
+
+/obj/item/storage/toolbox/rubber
+ name = "rubber toolbox"
+ desc = "Bouncy. Very safe."
+ flags_1 = null
+ materials = null
+ damtype = STAMINA
+ force = 17
+ throwforce = 17
+ attack_verb = list("robusted", "bounced")
+ can_rubberify = FALSE //we are already the future.
+
+/obj/item/storage/toolbox/rubber/Initialize()
+ icon_state = pick("blue", "red", "yellow", "green")
+ item_state = "toolbox_[icon_state]"
+ if(!GLOB.rubber_toolbox_icons[icon_state])
+ generate_rubber_toolbox_icon()
+ icon = GLOB.rubber_toolbox_icons[icon_state]
+ . = ..()
+ AddComponent(/datum/component/bouncy)
\ No newline at end of file
diff --git a/code/game/objects/items/taster.dm b/code/game/objects/items/taster.dm
index 8363c63c2c..3828beb921 100644
--- a/code/game/objects/items/taster.dm
+++ b/code/game/objects/items/taster.dm
@@ -6,10 +6,9 @@
w_class = WEIGHT_CLASS_TINY
- var/taste_sensitivity = 15
+ speech_span = null
-/obj/item/taster/get_spans()
- return list()
+ var/taste_sensitivity = 15
/obj/item/taster/afterattack(atom/O, mob/user, proximity)
. = ..()
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 274afe15e0..9239973247 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -294,7 +294,7 @@
name = "windup toolbox"
desc = "A replica toolbox that rumbles when you turn the key."
icon_state = "his_grace"
- item_state = "artistic_toolbox"
+ item_state = "toolbox_green"
lefthand_file = 'icons/mob/inhands/equipment/toolbox_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi'
var/active = FALSE
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 2db2cd08d8..70a05a8d40 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -48,7 +48,12 @@
/obj/hitby(atom/movable/AM)
..()
- take_damage(AM.throwforce, BRUTE, "melee", 1, get_dir(src, AM))
+ var/throwdamage = AM.throwforce
+ if(isobj(AM))
+ var/obj/O = AM
+ if(O.damtype == STAMINA)
+ throwdamage = 0
+ take_damage(throwdamage, BRUTE, "melee", 1, get_dir(src, AM))
/obj/ex_act(severity, target)
if(resistance_flags & INDESTRUCTIBLE)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index fd6a9f2141..6dd8a43130 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -2,6 +2,7 @@
/obj
var/crit_fail = FALSE
animate_movement = 2
+ speech_span = SPAN_ROBOT
var/obj_flags = CAN_BE_HIT
var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT.
@@ -204,9 +205,6 @@
if(!anchored || current_size >= STAGE_FIVE)
step_towards(src,S)
-/obj/get_spans()
- return ..() | SPAN_ROBOT
-
/obj/get_dumping_location(datum/component/storage/source,mob/user)
return get_turf(src)
diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm
index 964f60cb73..1ab28a33de 100644
--- a/code/game/objects/structures/barsigns.dm
+++ b/code/game/objects/structures/barsigns.dm
@@ -294,6 +294,16 @@
icon = "the_lightbulb"
desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms."
+/datum/barsign/cybersylph
+ name = "Cyber Sylph's"
+ icon = "cybersylph"
+ desc = "A cafe renowed for its out-of-boundaries futuristic insignia."
+
+/datum/barsign/meow_mix
+ name = "Meow Mix"
+ icon = "meow_mix"
+ desc = "No, we don't serve catnip, officer!"
+
/datum/barsign/hiddensigns
hidden = TRUE
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 6fac5da2a5..00d1690d86 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -262,7 +262,7 @@
if(isobj(AM))
if(prob(50) && anchored && !broken)
var/obj/O = AM
- if(O.throwforce != 0)//don't want to let people spam tesla bolts, this way it will break after time
+ if(O.throwforce != 0 && O.damtype != STAMINA)//don't want to let people spam tesla bolts, this way it will break after time
var/turf/T = get_turf(src)
var/obj/structure/cable/C = T.get_cable_node()
if(C)
diff --git a/code/game/say.dm b/code/game/say.dm
index e797fe5e64..4ce1d3c710 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -23,7 +23,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
return
if(message == "" || !message)
return
- spans |= get_spans()
+ spans |= speech_span
if(!language)
language = get_default_language()
send_speech(message, 7, src, , spans, message_language=language)
@@ -40,10 +40,6 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/atom/movable/AM = _AM
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
-//To get robot span classes, stuff like that.
-/atom/movable/proc/get_spans()
- return list()
-
/atom/movable/proc/compose_message(atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, face_name = FALSE)
//This proc uses text() because it is faster than appending strings. Thanks BYOND.
//Basic span
@@ -87,7 +83,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
else
return verb_say
-/atom/movable/proc/say_quote(input, list/spans=list(), message_mode)
+/atom/movable/proc/say_quote(input, list/spans=list(speech_span), message_mode)
if(!input)
input = "..."
diff --git a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
index e60209cb7b..3cb90d64bb 100644
--- a/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
+++ b/code/modules/antagonists/blob/blob/blobs/blob_mobs.dm
@@ -57,7 +57,7 @@
return ..()
/mob/living/simple_animal/hostile/blob/proc/blob_chat(msg)
- var/spanned_message = say_quote(msg, get_spans())
+ var/spanned_message = say_quote(msg)
var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]"
for(var/M in GLOB.mob_list)
if(isovermind(M) || istype(M, /mob/living/simple_animal/hostile/blob))
diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm
index ddf745c0f9..d32e38c194 100644
--- a/code/modules/antagonists/blob/blob/overmind.dm
+++ b/code/modules/antagonists/blob/blob/overmind.dm
@@ -210,7 +210,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
src.log_talk(message, LOG_SAY)
- var/message_a = say_quote(message, get_spans())
+ var/message_a = say_quote(message)
var/rendered = "\[Blob Telepathy\] [name]([blob_reagent_datum.name]) [message_a]"
for(var/mob/M in GLOB.mob_list)
diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
index 277aeca48d..4956a756e9 100644
--- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
@@ -69,7 +69,7 @@
heat_protection = CHEST|GROIN|LEGS
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list("melee" = 60, "bullet" = 70, "laser" = -25, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
- allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel)
+ allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/holyoil)
/obj/item/clothing/suit/armor/clockwork/Initialize()
. = ..()
diff --git a/code/modules/antagonists/clockcult/clock_mobs.dm b/code/modules/antagonists/clockcult/clock_mobs.dm
index bd9c52b19f..6268d15d44 100644
--- a/code/modules/antagonists/clockcult/clock_mobs.dm
+++ b/code/modules/antagonists/clockcult/clock_mobs.dm
@@ -19,6 +19,7 @@
bubble_icon = "clock"
light_color = "#E42742"
death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg'
+ speech_span = SPAN_ROBOT
var/playstyle_string = "You are a bug, yell at whoever spawned you!"
var/empower_string = "You have nothing to empower, yell at the coders!" //Shown to the mob when the herald beacon activates
@@ -26,9 +27,6 @@
. = ..()
update_values()
-/mob/living/simple_animal/hostile/clockwork/get_spans()
- return ..() | SPAN_ROBOT
-
/mob/living/simple_animal/hostile/clockwork/Login()
..()
add_servant_of_ratvar(src, TRUE)
diff --git a/code/modules/antagonists/swarmer/swarmer.dm b/code/modules/antagonists/swarmer/swarmer.dm
index 0a4a82b862..9fb2c3e2b7 100644
--- a/code/modules/antagonists/swarmer/swarmer.dm
+++ b/code/modules/antagonists/swarmer/swarmer.dm
@@ -100,6 +100,7 @@
deathmessage = "explodes with a sharp pop!"
light_color = LIGHT_COLOR_CYAN
hud_type = /datum/hud/swarmer
+ speech_span = SPAN_ROBOT
var/resources = 0 //Resource points, generated by consuming metal/glass
var/max_resources = 100
@@ -126,9 +127,6 @@
if(statpanel("Status"))
stat("Resources:",resources)
-/mob/living/simple_animal/hostile/swarmer/get_spans()
- return ..() | SPAN_ROBOT
-
/mob/living/simple_animal/hostile/swarmer/emp_act()
. = ..()
if(. & EMP_PROTECT_SELF)
@@ -666,7 +664,7 @@
set_light(0)
/mob/living/simple_animal/hostile/swarmer/proc/swarmer_chat(msg)
- var/rendered = "Swarm communication - [src] [say_quote(msg, get_spans())]"
+ var/rendered = "Swarm communication - [src] [say_quote(msg)]"
for(var/i in GLOB.mob_list)
var/mob/M = i
if(isswarmer(M))
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index bfe60cd573..552b9dbd64 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -167,10 +167,11 @@
on = FALSE
update_icon()
playsound(src, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors.
- radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language())
+ var/msg = "Patient fully restored."
if(autoeject) // Eject if configured.
- radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language())
+ msg += " Auto ejecting patient now."
open_machine()
+ radio.talk_into(src, msg, radio_channel)
return
var/datum/gas_mixture/air1 = airs[1]
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index 0cd96eaebc..e95a836a0d 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -32,7 +32,7 @@
. = ..()
siemens_coefficient = pick(0,0,0,0.5,0.5,0.5,0.75)
-/obj/item/clothing/gloves/cut
+/obj/item/clothing/gloves/cut
desc = "These gloves would protect the wearer from electric shock.. if the fingers were covered."
name = "fingerless insulated gloves"
icon_state = "yellowcut"
@@ -218,32 +218,3 @@
/obj/item/clothing/gloves/color/white/redcoat
item_color = "redcoat" //Exists for washing machines. Is not different from white gloves in any way.
-
-/obj/item/clothing/gloves/color/random
- name = "random gloves"
- desc = "These gloves are supposed to be a random color..."
- icon_state = "random_gloves"
- item_state = "wgloves"
- item_color = "mime"
-
-/obj/item/clothing/gloves/color/random/Initialize()
- ..()
- var/list/gloves = list(
- /obj/item/clothing/gloves/color/orange = 1,
- /obj/item/clothing/gloves/color/red = 1,
- /obj/item/clothing/gloves/color/blue = 1,
- /obj/item/clothing/gloves/color/purple = 1,
- /obj/item/clothing/gloves/color/green = 1,
- /obj/item/clothing/gloves/color/grey = 1,
- /obj/item/clothing/gloves/color/light_brown = 1,
- /obj/item/clothing/gloves/color/brown = 1,
- /obj/item/clothing/gloves/color/white = 1,
- /obj/item/clothing/gloves/color/rainbow = 1)
-
- var/obj/item/clothing/gloves/color/selected = pick(gloves)
- if(ishuman(loc))
- var/mob/living/carbon/human/H = loc
- H.equip_to_slot_or_del(new selected(H), SLOT_GLOVES)
- else
- new selected(loc)
- return INITIALIZE_HINT_QDEL
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 0f7766e364..429401a626 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -186,33 +186,41 @@
mode = DRILL_CANADIAN
return TRUE
-/obj/item/clothing/head/warden/drill/speechModification(M)
- if(copytext(M, 1, 2) != "*")
- if(mode == DRILL_DEFAULT)
- M = " [M]"
- return trim(M)
- if(mode == DRILL_SHOUTING)
- M = " [M]!"
- return trim(M)
- if(mode == DRILL_YELLING)
- M = " [M]!!"
- return trim(M)
- if(mode == DRILL_CANADIAN)
- M = " [M]"
- var/list/canadian_words = strings("canadian_replacement.json", "canadian")
+/obj/item/clothing/head/warden/drill/equipped(mob/M, slot)
+ . = ..()
+ if (slot == SLOT_HEAD)
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+ else
+ UnregisterSignal(M, COMSIG_MOB_SAY)
- for(var/key in canadian_words)
- var/value = canadian_words[key]
- if(islist(value))
- value = pick(value)
+/obj/item/clothing/head/warden/drill/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, COMSIG_MOB_SAY)
- M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
- M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
- M = replacetextEx(M, " [key]", " [value]")
+/obj/item/clothing/head/warden/drill/proc/handle_speech(datum/source, mob/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
+ switch (mode)
+ if(DRILL_SHOUTING)
+ message += "!"
+ if(DRILL_YELLING)
+ message += "!!"
+ if(DRILL_CANADIAN)
+ message = " [message]"
+ var/list/canadian_words = strings("canadian_replacement.json", "canadian")
- if(prob(30))
- M += pick(", eh?", ", EH?")
- return trim(M)
+ for(var/key in canadian_words)
+ var/value = canadian_words[key]
+ if(islist(value))
+ value = pick(value)
+
+ message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
+ message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
+ message = replacetextEx(message, " [key]", " [value]")
+
+ if(prob(30))
+ message += pick(", eh?", ", EH?")
+ speech_args[SPEECH_MESSAGE] = message
/obj/item/clothing/head/beret/sec
name = "security beret"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index d9c151a47b..277ce2a8ad 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -330,9 +330,21 @@
icon_state = "beretblack"
dynamic_hair_suffix = ""
-/obj/item/clothing/head/frenchberet/speechModification(M)
- if(copytext(M, 1, 2) != "*")
- M = " [M]"
+/obj/item/clothing/head/frenchberet/equipped(mob/M, slot)
+ . = ..()
+ if (slot == SLOT_HEAD)
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+ else
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+
+/obj/item/clothing/head/frenchberet/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+
+/obj/item/clothing/head/frenchberet/proc/handle_speech(datum/source, mob/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
+ message = " [message]"
var/list/french_words = strings("french_replacement.json", "french")
for(var/key in french_words)
@@ -340,10 +352,10 @@
if(islist(value))
value = pick(value)
- M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
- M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
- M = replacetextEx(M, " [key]", " [value]")
+ message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
+ message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
+ message = replacetextEx(message, " [key]", " [value]")
if(prob(3))
- M += pick(" Honh honh honh!"," Honh!"," Zut Alors!")
- return trim(M)
+ message += pick(" Honh honh honh!"," Honh!"," Zut Alors!")
+ speech_args[SPEECH_MESSAGE] = trim(message)
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index 8f10184f86..9ee2ebcd54 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -5,12 +5,54 @@
slot_flags = ITEM_SLOT_MASK
strip_delay = 40
equip_delay_other = 40
+ var/modifies_speech = FALSE
var/mask_adjusted = 0
var/adjusted_flags = null
var/muzzle_var = NORMAL_STYLE
mutantrace_variation = NO_MUTANTRACE_VARIATION //most masks have overrides, but not all probably.
+/obj/item/clothing/mask/attack_self(mob/user)
+ if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
+ TOGGLE_BITFIELD(clothing_flags, VOICEBOX_DISABLED)
+ var/status = !CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED)
+ to_chat(user, "You turn the voice box in [src] [status ? "on" : "off"].")
+
+/obj/item/clothing/mask/equipped(mob/M, slot)
+ . = ..()
+ if (slot == SLOT_WEAR_MASK && modifies_speech)
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+ else
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+ if(!ishuman(M))
+ return
+ var/mob/living/carbon/human/H = M
+ var/datum/species/pref_species = H.dna.species
+
+ if(mutantrace_variation)
+ if("mam_snouts" in pref_species.default_features)
+ if(H.dna.features["mam_snouts"] != "None")
+ muzzle_var = ALT_STYLE
+ else
+ muzzle_var = NORMAL_STYLE
+
+ else if("snout" in pref_species.default_features)
+ if(H.dna.features["snout"] != "None")
+ muzzle_var = ALT_STYLE
+ else
+ muzzle_var = NORMAL_STYLE
+
+ else
+ muzzle_var = NORMAL_STYLE
+
+ H.update_inv_wear_mask()
+
+/obj/item/clothing/mask/dropped(mob/M)
+ . = ..()
+ UnregisterSignal(M, COMSIG_MOB_SAY)
+
+/obj/item/clothing/mask/proc/handle_speech()
+
/obj/item/clothing/mask/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
@@ -20,31 +62,6 @@
IF_HAS_BLOOD_DNA(src)
. += mutable_appearance('icons/effects/blood.dmi', "maskblood")
-/obj/item/clothing/mask/equipped(mob/user, slot)
- ..()
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- var/datum/species/pref_species = H.dna.species
-
- if(mutantrace_variation)
- if("mam_snouts" in pref_species.default_features)
- if(H.dna.features["mam_snouts"] != "None")
- muzzle_var = ALT_STYLE
- else
- muzzle_var = NORMAL_STYLE
-
- else if("snout" in pref_species.default_features)
- if(H.dna.features["snout"] != "None")
- muzzle_var = ALT_STYLE
- else
- muzzle_var = NORMAL_STYLE
-
- else
- muzzle_var = NORMAL_STYLE
-
- H.update_inv_wear_mask()
-
-
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
..()
if(ismob(loc))
diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm
index c0752d9799..3960bdadeb 100644
--- a/code/modules/clothing/masks/boxing.dm
+++ b/code/modules/clothing/masks/boxing.dm
@@ -20,9 +20,11 @@
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
w_class = WEIGHT_CLASS_SMALL
mutantrace_variation = MUTANTRACE_VARIATION
+ modifies_speech = TRUE
-/obj/item/clothing/mask/luchador/speechModification(message)
- if(copytext(message, 1, 2) != "*")
+/obj/item/clothing/mask/luchador/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
message = replacetext(message, "captain", "CAPITÁN")
message = replacetext(message, "station", "ESTACIÓN")
message = replacetext(message, "sir", "SEÑOR")
@@ -42,7 +44,7 @@
message = uppertext(message) //Things end up looking better this way (no mixed cases), and it fits the macho wrestler image.
if(prob(25))
message += " OLE!"
- return message
+ speech_args[SPEECH_MESSAGE] = message
/obj/item/clothing/mask/luchador/tecnicos
name = "Tecnicos Mask"
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index 9476c50603..1716992e45 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -46,10 +46,12 @@
/obj/item/clothing/mask/fakemoustache/italian
name = "italian moustache"
desc = "Made from authentic Italian moustache hairs. Gives the wearer an irresistable urge to gesticulate wildly."
+ modifies_speech = TRUE
-/obj/item/clothing/mask/fakemoustache/italian/speechModification(M)
- if(copytext(M, 1, 2) != "*")
- M = " [M]"
+/obj/item/clothing/mask/fakemoustache/italian/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
+ message = " [message]"
var/list/italian_words = strings("italian_replacement.json", "italian")
for(var/key in italian_words)
@@ -57,13 +59,13 @@
if(islist(value))
value = pick(value)
- M = replacetextEx(M, " [uppertext(key)]", " [uppertext(value)]")
- M = replacetextEx(M, " [capitalize(key)]", " [capitalize(value)]")
- M = replacetextEx(M, " [key]", " [value]")
+ message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
+ message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
+ message = replacetextEx(message, " [key]", " [value]")
if(prob(3))
- M += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!")
- return trim(M)
+ message += pick(" Ravioli, ravioli, give me the formuoli!"," Mamma-mia!"," Mamma-mia! That's a spicy meat-ball!", " La la la la la funiculi funicula!")
+ speech_args[SPEECH_MESSAGE] = trim(message)
/obj/item/clothing/mask/joy
name = "joy mask"
@@ -77,32 +79,20 @@
icon_state = "pig"
item_state = "pig"
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
+ clothing_flags = VOICEBOX_TOGGLABLE
w_class = WEIGHT_CLASS_SMALL
- actions_types = list(/datum/action/item_action/toggle_voice_box)
- var/voicechange = 0
+ modifies_speech = TRUE
-/obj/item/clothing/mask/pig/attack_self(mob/user)
- voicechange = !voicechange
- to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!")
+/obj/item/clothing/mask/pig/handle_speech(datum/source, list/speech_args)
+ if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED))
+ speech_args[SPEECH_MESSAGE] = pick("Oink!","Squeeeeeeee!","Oink Oink!")
-/obj/item/clothing/mask/pig/speechModification(message)
- if(voicechange)
- message = pick("Oink!","Squeeeeeeee!","Oink Oink!")
- return message
-
-/obj/item/clothing/mask/spig //needs to be different otherwise you could turn the speedmodification off and on
+/obj/item/clothing/mask/pig/cursed //needs to be different otherwise you could turn the speedmodification off and on
name = "Pig face"
desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!" //It's only ever going to be attached to your face.
- icon_state = "pig"
- item_state = "pig"
- flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
- w_class = WEIGHT_CLASS_SMALL
- var/voicechange = 1
-
-/obj/item/clothing/mask/spig/speechModification(message)
- if(voicechange)
- message = pick("Oink!","Squeeeeeeee!","Oink Oink!")
- return message
+ flags_inv = HIDEFACIALHAIR
+ clothing_flags = NONE
+ item_flags = NODROP
///frog mask - reeee!!
/obj/item/clothing/mask/frog
@@ -112,47 +102,47 @@
item_state = "frog"
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
w_class = WEIGHT_CLASS_SMALL
- var/voicechange = TRUE
+ clothing_flags = VOICEBOX_TOGGLABLE
+ modifies_speech = TRUE
-/obj/item/clothing/mask/frog/attack_self(mob/user)
- voicechange = !voicechange
- to_chat(user, "You turn the voice box [voicechange ? "on" : "off"]!")
-
-/obj/item/clothing/mask/frog/speechModification(message) //whenever you speak
- if(voicechange)
+/obj/item/clothing/mask/frog/handle_speech(datum/source, list/speech_args) //whenever you speak
+ if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED))
if(prob(5)) //sometimes, the angry spirit finds others words to speak.
- message = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!")
+ speech_args[SPEECH_MESSAGE] = pick("HUUUUU!!","SMOOOOOKIN'!!","Hello my baby, hello my honey, hello my rag-time gal.", "Feels bad, man.", "GIT DIS GUY OFF ME!!" ,"SOMEBODY STOP ME!!", "NORMIES, GET OUT!!")
else
- message = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish,
- return message
+ speech_args[SPEECH_MESSAGE] = pick("Ree!!", "Reee!!","REEE!!","REEEEE!!") //but its usually just angry gibberish,
/obj/item/clothing/mask/frog/cursed
+ clothing_flags = NONE
item_flags = NODROP //reee!!
-/obj/item/clothing/mask/frog/cursed/attack_self(mob/user)
- return //no voicebox to alter.
-
/obj/item/clothing/mask/frog/cursed/equipped(mob/user, slot)
var/mob/living/carbon/C = user
if(C.wear_mask == src)
to_chat(user, "[src] was cursed! Ree!!")
return ..()
-
/obj/item/clothing/mask/cowmask
- name = "Cowface"
- desc = "It looks like a mask, but closer inspection reveals it's melded onto this persons face!"
+ name = "Cow mask"
+ desc = "A rubber cow mask,"
icon = 'icons/mob/mask.dmi'
icon_state = "cowmask"
item_state = "cowmask"
+ clothing_flags = VOICEBOX_TOGGLABLE
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
w_class = WEIGHT_CLASS_SMALL
- var/voicechange = 1
+ modifies_speech = TRUE
-/obj/item/clothing/mask/cowmask/speechModification(message)
- if(voicechange)
- message = pick("Moooooooo!","Moo!","Moooo!")
- return message
+/obj/item/clothing/mask/cowmask/handle_speech(datum/source, list/speech_args)
+ if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED))
+ speech_args[SPEECH_MESSAGE] = pick("Moooooooo!","Moo!","Moooo!")
+
+/obj/item/clothing/mask/cowmask/cursed
+ name = "cow face"
+ desc = "It looks like a cow mask, but closer inspection reveals it's melded onto this persons face!"
+ flags_inv = HIDEFACIALHAIR
+ clothing_flags = NONE
+ item_flags = NODROP
/obj/item/clothing/mask/horsehead
name = "horse head mask"
@@ -161,12 +151,18 @@
item_state = "horsehead"
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEYES|HIDEEARS
w_class = WEIGHT_CLASS_SMALL
- var/voicechange = 1
+ clothing_flags = VOICEBOX_TOGGLABLE
-/obj/item/clothing/mask/horsehead/speechModification(message)
- if(voicechange)
- message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
- return message
+/obj/item/clothing/mask/horsehead/handle_speech(datum/source, list/speech_args)
+ if(!CHECK_BITFIELD(clothing_flags, VOICEBOX_DISABLED))
+ speech_args[SPEECH_MESSAGE] = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
+
+/obj/item/clothing/mask/horsehead/cursed
+ name = "horse face"
+ desc = "It initially looks like a mask, but it's melded into the poor person's face."
+ clothing_flags = NONE
+ flags_inv = HIDEFACIALHAIR
+ item_flags = NODROP
/obj/item/clothing/mask/rat
name = "rat mask"
@@ -285,16 +281,18 @@
item_state = "gondola"
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
w_class = WEIGHT_CLASS_SMALL
+ modifies_speech = TRUE
-/obj/item/clothing/mask/gondola/speechModification(M)
- if(copytext(M, 1, 2) != "*")
- M = " [M]"
+/obj/item/clothing/mask/gondola/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
+ message = " [message]"
var/list/spurdo_words = strings("spurdo_replacement.json", "spurdo")
for(var/key in spurdo_words)
var/value = spurdo_words[key]
if(islist(value))
value = pick(value)
- M = replacetextEx(M,regex(uppertext(key),"g"), "[uppertext(value)]")
- M = replacetextEx(M,regex(capitalize(key),"g"), "[capitalize(value)]")
- M = replacetextEx(M,regex(key,"g"), "[value]")
- return trim(M)
+ message = replacetextEx(message,regex(uppertext(key),"g"), "[uppertext(value)]")
+ message = replacetextEx(message,regex(capitalize(key),"g"), "[capitalize(value)]")
+ message = replacetextEx(message,regex(key,"g"), "[value]")
+ speech_args[SPEECH_MESSAGE] = trim(message)
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index a6bcf23a2d..d314a4c48e 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -9,7 +9,7 @@
/obj/item/clothing/shoes/combat //basic syndicate combat boots for nuke ops and mob corpses
name = "combat boots"
desc = "High speed, low drag combat boots."
- icon_state = "jackboots"
+ icon_state = "combat"
item_state = "jackboots"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 5cd5d2c5c6..88f72d27c3 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -689,7 +689,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
chosen = capitalize(pick(speak_messages))
chosen = replacetext(chosen, "%TARGETNAME%", target_name)
var/image/speech_overlay = image('icons/mob/talk.dmi', person, "default0", layer = ABOVE_MOB_LAYER)
- var/message = target.compose_message(person,understood_language,chosen,null,person.get_spans(),face_name = TRUE)
+ var/message = target.compose_message(person,understood_language,chosen,null,list(person.speech_span),face_name = TRUE)
feedback_details += "Type: Talk, Source: [person.real_name], Message: [message]"
to_chat(target, message)
if(target.client)
@@ -705,7 +705,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
humans += H
person = pick(humans)
- var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",person.get_spans(),face_name = TRUE)
+ var/message = target.compose_message(person,understood_language,chosen,"[FREQ_COMMON]",list(person.speech_span),face_name = TRUE)
feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]"
to_chat(target, message)
qdel(src)
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index a2a1c6d03f..f85668d2b8 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -202,6 +202,19 @@
desc = "A flask of holy water...it's been sitting in the Necropolis a while though."
list_reagents = list("hell_water" = 100)
+/obj/item/reagent_containers/food/drinks/holyoil
+ name = "flask of zelus oil"
+ desc = "A brass flask of Zelus oil, a viscous fluid with a scenting of brass - this flask may be sipped or thrown."
+ icon_state = "zelusflask"
+ list_reagents = list("holyoil" = 30) //Powerfull
+ volume = 30
+ foodtype = NONE
+ force = 12 //Same as a toolbox
+ throwforce = 18
+
+/obj/item/reagent_containers/food/drinks/holyoil/null
+ list_reagents = list("holyoil" = 0)
+
/obj/item/reagent_containers/food/drinks/bottle/vermouth
name = "Goldeneye vermouth"
desc = "Sweet, sweet dryness~"
diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm
index 9d63d48f34..0b12ee4fcf 100644
--- a/code/modules/food_and_drinks/food/snacks_pie.dm
+++ b/code/modules/food_and_drinks/food/snacks_pie.dm
@@ -53,7 +53,7 @@
H.adjust_blurriness(1)
H.visible_message("[H] is creamed by [src]!", "You've been creamed by [src]!")
playsound(H, "desceration", 50, TRUE)
- reagents.trans_to(H,15) //Transfers the cream pies total volume of reagents to target on it
+ reagents.trans_to(H,15) //Cream pie combat
if(!H.creamed) // one layer at a time
H.add_overlay(creamoverlay)
H.creamed = TRUE
@@ -61,6 +61,7 @@
qdel(src)
/obj/item/reagent_containers/food/snacks/pie/cream/nostun
+ list_reagents = list("laughter" = 15)
stunning = FALSE
/obj/item/reagent_containers/food/snacks/pie/cream/body
diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm
index 5193545c4b..4a628c5f34 100644
--- a/code/modules/mining/laborcamp/laborstacker.dm
+++ b/code/modules/mining/laborcamp/laborstacker.dm
@@ -112,7 +112,7 @@ GLOBAL_LIST(labor_sheet_values)
else
if(!(obj_flags & EMAGGED))
Radio.set_frequency(FREQ_SECURITY)
- Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY, get_spans(), get_default_language())
+ Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY)
to_chat(usr, "Shuttle received message and will be sent shortly.")
/obj/machinery/mineral/labor_claim_console/proc/check_auth()
@@ -149,7 +149,7 @@ GLOBAL_LIST(labor_sheet_values)
var/obj/item/stack/sheet/inp = I
points += inp.point_value * inp.amount
return ..()
-
+
/**********************Point Lookup Console**************************/
/obj/machinery/mineral/labor_points_checker
name = "points checking console"
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 76b416772e..97b29ca4e1 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -5,6 +5,7 @@
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_LIVING
+ speech_span = SPAN_ROBOT
/mob/living/brain/Initialize()
. = ..()
diff --git a/code/modules/mob/living/brain/say.dm b/code/modules/mob/living/brain/say.dm
index ce0a09c27f..b7d7e1d7fc 100644
--- a/code/modules/mob/living/brain/say.dm
+++ b/code/modules/mob/living/brain/say.dm
@@ -10,14 +10,11 @@
..()
-/mob/living/brain/get_spans()
- return ..() | SPAN_ROBOT
-
/mob/living/brain/radio(message, message_mode, list/spans, language)
if(message_mode == MODE_HEADSET && istype(container, /obj/item/mmi))
var/obj/item/mmi/R = container
if(R.radio)
- R.radio.talk_into(src, message, , get_spans(), language)
+ R.radio.talk_into(src, message, language = language)
return ITALICS | REDUCE_RANGE
else
return ..()
diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm
index b921aea67e..5f1e1a2830 100644
--- a/code/modules/mob/living/carbon/alien/say.dm
+++ b/code/modules/mob/living/carbon/alien/say.dm
@@ -4,7 +4,7 @@
if(!message)
return
- var/message_a = say_quote(message, get_spans())
+ var/message_a = say_quote(message)
var/rendered = "Hivemind, [shown_name] [message_a]"
for(var/mob/S in GLOB.player_list)
if(!S.stat && S.hivecheck())
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 673249b186..56be62c75e 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -10,29 +10,6 @@
else
. = ..()
-/mob/living/carbon/human/treat_message(message)
- message = dna.species.handle_speech(message,src)
- if(diseases.len)
- for(var/datum/disease/pierrot_throat/D in diseases)
- var/list/temp_message = splittext(message, " ") //List each word in the message
- var/list/pick_list = list()
- for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line
- pick_list += i
- for(var/i=1, ((i <= D.stage) && (i <= temp_message.len)), i++) //Loop for each stage of the disease or until we run out of words
- if(prob(3 * D.stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12%
- var/H = pick(pick_list)
- if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":"))
- continue
- temp_message[H] = "HONK"
- pick_list -= H //Make sure that you dont HONK the same word twice
- message = jointext(temp_message, " ")
- message = ..(message)
- message = dna.mutations_say_mods(message)
- return message
-
-/mob/living/carbon/human/get_spans()
- return ..() | dna.mutations_get_spans() | dna.species_get_spans()
-
/mob/living/carbon/human/GetVoice()
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
var/obj/item/clothing/mask/chameleon/V = wear_mask
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 3324b07217..fabffaab60 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -1158,13 +1158,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return 1
return FALSE
-/datum/species/proc/handle_speech(message, mob/living/carbon/human/H)
- return message
-
-//return a list of spans or an empty list
-/datum/species/proc/get_spans()
- return list()
-
/datum/species/proc/check_weakness(obj/item, mob/living/attacker)
return FALSE
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index da7de39a03..4a7580e978 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -68,17 +68,17 @@
/obj/item/organ/tongue/dullahan
zone = "abstract"
+ modifies_speech = TRUE
-/obj/item/organ/tongue/dullahan/TongueSpeech(var/message)
+/obj/item/organ/tongue/dullahan/handle_speech(datum/source, list/speech_args)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.dna.species.id == "dullahan")
var/datum/species/dullahan/D = H.dna.species
if(isobj(D.myhead.loc))
var/obj/O = D.myhead.loc
- O.say(message)
- message = ""
- return message
+ O.say(speech_args[SPEECH_MESSAGE])
+ speech_args[SPEECH_MESSAGE] = ""
/obj/item/organ/ears/dullahan
zone = "abstract"
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 2907caff13..2c663b4094 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -519,6 +519,11 @@
..()
last_banana = world.time
last_honk = world.time
+ RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C)
+ . = ..()
+ UnregisterSignal(C, COMSIG_MOB_SAY)
/datum/species/golem/bananium/random_name(gender,unique,lastname)
var/clown_name = pick(GLOB.clown_names)
@@ -567,9 +572,8 @@
/datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H)
playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0)
-/datum/species/golem/bananium/get_spans()
- return list(SPAN_CLOWN)
-
+/datum/species/golem/bananium/proc/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_CLOWN
/datum/species/golem/runic
name = "Runic Golem"
@@ -646,14 +650,16 @@
/datum/species/golem/clockwork/on_species_gain(mob/living/carbon/human/H)
. = ..()
H.faction |= "ratvar"
+ RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/species/golem/clockwork/on_species_loss(mob/living/carbon/human/H)
if(!is_servant_of_ratvar(H))
H.faction -= "ratvar"
+ UnregisterSignal(H, COMSIG_MOB_SAY)
. = ..()
-/datum/species/golem/clockwork/get_spans()
- return SPAN_ROBOT //beep
+/datum/species/golem/clockwork/proc/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT //beep
/datum/species/golem/clockwork/spec_death(gibbed, mob/living/carbon/human/H)
gibbed = !has_corpse ? FALSE : gibbed
@@ -951,7 +957,7 @@
sexes = FALSE
fixed_mut_color = "ffffff"
attack_verb = "rattl"
- species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
info_text = "As a Bone Golem, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
var/datum/action/innate/bonechill/bonechill
diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm
index 7e838c857f..0ebd6e795b 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -28,6 +28,11 @@
/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
..()
assume_disguise(old_species, H)
+ RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech)
+
+/datum/species/synth/on_species_loss(mob/living/carbon/human/H)
+ . = ..()
+ UnregisterSignal(H, COMSIG_MOB_SAY)
/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "synthflesh")
@@ -110,18 +115,12 @@
else
return ..()
-
-/datum/species/synth/get_spans()
- if(fake_species)
- return fake_species.get_spans()
- return list()
-
-
-/datum/species/synth/handle_speech(message, mob/living/carbon/human/H)
- if(H.health > disguise_fail_health)
- if(fake_species)
- return fake_species.handle_speech(message,H)
- else
- return ..()
- else
- return ..()
\ No newline at end of file
+/datum/species/synth/proc/handle_speech(datum/source, list/speech_args)
+ if (isliving(source)) // yeah it's gonna be living but just to be clean
+ var/mob/living/L = source
+ if(fake_species && L.health > disguise_fail_health)
+ switch (fake_species.type)
+ if (/datum/species/golem/bananium)
+ speech_args[SPEECH_SPANS] |= SPAN_CLOWN
+ if (/datum/species/golem/clockwork)
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm
index 2711e44a98..47c9b6beb8 100644
--- a/code/modules/mob/living/carbon/say.dm
+++ b/code/modules/mob/living/carbon/say.dm
@@ -1,38 +1,17 @@
-/mob/living/carbon/treat_message(message)
- for(var/datum/brain_trauma/trauma in get_traumas())
- message = trauma.on_say(message)
- message = ..(message)
-
- var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
- if(!T) //hoooooouaah!
- var/regex/tongueless_lower = new("\[gdntke]+", "g")
- var/regex/tongueless_upper = new("\[GDNTKE]+", "g")
- if(copytext(message, 1, 2) != "*")
- message = tongueless_lower.Replace(message, pick("aa","oo","'"))
- message = tongueless_upper.Replace(message, pick("AA","OO","'"))
- else
- message = T.TongueSpeech(message)
- if(wear_mask)
- message = wear_mask.speechModification(message)
- if(head)
- message = head.speechModification(message)
- return message
+/mob/living/carbon/proc/handle_tongueless_speech(mob/living/carbon/speaker, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ var/static/regex/tongueless_lower = new("\[gdntke]+", "g")
+ var/static/regex/tongueless_upper = new("\[GDNTKE]+", "g")
+ if(message[1] != "*")
+ message = tongueless_lower.Replace(message, pick("aa","oo","'"))
+ message = tongueless_upper.Replace(message, pick("AA","OO","'"))
+ speech_args[SPEECH_MESSAGE] = message
/mob/living/carbon/can_speak_vocal(message)
if(silent)
return 0
return ..()
-/mob/living/carbon/get_spans()
- . = ..()
- var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
- if(T)
- . |= T.get_spans()
-
- var/obj/item/I = get_active_held_item()
- if(I)
- . |= I.get_held_item_speechspans(src)
-
/mob/living/carbon/could_speak_in_language(datum/language/dt)
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 93bc059533..6c9c6eb1a1 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -175,13 +175,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
else
src.log_talk(message, LOG_SAY, forced_by=forced)
- message = treat_message(message)
+ message = treat_message(message) // unfortunately we still need this
+ var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_SAY, args)
+ if (sigreturn & COMPONENT_UPPERCASE_SPEECH)
+ message = uppertext(message)
if(!message)
return
last_words = message
- spans |= get_spans()
+ spans |= speech_span
if(language)
var/datum/language/L = GLOB.language_datum_instances[language]
@@ -333,6 +336,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return null
/mob/living/proc/treat_message(message)
+
+ if(HAS_TRAIT(src, TRAIT_UNINTELLIGIBLE_SPEECH))
+ message = unintelligize(message)
+
if(derpspeech)
message = derpspeech(message, stuttering)
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index 928bd63dd1..4ac5c1f0bb 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -49,7 +49,7 @@
else
padloc = "(UNKNOWN)"
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
- send_speech(message, 7, T, "robot", get_spans(), language)
+ send_speech(message, 7, T, "robot", language = language)
to_chat(src, "Holopad transmitted, [real_name] \"[message]\"")
else
to_chat(src, "No holopad connected.")
diff --git a/code/modules/mob/living/silicon/pai/pai_shell.dm b/code/modules/mob/living/silicon/pai/pai_shell.dm
index 99484f395e..164a3e7389 100644
--- a/code/modules/mob/living/silicon/pai/pai_shell.dm
+++ b/code/modules/mob/living/silicon/pai/pai_shell.dm
@@ -29,6 +29,13 @@
if(!L.temporarilyRemoveItemFromInventory(card))
to_chat(src, "Error: Unable to expand to mobile form. Chassis is restrained by some device or person.")
return FALSE
+ if(istype(card.loc, /obj/item/integrated_circuit/input/pAI_connector))
+ var/obj/item/integrated_circuit/input/pAI_connector/C = card.loc
+ C.RemovepAI()
+ C.visible_message("[src] ejects itself from [C]!")
+ playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
+ C.installed_pai = null
+ C.push_data()
forceMove(get_turf(card))
card.forceMove(src)
if(client)
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index aca35762de..1d38a3c5a6 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,14 +1,10 @@
-
-/mob/living/silicon/get_spans()
- return ..() | SPAN_ROBOT
-
/mob/living/proc/robot_talk(message)
log_talk(message, LOG_SAY)
var/desig = "Default Cyborg" //ezmode for taters
if(issilicon(src))
var/mob/living/silicon/S = src
desig = trim_left(S.designation + " " + S.job)
- var/message_a = say_quote(message, get_spans())
+ var/message_a = say_quote(message)
var/rendered = "Robotic Talk, [name] [message_a]"
for(var/mob/M in GLOB.player_list)
if(M.binarycheck())
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index fa1ab7fc17..13520774c5 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -12,6 +12,7 @@
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
mob_biotypes = list(MOB_ROBOTIC)
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+ speech_span = SPAN_ROBOT
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index e9978d1e62..ce99e301c5 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -23,6 +23,7 @@
verb_yell = "alarms"
initial_language_holder = /datum/language_holder/synthetic
bubble_icon = "machine"
+ speech_span = SPAN_ROBOT
faction = list("neutral", "silicon" , "turret")
@@ -348,13 +349,10 @@
if((!on) || (!message))
return
if(channel && Radio.channels[channel])// Use radio if we have channel key
- Radio.talk_into(src, message, channel, get_spans(), get_default_language())
+ Radio.talk_into(src, message, channel)
else
say(message)
-/mob/living/simple_animal/bot/get_spans()
- return ..() | SPAN_ROBOT
-
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language)
. = ..()
if(. != 0)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index cf3742fcc5..e6bf7b3f20 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -37,6 +37,7 @@
gender = NEUTER
mob_biotypes = list(MOB_ROBOTIC)
speak_emote = list("chirps")
+ speech_span = SPAN_ROBOT
bubble_icon = "machine"
initial_language_holder = /datum/language_holder/drone
mob_size = MOB_SIZE_SMALL
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/say.dm b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
index 16bf370f02..7a5967948f 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/say.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/say.dm
@@ -1,13 +1,3 @@
-/////////////
-//DRONE SAY//
-/////////////
-//Drone speach
-
-/mob/living/simple_animal/drone/get_spans()
- return ..() | SPAN_ROBOT
-
-
-
//Base proc for anything to call
/proc/_alert_drones(msg, dead_can_hear = 0, atom/source, mob/living/faction_checked_mob, exact_faction_match)
if (dead_can_hear && source)
@@ -31,7 +21,7 @@
/mob/living/simple_animal/drone/proc/drone_chat(msg)
- alert_drones("Drone Chat: [name] [say_quote(msg, get_spans())]", TRUE)
+ alert_drones("Drone Chat: [name] [say_quote(msg)]", TRUE)
/mob/living/simple_animal/drone/binarycheck()
return TRUE
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index 9e127d4746..ecb869790c 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -69,16 +69,11 @@
if(name != real_name)
alt_name = " (died as [real_name])"
- var/K
-
- if(key)
- K = src.key
-
- var/spanned = src.say_quote(message, get_spans())
+ var/spanned = say_quote(message)
message = emoji_parse(message)
var/rendered = "DEAD: [name][alt_name] [emoji_parse(spanned)]"
log_talk(message, LOG_SAY, tag="DEAD")
- deadchat_broadcast(rendered, follow_target = src, speaker_key = K)
+ deadchat_broadcast(rendered, follow_target = src, speaker_key = key)
/mob/proc/check_emote(message)
if(copytext(message, 1, 2) == "*")
diff --git a/code/modules/mob/say_readme.dm b/code/modules/mob/say_readme.dm
index 00e0f66246..0e76d9b6ed 100644
--- a/code/modules/mob/say_readme.dm
+++ b/code/modules/mob/say_readme.dm
@@ -78,10 +78,6 @@ global procs
say_quote(input, spans, message_mode)
Adds a verb and quotes to a message. Also attaches span classes to a message. Verbs are determined by verb_say/verb_ask/verb_yell variables. Called on the speaker.
- get_spans(input, spans)
- Returns the list of spans that are always applied to messages of this atom.
- Always return ..() | + youroutput when overriding this proc!
-
/mob
say_dead(message)
Sends a message to all dead people. Does not use Hear().
diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm
index 2200af7cab..e97e39643a 100644
--- a/code/modules/ninja/suit/mask.dm
+++ b/code/modules/ninja/suit/mask.dm
@@ -17,16 +17,19 @@ Contents:
item_state = "s-ninja_mask"
strip_delay = 120
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ modifies_speech = TRUE
-/obj/item/clothing/mask/gas/space_ninja/speechModification(message)
- if(copytext(message, 1, 2) != "*")
+/obj/item/clothing/mask/gas/space_ninja/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
var/list/temp_message = text2list(message, " ")
var/list/pick_list = list()
- for(var/i = 1, i <= temp_message.len, i++)
+ for(var/i in 1 to temp_message.len)
pick_list += i
- for(var/i=1, i <= abs(temp_message.len/3), i++)
+ for(var/i in 1 to abs(temp_message.len/3))
var/H = pick(pick_list)
- if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":")) continue
+ if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":"))
+ continue
temp_message[H] = ninjaspeak(temp_message[H])
pick_list -= H
message = list2text(temp_message, " ")
@@ -56,5 +59,4 @@ Contents:
message = replacetext(message, "than", "sen")
message = replacetext(message, ".", "")
message = lowertext(message)
-
- return message
+ speech_args[SPEECH_MESSAGE] = message
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 7b2ea9398e..026c39c6cf 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -184,9 +184,6 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
to_chat(H, "You get headaches just from looking at it.")
return
-/obj/machinery/power/supermatter_crystal/get_spans()
- return list(SPAN_ROBOT)
-
#define CRITICAL_TEMPERATURE 10000
/obj/machinery/power/supermatter_crystal/proc/get_status()
@@ -244,10 +241,10 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
add_overlay(causality_field, TRUE)
var/speaking = "[emergency_alert] The supermatter has reached critical integrity failure. Emergency causality destabilization field has been activated."
- radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language())
+ radio.talk_into(src, speaking, common_channel, language = get_default_language())
for(var/i in SUPERMATTER_COUNTDOWN_TIME to 0 step -10)
if(damage < explosion_point) // Cutting it a bit close there engineers
- radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "[safe_alert] Failsafe has been disengaged.", common_channel)
cut_overlay(causality_field, TRUE)
final_countdown = FALSE
return
@@ -258,7 +255,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
speaking = "[DisplayTimeText(i, TRUE)] remain before causality stabilization."
else
speaking = "[i*0.1]..."
- radio.talk_into(src, speaking, common_channel, get_spans(), get_default_language())
+ radio.talk_into(src, speaking, common_channel)
sleep(10)
explode()
@@ -459,27 +456,27 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
alarm()
if(damage > emergency_point)
- radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "[emergency_alert] Integrity: [get_integrity()]%", common_channel)
lastwarning = REALTIMEOFDAY
if(!has_reached_emergency)
investigate_log("has reached the emergency point for the first time.", INVESTIGATE_SUPERMATTER)
message_admins("[src] has reached the emergency point [ADMIN_JMP(src)].")
has_reached_emergency = TRUE
else if(damage >= damage_archived) // The damage is still going up
- radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "[warning_alert] Integrity: [get_integrity()]%", engineering_channel)
lastwarning = REALTIMEOFDAY - (WARNING_DELAY * 5)
else // Phew, we're safe
- radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "[safe_alert] Integrity: [get_integrity()]%", engineering_channel)
lastwarning = REALTIMEOFDAY
if(power > POWER_PENALTY_THRESHOLD)
- radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "Warning: Hyperstructure has reached dangerous power level.", engineering_channel)
if(powerloss_inhibitor < 0.5)
- radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "DANGER: CHARGE INERTIA CHAIN REACTION IN PROGRESS.", engineering_channel)
if(combined_gas > MOLE_PENALTY_THRESHOLD)
- radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel, get_spans(), get_default_language())
+ radio.talk_into(src, "Warning: Critical coolant mass reached.", engineering_channel)
if(damage > explosion_point)
countdown()
diff --git a/code/modules/projectiles/ammunition/caseless/rocket.dm b/code/modules/projectiles/ammunition/caseless/rocket.dm
index 9d6befce53..bc693d96bc 100644
--- a/code/modules/projectiles/ammunition/caseless/rocket.dm
+++ b/code/modules/projectiles/ammunition/caseless/rocket.dm
@@ -9,7 +9,7 @@
name = "\improper PM-9HEDP"
desc = "An 84mm High Explosive Dual Purpose rocket. Pointy end toward mechs."
caliber = "84mm"
- icon_state = "s-casing-live"
+ icon_state = "84mm-hedp"
projectile_type = /obj/item/projectile/bullet/a84mm
/obj/item/ammo_casing/caseless/a75
diff --git a/code/modules/projectiles/boxes_magazines/internal/grenade.dm b/code/modules/projectiles/boxes_magazines/internal/grenade.dm
index 352d1eb951..79a005ee8a 100644
--- a/code/modules/projectiles/boxes_magazines/internal/grenade.dm
+++ b/code/modules/projectiles/boxes_magazines/internal/grenade.dm
@@ -11,7 +11,7 @@
max_ammo = 1
/obj/item/ammo_box/magazine/internal/rocketlauncher
- name = "grenade launcher internal magazine"
+ name = "rocket launcher internal magazine"
ammo_type = /obj/item/ammo_casing/caseless/rocket
caliber = "84mm"
max_ammo = 1
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 98fd774d63..fb3ed19f82 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -32,9 +32,10 @@
var/fire_delay = 0 //rate of fire for burst firing and semi auto
var/firing_burst = 0 //Prevent the weapon from firing again while already firing
var/semicd = 0 //cooldown handler
- var/weapon_weight = WEAPON_LIGHT
+ var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy
var/spread = 0 //Spread induced by the gun itself.
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
+ var/inaccuracy_modifier = 1
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
@@ -538,3 +539,13 @@
if(A == chambered)
chambered = null
update_icon()
+
+/obj/item/gun/proc/getinaccuracy(mob/living/user)
+ if(!iscarbon(user))
+ return FALSE
+ else
+ var/mob/living/carbon/holdingdude = user
+ if(istype(holdingdude) && holdingdude.combatmode)
+ return (max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0) * inaccuracy_modifier)
+ else
+ return ((weapon_weight * 25) * inaccuracy_modifier)
diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm
index eea4e1bc0b..f6356dce99 100644
--- a/code/modules/projectiles/guns/ballistic/launchers.dm
+++ b/code/modules/projectiles/guns/ballistic/launchers.dm
@@ -86,6 +86,7 @@
pin = /obj/item/firing_pin/implant/pindicate
burst_size = 1
fire_delay = 0
+ inaccuracy_modifier = 0.7
casing_ejector = FALSE
weapon_weight = WEAPON_HEAVY
magazine_wording = "rocket"
@@ -108,34 +109,34 @@
/obj/item/gun/ballistic/rocketlauncher/can_shoot()
return chambered?.BB
-/obj/item/gun/ballistic/rocketlauncher/process_chamber()
- if(chambered)
- chambered = null
- if(magazine)
- QDEL_NULL(magazine)
- update_icon()
-
/obj/item/gun/ballistic/rocketlauncher/attack_self_tk(mob/user)
return //too difficult to remove the rocket with TK
/obj/item/gun/ballistic/rocketlauncher/attack_self(mob/living/user)
if(magazine)
- if(chambered)
- chambered.forceMove(magazine)
- magazine.stored_ammo.Insert(1, chambered)
+ var/obj/item/ammo_casing/AC = chambered
+ if(AC)
+ if(!user.put_in_hands(AC))
+ AC.bounce_away(FALSE, NONE)
+ to_chat(user, "You remove \the [AC] from \the [src]!")
+ playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, TRUE)
chambered = null
else
- stack_trace("Removed [magazine] from [src] without a chambered round")
- magazine.forceMove(drop_location())
- if(user.is_holding(src))
- user.put_in_hands(magazine)
- playsound(src, 'sound/weapons/gun_magazine_remove_full.ogg', 70, TRUE)
- to_chat(user, "You work the [magazine] out from [src].")
- magazine = null
- else
- to_chat(user, "There's no rocket in [src].")
+ to_chat(user, "There's no [magazine_wording] in [src].")
update_icon()
+/obj/item/gun/ballistic/rocketlauncher/attackby(obj/item/A, mob/user, params)
+ if(magazine && istype(A, /obj/item/ammo_casing))
+ if(user.temporarilyRemoveItemFromInventory(A))
+ if(!chambered)
+ to_chat(user, "You load a new [A] into \the [src].")
+ playsound(src, "gun_insert_full_magazine", 70, 1)
+ chamber_round()
+ update_icon()
+ return TRUE
+ else
+ to_chat(user, "You cannot seem to get \the [A] out of your hands!")
+
/obj/item/gun/ballistic/rocketlauncher/update_icon()
icon_state = "[initial(icon_state)]-[chambered ? "1" : "0"]"
diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm
index a62fa25f7d..e15810c6bb 100644
--- a/code/modules/projectiles/projectile/special/rocket.dm
+++ b/code/modules/projectiles/projectile/special/rocket.dm
@@ -16,6 +16,7 @@
var/anti_armour_damage = 200
armour_penetration = 100
dismemberment = 100
+ ricochets_max = 0
/obj/item/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE)
..()
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index f7c9c95e40..c7b85efe81 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -209,7 +209,12 @@
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(is_servant_of_ratvar(M))
- to_chat(M, "A darkness begins to spread its unholy tendrils through your mind, purging the Justiciar's influence!")
+ to_chat(M, "A fog spreads through your mind, purging the Justiciar's influence!")
+ ..()
+
+/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
+ if(iscultist(M))
+ to_chat(M, "A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence")
..()
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
@@ -264,7 +269,7 @@
qdel(R)
T.Bless()
-/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke
+/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke
name = "Unholy Water"
id = "unholywater"
description = "Something that shouldn't exist on this plane of existence."
@@ -284,7 +289,7 @@
M.AdjustStun(-40, 0)
M.AdjustKnockdown(-40, 0)
M.adjustStaminaLoss(-10, 0)
- M.adjustToxLoss(-2, 0)
+ M.adjustToxLoss(-2, 0, TRUE)
M.adjustOxyLoss(-2, 0)
M.adjustBruteLoss(-2, 0)
M.adjustFireLoss(-2, 0)
@@ -314,6 +319,45 @@
holder.remove_reagent(id, 1)
pH = 0.1
+/datum/reagent/fuel/holyoil //Its oil
+ name = "Zelus Oil"
+ id = "holyoil"
+ description = "Oil blessed by a greater being."
+ taste_description = "metallic oil"
+
+/datum/reagent/fuel/holyoil/on_mob_life(mob/living/carbon/M)
+ if(is_servant_of_ratvar(M))
+ M.drowsyness = max(M.drowsyness-5, 0)
+ M.AdjustUnconscious(-60, 0)
+ M.AdjustStun(-30, 0)
+ M.AdjustKnockdown(-70, 0)
+ M.adjustStaminaLoss(-15, 0)
+ M.adjustToxLoss(-5, 0, TRUE)
+ M.adjustOxyLoss(-3, 0)
+ M.adjustBruteLoss(-3, 0)
+ M.adjustFireLoss(-5, 0)
+ if(iscultist(M))
+ M.AdjustUnconscious(1, 0)
+ M.AdjustStun(10, 0)
+ M.AdjustKnockdown(20, 0)
+ M.adjustStaminaLoss(15, 0)
+ else
+ M.adjustToxLoss(3, 0)
+ M.adjustOxyLoss(2, 0)
+ M.adjustStaminaLoss(10, 0)
+ holder.remove_reagent(id, 1)
+ return TRUE
+
+//We only get 30u to start with...
+
+/datum/reagent/fuel/holyoil/reaction_obj(obj/O, reac_volume)
+ . = ..()
+ if(istype(O, /obj/item/stack/sheet/metal))
+ var/obj/item/stack/sheet/metal/M = O
+ reac_volume = min(reac_volume, M.amount)
+ new/obj/item/stack/tile/brass(get_turf(M), reac_volume)
+ M.use(reac_volume)
+
/datum/reagent/medicine/omnizine/godblood
name = "Godblood"
id = "godblood"
diff --git a/code/modules/spells/spell_types/barnyard.dm b/code/modules/spells/spell_types/barnyard.dm
index 01b24fef98..b6a7878470 100644
--- a/code/modules/spells/spell_types/barnyard.dm
+++ b/code/modules/spells/spell_types/barnyard.dm
@@ -37,14 +37,13 @@
"Your face starts burning up, but the flames are repulsed by your anti-magic protection!")
return
- var/list/masks = list(/obj/item/clothing/mask/spig, /obj/item/clothing/mask/cowmask, /obj/item/clothing/mask/horsehead)
+ var/list/masks = list(/obj/item/clothing/mask/pig/cursed, /obj/item/clothing/mask/cowmask/cursed, /obj/item/clothing/mask/horsehead/cursed)
var/list/mSounds = list('sound/magic/pighead_curse.ogg', 'sound/magic/cowhead_curse.ogg', 'sound/magic/horsehead_curse.ogg')
var/randM = rand(1,3)
var/choice = masks[randM]
var/obj/item/clothing/mask/magichead = new choice
- magichead.item_flags |= NODROP
magichead.flags_inv = null
target.visible_message("[target]'s face bursts into flames, and a barnyard animal's head takes its place!", \
"Your face burns up, and shortly after the fire you realise you have the face of a barnyard animal!")
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index b657c93beb..539d70f8ad 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -12,6 +12,7 @@
var/taste_sensitivity = 15 // lower is more sensitive.
var/maxHealth = TONGUE_MAX_HEALTH
var/damage = 0
+ var/modifies_speech = FALSE
var/static/list/languages_possible_base = typecacheof(list(
/datum/language/common,
/datum/language/draconic,
@@ -28,11 +29,7 @@
. = ..()
languages_possible = languages_possible_base
-/obj/item/organ/tongue/get_spans()
- return list()
-
-/obj/item/organ/tongue/proc/TongueSpeech(var/message)
- return message
+/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args)
/obj/item/organ/tongue/proc/adjustTongueLoss(mob/living/carbon/M, damage_mod)
if (maxHealth == "alien")
@@ -61,14 +58,19 @@
..()
if(say_mod && M.dna && M.dna.species)
M.dna.species.say_mod = say_mod
+ if (modifies_speech)
+ RegisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+ M.UnregisterSignal(M, COMSIG_MOB_SAY)
/obj/item/organ/tongue/Remove(mob/living/carbon/M, special = 0)
..()
if(say_mod && M.dna && M.dna.species)
M.dna.species.say_mod = initial(M.dna.species.say_mod)
+ UnregisterSignal(M, COMSIG_MOB_SAY, .proc/handle_speech)
+ M.RegisterSignal(M, COMSIG_MOB_SAY, /mob/living/carbon/.proc/handle_tongueless_speech)
/obj/item/organ/tongue/could_speak_in_language(datum/language/dt)
- . = is_type_in_typecache(dt, languages_possible)
+ return is_type_in_typecache(dt, languages_possible)
/obj/item/organ/tongue/lizard
name = "forked tongue"
@@ -77,14 +79,16 @@
say_mod = "hisses"
taste_sensitivity = 10 // combined nose + tongue, extra sensitive
maxHealth = 40 //extra sensitivity means tongue is more susceptible to damage
+ modifies_speech = TRUE
-/obj/item/organ/tongue/lizard/TongueSpeech(var/message)
- var/regex/lizard_hiss = new("s+", "g")
- var/regex/lizard_hiSS = new("S+", "g")
- if(copytext(message, 1, 2) != "*")
+/obj/item/organ/tongue/lizard/handle_speech(datum/source, list/speech_args)
+ var/static/regex/lizard_hiss = new("s+", "g")
+ var/static/regex/lizard_hiSS = new("S+", "g")
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
message = lizard_hiss.Replace(message, "sss")
message = lizard_hiSS.Replace(message, "SSS")
- return message
+ speech_args[SPEECH_MESSAGE] = message
/obj/item/organ/tongue/fly
name = "proboscis"
@@ -93,14 +97,16 @@
say_mod = "buzzes"
taste_sensitivity = 25 // you eat vomit, this is a mercy
maxHealth = 80 //years of eatting trash has made your tongue strong
+ modifies_speech = TRUE
-/obj/item/organ/tongue/fly/TongueSpeech(var/message)
- var/regex/fly_buzz = new("z+", "g")
- var/regex/fly_buZZ = new("Z+", "g")
- if(copytext(message, 1, 2) != "*")
+/obj/item/organ/tongue/fly/handle_speech(datum/source, list/speech_args)
+ var/static/regex/fly_buzz = new("z+", "g")
+ var/static/regex/fly_buZZ = new("Z+", "g")
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
message = fly_buzz.Replace(message, "zzz")
message = fly_buZZ.Replace(message, "ZZZ")
- return message
+ speech_args[SPEECH_MESSAGE] = message
/obj/item/organ/tongue/abductor
name = "superlingual matrix"
@@ -109,9 +115,11 @@
say_mod = "gibbers"
taste_sensitivity = 101 // ayys cannot taste anything.
maxHealth = 120 //Ayys probe a lot
+ modifies_speech = TRUE
-/obj/item/organ/tongue/abductor/TongueSpeech(var/message)
+/obj/item/organ/tongue/abductor/handle_speech(datum/source, list/speech_args)
//Hacks
+ var/message = speech_args[SPEECH_MESSAGE]
var/mob/living/carbon/human/user = usr
var/rendered = "[user.name]: [message]"
user.log_talk(message, LOG_SAY, tag="abductor")
@@ -127,7 +135,7 @@
for(var/mob/M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, user)
to_chat(M, "[link] [rendered]")
- return ""
+ speech_args[SPEECH_MESSAGE] = ""
/obj/item/organ/tongue/zombie
name = "rotting tongue"
@@ -136,9 +144,10 @@
say_mod = "moans"
taste_sensitivity = 32
maxHealth = 65 //Stop! It's already dead...!
+ modifies_speech = TRUE
-/obj/item/organ/tongue/zombie/TongueSpeech(var/message)
- var/list/message_list = splittext(message, " ")
+/obj/item/organ/tongue/zombie/handle_speech(datum/source, list/speech_args)
+ var/list/message_list = splittext(speech_args[SPEECH_MESSAGE], " ")
var/maxchanges = max(round(message_list.len / 1.5), 2)
for(var/i = rand(maxchanges / 2, maxchanges), i > 0, i--)
@@ -151,7 +160,7 @@
if(prob(20) && message_list.len > 3)
message_list.Insert(insertpos, "[pick("BRAINS", "Brains", "Braaaiinnnsss", "BRAAAIIINNSSS")]...")
- return jointext(message_list, " ")
+ speech_args[SPEECH_MESSAGE] = jointext(message_list, " ")
/obj/item/organ/tongue/alien
name = "alien tongue"
@@ -160,6 +169,7 @@
say_mod = "hisses"
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
maxHealth = "alien" //Their blood is acid, so, no, though a tongueless xeno might be funny
+ modifies_speech = TRUE // not really, they just hiss
var/static/list/languages_possible_alien = typecacheof(list(
/datum/language/xenocommon,
/datum/language/common,
@@ -171,9 +181,8 @@
. = ..()
languages_possible = languages_possible_alien
-/obj/item/organ/tongue/alien/TongueSpeech(var/message)
+/obj/item/organ/tongue/alien/handle_speech(datum/source, list/speech_args)
playsound(owner, "hiss", 25, 1, 1)
- return message
/obj/item/organ/tongue/bone
name = "bone \"tongue\""
@@ -183,7 +192,7 @@
attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned")
taste_sensitivity = 101 // skeletons cannot taste anything
maxHealth = "bone" //Take brute damage instead
-
+ modifies_speech = TRUE
var/chattering = FALSE
var/phomeme_type = "sans"
var/list/phomeme_types = list("sans", "papyrus")
@@ -192,30 +201,21 @@
. = ..()
phomeme_type = pick(phomeme_types)
-/obj/item/organ/tongue/bone/TongueSpeech(var/message)
- . = message
-
- if(chattering)
- //Annoy everyone nearby with your chattering.
- chatter(message, phomeme_type, usr)
-
-/obj/item/organ/tongue/bone/get_spans()
- . = ..()
- // Feature, if the tongue talks directly, it will speak with its span
+/obj/item/organ/tongue/bone/handle_speech(datum/source, list/speech_args)
+ if (chattering)
+ chatter(speech_args[SPEECH_MESSAGE], phomeme_type, source)
switch(phomeme_type)
if("sans")
- . |= SPAN_SANS
+ speech_args[SPEECH_SPANS] |= SPAN_SANS
if("papyrus")
- . |= SPAN_PAPYRUS
+ speech_args[SPEECH_SPANS] |= SPAN_PAPYRUS
/obj/item/organ/tongue/bone/plasmaman
name = "plasma bone \"tongue\""
desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech."
icon_state = "tongueplasma"
maxHealth = "alien"
-
-/obj/item/organ/tongue/bone/plasmaman/get_spans()
- return
+ modifies_speech = FALSE
/obj/item/organ/tongue/robot
name = "robotic voicebox"
@@ -224,16 +224,17 @@
icon_state = "tonguerobot"
say_mod = "states"
attack_verb = list("beeped", "booped")
+ modifies_speech = TRUE
taste_sensitivity = 25 // not as good as an organic tongue
maxHealth = 100 //RoboTongue!
+ var/electronics_magic = TRUE
/obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt)
- . = TRUE // THE MAGIC OF ELECTRONICS
+ return ..() || electronics_magic
-/obj/item/organ/tongue/robot/get_spans()
- return ..() | SPAN_ROBOT
+/obj/item/organ/tongue/robot/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT
-//FermiChem
/obj/item/organ/tongue/fluffy
name = "fluffy tongue"
desc = "OwO what's this?"
@@ -262,5 +263,11 @@
taste_sensitivity = 10
maxHealth = 60 //It's robotic!
-/obj/item/organ/tongue/cybernetic/get_spans()
- return ..() | SPAN_ROBOT
+/obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args)
+ speech_args[SPEECH_SPANS] |= SPAN_ROBOT
+
+/obj/item/organ/tongue/robot/ipc
+ name = "positronic voicebox"
+ say_mod = "beeps"
+ desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms."
+ electronics_magic = FALSE
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index c9a3871511..b013e7f252 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -49,9 +49,14 @@
var/datum/surgery_step/S = get_surgery_step()
if(S)
- if(S.try_op(user, target, user.zone_selected, user.get_active_held_item(), src, try_to_fail))
- return 1
- return 0
+ var/obj/item/tool = user.get_active_held_item()
+ if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
+ return TRUE
+ if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
+ return TRUE
+ if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it
+ to_chat(user, "This step requires a different tool!")
+ return TRUE
/datum/surgery/proc/get_surgery_step()
var/step_type = steps[status]
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index 517dfb412a..db7445e0b0 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -4,6 +4,7 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "retractor"
materials = list(MAT_METAL=6000, MAT_GLASS=3000)
+ item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
@@ -33,6 +34,7 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "hemostat"
materials = list(MAT_METAL=5000, MAT_GLASS=2500)
+ item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
attack_verb = list("attacked", "pinched")
@@ -66,6 +68,7 @@
icon = 'icons/obj/surgery.dmi'
icon_state = "cautery"
materials = list(MAT_METAL=2500, MAT_GLASS=750)
+ item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
attack_verb = list("burnt")
@@ -102,6 +105,7 @@
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
hitsound = 'sound/weapons/circsawhit.ogg'
materials = list(MAT_METAL=10000, MAT_GLASS=6000)
+ item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
force = 15
w_class = WEIGHT_CLASS_NORMAL
@@ -151,6 +155,7 @@
throw_speed = 3
throw_range = 5
materials = list(MAT_METAL=4000, MAT_GLASS=1000)
+ item_flags = SURGICAL_TOOL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP_ACCURATE
@@ -209,6 +214,7 @@
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
hitsound = 'sound/weapons/circsawhit.ogg'
throwhitsound = 'sound/weapons/pierce.ogg'
+ item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
force = 15
w_class = WEIGHT_CLASS_NORMAL
@@ -278,6 +284,7 @@
desc = "A container for holding body parts."
icon = 'icons/obj/storage.dmi'
icon_state = "evidenceobj"
+ item_flags = SURGICAL_TOOL
/obj/item/organ_storage/afterattack(obj/item/I, mob/user, proximity)
. = ..()
diff --git a/html/changelogs/AutoChangeLog-pr-8734.yml b/html/changelogs/AutoChangeLog-pr-8734.yml
new file mode 100644
index 0000000000..4f746c4cd5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8734.yml
@@ -0,0 +1,5 @@
+author: "Ghommie (original PR by coiax)"
+delete-after: True
+changes:
+ - code_imp: "Randomly coloured gloves and randomly coloured glowsticks now have
+slightly different typepaths, but otherwise function the same."
diff --git a/html/changelogs/AutoChangeLog-pr-8761.yml b/html/changelogs/AutoChangeLog-pr-8761.yml
new file mode 100644
index 0000000000..4ee792c3a6
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8761.yml
@@ -0,0 +1,5 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - tweak: "melee and block harm"
+ - bugfix: "sprites*"
diff --git a/html/changelogs/AutoChangeLog-pr-8812.yml b/html/changelogs/AutoChangeLog-pr-8812.yml
new file mode 100644
index 0000000000..0de67cfe59
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8812.yml
@@ -0,0 +1,4 @@
+author: "Sishen1542, original by XDTM"
+delete-after: True
+changes:
+ - rscadd: "Using the wrong surgery tool during surgery no longer attacks the patient, if on help or disarm intent."
diff --git a/html/changelogs/AutoChangeLog-pr-8842.yml b/html/changelogs/AutoChangeLog-pr-8842.yml
new file mode 100644
index 0000000000..8a8903b7e5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8842.yml
@@ -0,0 +1,4 @@
+author: "UristMcAstronaut"
+delete-after: True
+changes:
+ - bugfix: "allows a pai to activate its holoform while in a pai connector without getting derped."
diff --git a/html/changelogs/AutoChangeLog-pr-8843.yml b/html/changelogs/AutoChangeLog-pr-8843.yml
new file mode 100644
index 0000000000..74a3cc07e8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8843.yml
@@ -0,0 +1,4 @@
+author: "Coolgat3"
+delete-after: True
+changes:
+ - imageadd: "added combat boots sprite"
diff --git a/html/changelogs/AutoChangeLog-pr-8844.yml b/html/changelogs/AutoChangeLog-pr-8844.yml
new file mode 100644
index 0000000000..05f0f2fb22
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8844.yml
@@ -0,0 +1,6 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixes the rocket launcher being unreloadable."
+ - balance: "Buffed its accuracy a bit."
+ - tweak: "Replaced the grenade launcher emagged minesweeper loot with the rocket launcher like it was originally supposed to be."
diff --git a/html/changelogs/AutoChangeLog-pr-8846.yml b/html/changelogs/AutoChangeLog-pr-8846.yml
new file mode 100644
index 0000000000..26b1dad6d5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8846.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - rscadd: "Rubber Toolboxes."
diff --git a/html/changelogs/AutoChangeLog-pr-8847.yml b/html/changelogs/AutoChangeLog-pr-8847.yml
new file mode 100644
index 0000000000..678b3d433b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8847.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - rscadd: "Porting in two bar signs: Cyber Sylph's and Meow Mix."
diff --git a/html/changelogs/AutoChangeLog-pr-8852.yml b/html/changelogs/AutoChangeLog-pr-8852.yml
new file mode 100644
index 0000000000..4d49f26831
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8852.yml
@@ -0,0 +1,4 @@
+author: "Tupinambis"
+delete-after: True
+changes:
+ - imagedel: "Removes a moth plush from the game."
diff --git a/html/changelogs/AutoChangeLog-pr-8853.yml b/html/changelogs/AutoChangeLog-pr-8853.yml
new file mode 100644
index 0000000000..1507e8620d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8853.yml
@@ -0,0 +1,6 @@
+author: "Ghommie (original PRs by Naksu and coiax, loser)"
+delete-after: True
+changes:
+ - code_imp: "Cleaned up saycode"
+ - bugfix: "Taking mutadone while having the communication disorder brain trauma will no longer spam your chat with messages."
+ - rscadd: "IPCs now come with a subtype of robotic tongue without the omnilingual ability, instead of innately having robotic voice spans."
diff --git a/html/changelogs/AutoChangeLog-pr-8854.yml b/html/changelogs/AutoChangeLog-pr-8854.yml
new file mode 100644
index 0000000000..fc45d2087e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8854.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixing stamina damage melee weaponry being unusable by pacifists, and still damaging objects and triggering electrified grilles when thrown."
diff --git a/html/changelogs/AutoChangeLog-pr-8858.yml b/html/changelogs/AutoChangeLog-pr-8858.yml
new file mode 100644
index 0000000000..6fc057f88d
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8858.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - bugfix: "Made unholy water healtoxinlover"
diff --git a/html/changelogs/AutoChangeLog-pr-8860.yml b/html/changelogs/AutoChangeLog-pr-8860.yml
new file mode 100644
index 0000000000..95593b1dad
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8860.yml
@@ -0,0 +1,4 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - rscadd: "Zelus Oil, brass flasks"
diff --git a/html/changelogs/AutoChangeLog-pr-8870.yml b/html/changelogs/AutoChangeLog-pr-8870.yml
new file mode 100644
index 0000000000..08c9860a30
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8870.yml
@@ -0,0 +1,5 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - tweak: "Toned down many species' female chest sprites to fit the smaller cups."
+ - bugfix: "Fixed some body parts sprites inconsistencies, such as the W/E female and male chest sprites being the same in some species, and jellypeople's legs being one tile off on W/E"
diff --git a/html/changelogs/AutoChangeLog-pr-8872.yml b/html/changelogs/AutoChangeLog-pr-8872.yml
new file mode 100644
index 0000000000..a79ec48298
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-8872.yml
@@ -0,0 +1,5 @@
+author: "deathride58"
+delete-after: True
+changes:
+ - balance: "Normal mops now only use 2 stamina to mop a tile, nerfed from their previous value of 5 stamina per tile mopped."
+ - balance: "Advanced mops now only use 1 stamina to mop turfs, from their former value of 2 stam."
diff --git a/icons/mob/human_parts.dmi b/icons/mob/human_parts.dmi
index 70aeba6a69..fc6fafb275 100644
Binary files a/icons/mob/human_parts.dmi and b/icons/mob/human_parts.dmi differ
diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi
index 3bb3874d35..7f10d992bc 100644
Binary files a/icons/mob/human_parts_greyscale.dmi and b/icons/mob/human_parts_greyscale.dmi differ
diff --git a/icons/mob/inhands/equipment/shields_lefthand.dmi b/icons/mob/inhands/equipment/shields_lefthand.dmi
index e9d0dd0d2b..3f29410f98 100644
Binary files a/icons/mob/inhands/equipment/shields_lefthand.dmi and b/icons/mob/inhands/equipment/shields_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/shields_righthand.dmi b/icons/mob/inhands/equipment/shields_righthand.dmi
index dda17156fe..2c3f291e43 100644
Binary files a/icons/mob/inhands/equipment/shields_righthand.dmi and b/icons/mob/inhands/equipment/shields_righthand.dmi differ
diff --git a/icons/mob/inhands/equipment/toolbox_lefthand.dmi b/icons/mob/inhands/equipment/toolbox_lefthand.dmi
index b2fa42ce5e..801df7abb8 100644
Binary files a/icons/mob/inhands/equipment/toolbox_lefthand.dmi and b/icons/mob/inhands/equipment/toolbox_lefthand.dmi differ
diff --git a/icons/mob/inhands/equipment/toolbox_righthand.dmi b/icons/mob/inhands/equipment/toolbox_righthand.dmi
index ccb15982dd..f38ddfc9a4 100644
Binary files a/icons/mob/inhands/equipment/toolbox_righthand.dmi and b/icons/mob/inhands/equipment/toolbox_righthand.dmi differ
diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi
index 50bfbace89..2c4d401088 100644
Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index db0634181b..8d7bd55426 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi
index dc3aca6b19..7822cdb8c2 100644
Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ
diff --git a/icons/obj/plushes.dmi b/icons/obj/plushes.dmi
index 586bca61aa..9048739e0c 100644
Binary files a/icons/obj/plushes.dmi and b/icons/obj/plushes.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index 9037bfc0d0..2a6ec3955a 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/modular_citadel/code/modules/admin/chat_commands.dm b/modular_citadel/code/modules/admin/chat_commands.dm
index deb3de589e..918b1dda5a 100644
--- a/modular_citadel/code/modules/admin/chat_commands.dm
+++ b/modular_citadel/code/modules/admin/chat_commands.dm
@@ -4,7 +4,7 @@
/datum/tgs_chat_command/wheelofsalt/Run(datum/tgs_chat_user/sender, params)
var/saltresult = "The wheel of salt [pick("clatters","screams","vibrates","clanks","resonates","groans","moans","squeaks","emits a[pick(" god-forsaken"," lewd"," creepy"," generic","n orgasmic"," demonic")] [pick("airhorn","bike horn","trumpet","clown","latex","vore","dog","laughing")] noise")] as it spins violently... And it seems the salt of the day is the "
- var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Jecca Qua","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
+ var/saltprimarysubject = "[pick("combat","medical","grab","furry","wall","orgasm","cat","ERP","lizard","dog","latex","vision cone","atmospherics","table","chem","vore","dogborg","Skylar Lineman","Mekhi Anderson","Peppermint","rework","cum","dick","cockvore","Medihound","sleeper","belly sleeper","door wires","flightsuit","coder privilege","Developer abuse","ban reason","github self merge","red panda","beret","male catgirl","powergame","hexacrocin","Discord server","Clitadel","Cargonia","Solarian Republic","Main and RP merger","bluespace","salt","chem dispenser theft","Botany","moth","BWOINK","anal vore","stamina","Mason Jakops","mining","noodle","milf","Lavaland","Necropolis","Ashwalker","Chase Redtail","Drew Mint","Pavel Marsk","Joker Amari","Durgit","chaplain","Antag","nanite","Syndicate","Nar-Sie","Ratvar","Cult","maint","Foam-Force","AI","cyborg","ghost","clockwork","cyberpunk","vaporwave","Clown","Leon Beech","Mime","security","research","Megafauna","Bubblegum","Ash Drake","Legion","Colossus","White Shuttle","Changeling","Cowboy","Space Ninja","Poly","Revolutionary","Skyrim","forbidden fruits","xenomorph","blob","Nuclear Operative","crossdressing")]"
var/saltsecondarysubject = "[pick("rework","changes","r34","ban","removal","addition","leak","proposal","fanart","introduction","tabling","ERP","bikeshedding","crossdressing","sprites","semen keg","argument","theft","nerf","screeching","salt","creampie","lewding","murder","kissing","marriage","replacement","fucking","ship","netflix adaptation","dance","remaster","system","voyeur","decoration","pre-order","bukkake","seduction","worship","gangbang","handholding")]"
if(prob(10))
saltresult += "@here for your salt, all day every day"
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm
index bbbe863ec2..25b8daf2cb 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/ipc.dm
@@ -11,6 +11,7 @@
mutant_bodyparts = list("ipc_screen", "ipc_antenna")
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
+ mutanttongue = /obj/item/organ/tongue/robot/ipc
exotic_blood = "oil"
@@ -27,9 +28,6 @@
screen.Remove(C)
..()
-/datum/species/ipc/get_spans()
- return SPAN_ROBOT
-
/datum/action/innate/monitor_change
name = "Screen Change"
check_flags = AB_CHECK_CONSCIOUS
diff --git a/modular_citadel/code/modules/projectiles/gun.dm b/modular_citadel/code/modules/projectiles/gun.dm
index ea8af7c74c..317f68b4c4 100644
--- a/modular_citadel/code/modules/projectiles/gun.dm
+++ b/modular_citadel/code/modules/projectiles/gun.dm
@@ -9,13 +9,3 @@
return 0
else
return ..()
-
-/obj/item/gun/proc/getinaccuracy(mob/living/user)
- if(!iscarbon(user))
- return 0
- else
- var/mob/living/carbon/holdingdude = user
- if(istype(holdingdude) && holdingdude.combatmode)
- return max((holdingdude.lastdirchange + weapon_weight * 25) - world.time,0)
- else
- return weapon_weight * 25
diff --git a/modular_citadel/icons/mob/mutant_bodyparts.dmi b/modular_citadel/icons/mob/mutant_bodyparts.dmi
index 5f72d1013b..1e12d2bf1a 100644
Binary files a/modular_citadel/icons/mob/mutant_bodyparts.dmi and b/modular_citadel/icons/mob/mutant_bodyparts.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index d254c1495f..27ef8e2eb4 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -338,6 +338,7 @@
#include "code\datums\components\_component.dm"
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\armor_plate.dm"
+#include "code\datums\components\bouncy.dm"
#include "code\datums\components\butchering.dm"
#include "code\datums\components\caltrop.dm"
#include "code\datums\components\chasm.dm"