634 lines
19 KiB
Plaintext
634 lines
19 KiB
Plaintext
/mob/living/simple_animal
|
|
name = "animal"
|
|
icon = 'icons/mob/animal.dmi'
|
|
health = 20
|
|
maxHealth = 20
|
|
|
|
status_flags = CANPUSH
|
|
|
|
var/icon_living = ""
|
|
var/icon_dead = "" //icon when the animal is dead. Don't use animated icons for this.
|
|
var/icon_gib = null //We only try to show a gibbing animation if this exists.
|
|
|
|
var/list/speak = list()
|
|
var/list/speak_emote = list()// Emotes while speaking IE: Ian [emote], [text] -- Ian barks, "WOOF!". Spoken text is generated from the speak variable.
|
|
var/speak_chance = 0
|
|
var/list/emote_hear = list() //Hearable emotes
|
|
var/list/emote_see = list() //Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
|
|
|
|
var/turns_per_move = 1
|
|
var/turns_since_move = 0
|
|
var/stop_automated_movement = 0 //Use this to temporarely stop random movement or to if you write special movement code for animals.
|
|
var/wander = 1 // Does the mob wander around when idle?
|
|
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
|
|
|
|
//Interaction
|
|
var/response_help = "pokes"
|
|
var/response_disarm = "shoves"
|
|
var/response_harm = "hits"
|
|
var/harm_intent_damage = 3
|
|
var/force_threshold = 0 //Minimum force required to deal any damage
|
|
|
|
//Temperature effect
|
|
var/minbodytemp = 250
|
|
var/maxbodytemp = 350
|
|
|
|
//Healable by medical stacks? Defaults to yes.
|
|
var/healable = 1
|
|
|
|
//Atmos effect - Yes, you can make creatures that require plasma or co2 to survive. N2O is a trace gas and handled separately, hence why it isn't here. It'd be hard to add it. Hard and me don't mix (Yes, yes make all the dick jokes you want with that.) - Errorage
|
|
var/list/atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) //Leaving something at 0 means it's off - has no maximum
|
|
var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
|
|
|
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
|
|
var/melee_damage_lower = 0
|
|
var/melee_damage_upper = 0
|
|
var/armour_penetration = 0 //How much armour they ignore, as a flat reduction from the targets armour value
|
|
var/melee_damage_type = BRUTE //Damage type of a simple mob's melee attack, should it do damage.
|
|
var/list/damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) // 1 for full damage , 0 for none , -1 for 1:1 heal from that source
|
|
var/attacktext = "attacks"
|
|
var/attack_sound = null
|
|
var/friendly = "nuzzles" //If the mob does no damage with it's attack
|
|
var/environment_smash = 0 //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
|
|
|
|
var/speed = 1 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster
|
|
|
|
//Hot simple_animal baby making vars
|
|
var/list/childtype = null
|
|
var/scan_ready = 1
|
|
var/animal_species //Sorry, no spider+corgi buttbabies.
|
|
|
|
//simple_animal access
|
|
var/obj/item/weapon/card/id/access_card = null //innate access uses an internal ID card
|
|
var/flying = 0 //whether it's flying or touching the ground.
|
|
var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against
|
|
var/gold_core_spawnable = 0 //if 1 can be spawned by plasma with gold core, 2 are 'friendlies' spawned with blood
|
|
|
|
var/mob/living/simple_animal/hostile/spawner/nest
|
|
|
|
var/sentience_type = SENTIENCE_ORGANIC // Sentience type, for slime potions
|
|
|
|
var/list/loot = list() //list of things spawned at mob's loc when it dies
|
|
var/del_on_death = 0 //causes mob to be deleted on death, useful for mobs that spawn lootable corpses
|
|
var/deathmessage = ""
|
|
var/death_sound = null //The sound played on death
|
|
|
|
var/allow_movement_on_non_turfs = FALSE
|
|
|
|
var/attacked_sound = "punch" //Played when someone punches the creature
|
|
|
|
var/dextrous = FALSE //If the creature has, and can use, hands
|
|
|
|
|
|
/mob/living/simple_animal/New()
|
|
..()
|
|
verbs -= /mob/verb/observe
|
|
if(!real_name)
|
|
real_name = name
|
|
if(!loc)
|
|
stack_trace("Simple animal being instantiated in nullspace")
|
|
|
|
/mob/living/simple_animal/Login()
|
|
if(src && src.client)
|
|
src.client.screen = list()
|
|
client.screen += client.void
|
|
..()
|
|
|
|
/mob/living/simple_animal/updatehealth()
|
|
..()
|
|
health = Clamp(health, 0, maxHealth)
|
|
|
|
/mob/living/simple_animal/Life()
|
|
if(..()) //alive
|
|
if(!ckey)
|
|
handle_automated_movement()
|
|
handle_automated_action()
|
|
handle_automated_speech()
|
|
return 1
|
|
|
|
/mob/living/simple_animal/update_stat()
|
|
if(status_flags & GODMODE)
|
|
return
|
|
if(stat != DEAD)
|
|
if(health <= 0)
|
|
death()
|
|
else
|
|
stat = CONSCIOUS
|
|
med_hud_set_status()
|
|
|
|
|
|
/mob/living/simple_animal/handle_status_effects()
|
|
..()
|
|
if(stuttering)
|
|
stuttering = 0
|
|
|
|
/mob/living/simple_animal/proc/handle_automated_action()
|
|
return
|
|
|
|
/mob/living/simple_animal/proc/handle_automated_movement()
|
|
if(!stop_automated_movement && wander)
|
|
if((isturf(src.loc) || allow_movement_on_non_turfs) && !resting && !buckled && canmove) //This is so it only moves if it's not inside a closet, gentics machine, etc.
|
|
turns_since_move++
|
|
if(turns_since_move >= turns_per_move)
|
|
if(!(stop_automated_movement_when_pulled && pulledby)) //Some animals don't move when pulled
|
|
var/anydir = pick(cardinal)
|
|
if(Process_Spacemove(anydir))
|
|
Move(get_step(src, anydir), anydir)
|
|
turns_since_move = 0
|
|
return 1
|
|
|
|
/mob/living/simple_animal/proc/handle_automated_speech(var/override)
|
|
if(speak_chance)
|
|
if(prob(speak_chance) || override)
|
|
if(speak && speak.len)
|
|
if((emote_hear && emote_hear.len) || (emote_see && emote_see.len))
|
|
var/length = speak.len
|
|
if(emote_hear && emote_hear.len)
|
|
length += emote_hear.len
|
|
if(emote_see && emote_see.len)
|
|
length += emote_see.len
|
|
var/randomValue = rand(1,length)
|
|
if(randomValue <= speak.len)
|
|
say(pick(speak))
|
|
else
|
|
randomValue -= speak.len
|
|
if(emote_see && randomValue <= emote_see.len)
|
|
emote("me", 1, pick(emote_see))
|
|
else
|
|
emote("me", 2, pick(emote_hear))
|
|
else
|
|
say(pick(speak))
|
|
else
|
|
if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
|
emote("me", 1, pick(emote_see))
|
|
if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len))
|
|
emote("me", 2, pick(emote_hear))
|
|
if((emote_hear && emote_hear.len) && (emote_see && emote_see.len))
|
|
var/length = emote_hear.len + emote_see.len
|
|
var/pick = rand(1,length)
|
|
if(pick <= emote_see.len)
|
|
emote("me", 1, pick(emote_see))
|
|
else
|
|
emote("me", 2, pick(emote_hear))
|
|
|
|
|
|
/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment)
|
|
var/atmos_suitable = 1
|
|
|
|
if(pulledby && pulledby.grab_state >= GRAB_KILL && atmos_requirements["min_oxy"])
|
|
atmos_suitable = 0 //getting choked
|
|
|
|
var/atom/A = src.loc
|
|
if(isturf(A))
|
|
var/turf/T = A
|
|
var/areatemp = get_temperature(environment)
|
|
if( abs(areatemp - bodytemperature) > 40 )
|
|
var/diff = areatemp - bodytemperature
|
|
diff = diff / 5
|
|
//world << "changed from [bodytemperature] by [diff] to [bodytemperature + diff]"
|
|
bodytemperature += diff
|
|
|
|
if(istype(T,/turf/open))
|
|
var/turf/open/ST = T
|
|
if(ST.air)
|
|
var/ST_gases = ST.air.gases
|
|
ST.air.assert_gases(arglist(hardcoded_gases))
|
|
|
|
var/tox = ST_gases["plasma"][MOLES]
|
|
var/oxy = ST_gases["o2"][MOLES]
|
|
var/n2 = ST_gases["n2"][MOLES]
|
|
var/co2 = ST_gases["co2"][MOLES]
|
|
|
|
ST.air.garbage_collect()
|
|
|
|
if(atmos_requirements["min_oxy"] && oxy < atmos_requirements["min_oxy"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["max_oxy"] && oxy > atmos_requirements["max_oxy"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["min_tox"] && tox < atmos_requirements["min_tox"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["max_tox"] && tox > atmos_requirements["max_tox"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["min_n2"] && n2 < atmos_requirements["min_n2"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["max_n2"] && n2 > atmos_requirements["max_n2"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["min_co2"] && co2 < atmos_requirements["min_co2"])
|
|
atmos_suitable = 0
|
|
else if(atmos_requirements["max_co2"] && co2 > atmos_requirements["max_co2"])
|
|
atmos_suitable = 0
|
|
|
|
if(!atmos_suitable)
|
|
adjustBruteLoss(unsuitable_atmos_damage)
|
|
|
|
else
|
|
if(atmos_requirements["min_oxy"] || atmos_requirements["min_tox"] || atmos_requirements["min_n2"] || atmos_requirements["min_co2"])
|
|
adjustBruteLoss(unsuitable_atmos_damage)
|
|
|
|
handle_temperature_damage()
|
|
|
|
/mob/living/simple_animal/proc/handle_temperature_damage()
|
|
if(bodytemperature < minbodytemp)
|
|
adjustBruteLoss(2)
|
|
else if(bodytemperature > maxbodytemp)
|
|
adjustBruteLoss(3)
|
|
|
|
/mob/living/simple_animal/gib()
|
|
if(butcher_results)
|
|
for(var/path in butcher_results)
|
|
for(var/i = 1; i <= butcher_results[path];i++)
|
|
new path(src.loc)
|
|
..()
|
|
|
|
/mob/living/simple_animal/gib_animation()
|
|
if(icon_gib)
|
|
new /obj/effect/overlay/temp/gib_animation/animal(loc, icon_gib)
|
|
|
|
/mob/living/simple_animal/blob_act(obj/effect/blob/B)
|
|
adjustBruteLoss(20)
|
|
return
|
|
|
|
/mob/living/simple_animal/say_quote(input)
|
|
var/ending = copytext(input, length(input))
|
|
if(speak_emote && speak_emote.len && ending != "?" && ending != "!")
|
|
var/emote = pick(speak_emote)
|
|
if(emote)
|
|
return "[emote], \"[input]\""
|
|
return ..()
|
|
|
|
/mob/living/simple_animal/emote(act, m_type=1, message = null)
|
|
if(stat)
|
|
return
|
|
if(act == "scream")
|
|
message = "makes a loud and pained whimper." //ugly hack to stop animals screaming when crushed :P
|
|
act = "me"
|
|
..(act, m_type, message)
|
|
|
|
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
|
|
if(..())
|
|
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
|
attack_threshold_check(damage,M.melee_damage_type)
|
|
return 1
|
|
|
|
/mob/living/simple_animal/bullet_act(obj/item/projectile/Proj)
|
|
if(!Proj)
|
|
return
|
|
apply_damage(Proj.damage, Proj.damage_type)
|
|
Proj.on_hit(src)
|
|
return 0
|
|
|
|
/mob/living/simple_animal/proc/adjustHealth(amount)
|
|
if(status_flags & GODMODE)
|
|
return 0
|
|
bruteloss = Clamp(bruteloss + amount, 0, maxHealth)
|
|
updatehealth()
|
|
return amount
|
|
|
|
/mob/living/simple_animal/adjustBruteLoss(amount)
|
|
if(damage_coeff[BRUTE])
|
|
. = adjustHealth(amount*damage_coeff[BRUTE])
|
|
|
|
/mob/living/simple_animal/adjustFireLoss(amount)
|
|
if(damage_coeff[BURN])
|
|
. = adjustHealth(amount*damage_coeff[BURN])
|
|
|
|
/mob/living/simple_animal/adjustOxyLoss(amount)
|
|
if(damage_coeff[OXY])
|
|
. = adjustHealth(amount*damage_coeff[OXY])
|
|
|
|
/mob/living/simple_animal/adjustToxLoss(amount)
|
|
if(damage_coeff[TOX])
|
|
. = adjustHealth(amount*damage_coeff[TOX])
|
|
|
|
/mob/living/simple_animal/adjustCloneLoss(amount)
|
|
if(damage_coeff[CLONE])
|
|
. = adjustHealth(amount*damage_coeff[CLONE])
|
|
|
|
/mob/living/simple_animal/adjustStaminaLoss(amount)
|
|
return
|
|
|
|
/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M)
|
|
..()
|
|
switch(M.a_intent)
|
|
|
|
if("help")
|
|
if (health > 0)
|
|
visible_message("<span class='notice'>[M] [response_help] [src].</span>")
|
|
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
|
|
|
if("grab")
|
|
grabbedby(M)
|
|
|
|
if("harm", "disarm")
|
|
M.do_attack_animation(src)
|
|
visible_message("<span class='danger'>[M] [response_harm] [src]!</span>")
|
|
playsound(loc, attacked_sound, 25, 1, -1)
|
|
attack_threshold_check(harm_intent_damage)
|
|
add_logs(M, src, "attacked")
|
|
updatehealth()
|
|
return 1
|
|
|
|
/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M)
|
|
if(..()) //successful monkey bite.
|
|
if(stat != DEAD)
|
|
var/damage = rand(1, 3)
|
|
attack_threshold_check(damage)
|
|
return 1
|
|
if (M.a_intent == "help")
|
|
if (health > 0)
|
|
visible_message("<span class='notice'>[M.name] [response_help] [src].</span>")
|
|
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
|
|
|
return
|
|
|
|
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M)
|
|
if(..()) //if harm or disarm intent.
|
|
if(M.a_intent == "disarm")
|
|
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
|
visible_message("<span class='danger'>[M] [response_disarm] [name]!</span>", \
|
|
"<span class='userdanger'>[M] [response_disarm] [name]!</span>")
|
|
add_logs(M, src, "disarmed")
|
|
else
|
|
var/damage = rand(15, 30)
|
|
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
|
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
|
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
|
attack_threshold_check(damage)
|
|
add_logs(M, src, "attacked")
|
|
return 1
|
|
|
|
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
|
|
if(..()) //successful larva bite
|
|
var/damage = rand(5, 10)
|
|
if(stat != DEAD)
|
|
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
|
attack_threshold_check(damage)
|
|
return 1
|
|
|
|
/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M)
|
|
if(..()) //successful slime attack
|
|
var/damage = rand(15, 25)
|
|
if(M.is_adult)
|
|
damage = rand(20, 35)
|
|
attack_threshold_check(damage)
|
|
return 1
|
|
|
|
/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE)
|
|
if(damage <= force_threshold || !damage_coeff[damagetype])
|
|
visible_message("<span class='warning'>[src] looks unharmed.</span>")
|
|
else
|
|
adjustBruteLoss(damage)
|
|
updatehealth()
|
|
|
|
/mob/living/simple_animal/movement_delay()
|
|
. = ..()
|
|
|
|
. = speed
|
|
|
|
. += config.animal_delay
|
|
|
|
/mob/living/simple_animal/Stat()
|
|
..()
|
|
if(statpanel("Status"))
|
|
stat(null, "Health: [round((health / maxHealth) * 100)]%")
|
|
return 1
|
|
|
|
/mob/living/simple_animal/death(gibbed)
|
|
if(nest)
|
|
nest.spawned_mobs -= src
|
|
nest = null
|
|
if(loot.len)
|
|
for(var/i in loot)
|
|
new i(loc)
|
|
if(dextrous)
|
|
unEquip(r_hand)
|
|
unEquip(l_hand)
|
|
if(!gibbed)
|
|
if(death_sound)
|
|
playsound(get_turf(src),death_sound, 200, 1)
|
|
if(deathmessage)
|
|
visible_message("<span class='danger'>\The [src] [deathmessage]</span>")
|
|
else if(!del_on_death)
|
|
visible_message("<span class='danger'>\The [src] stops moving...</span>")
|
|
if(del_on_death)
|
|
ghostize()
|
|
qdel(src)
|
|
else
|
|
health = 0
|
|
icon_state = icon_dead
|
|
stat = DEAD
|
|
density = 0
|
|
lying = 1
|
|
..()
|
|
|
|
/mob/living/simple_animal/ex_act(severity, target)
|
|
..()
|
|
switch (severity)
|
|
if (1)
|
|
gib()
|
|
return
|
|
|
|
if (2)
|
|
adjustBruteLoss(60)
|
|
|
|
if(3)
|
|
adjustBruteLoss(30)
|
|
|
|
/mob/living/simple_animal/proc/CanAttack(atom/the_target)
|
|
if(see_invisible < the_target.invisibility)
|
|
return 0
|
|
if (isliving(the_target))
|
|
var/mob/living/L = the_target
|
|
if(L.stat != CONSCIOUS)
|
|
return 0
|
|
if (istype(the_target, /obj/mecha))
|
|
var/obj/mecha/M = the_target
|
|
if (M.occupant)
|
|
return 0
|
|
return 1
|
|
|
|
/mob/living/simple_animal/handle_fire()
|
|
return
|
|
|
|
/mob/living/simple_animal/update_fire()
|
|
return
|
|
|
|
/mob/living/simple_animal/IgniteMob()
|
|
return FALSE
|
|
|
|
/mob/living/simple_animal/ExtinguishMob()
|
|
return
|
|
|
|
/mob/living/simple_animal/revive(full_heal = 0, admin_revive = 0)
|
|
if(..()) //successfully ressuscitated from death
|
|
icon = initial(icon)
|
|
icon_state = icon_living
|
|
density = initial(density)
|
|
lying = 0
|
|
. = 1
|
|
|
|
/mob/living/simple_animal/fully_heal(admin_revive = 0)
|
|
health = maxHealth
|
|
..()
|
|
|
|
/mob/living/simple_animal/proc/make_babies() // <3 <3 <3
|
|
if(gender != FEMALE || stat || !scan_ready || !childtype || !animal_species || ticker.current_state != GAME_STATE_PLAYING)
|
|
return 0
|
|
scan_ready = 0
|
|
spawn(400)
|
|
scan_ready = 1
|
|
var/alone = 1
|
|
var/mob/living/simple_animal/partner
|
|
var/children = 0
|
|
for(var/mob/M in view(7, src))
|
|
if(M.stat != CONSCIOUS) //Check if it's conscious FIRST.
|
|
continue
|
|
else if(istype(M, childtype)) //Check for children SECOND.
|
|
children++
|
|
else if(istype(M, animal_species))
|
|
if(M.ckey)
|
|
continue
|
|
else if(!istype(M, childtype) && M.gender == MALE) //Better safe than sorry ;_;
|
|
partner = M
|
|
|
|
else if(istype(M, /mob/living) && !faction_check(M)) //shyness check. we're not shy in front of things that share a faction with us.
|
|
alone = 0
|
|
continue
|
|
if(alone && partner && children < 3)
|
|
var/childspawn = pickweight(childtype)
|
|
new childspawn(loc)
|
|
return 1
|
|
return 0
|
|
|
|
/mob/living/simple_animal/stripPanelUnequip(obj/item/what, mob/who, where, child_override)
|
|
if(!child_override)
|
|
src << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
|
return
|
|
else
|
|
..()
|
|
|
|
/mob/living/simple_animal/stripPanelEquip(obj/item/what, mob/who, where, child_override)
|
|
if(!child_override)
|
|
src << "<span class='warning'>You don't have the dexterity to do this!</span>"
|
|
return
|
|
else
|
|
..()
|
|
|
|
/mob/living/simple_animal/update_canmove()
|
|
if(paralysis || stunned || weakened || stat || resting)
|
|
drop_r_hand()
|
|
drop_l_hand()
|
|
canmove = 0
|
|
else if(buckled)
|
|
canmove = 0
|
|
else
|
|
canmove = 1
|
|
update_transform()
|
|
update_action_buttons_icon()
|
|
return canmove
|
|
|
|
/mob/living/simple_animal/update_transform()
|
|
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
|
|
var/changed = 0
|
|
|
|
if(resize != RESIZE_DEFAULT_SIZE)
|
|
changed++
|
|
ntransform.Scale(resize)
|
|
resize = RESIZE_DEFAULT_SIZE
|
|
|
|
if(changed)
|
|
animate(src, transform = ntransform, time = 2, easing = EASE_IN|EASE_OUT)
|
|
|
|
|
|
|
|
/mob/living/simple_animal/Destroy()
|
|
if(nest)
|
|
nest.spawned_mobs -= src
|
|
nest = null
|
|
return ..()
|
|
|
|
|
|
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
|
|
return
|
|
|
|
/mob/living/simple_animal/update_sight()
|
|
if(!client)
|
|
return
|
|
if(stat == DEAD)
|
|
sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
|
see_in_dark = 8
|
|
see_invisible = SEE_INVISIBLE_OBSERVER
|
|
return
|
|
|
|
see_invisible = initial(see_invisible)
|
|
see_in_dark = initial(see_in_dark)
|
|
sight = initial(sight)
|
|
|
|
if(client.eye != src)
|
|
var/atom/A = client.eye
|
|
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
|
|
return
|
|
|
|
/mob/living/simple_animal/get_idcard()
|
|
return access_card
|
|
|
|
//Dextrous simple mobs can use hands!
|
|
/mob/living/simple_animal/create_mob_hud()
|
|
if(client && !hud_used && dextrous)
|
|
hud_used = new /datum/hud/dextrous(src, ui_style2icon(client.prefs.UI_style))
|
|
|
|
/mob/living/simple_animal/activate_hand(selhand)
|
|
if(!dextrous)
|
|
return ..()
|
|
if(istext(selhand))
|
|
selhand = lowertext(selhand)
|
|
if(selhand == "right" || selhand == "r")
|
|
selhand = 0
|
|
if(selhand == "left" || selhand == "l")
|
|
selhand = 1
|
|
if(selhand != src.hand)
|
|
swap_hand()
|
|
else
|
|
mode()
|
|
|
|
/mob/living/simple_animal/swap_hand()
|
|
if(!dextrous)
|
|
return ..()
|
|
var/obj/item/held_item = get_active_hand()
|
|
if(held_item)
|
|
if(istype(held_item, /obj/item/weapon/twohanded))
|
|
var/obj/item/weapon/twohanded/T = held_item
|
|
if(T.wielded == 1)
|
|
usr << "<span class='warning'>Your other hand is too busy holding the [T.name].</span>"
|
|
return
|
|
hand = !hand
|
|
if(hud_used && hud_used.inv_slots[slot_l_hand] && hud_used.inv_slots[slot_r_hand])
|
|
var/obj/screen/inventory/hand/H
|
|
H = hud_used.inv_slots[slot_l_hand]
|
|
H.update_icon()
|
|
H = hud_used.inv_slots[slot_r_hand]
|
|
H.update_icon()
|
|
|
|
/mob/living/simple_animal/UnarmedAttack(atom/A, proximity)
|
|
if(!dextrous)
|
|
return ..()
|
|
if(!ismob(A))
|
|
A.attack_hand(src)
|
|
update_hand_icons()
|
|
|
|
/mob/living/simple_animal/put_in_hands(obj/item/I)
|
|
..()
|
|
update_hand_icons()
|
|
|
|
/mob/living/simple_animal/proc/update_hand_icons()
|
|
if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD)
|
|
if(r_hand)
|
|
r_hand.layer = ABOVE_HUD_LAYER
|
|
r_hand.screen_loc = ui_rhand
|
|
client.screen |= r_hand
|
|
if(l_hand)
|
|
l_hand.layer = ABOVE_HUD_LAYER
|
|
l_hand.screen_loc = ui_lhand
|
|
client.screen |= l_hand
|
|
|