diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm
index a124ad211d0..bf3c7f3d118 100755
--- a/code/game/objects/items/item.dm
+++ b/code/game/objects/items/item.dm
@@ -369,6 +369,7 @@ mob/proc/flash_weak_pain()
M << "Aargh it burns!"
M.updatehealth()
src.add_fingerprint(user)
+ M.react_to_attack(user)
return 1
diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm
index 1bd2c27ea9a..a9b1353f519 100644
--- a/code/modules/chemical/Chemistry-Tools.dm
+++ b/code/modules/chemical/Chemistry-Tools.dm
@@ -1018,6 +1018,9 @@
for(var/mob/O in viewers(4, user))
O.show_message("\red [user] takes a blood sample from [target].", 1)
+ if(prob(2) && istype(T,/mob/living/carbon/monkey))
+ T:react_to_attack(user)
+
else //if not mob
if(!target.reagents.total_volume)
user << "\red [target] is empty."
@@ -1059,6 +1062,9 @@
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red [] injects [] with the syringe!", user, target), 1)
src.reagents.reaction(target, INGEST)
+ if(prob(2) && istype(target,/mob/living/carbon/monkey))
+ var/mob/living/carbon/monkey/M = target
+ M.react_to_attack(user)
if(ismob(target) && target == user)
src.reagents.reaction(target, INGEST)
spawn(5)
diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm
index e7ba23c39e4..d268b95ede2 100644
--- a/code/modules/mob/living/carbon/monkey/life.dm
+++ b/code/modules/mob/living/carbon/monkey/life.dm
@@ -88,11 +88,7 @@
for(var/obj/item/weapon/grab/G in src)
G.process()
- if(!client && !stat)
- if(prob(33) && canmove && isturf(loc))
- step(src, pick(cardinal))
- if(prob(1))
- emote(pick("scratch","jump","roll","tail"))
+ npc_act()
/mob/living/carbon/monkey
proc
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index dfbb87bb1b2..79e6d2f9c6b 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -177,6 +177,7 @@
for(var/datum/disease/D in M.viruses)
if(istype(D, /datum/disease/jungle_fever))
contract_disease(D,1,0)
+ react_to_attack(M)
else
for(var/mob/O in viewers(src, null))
O.show_message("\red [M.name] has attempted to bite [name]!", 1)
@@ -239,11 +240,13 @@
return
bruteloss += damage
updatehealth()
+ react_to_attack(M)
else
playsound(loc, 'punchmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has attempted to [attack_verb] [name]!", M), 1)
+ react_to_attack(M)
else
if (M.a_intent == "grab")
if (M == src)
@@ -265,6 +268,8 @@
playsound(loc, 'thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
O.show_message(text("\red [] has grabbed [name] passively!", M), 1)
+
+ if(prob(1)) react_to_attack(M)
else
if (!( paralysis ))
if (prob(25))
@@ -273,12 +278,14 @@
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has pushed down [name]!", M), 1)
+ react_to_attack(M)
else
drop_item()
playsound(loc, 'thudswoosh.ogg', 50, 1, -1)
for(var/mob/O in viewers(src, null))
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has disarmed [name]!", M), 1)
+ react_to_attack(M)
return
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
@@ -313,6 +320,7 @@
O.show_message(text("\red [] has slashed [name]!", M), 1)
bruteloss += damage
updatehealth()
+ react_to_attack(M)
else
playsound(loc, 'slashmiss.ogg', 25, 1, -1)
for(var/mob/O in viewers(src, null))
@@ -353,6 +361,7 @@
if ((O.client && !( O.blinded )))
O.show_message(text("\red [] has disarmed [name]!", M), 1)
bruteloss += damage
+ react_to_attack(M)
updatehealth()
return
@@ -415,6 +424,7 @@
updatehealth()
+ react_to_attack(M)
return
@@ -568,6 +578,15 @@
M.UpdateFeed(src)
return
+/mob/living/carbon/monkey/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ var/chealth = health
+ var/rval = ..()
+ if(chealth > health)
+ // we were damaged!
+ react_to_attack(user)
+
+ return rval
+
/mob/living/carbon/monkey/verb/removeinternal()
set name = "Remove Internals"
set category = "IC"
diff --git a/code/modules/mob/living/carbon/monkey/npc.dm b/code/modules/mob/living/carbon/monkey/npc.dm
new file mode 100644
index 00000000000..34f77bc75f4
--- /dev/null
+++ b/code/modules/mob/living/carbon/monkey/npc.dm
@@ -0,0 +1,99 @@
+mob/living/carbon/monkey/var
+ mob/npc_target = null // the NPC this monkey is attacking
+ mob/npc_fleeing = null // the monkey is scared of this mob
+ mob/hiding_behind = null
+ hid_behind = 0
+
+ var/list/hostiles = list()
+
+ fleeing_duration = 0
+
+mob/living/carbon/monkey/proc/npc_act()
+ if(!client && !stat)
+ if(npc_fleeing && canmove)
+ var/prevloc = loc
+ if(!hiding_behind)
+ for(var/mob/living/carbon/human/H in view(7, src))
+ if(!hostiles.Find(H))
+ hiding_behind = H
+
+ if(hiding_behind)
+ if(get_dist(src, hiding_behind) == 1)
+ if(!hid_behind)
+ emote("me", 1, "hides behind [hiding_behind]!")
+ hid_behind = 1
+ step_to(src, get_step(hiding_behind, get_dir(npc_fleeing, hiding_behind)))
+ else
+ if(!step_to(src, hiding_behind, 1))
+ hiding_behind = null
+ else
+ step_away(src, npc_fleeing, 7)
+
+ if(prob(7))
+ if(prob(50) && (npc_fleeing in view(8,src)))
+ switch(rand(1,3))
+ if(1)
+ emote("me", 1, "shows [npc_fleeing] its fangs!")
+ if(2)
+ emote("me", 2, "gnarls at [npc_fleeing].")
+ if(3)
+ emote("me", 2, "eyes [npc_fleeing] fearfully.")
+ else
+ switch(rand(1,3))
+ if(1)
+ emote("whimper")
+ if(2)
+ emote("me", 1, "trembles heavily.")
+ if(3)
+ emote("me", 2, "chimpers nervously.")
+
+ fleeing_duration--
+ if(fleeing_duration <= 0)
+ npc_fleeing = null
+ hiding_behind = null
+ hid_behind = 0
+
+ if(loc == prevloc) dir = get_dir(src, npc_fleeing)
+ else
+ if(prob(33) && canmove && isturf(loc))
+ step(src, pick(cardinal))
+ if(prob(1))
+ if(health < 70)
+ switch(rand(1,3))
+ if(1)
+ emote("me", 1, "cowers on the floor, writhing in pain.")
+ if(2)
+ emote("me", 1, "trembles visibly, it seems to be in pain.")
+ if(3)
+ emote("me", 1, "wraps its arms around its knees, breathing heavily.")
+ else
+ emote(pick("scratch","jump","roll","tail"))
+
+mob/living/carbon/monkey/react_to_attack(mob/M)
+ if(npc_fleeing == M)
+ fleeing_duration += 30
+ return
+
+ if(!hostiles.Find(M)) hostiles += M
+
+ spawn(5)
+ switch(rand(1,3))
+ if(1)
+ emote("me", 1, "flails about wildly!")
+ if(2)
+ emote("me", 2, "screams loudly at [M]!")
+ if(3)
+ emote("me", 2, "whimpers fearfully!")
+
+ npc_fleeing = M
+ fleeing_duration = 30
+
+
+/*/mob/living/proc/apply_damage(var/damage = 0,var/damagetype = BRUTE, var/def_zone = null, var/blocked = 0, var/slash = 0, var/used_weapon = null)
+ if(!client && !stat)
+ if(damage > 10)
+ if(prob(40) || health == 100)
+ emote("me", 2, pick("screams loudly!", "whimpers in pain!"))
+ else if(health == 100 || (damage > 0 && prob(10)))
+ emote("me", 1, pick("flails about wildly!", "cringes visibly!", "chimpers nervously."))
+ return ..()*/
\ No newline at end of file
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index ba9d524509a..6d0562ed537 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -72,4 +72,8 @@
if(slur) apply_effect(slur, SLUR, blocked)
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
- return 1
\ No newline at end of file
+ return 1
+
+
+/mob/living/proc/react_to_attack(mob/M)
+ return