mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 07:33:34 +01:00
Merge pull request #1178 from TheDZD/mobs
simple_animal and simple_animal/hostile Refactor
This commit is contained in:
@@ -603,6 +603,7 @@
|
||||
var/mob/living/simple_animal/hostile/H = M
|
||||
if(malfunctioning)
|
||||
H.faction |= list("lazarus", "\ref[user]")
|
||||
H.robust_searching = 1
|
||||
H.friends += user
|
||||
H.attack_same = 1
|
||||
log_game("[user] has revived hostile mob [target] with a malfunctioning lazarus injector")
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
health = 60
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 30
|
||||
attacktext = "mauls"
|
||||
attack_sound = 'sound/weapons/genhit3.ogg'
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
min_oxy = 0
|
||||
@@ -75,7 +77,7 @@
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
if(target && target in ListTargets())
|
||||
if(!(SA_attackable(target)))
|
||||
if(CanAttack(target))
|
||||
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
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
environment_smash = 1 //Set to 1 to break closets,tables,racks, etc; 2 for walls; 3 for rwalls
|
||||
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
|
||||
var/atom/target
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
|
||||
var/ranged = 0
|
||||
var/rapid = 0
|
||||
var/projectiletype
|
||||
@@ -13,20 +12,24 @@
|
||||
var/casingtype
|
||||
var/move_to_delay = 3 //delay for the automated movement.
|
||||
var/list/friends = list()
|
||||
var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view
|
||||
|
||||
var/aggro_vision_range = 9 //If a mob is aggro, we search in this radius. Defaults to 9 to keep in line with original simple mob aggro radius
|
||||
var/idle_vision_range = 9 //If a mob is just idling around, it's vision range is limited to this. Defaults to 9 to keep in line with original simple mob aggro radius
|
||||
var/ranged_message = "fires" //Fluff text for ranged mobs
|
||||
var/ranged_cooldown = 0 //What the starting cooldown is on ranged attacks
|
||||
var/ranged_cooldown_cap = 3 //What ranged attacks, after being used are set to, to go back on cooldown, defaults to 3 life() ticks
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
|
||||
|
||||
//These vars are related to how mobs locate and target
|
||||
var/robust_searching = 0 //By default, mobs have a simple searching method, set this to 1 for the more scrutinous searching (stat_attack, stat_exclusive, etc), should be disabled on most mobs
|
||||
var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view
|
||||
var/aggro_vision_range = 9 //If a mob is aggro, we search in this radius. Defaults to 9 to keep in line with original simple mob aggro radius
|
||||
var/idle_vision_range = 9 //If a mob is just idling around, it's vision range is limited to this. Defaults to 9 to keep in line with original simple mob aggro radius
|
||||
var/search_objects = 0 //If we want to consider objects when searching around, set this to 1. If you want to search for objects while also ignoring mobs until hurt, set it to 2. To completely ignore mobs, even when attacked, set it to 3
|
||||
var/list/wanted_objects = list() //A list of objects that will be checked against to attack, should we have search_objects enabled
|
||||
var/stat_attack = 0 //Mobs with stat_attack to 1 will attempt to attack things that are unconscious, Mobs with stat_attack set to 2 will attempt to attack the dead.
|
||||
var/stat_exclusive = 0 //Mobs with this set to 1 will exclusively attack things defined by stat_attack, stat_attack 2 means they will only attack corpses
|
||||
var/AIenabled = 1 //Badminnery and general AI toggle.
|
||||
var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction
|
||||
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_SLEEP (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
|
||||
|
||||
/mob/living/simple_animal/hostile/Life()
|
||||
|
||||
@@ -34,7 +37,11 @@
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
if(client || !AIenabled)
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
if(client)
|
||||
return 0
|
||||
if(!AICanContinue())
|
||||
return 0
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
@@ -50,30 +57,24 @@
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
|
||||
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets()//Step 1, find out what we can see
|
||||
var/list/L = list()
|
||||
if(search_objects < 2)
|
||||
var/list/Mobs = hearers(src, vision_range)
|
||||
for(var/mob/living/G in Mobs)
|
||||
L.Add(G)
|
||||
L.Remove(src)//So we don't suicide because we listed ourselves as a target!
|
||||
if(search_objects)
|
||||
var/list/Objects = oview(vision_range, src)
|
||||
for(var/obj/O in Objects)
|
||||
L.Add(O)
|
||||
else
|
||||
if(!search_objects)
|
||||
var/list/Mobs = hearers(vision_range, src) - src //Remove self, so we don't suicide
|
||||
L += Mobs
|
||||
for(var/obj/mecha/M in mechas_list)
|
||||
if(get_dist(M, src) <= vision_range && can_see(src, M, vision_range))
|
||||
L += M
|
||||
for(var/obj/spacepod/S in spacepods_list)
|
||||
if(get_dist(S, src) <= vision_range && can_see(src, S, vision_range))
|
||||
L += S
|
||||
else
|
||||
var/list/Objects = oview(vision_range, src)
|
||||
L += Objects
|
||||
return L
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()//Step 2, filter down possible targets to things we actually care about
|
||||
@@ -82,16 +83,14 @@
|
||||
for(var/atom/A in ListTargets())
|
||||
if(Found(A))//Just in case people want to override targetting
|
||||
var/list/FoundTarget = list()
|
||||
FoundTarget.Add(A)
|
||||
FoundTarget += A
|
||||
Targets = FoundTarget
|
||||
break
|
||||
if(CanAttack(A))//Can we attack it?
|
||||
if(istype(src, /mob/living/simple_animal/hostile/scarybat))
|
||||
if(A == src:owner)
|
||||
continue
|
||||
Targets += A
|
||||
continue
|
||||
Target = PickTarget(Targets)
|
||||
GiveTarget(Target)
|
||||
return Target //We now have a target
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)//This is here as a potential override to pick a specific target if available
|
||||
@@ -112,32 +111,35 @@
|
||||
/mob/living/simple_animal/hostile/CanAttack(var/atom/the_target)//Can we actually attack a possible target?
|
||||
if(see_invisible < the_target.invisibility)//Target's invisible to us, forget it
|
||||
return 0
|
||||
if(isobj(the_target) && search_objects)
|
||||
if(search_objects < 2)
|
||||
if(istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
if(CanAttack(M.occupant))
|
||||
return 1
|
||||
if(isliving(the_target))
|
||||
var/mob/living/L = the_target
|
||||
var/faction_check = 0
|
||||
for(var/F in faction)
|
||||
if(F in L.faction)
|
||||
faction_check = 1
|
||||
break
|
||||
if(robust_searching)
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1)
|
||||
return 0
|
||||
if(faction_check && !attack_same || !faction_check && attack_same == 2)
|
||||
return 0
|
||||
if(L in friends)
|
||||
return 0
|
||||
else
|
||||
if(L.stat)
|
||||
return 0
|
||||
if(faction_check && !attack_same)
|
||||
return 0
|
||||
return 1
|
||||
if(isobj(the_target))
|
||||
if(the_target.type in wanted_objects)
|
||||
return 1
|
||||
if(isliving(the_target) && search_objects < 2)
|
||||
var/mob/living/L = the_target
|
||||
if(L.stat > stat_attack || L.stat != stat_attack && stat_exclusive == 1)
|
||||
return 0
|
||||
var/faction_check = 0
|
||||
for(var/F in faction)
|
||||
if(F in L.faction)
|
||||
faction_check = 1
|
||||
break
|
||||
if(faction_check && !attack_same || !faction_check && attack_same == 2)
|
||||
return 0
|
||||
return 0
|
||||
if(L in friends)
|
||||
return 0
|
||||
return 1
|
||||
if(istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if(M.occupant)//Just so we don't attack empty mechs
|
||||
return 1
|
||||
if(istype(the_target, /obj/spacepod))
|
||||
var/obj/spacepod/S = the_target
|
||||
if(S.occupant || S.occupant2)//Just so we don't attack empty mechs
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target
|
||||
@@ -149,15 +151,16 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target
|
||||
stop_automated_movement = 1
|
||||
if(!target || SA_attackable(target))
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return
|
||||
if(target in ListTargets())
|
||||
var/TargetDistance = get_dist(src,target)
|
||||
var/target_distance = get_dist(src,target)
|
||||
if(ranged)//We ranged? Shoot at em
|
||||
if(TargetDistance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
OpenFire(target)
|
||||
if(retreat_distance != null)//If we have a retreat distance, check if we need to run from our target
|
||||
if(TargetDistance <= retreat_distance)//If target's closer than our retreat distance, run
|
||||
if(target_distance <= retreat_distance)//If target's closer than our retreat distance, run
|
||||
walk_away(src,target,retreat_distance,move_to_delay)
|
||||
else
|
||||
Goto(target,move_to_delay,minimum_distance)//Otherwise, get to our minimum distance so we chase them
|
||||
@@ -166,6 +169,15 @@
|
||||
if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
|
||||
AttackingTarget()
|
||||
return
|
||||
if(environment_smash)
|
||||
if(target.loc != null && get_dist(src, target.loc) <= vision_range)//We can't see our target, but he's in our vision range still
|
||||
if(environment_smash >= 2)//If we're capable of smashing through walls, forget about vision completely after finding our target
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
FindHidden()
|
||||
return
|
||||
else
|
||||
if(FindHidden())
|
||||
return
|
||||
LostTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance)
|
||||
@@ -189,7 +201,7 @@
|
||||
/mob/living/simple_animal/hostile/proc/AttackTarget()
|
||||
|
||||
stop_automated_movement = 1
|
||||
if(!target || SA_attackable(target))
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(!(target in ListTargets()))
|
||||
@@ -229,8 +241,9 @@
|
||||
walk(src, 0)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
|
||||
|
||||
var/target = the_target
|
||||
visible_message("\red <b>[src]</b> [ranged_message] at [target]!", 1)
|
||||
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [target]!</span>")
|
||||
|
||||
var/tturf = get_turf(target)
|
||||
if(rapid)
|
||||
@@ -250,9 +263,6 @@
|
||||
Shoot(tturf, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype
|
||||
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target = null
|
||||
ranged_cooldown = ranged_cooldown_cap
|
||||
return
|
||||
|
||||
@@ -265,9 +275,10 @@
|
||||
if(!A) return
|
||||
|
||||
if (!istype(target, /turf))
|
||||
del(A)
|
||||
qdel(A)
|
||||
return
|
||||
A.current = target
|
||||
A.firer = src
|
||||
A.yo = target:y - start:y
|
||||
A.xo = target:x - start:x
|
||||
spawn( 0 )
|
||||
@@ -276,18 +287,66 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/DestroySurroundings()
|
||||
if(environment_smash)
|
||||
if(buckled)//Beds and chairs are no longer hostile mob kryptonite
|
||||
buckled.attack_animal(src)
|
||||
var/list/directions = cardinal.Copy()
|
||||
for(var/dir in directions)
|
||||
EscapeConfinement()
|
||||
for(var/dir in cardinal)
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/simulated/wall) && T.Adjacent(src))
|
||||
T.attack_animal(src)
|
||||
if(istype(T, /turf/simulated/wall) || istype(T, /turf/simulated/mineral))
|
||||
if(T.Adjacent(src))
|
||||
T.attack_animal(src)
|
||||
for(var/atom/A in T)
|
||||
if(!A.Adjacent(src))
|
||||
continue
|
||||
if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || \
|
||||
istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || \
|
||||
istype(A, /obj/structure/rack) || istype(A, /obj/machinery/door/window))
|
||||
if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/rack))
|
||||
A.attack_animal(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/EscapeConfinement()
|
||||
if(buckled)
|
||||
buckled.attack_animal(src)
|
||||
if(!isturf(src.loc) && src.loc != null)//Did someone put us in something?
|
||||
var/atom/A = src.loc
|
||||
A.attack_animal(src)//Bang on it till we get out
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindHidden()
|
||||
if(istype(target.loc, /obj/structure/closet) || istype(target.loc, /obj/machinery/disposal) || istype(target.loc, /obj/machinery/sleeper))
|
||||
var/atom/A = target.loc
|
||||
Goto(A,move_to_delay,minimum_distance)
|
||||
if(A.Adjacent(src))
|
||||
A.attack_animal(src)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/RangedAttack(var/atom/A, var/params) //Player firing
|
||||
if(ranged && ranged_cooldown <= 0)
|
||||
target = A
|
||||
OpenFire(A)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
////// AI Status ///////
|
||||
/mob/living/simple_animal/hostile/proc/AICanContinue()
|
||||
switch(AIStatus)
|
||||
if(AI_ON)
|
||||
. = 1
|
||||
if(AI_SLEEP)
|
||||
if(AIShouldWake())
|
||||
. = 1
|
||||
AIStatus = AI_ON //Wake up for more than one Life() cycle.
|
||||
else
|
||||
. = 0
|
||||
if(AI_OFF)
|
||||
. = 0
|
||||
|
||||
|
||||
//Returns 1 if the AI should wake up
|
||||
//Returns 0 if the AI should remain asleep
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldWake()
|
||||
. = 0
|
||||
if(FindTarget())
|
||||
. = 1
|
||||
|
||||
|
||||
//Convenience
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldSleep()
|
||||
. = !(AIShouldWake())
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
a_intent = "harm"
|
||||
var/throw_message = "bounces off of"
|
||||
var/icon_aggro = null // for swapping to when we get aggressive
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||
..()
|
||||
@@ -138,6 +140,7 @@
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
attacktext = "barrels into"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
a_intent = "help"
|
||||
throw_message = "sinks in slowly, before being pushed out of "
|
||||
status_flags = CANPUSH
|
||||
@@ -238,6 +241,7 @@
|
||||
melee_damage_lower = 0
|
||||
melee_damage_upper = 0
|
||||
attacktext = "lashes out at"
|
||||
speak_emote = list("telepathically cries")
|
||||
throw_message = "falls right through the strange body of the"
|
||||
ranged_cooldown = 0
|
||||
ranged_cooldown_cap = 0
|
||||
@@ -288,7 +292,7 @@
|
||||
user << "<span class='notice'>You chomp into [src], barely managing to hold it down, but feel amazingly refreshed in mere moments.</span>"
|
||||
playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
|
||||
H.revive()
|
||||
del(src)
|
||||
qdel(src)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood
|
||||
@@ -311,6 +315,7 @@
|
||||
melee_damage_lower = 2
|
||||
melee_damage_upper = 2
|
||||
attacktext = "slashes"
|
||||
speak_emote = list("telepathically cries")
|
||||
throw_message = "falls right through the strange body of the"
|
||||
environment_smash = 0
|
||||
pass_flags = PASSTABLE
|
||||
@@ -318,10 +323,10 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/New()
|
||||
..()
|
||||
spawn(100)
|
||||
del(src)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/Die()
|
||||
del(src)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath
|
||||
name = "goliath"
|
||||
@@ -339,6 +344,7 @@
|
||||
ranged_cooldown = 2 //By default, start the Goliath with his cooldown off so that people can run away quickly on first sight
|
||||
ranged_cooldown_cap = 8
|
||||
friendly = "wails at"
|
||||
speak_emote = list("bellows")
|
||||
vision_range = 4
|
||||
speed = 3
|
||||
maxHealth = 300
|
||||
@@ -347,6 +353,7 @@
|
||||
melee_damage_lower = 25
|
||||
melee_damage_upper = 25
|
||||
attacktext = "pulverizes"
|
||||
attack_sound = 'sound/weapons/punch1.ogg'
|
||||
throw_message = "does nothing to the rocky hide of the"
|
||||
aggro_vision_range = 9
|
||||
idle_vision_range = 5
|
||||
@@ -398,6 +405,7 @@
|
||||
name = "Goliath tentacle"
|
||||
icon = 'icons/mob/animal.dmi'
|
||||
icon_state = "Goliath_tentacle"
|
||||
var/latched = 0
|
||||
|
||||
/obj/effect/goliath_tentacle/New()
|
||||
var/turftype = get_turf(src)
|
||||
@@ -425,15 +433,15 @@
|
||||
|
||||
/obj/effect/goliath_tentacle/proc/Trip()
|
||||
for(var/mob/living/M in src.loc)
|
||||
M.Weaken(5)
|
||||
visible_message("<span class='warning'>The [src.name] knocks [M.name] down!</span>")
|
||||
del(src)
|
||||
|
||||
/obj/effect/goliath_tentacle/Crossed(AM as mob|obj)
|
||||
if(isliving(AM))
|
||||
Trip()
|
||||
return
|
||||
..()
|
||||
M.Stun(5)
|
||||
M.adjustBruteLoss(rand(10,15))
|
||||
latched = 1
|
||||
visible_message("<span class='danger'>The [src.name] grabs hold of [M.name]!</span>")
|
||||
if(!latched)
|
||||
qdel(src)
|
||||
else
|
||||
spawn(50)
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/Die()
|
||||
var/obj/item/asteroid/goliath_hide/G = new /obj/item/asteroid/goliath_hide(src.loc)
|
||||
@@ -457,15 +465,18 @@
|
||||
if(current_armor.["melee"] < 80)
|
||||
current_armor.["melee"] = min(current_armor.["melee"] + 10, 80)
|
||||
user << "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>"
|
||||
del(src)
|
||||
qdel(src)
|
||||
else
|
||||
user << "<span class='info'>You can't improve [C] any further.</span>"
|
||||
return
|
||||
if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/D = target
|
||||
var/list/damage_absorption = D.damage_absorption
|
||||
if(damage_absorption.["brute"] > 0.3)
|
||||
damage_absorption.["brute"] = max(damage_absorption.["brute"] - 0.1, 0.3)
|
||||
if(damage_absorption["brute"] > 0.3)
|
||||
damage_absorption["brute"] = max(damage_absorption["brute"] - 0.1, 0.3)
|
||||
damage_absorption["bullet"] = damage_absorption["bullet"] - 0.05
|
||||
damage_absorption["fire"] = damage_absorption["fire"] - 0.05
|
||||
damage_absorption["laser"] = damage_absorption["laser"] - 0.025
|
||||
user << "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>"
|
||||
qdel(src)
|
||||
if(D.icon_state == "ripley-open")
|
||||
@@ -478,7 +489,7 @@
|
||||
D.overlays += image("icon"="mecha.dmi", "icon_state"="ripley-g-full-open")
|
||||
D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - the pilot must be an experienced monster hunter."
|
||||
else
|
||||
user << "<span class='info'>You can't add armour onto the mech while someone is inside!</span>"
|
||||
user << "<span class='warning'>You can't add armour onto the mech while someone is inside!</span>"
|
||||
else
|
||||
user << "<span class='info'>You can't improve [D] any further.</span>"
|
||||
user << "<span class='warning'>You can't improve [D] any further!</span>"
|
||||
return
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
speed = -1
|
||||
|
||||
AIenabled = 0 //The body isn't conscious
|
||||
AIStatus = AI_OFF
|
||||
|
||||
anchored = 1 //otherwise people can literally fucking pull spaceworms apart
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
animate_movement = SLIDE_STEPS
|
||||
|
||||
AIenabled = 1//The head is conscious
|
||||
AIStatus = AI_ON//The head is conscious
|
||||
stop_automated_movement = 0 //Ditto ^
|
||||
|
||||
faction = list("spaceworms") //head and body both have this faction JIC
|
||||
|
||||
@@ -474,19 +474,17 @@
|
||||
if(health < 1)
|
||||
Die()
|
||||
|
||||
/mob/living/simple_animal/proc/SA_attackable(target)
|
||||
if (isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.stat)
|
||||
/mob/living/simple_animal/proc/CanAttack(var/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(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
if (istype(the_target, /obj/mecha))
|
||||
var/obj/mecha/M = the_target
|
||||
if (M.occupant)
|
||||
return 0
|
||||
if (istype(target,/obj/spacepod))
|
||||
var/obj/spacepod/S = target
|
||||
if (S.occupant || S.occupant2)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/update_fire()
|
||||
@@ -529,24 +527,6 @@
|
||||
gib()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/proc/CanAttack(var/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
|
||||
if (istype(the_target, /obj/spacepod))
|
||||
var/obj/spacepod/S = the_target
|
||||
if (S.occupant || S.occupant2)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/say(var/message)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user