Bear Stuff (#877)

bugfix: "Space bears can now control their movement in space."
rscadd: "Bears are now stronger in space or low pressure, weaker in pressurised environments"
soundadd: "Rawr!"
rscadd: "Added more bears!"
rscadd: "Added a new severe event."
This commit is contained in:
NanakoAC
2016-09-15 12:19:04 +03:00
committed by skull132
parent 0fff845697
commit 11e30e99c4
23 changed files with 596 additions and 95 deletions
+33
View File
@@ -0,0 +1,33 @@
/datum/event/bear_attack
startWhen = 2
announceWhen = 20
var/list/possible_turfs = list()
var/spawn_type
var/spawn_number
/datum/event/bear_attack/setup()
for(var/areapath in typesof(/area/maintenance))
var/area/A = locate(areapath)
for(var/turf/simulated/floor/F in A.contents)
if(turf_clear(F))
possible_turfs |= F
if (severity <= EVENT_LEVEL_MODERATE)//Moderate spacebear event disabled by head developer veto
spawn_type = /mob/living/simple_animal/hostile/bear
spawn_number = rand(8,16)
else
spawn_type = /mob/living/simple_animal/hostile/bear/spatial
spawn_number = rand(4,6)
/datum/event/bear_attack/start()
var/i
for (i = 0,i < spawn_number, i++)
new spawn_type(pick(possible_turfs))
/datum/event/bear_attack/announce()
if (severity <= EVENT_LEVEL_MODERATE)
command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
else
command_announcement.Announce("Highly dangerous bioweapons have escaped from a nearby research facility and boarded [station_name()]. Station security is advised to be on high alert.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg')
+3
View File
@@ -165,6 +165,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 50, list(ASSIGNMENT_SECURITY = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 12), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Major Vermin Infestation", /datum/event/infestation, 60, list(ASSIGNMENT_JANITOR = 15, ASSIGNMENT_SECURITY = 15)),
)
/datum/event_container/major
@@ -176,6 +177,8 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 40, list(ASSIGNMENT_ENGINEER = 10),1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 50, list(ASSIGNMENT_ENGINEER = 10, ASSIGNMENT_GARDENER = 20), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 20, list(ASSIGNMENT_MEDICAL = 13), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Bluespace Bears", /datum/event/bear_attack, 60, list(ASSIGNMENT_SECURITY = 10), 1),
)
//NOTE: Re added nothing option, but with fairly low weight
@@ -6,7 +6,7 @@
var/list/antibodies = list()
var/last_eating = 0 //Not sure what this does... I found it hidden in food.dm
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
var/analgesic = 0 // when this is set, the mob isn't affected by shock or pain
// life should decrease this by 1 every tick
// total amount of wounds on mob, used to spread out healing and the like over all wounds
+2 -2
View File
@@ -189,14 +189,14 @@
// End BS12 momentum-transfer code.
/mob/living/attack_generic(var/mob/user, var/damage, var/attack_message)
if(!damage)
return
adjustBruteLoss(damage)
user.attack_log += text("\[[time_stamp()]\] <font color='red'>attacked [src.name] ([src.ckey])</font>")
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>was attacked by [user.name] ([user.ckey])</font>")
src.visible_message("<span class='danger'>[user] has [attack_message] [src]!</span>")
if (attack_message)
src.visible_message("<span class='danger'>[user] has [attack_message] [src]!</span>")
user.do_attack_animation(src)
spawn(1) updatehealth()
return 1
+2 -1
View File
@@ -46,4 +46,5 @@
var/mouth_size = 2//how large of a creature it can swallow at once, and how big of a bite it can take out of larger things
var/eat_types = 0//This is a bitfield which must be initialised in New(). The valid values for it are in devour.dm
var/datum/reagents/metabolism/ingested = null
var/underdoor //Used for mobs that can walk through maintenance hatches - drones, pais, and spiderbots
var/underdoor //Used for mobs that can walk through maintenance hatches - drones, pais, and spiderbots
var/life_tick = 0 // The amount of life ticks that have processed on this mob.
@@ -1,7 +1,10 @@
#define BEARMODE_INDOORS 1
#define BEARMODE_SPACE 2
//Space bears!
/mob/living/simple_animal/hostile/bear
name = "space bear"
desc = "RawrRawr!!"
desc = "You should walk away, quickly!"
icon_state = "bear"
icon_living = "bear"
icon_dead = "bear_dead"
@@ -10,19 +13,42 @@
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
speak_chance = 1
turns_per_move = 5
speak_chance = 10
turns_per_move = 7
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
stop_automated_movement_when_pulled = 0
maxHealth = 60
health = 60
melee_damage_lower = 20
melee_damage_upper = 30
maxHealth = 80
melee_damage_lower = 16
melee_damage_upper = 24
break_stuff_probability = 80
mob_size = 17
var/turns_since_hit = 0//If the bear chases someone too long without hitting them, it will try to change to another nearby target instead
attacktext = null//This allows custom attacking emotes
var/quiet_sounds = list('sound/effects/creatures/bear_quiet_1.ogg',
'sound/effects/creatures/bear_quiet_2.ogg',
'sound/effects/creatures/bear_quiet_3.ogg',
'sound/effects/creatures/bear_quiet_4.ogg',
'sound/effects/creatures/bear_quiet_5.ogg',
'sound/effects/creatures/bear_quiet_6.ogg')
var/loud_sounds = list('sound/effects/creatures/bear_loud_1.ogg',
'sound/effects/creatures/bear_loud_2.ogg',
'sound/effects/creatures/bear_loud_3.ogg',
'sound/effects/creatures/bear_loud_4.ogg')
var/bearmode
//Bears in space, or other low-pressure environments are stronger. Higher health, faster movement, longer aggression before being tired
var/anger
//An angry bear will immediately attack anyone it sees without warning
//Anger decreases at 1 point per minute
//Any amount of anger causes instant aggro, quantity of it is only a duration
var/health_last_tick = 0
//Space bears aren't affected by atmos.
min_oxy = 0
@@ -38,6 +64,9 @@
faction = "russian"
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
/mob/living/simple_animal/hostile/bear/Hudson
name = "Hudson"
@@ -46,128 +75,466 @@
response_disarm = "gently pushes aside"
response_harm = "pokes"
/mob/living/simple_animal/hostile/bear/New()
..()
update_bearmode()
/mob/living/simple_animal/hostile/bear/proc/set_stance(var/input)
var/previous = stance
stance = input
if (stance != previous)
stance_step = 0
/mob/living/simple_animal/hostile/bear/Life()
. =..()
if(!.)
if (stat != CONSCIOUS)
return
if(loc && istype(loc,/turf/space))
icon_state = "bear"
else
icon_state = "bearfloor"
if (life_tick % 5 == 0)
update_bearmode()
//This covers cases where the bear is damaged by things it can't detect.
//Most notably, security bots, beepsky kept murdering them without resistance
if (health < health_last_tick && stance != HOSTILE_STANCE_TIRED)
anger++
instant_aggro()
if (life_tick % 30 == 0)//A point of anger wears off per minute
anger = max(0, anger-1)
switch(stance)
if(HOSTILE_STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(stance_step >= 15) //rests for 10 ticks
if(target_mob && target_mob in ListTargets(10))
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
set_stance(HOSTILE_STANCE_ATTACK) //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
stance = HOSTILE_STANCE_IDLE
set_stance(HOSTILE_STANCE_IDLE)
if(HOSTILE_STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
if(target_mob && target_mob in ListTargets(10))
if(!(SA_attackable(target_mob)))
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
found_mob = 1
src.set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(target_mob && (target_mob in ListTargets(10)) && !(SA_attackable(target_mob)))
found_mob = 1
else
LoseTarget()
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
if(!found_mob)
if(target_mob)
found_mob = 1
if (found_mob)
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
stance_step++
set_dir(get_dir(src,target_mob)) //Keep staring at the mob
if(stance_step in list(1,4,7)) //every 3 ticks
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
if(action)
custom_emote(1,action)
speak_audio()
else
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
stance = HOSTILE_STANCE_IDLE
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
stance = HOSTILE_STANCE_ATTACK
if (anger && found_mob)
instant_aggro()//If we're angry and someone is nearby, skip waiting and charge them
if(stance_step <= -20*bearmode) //If we have not found a mob for 20-ish ticks, revert to idle mode
set_stance(HOSTILE_STANCE_IDLE)
stop_automated_movement = 0
if(stance_step >= 12) //If this mob just refuses to get out of our territory, then we attack
anger += 3
set_stance(HOSTILE_STANCE_ATTACK)
growl_loud()
if(HOSTILE_STANCE_ATTACKING)
if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest
custom_emote(1, "is worn out and needs to rest." )
stance = HOSTILE_STANCE_TIRED
stance_step = 0
walk(src, 0) //This stops the bear's walking
turns_since_hit++
stance_step++
if(stance_step >= (16+(anger*2))*bearmode) //attacks a while, then it gets tired and needs to rest. An angry bear will chase longer
tire_out()
return
//If we're having no luck attacking our current target
if (target_mob && !Adjacent(target_mob) && turns_since_hit > 3)
LoseTarget()
else
set_dir(get_dir(src,target_mob))
health_last_tick = health
//Causes the bear to find and start attacking the nearest target.
//This will overwrite any existing target if a different one is closer
//If there are no other suitable targets, targeting will not be changed
/mob/living/simple_animal/hostile/bear/FindTarget()
var/turf/here = get_turf(src)
var/mob/nearest_target = null
var/nearest_dist = 99999
var/mob/nearest_downed_target = null
var/nearest_downed_dist = 99999
for(var/atom/A in ListTargets(10))
if(A == src || A == target_mob)//We're only interested in alternatives to our current target
continue
var/dist = get_dist(here, get_turf(A)) < nearest_dist
if(isliving(A))
var/mob/living/L = A
if(L.faction == src.faction && !attack_same)
continue
else if(L in friends)
continue
else
if(!L.stat == CONSCIOUS)
if (dist < nearest_dist)
nearest_target = L
nearest_dist = dist
else if (L.stat != DEAD)//Unconscious people are lower priority, only targeted if nobody nearby is standing
if (dist < nearest_downed_dist)
nearest_downed_target = L
nearest_downed_dist = dist
else if(istype(A, /obj/mecha))
var/obj/mecha/M = A
if (M.occupant)
if (dist < nearest_dist)
nearest_target = M
nearest_dist = dist
if(istype(A, /obj/machinery/bot))
var/obj/machinery/bot/B = A
if (B.health > 0)
if (dist < nearest_dist)
nearest_target = B
nearest_dist = dist
if (nearest_target)
target_mob = nearest_target
FoundTarget()
return nearest_target
else if (nearest_downed_target)
target_mob = nearest_downed_target
FoundTarget()
return nearest_downed_target
return target_mob
//If neither of the above is true, dont change the target
/mob/living/simple_animal/hostile/bear/proc/tire_out()
custom_emote(1, "is worn out and needs to rest." )
set_stance(HOSTILE_STANCE_TIRED)
speak_audio()
stance_step = 0
walk(src, 0) //This stops the bear's walking
/mob/living/simple_animal/hostile/bear/spatial/tire_out()
..()
spawn(5)
teleport()//Bluespace bears teleport away to rest
/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
target_mob = user
var/healthbefore = health
..()
spawn(1)
if (health < healthbefore)//Hurting the bear makes it mad
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
target_mob = user
anger++
instant_aggro()
/mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob)
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
stance = HOSTILE_STANCE_ALERT
stance_step = 6
target_mob = M
var/healthbefore = health
..()
spawn(1)
if (health < healthbefore)//Hurting the bear makes it mad
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
target_mob = M
anger++
instant_aggro()
/mob/living/simple_animal/hostile/bear/bullet_act(obj/item/projectile/P, def_zone)//Teleport around when shot, so its harder to burst it down with a carbine
var/healthbefore = health
..()
spawn(1)
if (health < healthbefore)
instant_aggro()
/mob/living/simple_animal/hostile/bear/ex_act()
var/healthbefore = health
..()
spawn(1)
if (health < healthbefore)
instant_aggro()
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
return //No drifting in space for space bears!
inertia_dir = 0
return 1 //No drifting in space for space bears!
//Fixed this, it wasnt working
/mob/living/simple_animal/hostile/bear/FindTarget()
. = ..()
if(.)
custom_emote(1,"stares alertly at [.]")
stance = HOSTILE_STANCE_ALERT
/mob/living/simple_animal/hostile/bear/FoundTarget()
if(target_mob)
turns_since_hit = 0
custom_emote(1,"stares alertly at [target_mob]")
speak_audio()
//If we're idle, move up to alert.
//But don't drop down to alert if we're already in combat
if (stance == HOSTILE_STANCE_IDLE)
set_stance(HOSTILE_STANCE_ALERT)
else if (stance == HOSTILE_STANCE_ATTACKING)
MoveToTarget()
/mob/living/simple_animal/hostile/bear/LoseTarget()
..(5)
//If we're still angry, try to find someone else to attack
if (anger)
FindTarget()
if (!anger || !target_mob)
//If the anger has subsided, then give up the chase and let them go
//But we'll get mad again soon if they don't go.
if (stance > HOSTILE_STANCE_ALERT)//If we're currently above alert
set_stance(HOSTILE_STANCE_ALERT)//Drop to alert and cease attacking
target_mob = null
walk(src, 0)
/mob/living/simple_animal/hostile/bear/AttackingTarget()
if(!Adjacent(target_mob))
var/targetname = target_mob.name
if(..())
turns_since_hit = 0
custom_emote(1, pick( list("crushes [targetname] in its arms","slashes at [targetname]", "bites [targetname]", "mauls [targetname]", "tears into [targetname]", "rends [targetname]") ) )
if (prob(15))
growl_loud()
else if (prob(10))
growl_soft()
/mob/living/simple_animal/hostile/bear/proc/update_bearmode()
turns_per_move = initial(turns_per_move)
if (anger >= 3)
turns_per_move -= 1
var/former = bearmode
bearmode = BEARMODE_INDOORS
if(loc && istype(loc,/turf/space))
bearmode = BEARMODE_SPACE
else
if(istype(loc,/turf))
var/turf/T = loc
var/datum/gas_mixture/environment = T.return_air()
if (environment.return_pressure() <= 80)
bearmode = BEARMODE_SPACE
if (bearmode != former)
var/healthpercent
if (bearmode == BEARMODE_SPACE)
custom_emote(1, "looks bright, energised and aggressive!" )
healthpercent = health / maxHealth
maxHealth = initial(maxHealth) * 1.5
health = maxHealth * healthpercent
melee_damage_lower = initial(melee_damage_lower)*1.2
melee_damage_upper = initial(melee_damage_upper)*1.2
turns_per_move -= 2
growl_loud()
else
custom_emote(1, "looks darker and more subdued." )
healthpercent = health / maxHealth
maxHealth = initial(maxHealth)
health = maxHealth * healthpercent
melee_damage_lower = initial(melee_damage_lower)
melee_damage_upper = initial(melee_damage_upper)
growl_soft()
update_icons()
/mob/living/simple_animal/hostile/bear/update_icons()
if (stat == DEAD)
icon_state = "bear_dead"
else if (bearmode == BEARMODE_INDOORS)
icon_state = "bearfloor"
else
icon_state = "bear"
/mob/living/simple_animal/hostile/bear/speak_audio()
if (anger > 5 || (anger && prob(25)))
growl_loud()
else
growl_soft()
//Plays a random selection of six sounds, at a low volume
//This is triggered randomly periodically by the bear
/mob/living/simple_animal/hostile/bear/proc/growl_soft()
var/sound = pick(quiet_sounds)
playsound(src, sound, 50, 1,3, usepressure = 0)
//Plays a loud sound from a selection of four
//Played when bear is attacking or dies
/mob/living/simple_animal/hostile/bear/proc/growl_loud()
var/sound = pick(loud_sounds)
playsound(src, sound, 85, 1, 5, usepressure = 0)
//A special bear subclass which is more powerful and has the ability to teleport around to seek out prey.
//It dislikes other bears and refuses to cooperate with them. If two of them see each other, one or both will teleport away
//Therefore the crew never has to fight more than one at a time
/mob/living/simple_animal/hostile/bear/spatial
name = "bluespace bear"
desc = "*bzzt*..Rawr!!"
maxHealth = 130
turns_per_move = 7
break_stuff_probability = 100//Constantly smashing everything nearby
speak_chance = 15
var/idletime
var/focus_time//How long we've focused on this target
var/teleport_delay = 60
var/tactical_delay = 3//Procs between shortrange teleports
//Called when we want to bypass ticks and attack immediately. For example in response to being shot
//This calls several procs and some duplicated code from the parent class to immediately put us in an assault state and lash out
/mob/living/simple_animal/hostile/bear/proc/instant_aggro()
if (stance < HOSTILE_STANCE_ATTACK)
growl_loud()
if(!target_mob)
FindTarget()
if(target_mob)
growl_loud()
if(destroy_surroundings)
DestroySurroundings()
MoveToTarget()
AttackTarget()//When first aggroed, this causes the bear to instantly lash out and counter any melee attacker nearby
else
set_stance(HOSTILE_STANCE_ALERT)
//These bears are always in spacemode
/mob/living/simple_animal/hostile/bear/spatial/update_bearmode()
turns_per_move = initial(turns_per_move)
if (anger >= 3)
turns_per_move -= 1
bearmode = BEARMODE_SPACE
var/healthpercent = health / maxHealth
maxHealth = initial(maxHealth) * 1.5
health = maxHealth * healthpercent
melee_damage_lower = initial(melee_damage_lower)*1.2
melee_damage_upper = initial(melee_damage_upper)*1.2
turns_per_move -= 2
update_icons()
/mob/living/simple_animal/hostile/bear/spatial/Life()
..()
if (stat != CONSCIOUS)
return
custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
var/damage = rand(20,30)
if(ishuman(target_mob))
var/mob/living/carbon/human/H = target_mob
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
var/obj/item/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"), sharp=1, edge=1)
return H
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
return L
//else if(istype(target_mob,/obj/mecha))
//var/obj/mecha/M = target_mob
//M.attack_animal(src)
//return M
var/time_to_go = 0
//If they've sat around too long without finding a mob to target, then they'll teleport elsewhere to seek prey
if (stance == HOSTILE_STANCE_IDLE)
idletime++
if (idletime >= teleport_delay)
time_to_go = 1
else
idletime = 0
//Randomly make shortrange teleports in the vicinity of the target
if ((stance == HOSTILE_STANCE_ATTACKING)&& target_mob)
focus_time++
if (focus_time % tactical_delay == 0)
teleport_tactical(target_mob)
//Teleport away from other bears
for (var/mob/living/simple_animal/hostile/bear/bear in view(world.view, get_turf(src)))
if (bear != src && bear.stat != DEAD)
time_to_go = 1
if (time_to_go)
idletime = 0
stance = HOSTILE_STANCE_IDLE
teleport()
growl_soft()
//Used to move to a new part of the station when it sees another bear, or it hasnt found any prey
/mob/living/simple_animal/hostile/bear/spatial/proc/teleport()
if (stat == CONSCIOUS)
var/area/A = random_station_area()
var/turf/target = A.random_space()
sparks()
forceMove(target)
sparks()
//Used, with some luck, to reposition near the target. Hiding behind glass is a bad idea
//Picks a random tile in the target's area and teleports there. Might be closer, might be farther away
//Who knows, it's unpredictable. But definitely dangerous.
//This allows the target to escape as often as it allows the bear to attack
/mob/living/simple_animal/hostile/bear/spatial/proc/teleport_tactical()
if (target_mob && stat == CONSCIOUS)
var/area/A = get_area(target_mob)
if (A)
var/turf/target = A.random_space()
sparks()
forceMove(target)
sparks()
return 1
return 0
/mob/living/simple_animal/hostile/bear/spatial/bullet_act(obj/item/projectile/P, def_zone)//Teleport around when shot, so its harder to burst it down with a carbine
..(P, def_zone)
if (prob(P.damage*1.5))//Bear has a good chance of teleporting when shot, making it harder to burst down
teleport_tactical()
/mob/living/simple_animal/hostile/bear/spatial/proc/sparks()
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(10, 1, get_turf(src))
s.start()
spawn(2)
qdel(s)
/mob/living/simple_animal/hostile/bear/spatial/FoundTarget()
..()
focus_time = 0
#undef BEARMODE_INDOORS
#undef BEARMODE_SPACE
@@ -56,16 +56,24 @@
stance = HOSTILE_STANCE_ATTACK
T = B
break
if (T != target_mob)
target_mob = T
FoundTarget()
return T
//This proc is called after a target is acquired
/mob/living/simple_animal/hostile/proc/FoundTarget()
return
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
return
/mob/living/simple_animal/hostile/proc/MoveToTarget()
stop_automated_movement = 1
if(!target_mob || SA_attackable(target_mob))
stance = HOSTILE_STANCE_IDLE
LoseTarget()
if(target_mob in ListTargets(10))
if(ranged)
if(get_dist(src, target_mob) <= 6)
@@ -83,7 +91,7 @@
LoseTarget()
return 0
if(!(target_mob in ListTargets(10)))
LostTarget()
LoseTarget()
return 0
if(get_dist(src, target_mob) <= 1) //Attacking
AttackingTarget()
@@ -103,15 +111,16 @@
if(istype(target_mob,/obj/machinery/bot))
var/obj/machinery/bot/B = target_mob
B.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
return B
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE
target_mob = null
walk(src, 0)
LostTarget()
/mob/living/simple_animal/hostile/proc/LostTarget()
stance = HOSTILE_STANCE_IDLE
walk(src, 0)
return
/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
@@ -147,9 +156,9 @@
MoveToTarget()
if(HOSTILE_STANCE_ATTACKING)
if(destroy_surroundings)
if(!AttackTarget() && destroy_surroundings)//hit a window OR a mob, not both at once
DestroySurroundings()
AttackTarget()
/mob/living/simple_animal/hostile/proc/OpenFire(target_mob)
var/target = target_mob
@@ -197,10 +206,12 @@
for(var/obj/structure/window/obstacle in get_step(src, dir))
if(obstacle.dir == reverse_dir[dir]) // So that windows get smashed in the right order
obstacle.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
return
return 1
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
if(istype(obstacle, /obj/structure/window) || istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table) || istype(obstacle, /obj/structure/grille))
obstacle.attack_generic(src,rand(melee_damage_lower,melee_damage_upper),attacktext)
return 1
return 0
/mob/living/simple_animal/hostile/proc/check_horde()
@@ -234,7 +245,7 @@
else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille))
A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper))
Move(T)
FindTarget()
target_mob = FindTarget()
if(!target_mob || enroute)
spawn(10)
if(!src.stat)
@@ -103,6 +103,7 @@
..()
seek_move_delay = (1 / seek_speed) / (world.tick_lag / 10)//number of ticks between moves
turns_since_scan = rand(min_scan_interval, max_scan_interval)//Randomise this at the start so animals don't sync up
health = maxHealth
verbs -= /mob/verb/observe
health = maxHealth
if (mob_size)
@@ -144,7 +145,7 @@
/mob/living/simple_animal/Life()
..()
life_tick++
//Health
updatehealth()