SSthrowing (#19421)

Ported SSThrowing from TG, to handle throwings.
Updated movement system to the latest iteration, made it a datum as per
latest iteration.
Updated pass/hit handling of atoms, introduced pass_flag_self to
determine what atoms allow to pass.
Moved procs and defines around to make them more organized.
This commit is contained in:
Fluffy
2024-06-18 19:32:06 +00:00
committed by GitHub
parent 56a7300903
commit 92c3ec6caf
96 changed files with 1125 additions and 496 deletions
+1 -1
View File
@@ -58,7 +58,7 @@
facing_dir = null
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(!gibbed && deathmessage != "no message") // This is gross, but reliable. Only brains use it.
src.visible_message("<b>\The [src.name]</b> [deathmessage]", range = messagerange)
@@ -48,6 +48,6 @@
if(!gestalt)
if(stat != DEAD)
if(master_nymph && !client && master_nymph != src)
SSmove_manager.move_to(src, master_nymph, 1, movement_delay())
GLOB.move_manager.move_to(src, master_nymph, 1, movement_delay())
else
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
@@ -346,21 +346,21 @@ emp_act
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
var/zone
if (istype(O.thrower, /mob/living))
var/mob/living/L = O.thrower
if (istype(O.throwing?.thrower?.resolve(), /mob/living))
var/mob/living/L = O.throwing?.thrower?.resolve()
zone = check_zone(L.zone_sel.selecting)
else
zone = ran_zone(BP_CHEST,75) //Hits a random part of the body, geared towards the chest
//check if we hit
var/miss_chance = 15
if (O.throw_source)
var/distance = get_dist(O.throw_source, loc)
if (O.throwing?.thrower?.resolve())
var/distance = get_dist(O.throwing?.thrower?.resolve(), loc)
miss_chance = 15 * (distance - 2)
zone = get_zone_with_miss_chance(zone, src, miss_chance, 1)
if(zone && O.thrower != src)
var/shield_check = check_shields(throw_damage, O, thrower, zone, "[O]")
if(zone && O.throwing?.thrower?.resolve() != src)
var/shield_check = check_shields(throw_damage, O, throwing?.thrower?.resolve(), zone, "[O]")
if(shield_check == PROJECTILE_FORCE_MISS)
zone = null
else if(shield_check)
@@ -371,8 +371,6 @@ emp_act
playsound(src, 'sound/effects/throw_miss.ogg', rand(10, 50), 1)
return
O.throwing = 0 //it hit, so stop moving
var/obj/item/organ/external/affecting = get_organ(zone)
var/hit_area = affecting.name
@@ -380,8 +378,8 @@ emp_act
SPAN_WARNING("<font size=2>You're hit in the [hit_area] by [O]!</font>"))
apply_damage(throw_damage, dtype, zone, used_weapon = O, damage_flags = O.damage_flags(), armor_pen = O.armor_penetration)
if(ismob(O.thrower))
var/mob/M = O.thrower
if(ismob(O.throwing?.thrower?.resolve()))
var/mob/M = O.throwing?.thrower?.resolve()
var/client/assailant = M.client
if(assailant)
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been hit with a [O], thrown by [M.name] ([assailant.ckey])</font>")
@@ -413,8 +411,8 @@ emp_act
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
var/momentum = speed*mass
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
if(O.throwing?.thrower?.resolve() && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throwing?.thrower?.resolve(), src)
visible_message(SPAN_WARNING("[src] staggers under the impact!"),
SPAN_WARNING("You stagger under the impact!"))
@@ -167,7 +167,7 @@
visible_message(SPAN_DANGER("[src] leaps at [T]!"),
SPAN_DANGER("You leap at [T]!"))
throw_at(get_step(get_turf(T), get_turf(src)), 4, 1, src, do_throw_animation = FALSE)
throw_at(get_step(get_turf(T), get_turf(src)), 4, 1, src, spin = FALSE)
sleep(5)
@@ -202,7 +202,7 @@
if(istype(AM, /obj/structure/window) || istype(AM, /obj/structure/grille))
if(nutrition <= get_hunger_nutrition() && !Atkcool)
if(is_adult || prob(5))
UnarmedAttack(AM)
INVOKE_ASYNC(src, PROC_REF(UnarmedAttack), AM)
Atkcool = TRUE
addtimer(CALLBACK(src, PROC_REF(reset_atkcooldown)), 45)
+96 -97
View File
@@ -54,122 +54,121 @@ default behaviour is:
var/tmp/last_push_notif
/mob/living/Collide(atom/movable/AM)
spawn
if (now_pushing || !loc)
if (now_pushing || !loc)
return
now_pushing = TRUE
if (istype(AM, /mob/living))
var/mob/living/tmob = AM
for(var/mob/living/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/grab, tmob.grabbed_by.len)) )
if (last_push_notif + 0.5 SECONDS <= world.time)
to_chat(src, SPAN_WARNING("[tmob] is restrained, you cannot push past"))
last_push_notif = world.time
now_pushing = FALSE
return
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
if (last_push_notif + 0.5 SECONDS <= world.time)
to_chat(src, SPAN_WARNING("[tmob] is restraining [M], you cannot push past"))
last_push_notif = world.time
now_pushing = FALSE
return
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
forceMove(tmob.loc)
status_flags &= ~LEAPING
now_pushing = FALSE
return
now_pushing = TRUE
if (istype(AM, /mob/living))
var/mob/living/tmob = AM
for(var/mob/living/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/grab, tmob.grabbed_by.len)) )
if (last_push_notif + 0.5 SECONDS <= world.time)
to_chat(src, SPAN_WARNING("[tmob] is restrained, you cannot push past"))
last_push_notif = world.time
now_pushing = FALSE
return
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
if (last_push_notif + 0.5 SECONDS <= world.time)
to_chat(src, SPAN_WARNING("[tmob] is restraining [M], you cannot push past"))
last_push_notif = world.time
now_pushing = FALSE
return
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
forceMove(tmob.loc)
status_flags &= ~LEAPING
now_pushing = FALSE
return
if(can_swap_with(tmob)) // mutual brohugs all around!
var/turf/tmob_oldloc = get_turf(tmob)
var/turf/src_oldloc = get_turf(src)
if(pulling?.density)
tmob.forceMove(pulling.loc)
forceMove(tmob_oldloc)
if(can_swap_with(tmob)) // mutual brohugs all around!
var/turf/tmob_oldloc = get_turf(tmob)
var/turf/src_oldloc = get_turf(src)
if(pulling?.density)
tmob.forceMove(pulling.loc)
forceMove(tmob_oldloc)
pulling.forceMove(src_oldloc)
else if(tmob.pulling?.density)
forceMove(tmob.pulling.loc)
tmob.forceMove(src_oldloc)
tmob.pulling.forceMove(tmob_oldloc)
else
forceMove(tmob_oldloc)
if(pulling)
pulling.forceMove(src_oldloc)
else if(tmob.pulling?.density)
forceMove(tmob.pulling.loc)
tmob.forceMove(src_oldloc)
tmob.forceMove(src_oldloc)
if(tmob.pulling)
tmob.pulling.forceMove(tmob_oldloc)
else
forceMove(tmob_oldloc)
if(pulling)
pulling.forceMove(src_oldloc)
tmob.forceMove(src_oldloc)
if(tmob.pulling)
tmob.pulling.forceMove(tmob_oldloc)
for(var/obj/item/grab/G in list(l_hand, r_hand))
G.affecting.forceMove(loc)
for(var/obj/item/grab/G in list(tmob.l_hand, tmob.r_hand))
G.affecting.forceMove(tmob.loc)
now_pushing = FALSE
for(var/mob/living/carbon/slime/slime in view(2, tmob))
if(slime.victim == tmob)
slime.UpdateFeed()
return
for(var/obj/item/grab/G in list(l_hand, r_hand))
G.affecting.forceMove(loc)
for(var/obj/item/grab/G in list(tmob.l_hand, tmob.r_hand))
G.affecting.forceMove(tmob.loc)
now_pushing = FALSE
for(var/mob/living/carbon/slime/slime in view(2, tmob))
if(slime.victim == tmob)
slime.UpdateFeed()
return
if(!can_move_mob(tmob, 0, 0))
if(!can_move_mob(tmob, 0, 0))
now_pushing = FALSE
return
if(a_intent == I_HELP || src.restrained())
now_pushing = FALSE
return
if(istype(tmob, /mob/living/carbon/human) && (tmob.mutations & FAT))
if(prob(40) && !(mutations & FAT))
to_chat(src, SPAN_DANGER("You fail to push [tmob]'s fat ass out of the way."))
now_pushing = FALSE
return
if(a_intent == I_HELP || src.restrained())
if(istype(tmob.r_hand, /obj/item/shield/riot))
if(prob(99))
now_pushing = FALSE
return
if(istype(tmob, /mob/living/carbon/human) && (tmob.mutations & FAT))
if(prob(40) && !(mutations & FAT))
to_chat(src, SPAN_DANGER("You fail to push [tmob]'s fat ass out of the way."))
if(istype(tmob.l_hand, /obj/item/shield/riot))
if(prob(99))
now_pushing = FALSE
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = FALSE
return
tmob.LAssailant = WEAKREF(src)
now_pushing = FALSE
. = ..()
if (!istype(AM, /atom/movable))
return
if (!now_pushing)
now_pushing = TRUE
if (!AM.anchored)
if(isobj(AM))
var/obj/O = AM
if ((can_pull_size == 0) || (can_pull_size < O.w_class))
now_pushing = FALSE
return
if(istype(tmob.r_hand, /obj/item/shield/riot))
if(prob(99))
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = FALSE
return
if(istype(tmob.l_hand, /obj/item/shield/riot))
if(prob(99))
now_pushing = FALSE
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = FALSE
return
tmob.LAssailant = WEAKREF(src)
step(AM, t)
if(ishuman(AM) && AM:grabbed_by)
for(var/obj/item/grab/G in AM:grabbed_by)
step(G:assailant, get_dir(G:assailant, AM))
G.adjust_position()
now_pushing = FALSE
. = ..()
if (!istype(AM, /atom/movable))
return
if (!now_pushing)
now_pushing = TRUE
if (!AM.anchored)
if(isobj(AM))
var/obj/O = AM
if ((can_pull_size == 0) || (can_pull_size < O.w_class))
now_pushing = FALSE
return
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = FALSE
return
step(AM, t)
if(ishuman(AM) && AM:grabbed_by)
for(var/obj/item/grab/G in AM:grabbed_by)
step(G:assailant, get_dir(G:assailant, AM))
G.adjust_position()
now_pushing = FALSE
/**
* Checks if two mobs can swap with each other based on the density
+7 -7
View File
@@ -175,8 +175,8 @@
var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
var/miss_chance = 15
if (O.throw_source)
var/distance = get_dist(O.throw_source, loc)
if (O.throwing?.thrower?.resolve())
var/distance = get_dist(O.throwing?.thrower?.resolve(), loc)
miss_chance = max(15*(distance-2), 0)
if (prob(miss_chance))
@@ -187,10 +187,10 @@
src.visible_message(SPAN_WARNING("[src] has been hit by [O]."))
apply_damage(throw_damage, dtype, null, damage_flags = O.damage_flags(), used_weapon = O)
O.throwing = 0 //it hit, so stop moving
O.throwing?.finalize(hit = TRUE, target = src) //it hit, so stop moving
if(ismob(O.thrower))
var/mob/M = O.thrower
if(ismob(O.throwing?.thrower?.resolve()))
var/mob/M = O.throwing?.thrower?.resolve()
var/client/assailant = M.client
if(assailant)
src.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been hit with a [O], thrown by [M.name] ([assailant.ckey])</font>")
@@ -205,8 +205,8 @@
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
var/momentum = speed*mass
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
if(O.throwing?.thrower?.resolve() && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throwing?.thrower?.resolve(), src)
visible_message(SPAN_WARNING("[src] staggers under the impact!"),
SPAN_WARNING("You stagger under the impact!"))
@@ -15,8 +15,8 @@
strength *= reflexive_modifier
animate(user, pixel_z = 16, time = 3, easing = SINE_EASING | EASE_IN)
animate(pixel_z = 0, time = 3, easing = SINE_EASING | EASE_OUT)
user.throw_at(get_turf(target), strength, 1, user, FALSE)
end_leap(user, target, old_pass_flags)
var/end_leap_callback = CALLBACK(src, PROC_REF(end_leap), user, target, old_pass_flags)
user.throw_at(get_turf(target), strength, 1, user, spin = FALSE, diagonals_first = TRUE, callback = end_leap_callback)
/singleton/maneuver/leap/proc/end_leap(var/mob/living/user, var/atom/target, var/pass_flag)
SHOULD_NOT_SLEEP(TRUE)
@@ -70,11 +70,11 @@
/mob/living/simple_animal/carp/fluff/think()
..()
if(!stat && !buckled_to && (turns_since_move > 5))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
turns_since_move = 0
handle_movement_target()
if(!movement_target && (turns_since_move > 5))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
/mob/living/simple_animal/carp/fluff/proc/handle_movement_target()
if(!QDELETED(friend))
@@ -89,17 +89,17 @@
if(movement_target != friend)
if(current_dist > follow_dist && (friend in oview(src)))
//stop existing movement
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
turns_since_scan = 0
//walk to friend
stop_automated_movement = 1
movement_target = friend
SSmove_manager.move_to(src, movement_target, near_dist, seek_move_delay)
GLOB.move_manager.move_to(src, movement_target, near_dist, seek_move_delay)
//already following and close enough, stop
else if(current_dist <= near_dist)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
movement_target = null
stop_automated_movement = 0
if(prob(10))
@@ -64,7 +64,7 @@
if(!buckled_to)
if (turns_since_move > 5 || (flee_target || rattarget))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
turns_since_move = 0
if (flee_target) //fleeing takes precendence
@@ -73,7 +73,7 @@
handle_movement_target()
if (!movement_target)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(prob(2)) //spooky
var/mob/abstract/observer/spook = locate() in range(src,5)
@@ -164,7 +164,7 @@
if (flee_target)
if(prob(25)) say("HSSSSS")
stop_automated_movement = 1
SSmove_manager.move_away(src, flee_target, 7, 2)
GLOB.move_manager.move_away(src, flee_target, 7, 2)
/mob/living/simple_animal/cat/proc/set_flee_target(atom/A)
if(A)
@@ -191,7 +191,7 @@
/mob/living/simple_animal/cat/hitby(atom/movable/AM)
. = ..()
set_flee_target(AM.thrower? AM.thrower : src.loc)
set_flee_target(AM.throwing?.thrower?.resolve() ? AM.throwing?.thrower?.resolve() : src.loc)
/mob/living/simple_animal/cat/fall_impact()
src.visible_message(SPAN_NOTICE("\The [src] lands softly on \the [loc]!"))
@@ -215,17 +215,17 @@
if (movement_target != friend)
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/rat) && (friend in oview(src)))
//stop existing movement
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
turns_since_scan = 0
//walk to friend
stop_automated_movement = 1
movement_target = friend
SSmove_manager.move_to(src, movement_target, near_dist, seek_move_delay)
GLOB.move_manager.move_to(src, movement_target, near_dist, seek_move_delay)
//already following and close enough, stop
else if (current_dist <= near_dist)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
movement_target = null
stop_automated_movement = 0
if (prob(10))
@@ -247,7 +247,7 @@
set_stance(HOSTILE_STANCE_TIRED)
speak_audio()
stance_step = 0
SSmove_manager.stop_looping(src) //This stops the bear's walking
GLOB.move_manager.stop_looping(src) //This stops the bear's walking
/mob/living/simple_animal/hostile/bear/spatial/tire_out()
..()
@@ -320,7 +320,7 @@
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
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
/mob/living/simple_animal/hostile/bear/AttackingTarget()
var/targetname = target_mob.name
@@ -333,8 +333,8 @@
if(istype(AM,/obj/))
var/obj/O = AM
if(ismob(O.thrower))
if(O.thrower == master)
if(ismob(O.throwing?.thrower?.resolve()))
if(O.throwing?.thrower?.resolve() == master)
target_mob = null
change_stance(HOSTILE_STANCE_IDLE)
audible_emote("[pick(sad_emote)].",0)
@@ -222,12 +222,12 @@
for(var/turf/T in orange(20, src))
move_targets.Add(T)*/
stop_automated_movement = 1
SSmove_manager.move_to(src, pick(orange(20, src)), 1, move_to_delay)
GLOB.move_manager.move_to(src, pick(orange(20, src)), 1, move_to_delay)
addtimer(CALLBACK(src, PROC_REF(stop_walking)), 50, TIMER_UNIQUE)
/mob/living/simple_animal/hostile/giant_spider/proc/stop_walking()
stop_automated_movement = 0
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
/mob/living/simple_animal/hostile/giant_spider/nurse/think()
..()
@@ -240,7 +240,7 @@
if(C.stat)
cocoon_target = C
busy = MOVING_TO_TARGET
SSmove_manager.move_to(src, C, 1, move_to_delay)
GLOB.move_manager.move_to(src, C, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
addtimer(CALLBACK(src, PROC_REF(GiveUp), C), 100, TIMER_UNIQUE)
return
@@ -270,7 +270,7 @@
cocoon_target = O
busy = MOVING_TO_TARGET
stop_automated_movement = 1
SSmove_manager.move_to(src, O, 1, move_to_delay)
GLOB.move_manager.move_to(src, O, 1, move_to_delay)
//give up if we can't reach them after 10 seconds
GiveUp(O)
@@ -279,7 +279,7 @@
busy = SPINNING_COCOON
src.visible_message(SPAN_NOTICE("\The [src] begins to secrete a sticky substance around \the [cocoon_target]."))
stop_automated_movement = 1
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
addtimer(CALLBACK(src, PROC_REF(finalize_cocoon)), 50, TIMER_UNIQUE)
else
@@ -188,7 +188,7 @@
LoseTarget()
if(target_mob in targets)
if(get_dist(src, target_mob) <= 6)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
OpenFire(target_mob)
/mob/living/simple_animal/hostile/hivebotbeacon/proc/activate_beacon()
@@ -136,8 +136,8 @@
..()
if(istype(AM,/obj/))
var/obj/O = AM
if((target_mob != O.thrower) && ismob(O.thrower))
target_mob = O.thrower
if((target_mob != O.throwing?.thrower?.resolve()) && ismob(O.throwing?.thrower?.resolve()))
target_mob = O.throwing?.thrower?.resolve()
change_stance(HOSTILE_STANCE_ATTACK)
/mob/living/simple_animal/hostile/attack_generic(var/mob/user, var/damage, var/attack_message)
@@ -168,13 +168,13 @@
if(target_mob in targets)
if(ranged)
if(get_dist(src, target_mob) <= ranged_attack_range)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
OpenFire(target_mob)
else
SSmove_manager.move_to(src, target_mob, 6, move_to_delay)
GLOB.move_manager.move_to(src, target_mob, 6, move_to_delay)
else
change_stance(HOSTILE_STANCE_ATTACKING)
SSmove_manager.move_to(src, target_mob, 1, move_to_delay)
GLOB.move_manager.move_to(src, target_mob, 1, move_to_delay)
/mob/living/simple_animal/hostile/proc/AttackTarget()
stop_automated_movement = 1
@@ -265,7 +265,7 @@
/mob/living/simple_animal/hostile/proc/LoseTarget()
change_stance(HOSTILE_STANCE_IDLE)
target_mob = null
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
LostTarget()
/mob/living/simple_animal/hostile/proc/LostTarget()
@@ -276,7 +276,7 @@
/mob/living/simple_animal/hostile/death()
..()
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
/mob/living/simple_animal/hostile/think()
..()
@@ -207,7 +207,7 @@
else
visible_message(SPAN_NOTICE("\The [src] suddenly lies still and quiet."))
disabled = rand(150, 600)
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(exploding && prob(20))
if(prob(50))
@@ -220,7 +220,7 @@
exploding = TRUE
set_stat(UNCONSCIOUS)
wander = 1
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
spawn(rand(50, 150))
if(!disabled && exploding)
explosion(get_turf(src), 0, 1, 4, 7)
@@ -233,7 +233,7 @@
health -= rand(3, 15) * (severity + 1)
disabled = rand(150, 600)
hostile_drone = FALSE
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
/mob/living/simple_animal/hostile/icarus_drone/death()
..(null, "suddenly breaks apart.")
@@ -175,7 +175,7 @@
break
if(target_ore)
SSmove_manager.move_to(src, target_ore, 1, move_to_delay)
GLOB.move_manager.move_to(src, target_ore, 1, move_to_delay)
else if(found_turfs.len)
for(var/turf/simulated/mineral/M in found_turfs)
if(!QDELETED(M) || !M.mineral)
@@ -67,7 +67,7 @@
stop_automated_movement = 1
if(istype(target_mob, /obj/effect/energy_field) && !QDELETED(target_mob) && (target_mob in targets))
change_stance(HOSTILE_STANCE_ATTACKING)
SSmove_manager.move_to(src, target_mob, 1, move_to_delay)
GLOB.move_manager.move_to(src, target_mob, 1, move_to_delay)
return 1
..()
+10 -10
View File
@@ -116,7 +116,7 @@
if(held_item)
held_item.forceMove(src.loc)
held_item = null
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
..()
/mob/living/simple_animal/parrot/get_status_tab_items()
@@ -356,7 +356,7 @@
//-----WANDERING - This is basically a 'I dont know what to do yet' state
else if(parrot_state == PARROT_WANDER)
//Stop movement, we'll set it later
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
parrot_interest = null
//Wander around aimlessly. This will help keep the loops from searches down
@@ -394,7 +394,7 @@
return
//-----STEALING
else if(parrot_state == (PARROT_SWOOP | PARROT_STEAL))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(!parrot_interest || held_item)
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
@@ -418,12 +418,12 @@
parrot_state = PARROT_SWOOP | PARROT_RETURN
return
SSmove_manager.move_to(src, parrot_interest, 1, parrot_speed)
GLOB.move_manager.move_to(src, parrot_interest, 1, parrot_speed)
return
//-----RETURNING TO PERCH
else if(parrot_state == (PARROT_SWOOP | PARROT_RETURN))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(!parrot_perch || !isturf(parrot_perch.loc)) //Make sure the perch exists and somehow isnt inside of something else.
parrot_perch = null
parrot_state = PARROT_WANDER
@@ -436,16 +436,16 @@
icon_state = "parrot_sit"
return
SSmove_manager.move_to(src, parrot_perch, 1, parrot_speed)
GLOB.move_manager.move_to(src, parrot_perch, 1, parrot_speed)
return
//-----FLEEING
else if(parrot_state == (PARROT_SWOOP | PARROT_FLEE))
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
if(!parrot_interest || !isliving(parrot_interest)) //Sanity
parrot_state = PARROT_WANDER
SSmove_manager.move_away(src, parrot_interest, 1, (parrot_speed-parrot_been_shot))
GLOB.move_manager.move_away(src, parrot_interest, 1, (parrot_speed-parrot_been_shot))
parrot_been_shot--
return
@@ -493,11 +493,11 @@
//Otherwise, fly towards the mob!
else
SSmove_manager.move_to(src, parrot_interest, 1, parrot_speed)
GLOB.move_manager.move_to(src, parrot_interest, 1, parrot_speed)
return
//-----STATE MISHAP
else //This should not happen. If it does lets reset everything and try again
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
parrot_interest = null
parrot_perch = null
drop_held_item()
@@ -642,8 +642,8 @@
/mob/living/simple_animal/hitby(atom/movable/AM, speed)
. = ..()
if(ismob(AM.thrower))
handle_attack_by(AM.thrower)
if(ismob(AM.throwing?.thrower?.resolve()))
handle_attack_by(AM.throwing?.thrower?.resolve())
/mob/living/simple_animal/bullet_act(obj/item/projectile/P, def_zone)
. = ..()
@@ -700,7 +700,7 @@
if(movement_target)
stop_automated_movement = 1
SSmove_manager.move_to(src, movement_target, 0, seek_move_delay)
GLOB.move_manager.move_to(src, movement_target, 0, seek_move_delay)
/mob/living/simple_animal/get_status_tab_items()
. = ..()
@@ -715,7 +715,7 @@
death()
/mob/living/simple_animal/death(gibbed, deathmessage = "dies!")
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
movement_target = null
density = FALSE
if (isopenturf(loc))
@@ -881,7 +881,7 @@
set_stat(UNCONSCIOUS)
canmove = 0
wander = 0
SSmove_manager.stop_looping(src)
GLOB.move_manager.stop_looping(src)
movement_target = null
update_icon()
+1 -1
View File
@@ -752,7 +752,7 @@
src.pulling = AM
AM.pulledby = src
SSmove_manager.stop_looping(AM)
GLOB.move_manager.stop_looping(AM)
if(pullin)
pullin.icon_state = "pull1"
+32 -25
View File
@@ -131,47 +131,54 @@
return
//This proc should never be overridden elsewhere at /atom/movable to keep directions sane.
/atom/movable/Move(atom/newloc, direction)
/atom/movable/Move(atom/newloc, direction, glide_size_override = 0, update_dir = TRUE) //Last 2 parameters are not used but they're caught
. = FALSE
if(!newloc || newloc == loc)
return
if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_MOVE, newloc) & COMPONENT_MOVABLE_BLOCK_PRE_MOVE)
return
var/old_loc = loc
if (direction & (direction - 1))
if (direction & 1)
if (direction & 4)
if (step(src, NORTH))
step(src, EAST)
//Cardinal move
if(direction & (direction - 1))
if(direction & 1)
if(direction & 4)
if(step(src, NORTH))
. = step(src, EAST)
else
if (step(src, EAST))
step(src, NORTH)
if(step(src, EAST))
. = step(src, NORTH)
else
if (direction & 8)
if (step(src, NORTH))
step(src, WEST)
if(direction & 8)
if(step(src, NORTH))
. = step(src, WEST)
else
if (step(src, WEST))
step(src, NORTH)
if(step(src, WEST))
. = step(src, NORTH)
else
if (direction & 2)
if (direction & 4)
if (step(src, SOUTH))
step(src, EAST)
if(direction & 2)
if(direction & 4)
if(step(src, SOUTH))
. = step(src, EAST)
else
if (step(src, EAST))
step(src, SOUTH)
if(step(src, EAST))
. = step(src, SOUTH)
else
if (direction & 8)
if (step(src, SOUTH))
step(src, WEST)
if(direction & 8)
if(step(src, SOUTH))
. = step(src, WEST)
else
if (step(src, WEST))
step(src, SOUTH)
if(step(src, WEST))
. = step(src, SOUTH)
//Diagonal move
else
var/atom/A = src.loc
var/olddir = dir //we can't override this without sacrificing the rest of movable/New()
. = ..()
. = ..(newloc, direction)
if(.)
// Events.