48088b79d9
Replaced every l_hand = and r_hand = and all that if(hand) crap to use standardised procs. This means we can use procs like Dropped() reliably as they will always be called when things are dropped. Thorough documentation to come. But generally, if you want a mob's icons to update after deleting something in the inventory...use drop_from_inventory(the_thing_you_wanna_drop) just before deleting it. If you wanna put something in a mob's hands use put_in_hands() (or one of the variants). It'll try putting it in active hand first, then inactive, then the floor. They handle layers, overlays, screenlocs calling various procs such as dropped() etc for you. Easy mob.equipped() is now mob.get_active_hand() because there was another totally unrelated proc named equipped() and stuff was confusing. Weakening was made instantaneous. Minor optimisations for human/handle_regular_status_updates(). I'll port these changes over to the other mobs next. Basically it should stop it constantly incrementing every status effect even after death. umm... bunch of overlays related fixes... I think that's everything. :/ git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3900 316c924e-a436-60f5-8080-3fe189b3f50e
512 lines
14 KiB
Plaintext
512 lines
14 KiB
Plaintext
/mob/living/carbon/monkey/New()
|
|
var/datum/reagents/R = new/datum/reagents(1000)
|
|
reagents = R
|
|
R.my_atom = src
|
|
if (!(dna))
|
|
if(gender == NEUTER)
|
|
gender = pick(MALE, FEMALE)
|
|
dna = new /datum/dna( null )
|
|
dna.uni_identity = "00600200A00E0110148FC01300B009"
|
|
dna.struc_enzymes = "0983E840344C39F4B059D5145FC5785DC6406A4BB8"
|
|
dna.unique_enzymes = md5(name)
|
|
//////////blah
|
|
var/gendervar
|
|
if (gender == "male")
|
|
gendervar = add_zero2(num2hex((rand(1,2049)),1), 3)
|
|
else
|
|
gendervar = add_zero2(num2hex((rand(2051,4094)),1), 3)
|
|
dna.uni_identity += gendervar
|
|
dna.uni_identity += "12C"
|
|
dna.uni_identity += "4E2"
|
|
|
|
if(name == "monkey")
|
|
name = text("monkey ([rand(1, 1000)])")
|
|
real_name = name
|
|
..()
|
|
return
|
|
|
|
/mob/living/carbon/monkey/movement_delay()
|
|
var/tally = 0
|
|
if(reagents)
|
|
if(reagents.has_reagent("hyperzine")) return -1
|
|
|
|
if(reagents.has_reagent("nuka_cola")) return -1
|
|
|
|
var/health_deficiency = (100 - health)
|
|
if(health_deficiency >= 45) tally += (health_deficiency / 25)
|
|
|
|
if (bodytemperature < 283.222)
|
|
tally += (283.222 - bodytemperature) / 10 * 1.75
|
|
return tally
|
|
|
|
/mob/living/carbon/monkey/Bump(atom/movable/AM as mob|obj, yes)
|
|
|
|
spawn( 0 )
|
|
if ((!( yes ) || now_pushing))
|
|
return
|
|
now_pushing = 1
|
|
if(ismob(AM))
|
|
var/mob/tmob = AM
|
|
if(istype(tmob, /mob/living/carbon/human) && (HULK in tmob.mutations))
|
|
if(prob(70))
|
|
usr << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
|
|
now_pushing = 0
|
|
return
|
|
if(tmob.nopush)
|
|
now_pushing = 0
|
|
return
|
|
|
|
tmob.LAssailant = src
|
|
now_pushing = 0
|
|
..()
|
|
if (!( istype(AM, /atom/movable) ))
|
|
return
|
|
if (!( now_pushing ))
|
|
now_pushing = 1
|
|
if (!( AM.anchored ))
|
|
var/t = get_dir(src, AM)
|
|
if (istype(AM, /obj/structure/window))
|
|
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
|
|
for(var/obj/structure/window/win in get_step(AM,t))
|
|
now_pushing = 0
|
|
return
|
|
step(AM, t)
|
|
now_pushing = null
|
|
return
|
|
return
|
|
|
|
/mob/living/carbon/monkey/Topic(href, href_list)
|
|
..()
|
|
if (href_list["mach_close"])
|
|
var/t1 = text("window=[]", href_list["mach_close"])
|
|
machine = null
|
|
src << browse(null, t1)
|
|
if ((href_list["item"] && !( usr.stat ) && !( usr.restrained() ) && in_range(src, usr) ))
|
|
var/obj/effect/equip_e/monkey/O = new /obj/effect/equip_e/monkey( )
|
|
O.source = usr
|
|
O.target = src
|
|
O.item = usr.get_active_hand()
|
|
O.s_loc = usr.loc
|
|
O.t_loc = loc
|
|
O.place = href_list["item"]
|
|
requests += O
|
|
spawn( 0 )
|
|
O.process()
|
|
return
|
|
..()
|
|
return
|
|
|
|
/mob/living/carbon/monkey/meteorhit(obj/O as obj)
|
|
for(var/mob/M in viewers(src, null))
|
|
M.show_message(text("\red [] has been hit by []", src, O), 1)
|
|
if (health > 0)
|
|
var/shielded = 0
|
|
adjustBruteLoss(30)
|
|
if ((O.icon_state == "flaming" && !( shielded )))
|
|
adjustFireLoss(40)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
return
|
|
|
|
//mob/living/carbon/monkey/bullet_act(var/obj/item/projectile/Proj)taken care of in living
|
|
|
|
/mob/living/carbon/monkey/hand_p(mob/M as mob)
|
|
if ((M.a_intent == "hurt" && !( istype(wear_mask, /obj/item/clothing/mask/muzzle) )))
|
|
if ((prob(75) && health > 0))
|
|
for(var/mob/O in viewers(src, null))
|
|
O.show_message(text("\red <B>[M.name] has bit []!</B>", src), 1)
|
|
var/damage = rand(1, 5)
|
|
if (HULK in mutations) damage += 10
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
|
|
for(var/datum/disease/D in M.viruses)
|
|
if(istype(D, /datum/disease/jungle_fever))
|
|
contract_disease(D,1,0)
|
|
else
|
|
for(var/mob/O in viewers(src, null))
|
|
O.show_message(text("\red <B>[M.name] has attempted to bite []!</B>", src), 1)
|
|
return
|
|
|
|
/mob/living/carbon/monkey/attack_paw(mob/M as mob)
|
|
..()
|
|
|
|
if (M.a_intent == "help")
|
|
help_shake_act(M)
|
|
else
|
|
if ((M.a_intent == "hurt" && !( istype(wear_mask, /obj/item/clothing/mask/muzzle) )))
|
|
if ((prob(75) && health > 0))
|
|
playsound(loc, 'bite.ogg', 50, 1, -1)
|
|
for(var/mob/O in viewers(src, null))
|
|
O.show_message("\red <B>[M.name] has bit [name]!</B>", 1)
|
|
var/damage = rand(1, 5)
|
|
adjustBruteLoss(damage)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
for(var/datum/disease/D in M.viruses)
|
|
if(istype(D, /datum/disease/jungle_fever))
|
|
contract_disease(D,1,0)
|
|
else
|
|
for(var/mob/O in viewers(src, null))
|
|
O.show_message("\red <B>[M.name] has attempted to bite [name]!</B>", 1)
|
|
return
|
|
|
|
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M as mob)
|
|
if (!ticker)
|
|
M << "You cannot attack people before the game has started."
|
|
return
|
|
|
|
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
|
M << "No attacking people at spawn, you jackass."
|
|
return
|
|
|
|
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
|
|
var/obj/item/clothing/gloves/G = M.gloves
|
|
if(G.cell)
|
|
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
|
|
if(G.cell.charge >= 2500)
|
|
G.cell.charge -= 2500
|
|
Weaken(5)
|
|
if (stuttering < 5)
|
|
stuttering = 5
|
|
Stun(5)
|
|
|
|
for(var/mob/O in viewers(src, null))
|
|
if (O.client)
|
|
O.show_message("\red <B>[src] has been touched with the stun gloves by [M]!</B>", 1, "\red You hear someone fall", 2)
|
|
return
|
|
else
|
|
M << "\red Not enough charge! "
|
|
return
|
|
|
|
if (M.a_intent == "help")
|
|
help_shake_act(M)
|
|
else
|
|
if (M.a_intent == "hurt")
|
|
if ((prob(75) && health > 0))
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has punched [name]!</B>", M), 1)
|
|
|
|
playsound(loc, "punch", 25, 1, -1)
|
|
var/damage = rand(5, 10)
|
|
if (prob(40))
|
|
damage = rand(10, 15)
|
|
if (paralysis < 5)
|
|
Paralyse(rand(10, 15))
|
|
spawn( 0 )
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has knocked out [name]!</B>", M), 1)
|
|
return
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
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 <B>[] has attempted to punch [name]!</B>", M), 1)
|
|
else
|
|
if (M.a_intent == "grab")
|
|
if (M == src)
|
|
return
|
|
|
|
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
|
|
G.assailant = M
|
|
G.affecting = src
|
|
|
|
M.put_in_active_hand(G)
|
|
|
|
grabbed_by += G
|
|
G.synch()
|
|
|
|
LAssailant = M
|
|
|
|
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)
|
|
else
|
|
if (!( paralysis ))
|
|
if (prob(25))
|
|
Paralyse(2)
|
|
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 <B>[] has pushed down [name]!</B>", M), 1)
|
|
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 <B>[] has disarmed [name]!</B>", M), 1)
|
|
return
|
|
|
|
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
|
|
if (!ticker)
|
|
M << "You cannot attack people before the game has started."
|
|
return
|
|
|
|
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
|
M << "No attacking people at spawn, you jackass."
|
|
return
|
|
|
|
switch(M.a_intent)
|
|
if ("help")
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\blue [M] caresses [src] with its scythe like arm."), 1)
|
|
|
|
if ("hurt")
|
|
if ((prob(95) && health > 0))
|
|
playsound(loc, 'slice.ogg', 25, 1, -1)
|
|
var/damage = rand(15, 30)
|
|
if (damage >= 25)
|
|
damage = rand(20, 40)
|
|
if (paralysis < 15)
|
|
Paralyse(rand(10, 15))
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has wounded [name]!</B>", M), 1)
|
|
else
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has slashed [name]!</B>", M), 1)
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
else
|
|
playsound(loc, 'slashmiss.ogg', 25, 1, -1)
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has attempted to lunge at [name]!</B>", M), 1)
|
|
|
|
if ("grab")
|
|
if (M == src)
|
|
return
|
|
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M )
|
|
G.assailant = M
|
|
G.affecting = src
|
|
|
|
M.put_in_active_hand(G)
|
|
|
|
grabbed_by += G
|
|
G.synch()
|
|
|
|
LAssailant = M
|
|
|
|
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 ("disarm")
|
|
playsound(loc, 'pierce.ogg', 25, 1, -1)
|
|
var/damage = 5
|
|
if(prob(95))
|
|
Weaken(rand(10,15))
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has tackled down [name]!</B>", M), 1)
|
|
else
|
|
drop_item()
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>[] has disarmed [name]!</B>", M), 1)
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
return
|
|
|
|
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M as mob)
|
|
if(M.melee_damage_upper == 0)
|
|
M.emote("[M.friendly] [src]")
|
|
else
|
|
for(var/mob/O in viewers(src, null))
|
|
O.show_message("\red <B>[M]</B> [M.attacktext] [src]!", 1)
|
|
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
|
|
|
|
/mob/living/carbon/monkey/attack_metroid(mob/living/carbon/metroid/M as mob)
|
|
if (!ticker)
|
|
M << "You cannot attack people before the game has started."
|
|
return
|
|
|
|
if(M.Victim) return // can't attack while eating!
|
|
|
|
if (health > -100)
|
|
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>The [M.name] has [pick("bit","slashed")] []!</B>", src), 1)
|
|
|
|
var/damage = rand(1, 3)
|
|
|
|
if(istype(src, /mob/living/carbon/metroid/adult))
|
|
damage = rand(20, 40)
|
|
else
|
|
damage = rand(5, 35)
|
|
|
|
adjustBruteLoss(damage)
|
|
|
|
if(M.powerlevel > 0)
|
|
var/stunprob = 10
|
|
var/power = M.powerlevel + rand(0,3)
|
|
|
|
switch(M.powerlevel)
|
|
if(1 to 2) stunprob = 20
|
|
if(3 to 4) stunprob = 30
|
|
if(5 to 6) stunprob = 40
|
|
if(7 to 8) stunprob = 60
|
|
if(9) stunprob = 70
|
|
if(10) stunprob = 95
|
|
|
|
if(prob(stunprob))
|
|
M.powerlevel -= 3
|
|
if(M.powerlevel < 0)
|
|
M.powerlevel = 0
|
|
|
|
for(var/mob/O in viewers(src, null))
|
|
if ((O.client && !( O.blinded )))
|
|
O.show_message(text("\red <B>The [M.name] has shocked []!</B>", src), 1)
|
|
|
|
Weaken(power)
|
|
if (stuttering < power)
|
|
stuttering = power
|
|
Stun(power)
|
|
|
|
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
|
s.set_up(5, 1, src)
|
|
s.start()
|
|
|
|
if (prob(stunprob) && M.powerlevel >= 8)
|
|
adjustFireLoss(M.powerlevel * rand(6,10))
|
|
|
|
|
|
updatehealth()
|
|
|
|
return
|
|
|
|
/mob/living/carbon/monkey/Stat()
|
|
..()
|
|
statpanel("Status")
|
|
stat(null, text("Intent: []", a_intent))
|
|
stat(null, text("Move Mode: []", m_intent))
|
|
if(client && mind)
|
|
if (client.statpanel == "Status")
|
|
if (mind.special_role == "Changeling" && changeling)
|
|
stat("Chemical Storage", changeling.chem_charges)
|
|
stat("Genetic Damage Time", changeling.geneticdamage)
|
|
return
|
|
|
|
|
|
|
|
/mob/living/carbon/monkey/Move()
|
|
if ((!( buckled ) || buckled.loc != loc))
|
|
buckled = null
|
|
if (buckled)
|
|
return
|
|
if (restrained())
|
|
pulling = null
|
|
var/t7 = 1
|
|
if (restrained())
|
|
for(var/mob/M in range(src, 1))
|
|
if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
|
|
return 0
|
|
if ((t7 && pulling && get_dist(src, pulling) <= 1))
|
|
if (pulling.anchored)
|
|
pulling = null
|
|
var/T = loc
|
|
. = ..()
|
|
if (!( isturf(pulling.loc) ))
|
|
pulling = null
|
|
return
|
|
if (!( restrained() ))
|
|
var/diag = get_dir(src, pulling)
|
|
if ((diag - 1) & diag)
|
|
else
|
|
diag = null
|
|
if ((ismob(pulling) && (get_dist(src, pulling) > 1 || diag)))
|
|
if (istype(pulling, type))
|
|
var/mob/M = pulling
|
|
var/mob/t = M.pulling
|
|
M.pulling = null
|
|
step(pulling, get_dir(pulling.loc, T))
|
|
M.pulling = t
|
|
else
|
|
if (pulling)
|
|
if (istype(pulling, /obj/structure/window))
|
|
if(pulling:ini_dir == NORTHWEST || pulling:ini_dir == NORTHEAST || pulling:ini_dir == SOUTHWEST || pulling:ini_dir == SOUTHEAST)
|
|
for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
|
|
pulling = null
|
|
if (pulling)
|
|
step(pulling, get_dir(pulling.loc, T))
|
|
else
|
|
pulling = null
|
|
. = ..()
|
|
if ((s_active && !( contents.Find(s_active) )))
|
|
s_active.close(src)
|
|
|
|
for(var/mob/living/carbon/metroid/M in view(1,src))
|
|
M.UpdateFeed(src)
|
|
return
|
|
|
|
/mob/living/carbon/monkey/verb/removeinternal()
|
|
set name = "Remove Internals"
|
|
set category = "IC"
|
|
internal = null
|
|
return
|
|
|
|
/mob/living/carbon/monkey/var/co2overloadtime = null
|
|
/mob/living/carbon/monkey/var/temperature_resistance = T0C+75
|
|
|
|
/mob/living/carbon/monkey/emp_act(severity)
|
|
if(wear_id) wear_id.emp_act(severity)
|
|
..()
|
|
|
|
/mob/living/carbon/monkey/ex_act(severity)
|
|
flick("flash", flash)
|
|
if (stat == 2 && client)
|
|
gib()
|
|
return
|
|
|
|
if (stat == 2 && !client)
|
|
gibs(loc, viruses)
|
|
del(src)
|
|
return
|
|
switch(severity)
|
|
if(1.0)
|
|
if (stat != 2)
|
|
adjustBruteLoss(200)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
if(2.0)
|
|
if (stat != 2)
|
|
adjustBruteLoss(60)
|
|
adjustFireLoss(60)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
if(3.0)
|
|
if (stat != 2)
|
|
adjustBruteLoss(30)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
if (prob(50))
|
|
Paralyse(10)
|
|
else
|
|
return
|
|
|
|
/mob/living/carbon/monkey/blob_act()
|
|
if (stat != 2)
|
|
adjustFireLoss(60)
|
|
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
|
if (prob(50))
|
|
Paralyse(10)
|
|
if (stat == DEAD && client)
|
|
gib()
|
|
return
|
|
if (stat == DEAD && !client)
|
|
gibs(loc, viruses)
|
|
del(src)
|
|
return
|
|
|
|
|
|
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
|
|
if(!ticker) return 0
|
|
if(!ticker.mode.name == "monkey") return 0
|
|
return 1
|
|
|