diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c820e830bb7..1073b44cbfc 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -174,13 +174,8 @@ if(now_pushing) return TRUE - var/they_can_move = TRUE - var/their_combat_mode = FALSE - if(isliving(M)) var/mob/living/L = M - their_combat_mode = L.combat_mode - they_can_move = L.mobility_flags & MOBILITY_MOVE //Also spread diseases for(var/thing in diseases) var/datum/disease/D = thing @@ -226,22 +221,7 @@ return TRUE if(!M.buckled && !M.has_buckled_mobs()) - var/mob_swap = FALSE - var/too_strong = (M.move_resist > move_force) //can't swap with immovable objects unless they help us - if(!they_can_move) //we have to physically move them - if(!too_strong) - mob_swap = TRUE - else - //You can swap with the person you are dragging on grab intent, and restrained people in most cases - if(M.pulledby == src && !too_strong) - mob_swap = TRUE - else if( - !(HAS_TRAIT(M, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP)) &&\ - ((HAS_TRAIT(M, TRAIT_RESTRAINED) && !too_strong) || !their_combat_mode) &&\ - (HAS_TRAIT(src, TRAIT_RESTRAINED) || !combat_mode) - ) - mob_swap = TRUE - if(mob_swap) + if(can_mobswap_with(M)) //switch our position with M if(loc && !loc.Adjacent(M.loc)) return TRUE @@ -294,6 +274,46 @@ if(prob(I.block_chance*2)) return +/mob/living/proc/can_mobswap_with(mob/other) + if (HAS_TRAIT(other, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP)) + return FALSE + + var/they_can_move = TRUE + var/their_combat_mode = FALSE + + if(isliving(other)) + var/mob/living/other_living = other + their_combat_mode = other_living.combat_mode + they_can_move = other_living.mobility_flags & MOBILITY_MOVE + + var/too_strong = other.move_resist > move_force + + // They cannot move, see if we can push through them + if (!they_can_move) + return !too_strong + + // We are pulling them and can move through + if (other.pulledby == src && !too_strong) + return TRUE + + // If we're in combat mode and not restrained we don't try to pass through people + if (combat_mode && !HAS_TRAIT(src, TRAIT_RESTRAINED)) + return FALSE + + // Nor can we pass through non-restrained people in combat mode (or if they're restrained but still too strong for us) + if (their_combat_mode && (!HAS_TRAIT(other, TRAIT_RESTRAINED) || too_strong)) + return FALSE + + if (isnull(other.client) || isnull(client)) + return TRUE + + // If both of us are trying to move in the same direction, let the fastest one through first + if (client.intended_direction == other.client.intended_direction) + return cached_multiplicative_slowdown < other.cached_multiplicative_slowdown + + // Else, sure, let us pass + return TRUE + /mob/living/get_photo_description(obj/item/camera/camera) var/list/holding = list() var/len = length(held_items)