mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-21 20:13:45 +01:00
Refactors hostile mob code, unsnowflakes bears, panthers, and snakes
Also fixes some bee stuff.
This commit is contained in:
@@ -14,6 +14,13 @@
|
||||
/mob/living/simple_animal/hostile/poison/bees/bee_friendly()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/bot/bee_friendly()
|
||||
if(paicard)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/diona/bee_friendly()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/bee_friendly()
|
||||
if(get_species() == "Diona") //bees pollinate plants, duh.
|
||||
@@ -205,8 +212,8 @@
|
||||
if(bees)
|
||||
visible_message("<span class='danger'>[user] disturbs the bees!</span>")
|
||||
else
|
||||
var/option = alert(user, "What Action do you wish to perform?","Apiary","Remove a Honey Frame","Remove the Queen Bee")
|
||||
if(!Adjacent(user))
|
||||
var/option = input(user, "What Action do you wish to perform?", "Apiary") as null|anything in list("Remove a Honey Frame","Remove the Queen Bee")
|
||||
if(!Adjacent(user) || !option)
|
||||
return
|
||||
switch(option)
|
||||
if("Remove a Honey Frame")
|
||||
|
||||
@@ -13,4 +13,4 @@
|
||||
icon_state = "beekeeper"
|
||||
item_state = "beekeeper"
|
||||
flags = THICKMATERIAL
|
||||
|
||||
allowed = list (/obj/item/weapon/reagent_containers/spray/plantbgone,/obj/item/device/analyzer/plant_analyzer,/obj/item/seeds,/obj/item/weapon/reagent_containers/glass/fertilizer,/obj/item/weapon/minihoe)
|
||||
|
||||
@@ -730,7 +730,7 @@
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/W = I
|
||||
if(W.welding && !stat)
|
||||
if(stance != HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_ON)
|
||||
to_chat(user, "<span class='info'>[src] is moving around too much to repair!</span>")
|
||||
return
|
||||
if(maxHealth == health)
|
||||
@@ -1061,4 +1061,4 @@
|
||||
return ..()
|
||||
C.preserved = 1
|
||||
to_chat(user, "<span class='notice'>You inject the hivelord core with the stabilizer. It will no longer go inert.</span>")
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -43,13 +43,12 @@
|
||||
var/plant_cooldown = 30
|
||||
var/plants_off = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/drone/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
/mob/living/simple_animal/hostile/alien/drone/handle_automated_action()
|
||||
if(!..()) //AIStatus is off
|
||||
return
|
||||
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
@@ -90,12 +89,12 @@
|
||||
var/egg_cooldown = 30
|
||||
var/plant_cooldown = 30
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/process_ai()
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/alien/queen/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
egg_cooldown--
|
||||
plant_cooldown--
|
||||
if(stance==HOSTILE_STANCE_IDLE)
|
||||
if(AIStatus == AI_IDLE)
|
||||
if(!plants_off && prob(10) && plant_cooldown<=0)
|
||||
plant_cooldown = initial(plant_cooldown)
|
||||
SpreadPlants()
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 30
|
||||
attacktext = "mauls"
|
||||
friendly = "bear hugs"
|
||||
attack_sound = 'sound/weapons/genhit3.ogg'
|
||||
|
||||
//Space bears aren't affected by atmos.
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
var/stance_step = 0
|
||||
|
||||
faction = list("russian")
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
@@ -36,10 +36,12 @@
|
||||
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
|
||||
/mob/living/simple_animal/hostile/bear/Hudson
|
||||
name = "Hudson"
|
||||
desc = ""
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "hits"
|
||||
desc = "Feared outlaw, this guy is one bad news bear." //I'm sorry...
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Hudson/New()
|
||||
..()
|
||||
var/unbearable_pun = pick("He's unbearably cute.", "It looks like he is a bearer of bad news.", "Sadly, he is bearly able to comprehend puns.")
|
||||
desc = "That's Hudson. " + unbearable_pun// I am not sorry for this.
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Move()
|
||||
..()
|
||||
@@ -49,121 +51,5 @@
|
||||
else
|
||||
icon_state = "bearfloor"
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
|
||||
switch(stance)
|
||||
|
||||
if(HOSTILE_STANCE_TIRED)
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(stance_step >= 10) //rests for 10 ticks
|
||||
if(target && target in ListTargets())
|
||||
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
|
||||
else
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
|
||||
if(HOSTILE_STANCE_ALERT)
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
if(target && target in ListTargets())
|
||||
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
|
||||
src.dir = get_dir(src,target) //Keep staring at the mob
|
||||
|
||||
if(stance_step in list(1,4,7)) //every 3 ticks
|
||||
var/action = pick( list( "growls at [target]", "stares angrily at [target]", "prepares to attack [target]", "closely watches [target]" ) )
|
||||
if(action)
|
||||
custom_emote(1, action)
|
||||
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 = HOSTILE_STANCE_IDLE
|
||||
if(stance_step >= 7) //If we have been staring at a mob for 7 ticks,
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
|
||||
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
|
||||
return
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target = user
|
||||
..()
|
||||
|
||||
/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 = M
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/movement_dir = 0)
|
||||
return 1 //No drifting in space for space bears!
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
custom_emote(1, "stares alertly at [.]")
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/LoseTarget()
|
||||
..(5)
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/AttackingTarget()
|
||||
custom_emote(1, pick( list("slashes at [target]", "bites [target]") ) )
|
||||
|
||||
var/damage = rand(20,30)
|
||||
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
|
||||
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))
|
||||
var/mob/living/L = target
|
||||
L.adjustBruteLoss(damage)
|
||||
return L
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.attack_animal(src)
|
||||
return M
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
flying = 1
|
||||
search_objects = 1 //have to find those plant trays!
|
||||
density = 0
|
||||
small = 1
|
||||
|
||||
//Spaceborn beings don't get hurt by space
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
@@ -57,7 +59,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/Destroy()
|
||||
if(beehome)
|
||||
beehome.bees -= src
|
||||
beehome.bees.Remove(src)
|
||||
beehome = null
|
||||
beegent = null
|
||||
return ..()
|
||||
@@ -65,7 +67,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/bees/death(gibbed)
|
||||
if(beehome)
|
||||
beehome.bees -= src
|
||||
beehome.bees.Remove(src)
|
||||
beehome = null
|
||||
beegent = null
|
||||
..()
|
||||
@@ -137,12 +139,13 @@
|
||||
var/obj/structure/beebox/BB = target
|
||||
forceMove(BB)
|
||||
target = null
|
||||
wanted_objects -= /obj/structure/beebox //so we don't attack beeboxes when not going home
|
||||
wanted_objects.Remove(/obj/structure/beebox) //so we don't attack beeboxes when not going home
|
||||
else
|
||||
if(beegent && isliving(target))
|
||||
var/mob/living/L = target
|
||||
beegent.reaction_mob(L, TOUCH)
|
||||
L.reagents.add_reagent(beegent.id, rand(1,5))
|
||||
if(!isnull(target.reagents))
|
||||
beegent.reaction_mob(L, TOUCH)
|
||||
L.reagents.add_reagent(beegent.id, rand(1,5))
|
||||
target.attack_animal(src)
|
||||
|
||||
|
||||
@@ -159,7 +162,7 @@
|
||||
return
|
||||
|
||||
target = null //so we pick a new hydro tray next FindTarget(), instead of loving the same plant for eternity
|
||||
wanted_objects -= /obj/machinery/portable_atmospherics/hydroponics //so we only hunt them while they're alive/seeded/not visisted
|
||||
wanted_objects.Remove(/obj/machinery/portable_atmospherics/hydroponics) //so we only hunt them while they're alive/seeded/not visisted
|
||||
Hydro.recent_bee_visit = TRUE
|
||||
spawn(BEE_TRAY_RECENT_VISIT)
|
||||
if(Hydro)
|
||||
@@ -199,7 +202,7 @@
|
||||
idle = max(0, --idle)
|
||||
if(idle <= BEE_IDLE_GOHOME && prob(BEE_PROB_GOHOME))
|
||||
if(!FindTarget())
|
||||
wanted_objects += /obj/structure/beebox //so we don't attack beeboxes when not going home
|
||||
wanted_objects.Add(/obj/structure/beebox) //so we don't attack beeboxes when not going home
|
||||
target = beehome
|
||||
if(!beehome) //add outselves to a beebox (of the same reagent) if we have no home
|
||||
for(var/obj/structure/beebox/BB in view(vision_range, src))
|
||||
@@ -282,7 +285,6 @@
|
||||
..()
|
||||
queen = new(src)
|
||||
|
||||
|
||||
/obj/item/queen_bee/Destroy()
|
||||
qdel(queen)
|
||||
return ..()
|
||||
|
||||
@@ -82,18 +82,17 @@
|
||||
move_to_delay = 5
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/hunter/handle_automated_action()
|
||||
if(!stat)
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
//1% chance to skitter madly away
|
||||
if(!busy && prob(1))
|
||||
/*var/list/move_targets = list()
|
||||
for(var/turf/T in orange(20, src))
|
||||
move_targets.Add(T)*/
|
||||
stop_automated_movement = 1
|
||||
Goto(pick(orange(20, src)), move_to_delay)
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
if(!..()) //AIStatus is off
|
||||
return
|
||||
if(AIStatus == AI_IDLE)
|
||||
//1% chance to skitter madly away
|
||||
if(!busy && prob(1))
|
||||
stop_automated_movement = 1
|
||||
Goto(pick(orange(20, src)), move_to_delay)
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/proc/GiveUp(var/C)
|
||||
spawn(100)
|
||||
@@ -104,36 +103,31 @@
|
||||
stop_automated_movement = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/handle_automated_action()
|
||||
if(!stat && !ckey)
|
||||
if(stance == HOSTILE_STANCE_IDLE)
|
||||
var/list/can_see = view(src, 10)
|
||||
//30% chance to stop wandering and do something
|
||||
if(!busy && prob(30))
|
||||
//first, check for potential food nearby to cocoon
|
||||
for(var/mob/living/C in can_see)
|
||||
if(C.stat && !istype(C,/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
cocoon_target = C
|
||||
busy = MOVING_TO_TARGET
|
||||
Goto(C, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(C)
|
||||
return
|
||||
|
||||
//second, spin a sticky spiderweb on this tile
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
|
||||
if(!W)
|
||||
Web()
|
||||
if(..())
|
||||
var/list/can_see = view(src, 10)
|
||||
if(!busy && prob(30)) //30% chance to stop wandering and do something
|
||||
//first, check for potential food nearby to cocoon
|
||||
for(var/mob/living/C in can_see)
|
||||
if(C.stat && !istype(C,/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
cocoon_target = C
|
||||
busy = MOVING_TO_TARGET
|
||||
Goto(C, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(C)
|
||||
return
|
||||
//second, spin a sticky spiderweb on this tile
|
||||
var/obj/effect/spider/stickyweb/W = locate() in get_turf(src)
|
||||
if(!W)
|
||||
Web()
|
||||
else
|
||||
//third, lay an egg cluster there
|
||||
if(fed)
|
||||
LayEggs()
|
||||
else
|
||||
//third, lay an egg cluster there
|
||||
if(fed)
|
||||
LayEggs()
|
||||
else
|
||||
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
|
||||
for(var/obj/O in can_see)
|
||||
|
||||
if(O.anchored)
|
||||
continue
|
||||
|
||||
//fourthly, cocoon any nearby items so those pesky pinkskins can't use them
|
||||
for(var/obj/O in can_see)
|
||||
if(O.anchored)
|
||||
continue
|
||||
if(istype(O, /obj/item) || istype(O, /obj/structure) || istype(O, /obj/machinery))
|
||||
cocoon_target = O
|
||||
busy = MOVING_TO_TARGET
|
||||
@@ -142,13 +136,13 @@
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(O)
|
||||
|
||||
else if(busy == MOVING_TO_TARGET && cocoon_target)
|
||||
if(get_dist(src, cocoon_target) <= 1)
|
||||
Wrap()
|
||||
else if(busy == MOVING_TO_TARGET && cocoon_target)
|
||||
if(get_dist(src, cocoon_target) <= 1)
|
||||
Wrap()
|
||||
|
||||
else
|
||||
busy = 0
|
||||
stop_automated_movement = 0
|
||||
else
|
||||
busy = 0
|
||||
stop_automated_movement = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider/verb/Web()
|
||||
set name = "Lay Web"
|
||||
@@ -254,4 +248,4 @@
|
||||
#undef SPINNING_WEB
|
||||
#undef LAYING_EGGS
|
||||
#undef MOVING_TO_TARGET
|
||||
#undef SPINNING_COCOON
|
||||
#undef SPINNING_COCOON
|
||||
|
||||
@@ -101,9 +101,8 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/process_ai()
|
||||
. = ..()
|
||||
if(!.)
|
||||
/mob/living/simple_animal/hostile/hivebot/tele/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
if(prob(2))//Might be a bit low, will mess with it likely
|
||||
warpbots()
|
||||
warpbots()
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
mouse_opacity = 2 //This makes it easier to hit hostile mobs, you only need to click on their tile, and is set back to 1 when they die
|
||||
stop_automated_movement_when_pulled = 0
|
||||
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/ranged = 0
|
||||
var/rapid = 0
|
||||
@@ -30,39 +29,35 @@
|
||||
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/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)
|
||||
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (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()
|
||||
. = ..()
|
||||
if(!.)
|
||||
walk(src, 0)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
|
||||
/mob/living/simple_animal/hostile/process_ai()
|
||||
..()
|
||||
if(!AICanContinue())
|
||||
return 0
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
MoveToTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
AttackTarget()
|
||||
DestroySurroundings()
|
||||
|
||||
if(AIShouldSleep())
|
||||
AIStatus = AI_SLEEP
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/handle_automated_action()
|
||||
if(AIStatus == AI_OFF)
|
||||
return 0
|
||||
if(ranged)
|
||||
ranged_cooldown--
|
||||
var/list/possible_targets = ListTargets() //we look around for potential targets and make it a list for later use.
|
||||
if(environment_smash)
|
||||
EscapeConfinement()
|
||||
|
||||
if(AICanContinue(possible_targets))
|
||||
DestroySurroundings()
|
||||
if(!MoveToTarget(possible_targets)) //if we lose our target
|
||||
if(AIShouldSleep(possible_targets)) // we try to acquire a new one
|
||||
AIStatus = AI_IDLE // otherwise we go idle
|
||||
return 1
|
||||
//////////////HOSTILE MOB TARGETTING AND AGGRESSION////////////
|
||||
|
||||
|
||||
@@ -82,19 +77,18 @@
|
||||
L += Objects
|
||||
return L
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()//Step 2, filter down possible targets to things we actually care about
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget(var/list/possible_targets, var/HasTargetsList = 0)//Step 2, filter down possible targets to things we actually care about
|
||||
var/list/Targets = list()
|
||||
var/Target
|
||||
for(var/atom/A in ListTargets())
|
||||
if(!HasTargetsList)
|
||||
possible_targets = ListTargets()
|
||||
for(var/atom/A in possible_targets)
|
||||
if(Found(A))//Just in case people want to override targetting
|
||||
var/list/FoundTarget = list()
|
||||
FoundTarget += A
|
||||
Targets = FoundTarget
|
||||
Targets = list(A)
|
||||
break
|
||||
if(CanAttack(A))//Can we attack it?
|
||||
Targets += A
|
||||
continue
|
||||
Target = PickTarget(Targets)
|
||||
var/Target = PickTarget(Targets)
|
||||
GiveTarget(Target)
|
||||
return Target //We now have a target
|
||||
|
||||
@@ -102,14 +96,14 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/PickTarget(var/list/Targets)//Step 3, pick amongst the possible, attackable targets
|
||||
if(!Targets.len)//We didnt find nothin!
|
||||
return
|
||||
if(target != null)//If we already have a target, but are told to pick again, calculate the lowest distance between all possible, and pick from the lowest distance targets
|
||||
for(var/atom/A in Targets)
|
||||
var/target_dist = get_dist(src, target)
|
||||
var/possible_target_distance = get_dist(src, A)
|
||||
if(target_dist < possible_target_distance)
|
||||
Targets -= A
|
||||
if(!Targets.len)//We didnt find nothin!
|
||||
return
|
||||
var/chosen_target = pick(Targets)//Pick the remaining targets (if any) at random
|
||||
return chosen_target
|
||||
|
||||
@@ -155,16 +149,14 @@
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget(var/list/possible_targets)//Step 5, handle movement between us and our target
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return
|
||||
if(target in ListTargets())
|
||||
return 0
|
||||
if(target in possible_targets)
|
||||
var/target_distance = get_dist(src,target)
|
||||
if(ranged)//We ranged? Shoot at em
|
||||
if(target_distance >= 2 && ranged_cooldown <= 0)//But make sure they're a tile away at least, and our range attack is off cooldown
|
||||
@@ -178,17 +170,18 @@
|
||||
Goto(target,move_to_delay,minimum_distance)
|
||||
if(isturf(loc) && target.Adjacent(src)) //If they're next to us, attack
|
||||
AttackingTarget()
|
||||
return
|
||||
return 1
|
||||
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
|
||||
return 1
|
||||
else
|
||||
if(FindHidden())
|
||||
return
|
||||
return 1
|
||||
LostTarget()
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay, var/minimum_distance)
|
||||
walk_to(src, target, minimum_distance, delay)
|
||||
@@ -199,27 +192,11 @@
|
||||
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
|
||||
search_objects = 0
|
||||
target = null
|
||||
if(stance == HOSTILE_STANCE_IDLE)//If we took damage while idle, immediately attempt to find the source of it so we find a living target
|
||||
Aggro()
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
if(stance == HOSTILE_STANCE_ATTACK)//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
|
||||
if(target != null && prob(25))
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackTarget()
|
||||
|
||||
stop_automated_movement = 1
|
||||
if(!target || !CanAttack(target))
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(!(target in ListTargets()))
|
||||
LostTarget()
|
||||
return 0
|
||||
if(isturf(loc) && target.Adjacent(src))
|
||||
AttackingTarget()
|
||||
return 1
|
||||
if(AIStatus == AI_IDLE)
|
||||
AIStatus = AI_ON
|
||||
FindTarget()
|
||||
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
|
||||
FindTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
target.attack_animal(src)
|
||||
@@ -232,13 +209,11 @@
|
||||
vision_range = idle_vision_range
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseTarget()
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target = null
|
||||
walk(src, 0)
|
||||
LoseAggro()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LostTarget()
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
walk(src, 0)
|
||||
LoseAggro()
|
||||
|
||||
@@ -340,28 +315,16 @@
|
||||
|
||||
|
||||
////// AI Status ///////
|
||||
/mob/living/simple_animal/hostile/proc/AICanContinue()
|
||||
/mob/living/simple_animal/hostile/proc/AICanContinue(var/list/possible_targets)
|
||||
switch(AIStatus)
|
||||
if(AI_ON)
|
||||
. = 1
|
||||
if(AI_SLEEP)
|
||||
if(AIShouldWake())
|
||||
if(AI_IDLE)
|
||||
if(FindTarget(possible_targets, 1))
|
||||
. = 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())
|
||||
/mob/living/simple_animal/hostile/proc/AIShouldSleep(var/list/possible_targets)
|
||||
return !FindTarget(possible_targets, 1)
|
||||
|
||||
@@ -32,13 +32,7 @@
|
||||
var/stalk_tick_delay = 3
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/ListTargets()
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/human/H in view(src, 10))
|
||||
targets += H
|
||||
return targets
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/FindTarget()
|
||||
/mob/living/simple_animal/hostile/panther/FindTarget(var/list/possible_targets)
|
||||
. = ..()
|
||||
if(.)
|
||||
emote("nashes at [.]")
|
||||
@@ -51,14 +45,6 @@
|
||||
L.Weaken(3)
|
||||
L.visible_message("<span class='danger'>\the [src] knocks down \the [L]!</span>")
|
||||
|
||||
/mob/living/simple_animal/hostile/panther/AttackTarget()
|
||||
..()
|
||||
if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
|
||||
stalk_tick_delay -= 1
|
||||
if(stalk_tick_delay <= 0)
|
||||
src.loc = get_step_towards(src, target)
|
||||
stalk_tick_delay = 3
|
||||
|
||||
//*******//
|
||||
// Snake //
|
||||
//*******//
|
||||
@@ -90,12 +76,6 @@
|
||||
var/stalk_tick_delay = 3
|
||||
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/ListTargets()
|
||||
var/list/targets = list()
|
||||
for(var/mob/living/carbon/human/H in view(src, 10))
|
||||
targets += H
|
||||
return targets
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -106,11 +86,3 @@
|
||||
var/mob/living/L = .
|
||||
if(istype(L))
|
||||
L.apply_damage(rand(3,12), TOX)
|
||||
|
||||
/mob/living/simple_animal/hostile/snake/AttackTarget()
|
||||
..()
|
||||
if(stance == HOSTILE_STANCE_ATTACKING && get_dist(src, target))
|
||||
stalk_tick_delay -= 1
|
||||
if(stalk_tick_delay <= 0)
|
||||
src.loc = get_step_towards(src, target)
|
||||
stalk_tick_delay = 3
|
||||
|
||||
@@ -84,16 +84,12 @@
|
||||
temperature = 50
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
if(target != null)
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
if(..()) //we have a target
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.bodytemperature > 261)
|
||||
L.bodytemperature = 261
|
||||
visible_message("<span class='danger'>The [src.name]'s stare chills [L.name] to the bone!</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/ex_act(severity)
|
||||
switch(severity)
|
||||
@@ -156,17 +152,12 @@
|
||||
if(target != null)
|
||||
if(istype(target, /obj/item/weapon/ore))
|
||||
visible_message("<span class='notice'>The [src.name] looks at [target.name] with hungry eyes.</span>")
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
if(isliving(target))
|
||||
else if(isliving(target))
|
||||
Aggro()
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
visible_message("<span class='danger'>The [src.name] tries to flee from [target.name]!</span>")
|
||||
retreat_distance = 10
|
||||
minimum_distance = 10
|
||||
Burrow()
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goldgrub/AttackingTarget()
|
||||
if(istype(target, /obj/item/weapon/ore))
|
||||
@@ -387,7 +378,7 @@
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath/proc/handle_preattack()
|
||||
if(ranged_cooldown <= 2 && !pre_attack)
|
||||
pre_attack++
|
||||
if(!pre_attack || stat || stance == HOSTILE_STANCE_IDLE)
|
||||
if(!pre_attack || stat || AIStatus == AI_IDLE)
|
||||
return
|
||||
icon_state = "Goliath_preattack"
|
||||
|
||||
@@ -511,4 +502,4 @@
|
||||
to_chat(user, "<span class='warning'>You can't add armour onto the mech while someone is inside!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
return
|
||||
return
|
||||
|
||||
@@ -5,19 +5,16 @@
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(!L.stat)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return L
|
||||
else
|
||||
enemies -= L
|
||||
else if(istype(A, /obj/mecha))
|
||||
var/obj/mecha/M = A
|
||||
if(M.occupant)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return A
|
||||
else if(istype(A, /obj/spacepod))
|
||||
var/obj/spacepod/M = A
|
||||
if(M.occupant || M.occupant2)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return A
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/ListTargets()
|
||||
@@ -72,4 +69,4 @@
|
||||
for(var/dir in cardinal) // North, South, East, West
|
||||
var/obj/structure/obstacle = locate(/obj/structure, get_step(src, dir))
|
||||
if(istype(obstacle, /obj/structure/closet) || istype(obstacle, /obj/structure/table))
|
||||
obstacle.attack_animal(src)
|
||||
obstacle.attack_animal(src)
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/process_ai()
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/statue/handle_automated_action()
|
||||
if(!..())
|
||||
return
|
||||
if(target) // If we have a target and we're AI controlled
|
||||
var/mob/watching = can_be_seen()
|
||||
// If they're not our target
|
||||
@@ -211,11 +211,10 @@
|
||||
name = "Toggle Nightvision \[OFF\]"
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/sentience_act()
|
||||
faction -= "neutral"
|
||||
|
||||
/mob/living/simple_animal/hostile/statue/restrained()
|
||||
. = ..()
|
||||
if(can_be_seen(loc))
|
||||
return 1
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user