Cooler Combat Mobs (#15649)

This commit is contained in:
Geeves
2023-02-03 23:39:32 +01:00
committed by GitHub
parent 14d41d1e84
commit 377843f40c
15 changed files with 117 additions and 62 deletions
@@ -91,6 +91,7 @@
var/previous = stance
stance = input
if (stance != previous)
change_stance(stance)
stance_step = 0
/mob/living/simple_animal/hostile/bear/think()
@@ -56,7 +56,7 @@
//WE DANCE!
/mob/living/simple_animal/hostile/commanded/bear/misc_command(var/mob/speaker,var/text)
stay_command()
stance = COMMANDED_MISC //nothing can stop this ride
change_stance(COMMANDED_MISC) //nothing can stop this ride
INVOKE_ASYNC(src, PROC_REF(command_dance))
/mob/living/simple_animal/hostile/commanded/bear/proc/command_dance()
@@ -78,6 +78,6 @@
set_dir(EAST)
visible_message("\The [src] [message]")
sleep(30)
stance = COMMANDED_STOP
change_stance(COMMANDED_STOP)
set_dir(SOUTH)
visible_message("\The [src] bows, finished with [get_pronoun("his")] dance.")
@@ -68,6 +68,19 @@
if(COMMANDED_STOP)
commanded_stop()
/mob/living/simple_animal/hostile/commanded/change_stance(var/new_stance)
. = ..()
if(!.)
return
switch(stance)
if(COMMANDED_STOP)
MOB_SHIFT_TO_NORMAL_THINKING(src)
if(COMMANDED_FOLLOW)
MOB_SHIFT_TO_FAST_THINKING(src)
if(COMMANDED_MISC)
MOB_SHIFT_TO_NORMAL_THINKING(src)
/mob/living/simple_animal/hostile/commanded/on_think_disabled()
..()
command_buffer.Cut()
@@ -89,12 +102,12 @@
if(mode == "specific")
if(!(A in allowed_targets))
continue
stance = new_stance
change_stance(new_stance)
return A
else
if(M == master || (M in friends))
continue
stance = new_stance
change_stance(new_stance)
return A
@@ -154,7 +167,7 @@
/mob/living/simple_animal/hostile/commanded/proc/attack_command(var/mob/speaker,var/text)
target_mob = null //want me to attack something? Well I better forget my old target.
walk_to(src,0)
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
if(text == "attack" || findtext(text,"everyone") || findtext(text,"anybody") || findtext(text, "somebody") || findtext(text, "someone")) //if its just 'attack' then just attack anybody, same for if they say 'everyone', somebody, anybody. Assuming non-pickiness.
allowed_targets = list("everyone")//everyone? EVERYONE
return 1
@@ -166,7 +179,7 @@
/mob/living/simple_animal/hostile/commanded/proc/stay_command(var/mob/speaker,var/text)
target_mob = null
stance = COMMANDED_STOP
change_stance(COMMANDED_STOP)
stop_automated_movement = 1
walk_to(src,0)
if(emote_hear && emote_hear.len)
@@ -177,7 +190,7 @@
allowed_targets = list()
walk_to(src,0)
target_mob = null //gotta stop SOMETHIN
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
stop_automated_movement = 0
if(emote_hear && emote_hear.len)
audible_emote("[pick(emote_hear)].",0)
@@ -186,7 +199,7 @@
/mob/living/simple_animal/hostile/commanded/proc/follow_command(var/mob/speaker,var/text)
//we can assume 'stop following' is handled by stop_command
if(findtext(text,"me"))
stance = COMMANDED_FOLLOW
change_stance(COMMANDED_FOLLOW)
target_mob = speaker //this wont bite me in the ass later.
return 1
var/list/targets = get_targets_by_name(text)
@@ -195,7 +208,7 @@
if(emote_hear && emote_hear.len)
audible_emote("[pick(emote_hear)].",0)
stance = COMMANDED_FOLLOW //GOT SOMEBODY. BETTER FOLLOW EM.
change_stance(COMMANDED_FOLLOW) //GOT SOMEBODY. BETTER FOLLOW EM.
target_mob = targets[1] //YEAH GOOD IDEA
return 1
@@ -210,12 +223,12 @@
// We forgive our master
if(user == master)
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
audible_emote("[pick(sad_emote)].",0)
return
if(. && retribution)
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
target_mob = user
allowed_targets += user //fuck this guy in particular.
if(user in friends) //We were buds :'(
@@ -227,13 +240,13 @@
// We forgive our master
if(M == master)
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
if(M.a_intent == I_HURT)
audible_emote("[pick(sad_emote)].",0)
return
if(M.a_intent == I_HELP && prob(40)) //chance that they won't immediately kill anyone who pets them. But only a chance.
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
audible_emote("growls at [M].")
to_chat(M, SPAN_WARNING("Maybe you should keep your hands to yourself..."))
@@ -243,7 +256,7 @@
target_mob = M
allowed_targets += M
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
if(M in friends)
friends -= M
@@ -253,7 +266,7 @@
// We forgive our master
if(user == master)
target_mob = null
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
audible_emote("[pick(sad_emote)].",0)
/mob/living/simple_animal/hostile/commanded/bullet_act(var/obj/item/projectile/P, var/def_zone)
@@ -262,7 +275,7 @@
// We forgive our master
if (ismob(P.firer) && P.firer == master)
target_mob = null
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
audible_emote("[pick(sad_emote)].",0)
/mob/living/simple_animal/hostile/commanded/attackby(var/obj/item/O, var/mob/user)
@@ -271,7 +284,7 @@
// We forgive our master
if(user == master)
target_mob = null
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
if(!istype(O, brush)) //we don't get sad if we're brushed!
audible_emote("[pick(sad_emote)].",0)
@@ -283,5 +296,5 @@
if(ismob(O.thrower))
if(O.thrower == master)
target_mob = null
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
audible_emote("[pick(sad_emote)].",0)
@@ -94,7 +94,7 @@
/mob/living/simple_animal/hostile/hivebot/bomber/AttackingTarget()
..()
LoseTarget()
stance = HOSTILE_STANCE_TIRED
change_stance(HOSTILE_STANCE_TIRED)
stop_automated_movement = 1
wander = 0
if(!has_exploded)
@@ -167,7 +167,7 @@
/mob/living/simple_animal/hostile/hivebot/emp_act(severity)
LoseTarget()
stance = HOSTILE_STANCE_TIRED
change_stance(HOSTILE_STANCE_TIRED)
addtimer(CALLBACK(src, PROC_REF(wakeup)), 50)
visible_message(SPAN_DANGER("[src] suffers a teleportation malfunction!"))
playsound(src.loc, 'sound/effects/teleport.ogg', 25, 1)
@@ -175,4 +175,4 @@
do_teleport(src, random_turf)
/mob/living/simple_animal/hostile/hivebot/proc/wakeup()
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
@@ -157,7 +157,7 @@
/mob/living/simple_animal/hostile/hivebotbeacon/emp_act()
if(activated != -1)
LoseTarget()
stance = HOSTILE_STANCE_TIRED
change_stance(HOSTILE_STANCE_TIRED)
icon_state = "hivebotbeacon_off"
activated = -1
addtimer(CALLBACK(src, PROC_REF(wakeup)), 900)
@@ -174,7 +174,7 @@
do_teleport(src, random_turf)
/mob/living/simple_animal/hostile/hivebotbeacon/proc/wakeup()
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
activated = 0
activate_beacon()
@@ -42,7 +42,7 @@
mob_bump_flag = HEAVY
mob_swap_flags = ~HEAVY
mob_push_flags = 0
psi_pingable = FALSE
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/Initialize(mapload,mob/living/simple_animal/hostile/hivebot/hivebotbeacon)
@@ -83,7 +83,7 @@
/mob/living/simple_animal/hostile/retaliate/hivebotharvester/emp_act(severity)
LoseTarget()
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
visible_message(SPAN_DANGER("[src] suffers a teleportation malfunction!"))
playsound(src.loc, 'sound/effects/teleport.ogg', 25, 1)
var/turf/random_turf = get_turf(pick(orange(src,7)))
@@ -341,4 +341,4 @@
if(see_target())
Shoot(target, location, user)
target_mob = null
return
return
@@ -32,6 +32,12 @@
var/smart_ranged = FALSE // This makes ranged mob check for friendly fire and obstacles
var/hostile_nameable = FALSE //If we can rename this hostile mob. Mostly to prevent repeat checks with guard dogs and hostile/retaliate farm animals
var/is_fast_processing = FALSE
// actions measured in deciseconds
var/hostile_time_between_attacks = 10
var/hostile_last_attack = 0
/mob/living/simple_animal/hostile/Initialize()
. = ..()
setup_target_type_validators()
@@ -59,6 +65,7 @@
return null
var/atom/T = null
var/target_range = INFINITY
for (var/atom/A in targets)
if(A == src)
continue
@@ -71,20 +78,23 @@
if (!cb)
continue
else if (!istype(cb) || cb.Invoke(A, T))
T = A
var/range_to_atom = get_dist(src, A)
if(range_to_atom < target_range)
T = A
target_range = range_to_atom
stop_automated_movement = 0
if (T != target_mob)
target_mob = T
FoundTarget()
if(isliving(T))
visible_message(SPAN_WARNING("\The [src] [attack_emote] [T]."))
if(istype(T, /mob/living/simple_animal/hostile))
var/mob/living/simple_animal/hostile/H = T
H.being_targeted(src)
if(!isnull(T))
stance = HOSTILE_STANCE_ATTACK
if(isliving(T))
visible_message(SPAN_WARNING("\The [src] [attack_emote] [T]."))
if(istype(T, /mob/living/simple_animal/hostile))
var/mob/living/simple_animal/hostile/H = T
H.being_targeted(src)
change_stance(HOSTILE_STANCE_ATTACK)
return T
// This proc is used when one hostile mob targets another hostile mob.
@@ -93,20 +103,20 @@
return
target_mob = H
FoundTarget()
stance = HOSTILE_STANCE_ATTACKING
change_stance(HOSTILE_STANCE_ATTACKING)
visible_message(SPAN_WARNING("\The [src] gets taunted by \the [H] and begins to retaliate!"))
/mob/living/simple_animal/hostile/bullet_act(var/obj/item/projectile/P, var/def_zone)
..()
if (ismob(P.firer) && target_mob != P.firer)
target_mob = P.firer
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
/mob/living/simple_animal/hostile/attackby(var/obj/item/O, var/mob/user)
..()
if(target_mob != user)
target_mob = user
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
..()
@@ -114,19 +124,19 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
var/obj/O = AM
if((target_mob != O.thrower) && ismob(O.thrower))
target_mob = O.thrower
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
/mob/living/simple_animal/hostile/attack_generic(var/mob/user, var/damage, var/attack_message)
..()
if(target_mob != user)
target_mob = user
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
/mob/living/simple_animal/hostile/attack_hand(mob/living/carbon/human/M as mob)
..()
if(target_mob != M)
target_mob = M
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
//This proc is called after a target is acquired
/mob/living/simple_animal/hostile/proc/FoundTarget()
@@ -152,9 +162,8 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
else
walk_to(src, target_mob, 6, move_to_delay)
else
stance = HOSTILE_STANCE_ATTACKING
var/move_distance = smart_melee ? 2 : 1
walk_to(src, target_mob, move_distance, move_to_delay)
change_stance(HOSTILE_STANCE_ATTACKING)
walk_to(src, target_mob, 1, move_to_delay)
/mob/living/simple_animal/hostile/proc/AttackTarget()
stop_automated_movement = 1
@@ -166,11 +175,12 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
return 0
if(!see_target())
LoseTarget()
if(!ranged)
step_to(src, target_mob, 1)
if(world.time < hostile_time_between_attacks + hostile_last_attack)
return
if(get_dist(src, target_mob) <= 1) //Attacking
AttackingTarget()
attacked_times += 1
hostile_last_attack = world.time
return 1
else
return 0
@@ -234,7 +244,7 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
facing_dir = null
/mob/living/simple_animal/hostile/proc/LoseTarget()
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
walk(src, 0)
LostTarget()
@@ -276,6 +286,24 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
target_mob = FindTarget()
attacked_times = 0
/mob/living/simple_animal/hostile/proc/change_stance(var/new_stance)
if(new_stance == stance)
return FALSE
stance = new_stance
switch(stance)
if(HOSTILE_STANCE_IDLE)
MOB_SHIFT_TO_NORMAL_THINKING(src)
if(HOSTILE_STANCE_ALERT)
MOB_SHIFT_TO_FAST_THINKING(src)
if(HOSTILE_STANCE_ATTACK)
MOB_SHIFT_TO_FAST_THINKING(src)
if(HOSTILE_STANCE_ATTACKING)
MOB_SHIFT_TO_FAST_THINKING(src)
if(HOSTILE_STANCE_TIRED)
MOB_SHIFT_TO_NORMAL_THINKING(src)
return TRUE
/mob/living/simple_animal/hostile/proc/OpenFire(target_mob)
if(!see_target())
@@ -294,7 +322,7 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
else
shoot_wrapper(target, loc, src)
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
/mob/living/simple_animal/hostile/proc/check_fire(target_mob)
@@ -340,7 +368,7 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
visible_message(SPAN_DANGER("[capitalize_first_letters(src.name)] [attacktext] \the [e]!"))
src.do_attack_animation(e)
target_mob = e
stance = HOSTILE_STANCE_ATTACKING
change_stance(HOSTILE_STANCE_ATTACKING)
return TRUE
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
@@ -209,12 +209,6 @@
return
return ..()
/mob/living/simple_animal/hostile/bullet_act(obj/item/projectile/P, def_zone)
..()
if (ismob(P.firer) && target_mob != P.firer)
target_mob = P.firer
stance = HOSTILE_STANCE_ATTACK
/mob/living/simple_animal/hostile/morph/attackby(obj/item/O, mob/user)
..()
if(morphed && user != src)
@@ -9,7 +9,7 @@
if(isliving(A))
var/mob/living/L = A
if(!L.stat)
stance = HOSTILE_STANCE_ATTACK
change_stance(HOSTILE_STANCE_ATTACK)
return L
else
enemies -= L
@@ -49,4 +49,4 @@
to_chat(usr,"<span class='notice'>This species will be known from now on as '[newname]'.</span>")
else
to_chat(usr,"<span class='warning'>This species has already been named!</span>")
return
return
@@ -65,7 +65,7 @@
/mob/living/simple_animal/hostile/carp/MoveToTarget()
stop_automated_movement = 1
if(istype(target_mob, /obj/effect/energy_field) && !QDELETED(target_mob) && (target_mob in targets))
stance = HOSTILE_STANCE_ATTACKING
change_stance(HOSTILE_STANCE_ATTACKING)
walk_to(src, target_mob, 1, move_to_delay)
return 1
..()
@@ -100,7 +100,7 @@
visible_message("<span class='danger'>\the [src] bites \the [e]!</span>")
src.do_attack_animation(e)
target_mob = e
stance = HOSTILE_STANCE_ATTACKING
change_stance(HOSTILE_STANCE_ATTACKING)
return 1
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
@@ -189,8 +189,8 @@
melee_damage_lower = 20
melee_damage_upper = 20
armor_penetration = 25
/mob/living/simple_animal/hostile/carp/bloater
/mob/living/simple_animal/hostile/carp/bloater
name = "bloater"
desc = "A fat, mineral-devouring creature frequently herded for mining expeditions. Its actual ability to dig is less valuable than its volatile nature, however."
icon = 'icons/mob/npc/large_space_xenofauna.dmi'
@@ -212,7 +212,7 @@
/mob/living/simple_animal/hostile/carp/bloater/AttackingTarget()
..()
LoseTarget()
stance = HOSTILE_STANCE_TIRED
change_stance(HOSTILE_STANCE_TIRED)
stop_automated_movement = 1
wander = 0
if(!has_exploded)
@@ -47,11 +47,11 @@
return FALSE
/mob/living/simple_animal/hostile/viscerator/proc/wakeup()
stance = HOSTILE_STANCE_IDLE
change_stance(HOSTILE_STANCE_IDLE)
/mob/living/simple_animal/hostile/viscerator/emp_act(severity)
LoseTarget()
stance = HOSTILE_STANCE_TIRED
change_stance(HOSTILE_STANCE_TIRED)
addtimer(CALLBACK(src, PROC_REF(wakeup)), 150)
if(severity == 1.0)
apply_damage(5)