From 76e1ee80b762f3e66dd48eda81ae61adb60e5444 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sun, 3 May 2020 07:12:41 +0200 Subject: [PATCH] Porting "Mobs now turn towards and are shifted based on grab state towards something pulling them" --- code/__DEFINES/atmospherics.dm | 4 +- code/__DEFINES/mobs.dm | 4 ++ code/datums/components/riding.dm | 7 ++++ code/game/atoms_movable.dm | 4 ++ code/game/atoms_movement.dm | 18 +++----- code/game/objects/buckling.dm | 11 ++++- .../atmospherics/machinery/pipes/manifold.dm | 2 + .../machinery/pipes/manifold4w.dm | 2 + code/modules/mob/living/living.dm | 41 +++++++++++++++++++ code/modules/mob/living/living_defense.dm | 1 + code/modules/mob/living/living_movement.dm | 14 ++++++- code/modules/mob/mob_movement.dm | 2 + 12 files changed, 92 insertions(+), 18 deletions(-) diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index e728d49956..88c1b763a5 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -255,10 +255,10 @@ //HELPERS #define PIPING_LAYER_SHIFT(T, PipingLayer) \ - if(T.dir & NORTH || T.dir & SOUTH) { \ + if(T.dir & (NORTH|SOUTH)) { \ T.pixel_x = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_X;\ } \ - if(T.dir & WEST || T.dir & EAST) { \ + if(T.dir & (WEST|EAST)) { \ T.pixel_y = (PipingLayer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y;\ } diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index c89bd4843e..61850ed2fd 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -288,6 +288,10 @@ #define HUMAN_FIRE_STACK_ICON_NUM 3 +#define GRAB_PIXEL_SHIFT_PASSIVE 6 +#define GRAB_PIXEL_SHIFT_AGGRESSIVE 12 +#define GRAB_PIXEL_SHIFT_NECK 16 + #define PULL_PRONE_SLOWDOWN 0.6 #define FIREMAN_CARRY_SLOWDOWN 0 #define PIGGYBACK_CARRY_SLOWDOWN 1 diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index 00bb392787..651acda6e1 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -20,6 +20,8 @@ var/ride_check_ridden_incapacitated = FALSE var/list/offhands = list() // keyed list containing all the current riding offsets associated by mob + var/del_on_unbuckle_all = FALSE + /datum/component/riding/Initialize() if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE @@ -28,8 +30,11 @@ RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) /datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) + var/atom/movable/AM = parent restore_position(M) unequip_buckle_inhands(M) + if(del_on_unbuckle_all && !AM.has_buckled_mobs()) + qdel(src) /datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) handle_vehicle_offsets() @@ -194,6 +199,7 @@ ///////Yes, I said humans. No, this won't end well...////////// /datum/component/riding/human + del_on_unbuckle_all = TRUE var/fireman_carrying = FALSE /datum/component/riding/human/Initialize() @@ -261,6 +267,7 @@ user.visible_message("[AM] pushes [user] off of [AM.p_them()]!") /datum/component/riding/cyborg + del_on_unbuckle_all = TRUE /datum/component/riding/cyborg/Initialize() . = ..() diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b86c7e9729..32dde45195 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -25,6 +25,7 @@ var/inertia_move_delay = 5 var/pass_flags = 0 var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move + var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before. var/list/client_mobs_in_contents // This contains all the client mobs within this container var/list/acted_explosions //for explosion dodging glide_size = 8 @@ -207,6 +208,7 @@ if(!Process_Spacemove(get_dir(pulling.loc, A))) return step(pulling, get_dir(pulling.loc, A)) + return TRUE /atom/movable/proc/check_pulling() if(pulling) @@ -224,6 +226,8 @@ if(pulling.anchored || pulling.move_resist > move_force) stop_pulling() return + if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move. + pulledby.stop_pulling() /atom/movable/Destroy(force) QDEL_NULL(proximity_monitor) diff --git a/code/game/atoms_movement.dm b/code/game/atoms_movement.dm index d418652cd8..3d2b6d9e91 100644 --- a/code/game/atoms_movement.dm +++ b/code/game/atoms_movement.dm @@ -51,13 +51,8 @@ /atom/movable/Move(atom/newloc, direct) var/atom/movable/pullee = pulling var/turf/T = loc - if(pulling) - if(pullee && get_dist(src, pullee) > 1) - stop_pulling() - - if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove(). - log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") - stop_pulling() + if(!moving_from_pull) + check_pulling() if(!loc || !newloc) return FALSE var/atom/oldloc = loc @@ -130,19 +125,16 @@ if(has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) return FALSE - if(pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move. + if(pulling && pulling == pullee && pulling != moving_from_pull) //we were pulling a thing and didn't lose it during our move. if(pulling.anchored) stop_pulling() else var/pull_dir = get_dir(src, pulling) //puller and pullee more than one tile away or in diagonal position if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) + pulling.moving_from_pull = src pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position - if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up - stop_pulling() - if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move. - pulledby.stop_pulling() - + pulling.moving_from_pull = null Moved(oldloc, direct) /atom/movable/proc/handle_buckled_mob_movement(newloc,direct) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 0e14af75a9..bacb8c6669 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -55,8 +55,12 @@ M.buckling = null return FALSE - if(M.pulledby && buckle_prevents_pull) - M.pulledby.stop_pulling() + if(M.pulledby) + if(buckle_prevents_pull) + M.pulledby.stop_pulling() + else if(isliving(M.pulledby)) + var/mob/living/L = M.pulledby + L.reset_pull_offsets(M, TRUE) if(!check_loc && M.loc != loc) M.forceMove(loc) @@ -137,4 +141,7 @@ "You unbuckle yourself from [src].",\ "You hear metal clanking.") add_fingerprint(user) + if(isliving(M.pulledby)) + var/mob/living/L = M.pulledby + L.set_pull_offsets(M, L.grab_state) return M diff --git a/code/modules/atmospherics/machinery/pipes/manifold.dm b/code/modules/atmospherics/machinery/pipes/manifold.dm index 77452fd6fd..aa8ee65bd8 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold.dm @@ -28,6 +28,8 @@ /obj/machinery/atmospherics/pipe/manifold/update_icon() cut_overlays() + if(!center) + center = mutable_appearance(icon, "manifold_center") PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) add_overlay(center) diff --git a/code/modules/atmospherics/machinery/pipes/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/manifold4w.dm index 1bcca8d5ae..56c0408d18 100644 --- a/code/modules/atmospherics/machinery/pipes/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/manifold4w.dm @@ -26,6 +26,8 @@ /obj/machinery/atmospherics/pipe/manifold4w/update_icon() cut_overlays() + if(!center) + center = mutable_appearance(icon, "manifold_center") PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) add_overlay(center) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 89f8381087..5189f47fbc 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -316,6 +316,45 @@ update_pull_movespeed() + set_pull_offsets(M, state) + +/mob/living/proc/set_pull_offsets(mob/living/M, grab_state = GRAB_PASSIVE) + if(M.buckled) + return //don't make them change direction or offset them if they're buckled into something. + var/offset = 0 + switch(grab_state) + if(GRAB_PASSIVE) + offset = GRAB_PIXEL_SHIFT_PASSIVE + if(GRAB_AGGRESSIVE) + offset = GRAB_PIXEL_SHIFT_AGGRESSIVE + if(GRAB_NECK) + offset = GRAB_PIXEL_SHIFT_NECK + if(GRAB_KILL) + offset = GRAB_PIXEL_SHIFT_NECK + M.setDir(get_dir(M, src)) + switch(M.dir) + if(NORTH) + animate(M, pixel_x = 0, pixel_y = offset, 3) + if(SOUTH) + animate(M, pixel_x = 0, pixel_y = -offset, 3) + if(EAST) + if(M.lying == 270) //update the dragged dude's direction if we've turned + M.lying = 90 + M.update_transform() //force a transformation update, otherwise it'll take a few ticks for update_mobility() to do so + M.lying_prev = M.lying + animate(M, pixel_x = offset, pixel_y = 0, 3) + if(WEST) + if(M.lying == 90) + M.lying = 270 + M.update_transform() + M.lying_prev = M.lying + animate(M, pixel_x = -offset, pixel_y = 0, 3) + +/mob/living/proc/reset_pull_offsets(mob/living/M, override) + if(!override && M.buckled) + return + animate(M, pixel_x = 0, pixel_y = 0, 1) + //mob verbs are a lot faster than object verbs //for more info on why this is not atom/pull, see examinate() in mob.dm /mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1)) @@ -328,6 +367,8 @@ stop_pulling() /mob/living/stop_pulling() + if(ismob(pulling)) + reset_pull_offsets(pulling) ..() update_pull_movespeed() update_pull_hud_icon() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 39a94232a3..3e4fbd9625 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -264,6 +264,7 @@ update_mobility() //we fall down if(!buckled && !density) Move(user.loc) + user.set_pull_offsets(src, grab_state) return 1 /mob/living/attack_hand(mob/user) diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index ddcf3e6292..6a84162ea8 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -75,8 +75,12 @@ . = ..() - if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move. + if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1 && (pulledby != moving_from_pull))//separated from our puller and not in the middle of a diagonal move. pulledby.stop_pulling() + else + if(isliving(pulledby)) + var/mob/living/L = pulledby + L.set_pull_offsets(src, pulledby.grab_state) if(active_storage && !(CanReach(active_storage.parent,view_only = TRUE))) active_storage.close(src) @@ -84,6 +88,14 @@ if(lying && !buckled && prob(getBruteLoss()*200/maxHealth)) makeTrail(newloc, T, old_direction) + +/mob/living/Move_Pulled(atom/A) + . = ..() + if(!. || !isliving(A)) + return + var/mob/living/L = A + set_pull_offsets(L, grab_state) + /mob/living/forceMove(atom/destination) stop_pulling() if(buckled) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index fdc60b30cb..adf3e349b7 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -109,6 +109,8 @@ /// Process_Grab(): checks for grab, attempts to break if so. Return TRUE to prevent movement. /client/proc/Process_Grab() if(mob.pulledby) + if((mob.pulledby == mob.pulling) && (mob.pulledby.grab_state == GRAB_PASSIVE)) //Don't autoresist passive grabs if we're grabbing them too. + return if(mob.incapacitated(ignore_restraints = 1)) move_delay = world.time + 10 return TRUE