- Removed the 'alive' variable from simple animals. It was redundant, since stat already tells that.

- Standardized critter proc declarations
- Added an AdjustBruteLocc() proc to simple animals
- Fixed the bug where simple animals would move when bumped, even when buckled
- Added space bears. They have some decently complex AI which revolves around stances, which include idle, alert, attack, attacking and tired. They are quite a fun little thing. Sprites were in code forever.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4153 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
baloh.matevz
2012-07-23 05:25:13 +00:00
parent 64ddd6d2d9
commit 6adacc576d
12 changed files with 392 additions and 39 deletions
+2 -10
View File
@@ -80,16 +80,8 @@
var/attack_speed = 25 // delay of attack
proc
patrol_step()
seek_target()
Die()
ChaseAttack()
RunAttack()
TakeDamage(var/damage = 0)
Target_Attacker(var/target)
Harvest(var/obj/item/weapon/W, var/mob/living/user)//Controls havesting things from dead critters
AfterAttack(var/mob/living/target)
proc/AfterAttack(var/mob/living/target)
return
+4 -4
View File
@@ -86,7 +86,7 @@
return
patrol_step()
proc/patrol_step()
var/moveto = locate(src.x + rand(-1,1),src.y + rand(-1, 1),src.z)
if (istype(moveto, /turf/simulated/floor) || istype(moveto, /turf/simulated/shuttle/floor) || istype(moveto, /turf/unsimulated/floor)) step_towards(src, moveto)
if(src.aggressive) seek_target()
@@ -114,7 +114,7 @@
M:loc = T
seek_target()
proc/seek_target()
src.anchored = 0
var/T = null
for(var/mob/living/C in view(src.seekrange,src))//TODO: mess with this
@@ -179,13 +179,13 @@
return
ChaseAttack()
proc/ChaseAttack()
for(var/mob/O in viewers(src, null))
O.show_message("\red <B>[src]</B> [src.angertext] at [src.target]!", 1)
return
RunAttack()
proc/RunAttack()
src.attacking = 1
if(ismob(src.target))
+4 -4
View File
@@ -42,7 +42,7 @@ Contains the procs that control attacking critters
O.show_message("\blue [user] touches [src]!", 1)
Target_Attacker(var/target)
proc/Target_Attacker(var/target)
if(!target) return
src.target = target
src.oldtarget_name = target:name
@@ -54,7 +54,7 @@ Contains the procs that control attacking critters
return
TakeDamage(var/damage = 0)
proc/TakeDamage(var/damage = 0)
var/tempdamage = (damage-armor)
if(tempdamage > 0)
src.health -= tempdamage
@@ -64,7 +64,7 @@ Contains the procs that control attacking critters
src.Die()
Die()
proc/Die()
if (!src.alive) return
src.icon_state += "-dead"
src.alive = 0
@@ -74,7 +74,7 @@ Contains the procs that control attacking critters
src.visible_message("<b>[src]</b> [deathtext]")
Harvest(var/obj/item/weapon/W, var/mob/living/user)
proc/Harvest(var/obj/item/weapon/W, var/mob/living/user)
if((!W) || (!user)) return 0
if(src.alive) return 0
return 1
@@ -0,0 +1,163 @@
#define BEAR_STANCE_IDLE 1
#define BEAR_STANCE_ALERT 2
#define BEAR_STANCE_ATTACK 3
#define BEAR_STANCE_ATTACKING 4
#define BEAR_STANCE_TIRED 4
//Space bears!
/mob/living/simple_animal/bear
name = "space bear"
desc = "RawrRawr!!"
icon = 'icons/mob/mob.dmi'
icon_state = "bearspace"
icon_living = "bearspace"
icon_dead = "bear_d"
speak = list("RAWR!","Rawr!","GRR!","Growl!")
speak_emote = list("growls", "roars")
emote_hear = list("rawrs","grumbles","grawls")
emote_see = list("stares ferociously", "stomps")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "pokes the"
health = 60
//Space bears aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
var/stance = BEAR_STANCE_IDLE //Used to determine behavior
var/stance_step = 0 //Used to delay checks depending on what stance the bear is in
var/mob/living/target_mob //Once the bear enters attack stance, it will try to chase this mob. This it to prevent it changing it's mind between multiple mobs.
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
/mob/living/simple_animal/bear/Hudson
name = "Hudson"
desc = ""
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "pokes"
/mob/living/simple_animal/bear/Life()
..()
if(!stat)
if( loc && istype(loc,/turf/space) )
icon_state = "bearspace"
else
icon_state = "bearfloor"
switch(stance)
if(BEAR_STANCE_IDLE)
stop_automated_movement = 0
stance_step++
if(stance_step > 5)
stance_step = 0
for( var/mob/living/L in viewers(7,src) )
if(isbear(L)) continue
if(!L.stat)
emote("stares alertly at [L]")
stance = BEAR_STANCE_ALERT
break
if(BEAR_STANCE_ALERT)
stop_automated_movement = 1
var/found_mob = 0
for( var/mob/living/L in viewers(7,src) )
if(isbear(L)) continue
if(!L.stat)
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
target_mob = L
src.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 [L]", "stares angrily at [L]", "prepares to attack [L]", "closely watches [L]" ) )
if(action)
emote(action)
break
if(!found_mob)
stance_step--
if(stance_step <= -20) //If we have not found a mob for 20-ish ticks, revert to idle mode
stance = BEAR_STANCE_IDLE
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
stance = BEAR_STANCE_ATTACK
if(BEAR_STANCE_ATTACK) //This one should only be active for one tick,
stop_automated_movement = 1
if(!target_mob || target_mob.stat)
stance = BEAR_STANCE_ALERT
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
if(target_mob in viewers(7,src))
walk_to(src, target_mob, 1, 3)
stance = BEAR_STANCE_ATTACKING
stance_step = 0
if(BEAR_STANCE_ATTACKING)
stop_automated_movement = 1
stance_step++
if(!target_mob || target_mob.stat)
stance = BEAR_STANCE_ALERT
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
return
if( !(target_mob in viewers(7,src)) )
stance = BEAR_STANCE_ALERT
stance_step = 5 //Make it very alert, so it quickly attacks again if a mob returns
target_mob = null
return
if( get_dist(src, target_mob) <= 1 ) //Attacking
emote( 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/datum/organ/external/affecting = H.get_organ(ran_zone(dam_zone))
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
else if(isliving(target_mob))
var/mob/living/L = target_mob
L.adjustBruteLoss(damage)
if( stance_step >= 20 ) //attacks for 20 ticks, then it gets tired and needs to rest
emote( "is worn out and needs to rest" )
stance = BEAR_STANCE_TIRED
stance_step = 0
walk(src, 0) //This stops the bear's walking
return
if(BEAR_STANCE_TIRED)
stop_automated_movement = 1
stance_step++
if(stance_step >= 10) //rests for 10 ticks
if(target_mob && target_mob in viewers(7,src))
stance = BEAR_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
else
stance = BEAR_STANCE_IDLE
/mob/living/simple_animal/bear/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(stance != BEAR_STANCE_ATTACK && stance != BEAR_STANCE_ATTACKING)
stance = BEAR_STANCE_ALERT
stance_step = 6
target_mob = user
..()
/mob/living/simple_animal/bear/attack_hand(mob/living/carbon/human/M as mob)
if(stance != BEAR_STANCE_ATTACK && stance != BEAR_STANCE_ATTACKING)
stance = BEAR_STANCE_ALERT
stance_step = 6
target_mob = M
..()
/mob/living/simple_animal/bear/Process_Spacemove(var/check_drift = 0)
return //No drifting in space for space bears!
@@ -267,7 +267,7 @@
..()
//Feeding, chasing food, FOOOOODDDD
if(alive && !resting && !buckled)
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
turns_since_scan = 0
@@ -364,7 +364,7 @@
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/weapon/newspaper))
if(alive)
if(!stat)
for(var/mob/M in viewers(user, null))
if ((M.client && !( M.blinded )))
M.show_message("\blue [user] baps [name] on the nose with the rolled up [O]")
@@ -21,7 +21,7 @@
/mob/living/simple_animal/crab/Life()
..()
//CRAB movement
if(!ckey && alive)
if(!ckey && !stat)
if(isturf(src.loc) && !resting && !buckled) //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)
@@ -43,7 +43,7 @@
health -= 20
Die()
if(istype(O, /obj/item/stack/medical))
if(alive)
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(MED.amount >= 1)
+11 -7
View File
@@ -3,7 +3,6 @@
var/icon_living = ""
var/icon_dead = ""
maxHealth = 20
var/alive = 1
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
@@ -64,10 +63,9 @@
/mob/living/simple_animal/Life()
//Health
if(!alive)
if(stat == DEAD)
if(health > 0)
icon_state = icon_living
alive = 1
stat = CONSCIOUS
density = 1
return
@@ -217,7 +215,11 @@
/mob/living/simple_animal/Bumped(AM as mob|obj)
if(!AM) return
if(isturf(src.loc) && !resting && !buckled)
if(resting || buckled)
return
if(isturf(src.loc))
if(ismob(AM))
var/newamloc = src.loc
src.loc = AM:loc
@@ -304,7 +306,7 @@
/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
if(istype(O, /obj/item/stack/medical))
if(alive)
if(stat != DEAD)
var/obj/item/stack/medical/MED = O
if(health < maxHealth)
if(MED.amount >= 1)
@@ -344,7 +346,6 @@
stat(null, "Health: [round((health / maxHealth) * 100)]%")
/mob/living/simple_animal/proc/Die()
alive = 0
icon_state = icon_dead
stat = DEAD
density = 0
@@ -363,4 +364,7 @@
if(3.0)
health -= 30
health -= 30
/mob/living/simple_animal/adjustBruteLoss(damage)
health -= damage
+4 -9
View File
@@ -56,19 +56,14 @@
return 0
/proc/iscat(A)
if(istype(A, /mob/living/simple_animal/cat/))
if(istype(A, /mob/living/simple_animal/cat))
return 1
return 0
/*proc/ishivebot(A)
if(A && istype(A, /mob/living/silicon/hivebot))
/proc/isbear(A)
if(istype(A, /mob/living/simple_animal/bear))
return 1
return 0*/
/*proc/ishivemainframe(A)
if(A && istype(A, /mob/living/silicon/hive_mainframe))
return 1
return 0*/
return 0
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))