diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 87b9094b47e..8bf1fa25429 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -55,6 +55,7 @@
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume)
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone)
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob)
+#define COMSIG_ATOM_ATTACK_ALIEN "atom_attack_alien" //from base of atom/attack_alien()
#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume)
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): ()
#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity)
@@ -220,6 +221,9 @@
//Food
#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
+//Reagents
+#define COMSIG_ON_MOB_LIFE "on_mob_life" //Called when a reagent calls on_mob_life
+
//Mood
#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index d69c7fbf28f..da462cb97ed 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -63,8 +63,10 @@
if(!force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
- else if(hitsound)
- playsound(loc, hitsound, get_clamped_volume(), 1, -1)
+ else
+ M.SendSignal(COMSIG_ITEM_ATTACK, M)
+ if(hitsound)
+ playsound(loc, hitsound, get_clamped_volume(), 1, -1)
user.lastattacked = M
M.lastattacker = user
diff --git a/code/datums/components/jestosterone.dm b/code/datums/components/jestosterone.dm
new file mode 100644
index 00000000000..04752403508
--- /dev/null
+++ b/code/datums/components/jestosterone.dm
@@ -0,0 +1,44 @@
+/datum/component/jestosterone
+ var/mob_is_clown //Is the affected mob a clown?
+
+/datum/component/jestosterone/Initialize(mob/user, is_this_mob_a_clown)
+ mob_is_clown = is_this_mob_a_clown
+ if(mob_is_clown)
+ to_chat(user, "Whatever that was, it feels great!")
+ else
+ to_chat(user, "Something doesn't feel right...")
+ RegisterSignal(COMSIG_MOVABLE_MOVED, .proc/on_move)
+ RegisterSignal(COMSIG_PARENT_ATTACKBY, .proc/mob_was_attacked)
+ RegisterSignal(COMSIG_ITEM_ATTACK, .proc/mob_was_attacked)
+ RegisterSignal(COMSIG_ATOM_ATTACK_ALIEN, .proc/mob_was_attacked)
+ RegisterSignal(COMSIG_ON_MOB_LIFE, .proc/process_jestosterone)
+
+/datum/component/jestosterone/proc/on_move(mob/user)
+ playsound(user.loc, "clownstep", 25, 1) //Yes, this means that if you put jestosterone inside an alien, it will squeak. Also it stacks with shoes, THE HORROR!
+
+/datum/component/jestosterone/proc/mob_was_attacked(mob/user)
+ to_chat(user, "was attacked")
+ playsound(user.loc, 'sound/items/bikehorn.ogg', 50, 1)
+
+/datum/component/jestosterone/proc/process_jestosterone(mob/living/user)
+ if(prob(10))
+ user.emote("giggle")
+ if(mob_is_clown)
+ user.adjustBruteLoss(-1.5 * REAGENTS_EFFECT_MULTIPLIER) //Screw those pesky clown beatings!
+ else
+ user.AdjustDizzy(10, 0, 500)
+ user.Druggy(15)
+ if(prob(10))
+ user.EyeBlurry(5)
+ if(prob(6))
+ var/list/clown_message = list("You feel light-headed.",
+ "You can't see straight.",
+ "You feel about as funny as the station clown.",
+ "Bright colours and rainbows cloud your vision.",
+ "Your funny bone aches.",
+ "You can hear bike horns in the distance.",
+ "You feel like SHOUTING!",
+ "Sinister laughter echoes in your ears.",
+ "Your legs feel like jelly.",
+ "You feel like telling a pun.")
+ to_chat(user, "[pick(clown_message)]")
diff --git a/code/modules/admin/verbs/honksquad.dm b/code/modules/admin/verbs/honksquad.dm
index c9068049c75..ce1803c2067 100644
--- a/code/modules/admin/verbs/honksquad.dm
+++ b/code/modules/admin/verbs/honksquad.dm
@@ -119,6 +119,7 @@ var/global/sent_honksquad = 0
equip_to_slot_or_del(new /obj/item/stamp/clown(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/toy/crayon/rainbow(src), slot_in_backpack)
equip_to_slot_or_del(new /obj/item/reagent_containers/spray/waterflower(src), slot_in_backpack)
+ equip_to_slot_or_del(new /obj/item/reagent_containers/food/pill/patch/jestosterone(src), slot_r_store)
if(prob(50))
equip_to_slot_or_del(new /obj/item/gun/energy/clown(src), slot_in_backpack)
else
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index bfad9a4db9a..8a6324e0ebd 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -25,8 +25,6 @@
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(.)
- if(reagents.has_reagent("jestosterone"))
- playsound(loc, "clownstep", 25, 1) //Yes, this means that if you put jestosterone inside an alien, it will squeak. Also it stacks with shoes, THE HORROR!
if(nutrition && stat != DEAD)
nutrition -= hunger_drain / 10
if(m_intent == MOVE_INTENT_RUN)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index c26dd5168c7..d4cafa847fd 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -26,8 +26,6 @@
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
- if(reagents.has_reagent("jestosterone") && I.force)
- playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
return ..()
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index d7a9ed07f21..fc5d3156b01 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -381,8 +381,6 @@
playsound(target.loc, attack.attack_sound, 25, 1, -1)
target.visible_message("[user] [pick(attack.attack_verb)]ed [target]!")
- if(target.reagents.has_reagent("jestosterone"))
- playsound(target.loc, 'sound/items/bikehorn.ogg', 50, 1)
target.apply_damage(damage, BRUTE, affecting, armor_block, sharp = attack.sharp) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway.
if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold)
target.visible_message("[user] has weakened [target]!", \
@@ -391,6 +389,7 @@
target.forcesay(GLOB.hit_appends)
else if(target.lying)
target.forcesay(GLOB.hit_appends)
+ target.SendSignal(COMSIG_PARENT_ATTACKBY, target)
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.check_block()) //cqc
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 25380d26fb2..f045b54b8d8 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -508,6 +508,7 @@
var/turf/T = loc
. = ..()
if(.)
+ SendSignal(COMSIG_MOVABLE_MOVED, src)
handle_footstep(loc)
step_count++
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index cfe35b58983..2677b5a0f9e 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -333,6 +333,7 @@
return FALSE
if(INTENT_HARM)
M.do_attack_animation(src)
+ SendSignal(COMSIG_ATOM_ATTACK_ALIEN, src)
return TRUE
if(INTENT_DISARM)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
diff --git a/code/modules/reagents/chemistry/reagents/misc.dm b/code/modules/reagents/chemistry/reagents/misc.dm
index a5376cf06a8..bd004ff2c20 100644
--- a/code/modules/reagents/chemistry/reagents/misc.dm
+++ b/code/modules/reagents/chemistry/reagents/misc.dm
@@ -428,37 +428,25 @@
/datum/reagent/jestosterone/reaction_mob(mob/living/M, method, volume)
..()
+ if(istype(M, /mob/living/carbon)
+ return
+ var/is_a_clown = FALSE
if(M.mind && (M.mind.assigned_role == "Clown" || M.mind.assigned_role == SPECIAL_ROLE_HONKSQUAD))
- to_chat(M, "Whatever that was, it feels great!")
- else
+ is_a_clown = TRUE
+ if(!is_a_clown)
M.AdjustDizzy(volume)
- if(!M.reagents.has_reagent("jestosterone"))
- to_chat(M, "Something doesn't feel right...")
+ if(!issilicon(user))
+ M.AddComponent(/datum/component/jestosterone, M, is_a_clown)
/datum/reagent/jestosterone/on_mob_life(mob/living/M)
- if(prob(10))
- M.emote("giggle")
- if(M.mind && (M.mind.assigned_role == "Clown" || M.mind.assigned_role == SPECIAL_ROLE_HONKSQUAD))
- M.adjustBruteLoss(-1.5 * REAGENTS_EFFECT_MULTIPLIER) //Screw those pesky clown beatings!
- else
- M.AdjustDizzy(10, 0, 500)
- M.Druggy(15)
- if(prob(10))
- M.EyeBlurry(5)
- if(prob(6))
- var/list/clown_message = list("You feel light-headed.",
- "You can't see straight.",
- "You feel about as funny as the station clown.",
- "Bright colours and rainbows cloud your vision.",
- "Your funny bone aches.",
- "You can hear bike horns in the distance.",
- "You feel like SHOUTING!",
- "Sinister laughter echoes in your ears.",
- "Your legs feel like jelly.",
- "You feel like telling a pun.")
- to_chat(M, "[pick(clown_message)]")
+ M.SendSignal(COMSIG_ON_MOB_LIFE, M)
..()
+/datum/reagent/jestosterone/on_mob_delete(mob/living/M)
+ ..()
+ GET_COMPONENT_FROM(remove_fun, /datum/component/jestosterone, M)
+ remove_fun.Destroy()
+
/datum/reagent/royal_bee_jelly
name = "royal bee jelly"
id = "royal_bee_jelly"
diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm
index b9faa296987..486111821f1 100644
--- a/code/modules/reagents/reagent_containers/patch.dm
+++ b/code/modules/reagents/reagent_containers/patch.dm
@@ -37,4 +37,10 @@
/obj/item/reagent_containers/food/pill/patch/nicotine
name = "nicotine patch"
desc = "Helps temporarily curb the cravings of nicotine dependency."
- list_reagents = list("nicotine" = 20)
\ No newline at end of file
+ list_reagents = list("nicotine" = 20)
+
+/obj/item/reagent_containers/food/pill/patch/jestosterone
+ name = "jestosterone patch"
+ desc = "Helps with brute injuries if the affected person is a clown, otherwise inflicts various annoying effects."
+ icon_state = "bandaid_clown"
+ list_reagents = list("jestosterone" = 30)
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index f12159de67d..f692814d18c 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 9e36bf7b5af..8a403c97472 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -265,6 +265,7 @@
#include "code\datums\cache\powermonitor.dm"
#include "code\datums\components\_component.dm"
#include "code\datums\components\ducttape.dm"
+#include "code\datums\components\jestosterone.dm"
#include "code\datums\components\material_container.dm"
#include "code\datums\components\squeak.dm"
#include "code\datums\diseases\_disease.dm"