Merge pull request #10451 from kevinz000/mobility_flags
Mobility flags + combat rework stuff refactoring, fixes a few edge cases including the Oh Dreaded Xenomorph Hardstuns, etc etc time to break the game
This commit is contained in:
+5
-5
@@ -28,7 +28,6 @@
|
||||
var/list/managed_overlays
|
||||
|
||||
var/datum/proximity_monitor/proximity_monitor
|
||||
var/buckle_message_cooldown = 0
|
||||
var/fingerprintslast
|
||||
|
||||
var/list/filter_data //For handling persistent filters
|
||||
@@ -361,11 +360,12 @@
|
||||
. = list()
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .)
|
||||
|
||||
/atom/proc/relaymove(mob/user)
|
||||
if(buckle_message_cooldown <= world.time)
|
||||
buckle_message_cooldown = world.time + 50
|
||||
/atom/proc/relaymove(mob/living/user)
|
||||
if(!istype(user))
|
||||
return //why are you buckling nonliving mobs to atoms?
|
||||
if(user.buckle_message_cooldown <= world.time)
|
||||
user.buckle_message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>You can't move while buckled to [src]!</span>")
|
||||
return
|
||||
|
||||
/atom/proc/contents_explosion(severity, target)
|
||||
return //For handling the effects of explosions on contents that would not normally be effected
|
||||
|
||||
+2
-304
@@ -158,7 +158,7 @@
|
||||
grab_state = 0
|
||||
if(isliving(ex_pulled))
|
||||
var/mob/living/L = ex_pulled
|
||||
L.update_canmove()// mob gets up if it was lyng down in a chokehold
|
||||
L.update_mobility()// mob gets up if it was lyng down in a chokehold
|
||||
|
||||
/atom/movable/proc/Move_Pulled(atom/A)
|
||||
if(!pulling)
|
||||
@@ -194,160 +194,6 @@
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
////////////////////////////////////////
|
||||
// Here's where we rewrite how byond handles movement except slightly different
|
||||
// To be removed on step_ conversion
|
||||
// All this work to prevent a second bump
|
||||
/atom/movable/Move(atom/newloc, direct=0)
|
||||
. = FALSE
|
||||
if(!newloc || newloc == loc)
|
||||
return
|
||||
|
||||
if(!direct)
|
||||
direct = get_dir(src, newloc)
|
||||
setDir(direct)
|
||||
|
||||
if(!loc.Exit(src, newloc))
|
||||
return
|
||||
|
||||
if(!newloc.Enter(src, src.loc))
|
||||
return
|
||||
|
||||
// Past this is the point of no return
|
||||
var/atom/oldloc = loc
|
||||
var/area/oldarea = get_area(oldloc)
|
||||
var/area/newarea = get_area(newloc)
|
||||
loc = newloc
|
||||
. = TRUE
|
||||
oldloc.Exited(src, newloc)
|
||||
if(oldarea != newarea)
|
||||
oldarea.Exited(src, newloc)
|
||||
|
||||
for(var/i in oldloc)
|
||||
if(i == src) // Multi tile objects
|
||||
continue
|
||||
var/atom/movable/thing = i
|
||||
thing.Uncrossed(src)
|
||||
|
||||
newloc.Entered(src, oldloc)
|
||||
if(oldarea != newarea)
|
||||
newarea.Entered(src, oldloc)
|
||||
|
||||
for(var/i in loc)
|
||||
if(i == src) // Multi tile objects
|
||||
continue
|
||||
var/atom/movable/thing = i
|
||||
thing.Crossed(src)
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
||||
/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(!loc || !newloc)
|
||||
return FALSE
|
||||
var/atom/oldloc = loc
|
||||
|
||||
if(loc != newloc)
|
||||
if (!(direct & (direct - 1))) //Cardinal move
|
||||
. = ..()
|
||||
else //Diagonal move, split it into cardinal moves
|
||||
moving_diagonally = FIRST_DIAG_STEP
|
||||
var/first_step_dir
|
||||
// The `&& moving_diagonally` checks are so that a forceMove taking
|
||||
// place due to a Crossed, Bumped, etc. call will interrupt
|
||||
// the second half of the diagonal movement, or the second attempt
|
||||
// at a first half if step() fails because we hit something.
|
||||
if (direct & NORTH)
|
||||
if (direct & EAST)
|
||||
if (step(src, NORTH) && moving_diagonally)
|
||||
first_step_dir = NORTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if (moving_diagonally && step(src, EAST))
|
||||
first_step_dir = EAST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if (direct & WEST)
|
||||
if (step(src, NORTH) && moving_diagonally)
|
||||
first_step_dir = NORTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if (moving_diagonally && step(src, WEST))
|
||||
first_step_dir = WEST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if (direct & SOUTH)
|
||||
if (direct & EAST)
|
||||
if (step(src, SOUTH) && moving_diagonally)
|
||||
first_step_dir = SOUTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if (moving_diagonally && step(src, EAST))
|
||||
first_step_dir = EAST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
else if (direct & WEST)
|
||||
if (step(src, SOUTH) && moving_diagonally)
|
||||
first_step_dir = SOUTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if (moving_diagonally && step(src, WEST))
|
||||
first_step_dir = WEST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
if(moving_diagonally == SECOND_DIAG_STEP)
|
||||
if(!.)
|
||||
setDir(first_step_dir)
|
||||
else if (!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(direct)
|
||||
moving_diagonally = 0
|
||||
return
|
||||
|
||||
if(!loc || (loc == oldloc && oldloc != newloc))
|
||||
last_move = 0
|
||||
return
|
||||
|
||||
if(.)
|
||||
Moved(oldloc, direct)
|
||||
if(. && pulling && pulling == pullee) //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.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()
|
||||
|
||||
|
||||
last_move = direct
|
||||
setDir(direct)
|
||||
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
|
||||
return FALSE
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
|
||||
if (!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(Dir)
|
||||
if (length(client_mobs_in_contents))
|
||||
update_parallax_contents()
|
||||
|
||||
return TRUE
|
||||
|
||||
/atom/movable/Destroy(force)
|
||||
QDEL_NULL(proximity_monitor)
|
||||
QDEL_NULL(language_holder)
|
||||
@@ -372,143 +218,6 @@
|
||||
orbiting.end_orbit(src)
|
||||
orbiting = null
|
||||
|
||||
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
|
||||
// You probably want CanPass()
|
||||
/atom/movable/Cross(atom/movable/AM)
|
||||
. = TRUE
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM)
|
||||
return CanPass(AM, AM.loc, TRUE)
|
||||
|
||||
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
|
||||
/atom/movable/Crossed(atom/movable/AM, oldloc)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
|
||||
|
||||
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
|
||||
. = ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS)
|
||||
return FALSE
|
||||
if(isturf(newloc) && !CheckExit(AM, newloc))
|
||||
return FALSE
|
||||
|
||||
/atom/movable/Uncrossed(atom/movable/AM)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM)
|
||||
|
||||
/atom/movable/Bump(atom/A)
|
||||
if(!A)
|
||||
CRASH("Bump was called with no argument.")
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
|
||||
. = ..()
|
||||
if(!QDELETED(throwing))
|
||||
throwing.hit_atom(A)
|
||||
. = TRUE
|
||||
if(QDELETED(A))
|
||||
return
|
||||
A.Bumped(src)
|
||||
|
||||
/atom/movable/proc/forceMove(atom/destination)
|
||||
. = FALSE
|
||||
if(destination)
|
||||
. = doMove(destination)
|
||||
else
|
||||
CRASH("No valid destination passed into forceMove")
|
||||
|
||||
/atom/movable/proc/moveToNullspace()
|
||||
return doMove(null)
|
||||
|
||||
/atom/movable/proc/doMove(atom/destination)
|
||||
. = FALSE
|
||||
if(destination)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
var/atom/oldloc = loc
|
||||
var/same_loc = oldloc == destination
|
||||
var/area/old_area = get_area(oldloc)
|
||||
var/area/destarea = get_area(destination)
|
||||
|
||||
loc = destination
|
||||
moving_diagonally = 0
|
||||
|
||||
if(!same_loc)
|
||||
if(oldloc)
|
||||
oldloc.Exited(src, destination)
|
||||
if(old_area && old_area != destarea)
|
||||
old_area.Exited(src, destination)
|
||||
for(var/atom/movable/AM in oldloc)
|
||||
AM.Uncrossed(src)
|
||||
var/turf/oldturf = get_turf(oldloc)
|
||||
var/turf/destturf = get_turf(destination)
|
||||
var/old_z = (oldturf ? oldturf.z : null)
|
||||
var/dest_z = (destturf ? destturf.z : null)
|
||||
if (old_z != dest_z)
|
||||
onTransitZ(old_z, dest_z)
|
||||
destination.Entered(src, oldloc)
|
||||
if(destarea && old_area != destarea)
|
||||
destarea.Entered(src, oldloc)
|
||||
|
||||
for(var/atom/movable/AM in destination)
|
||||
if(AM == src)
|
||||
continue
|
||||
AM.Crossed(src, oldloc)
|
||||
|
||||
Moved(oldloc, NONE, TRUE)
|
||||
. = TRUE
|
||||
|
||||
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
|
||||
else
|
||||
. = TRUE
|
||||
if (loc)
|
||||
var/atom/oldloc = loc
|
||||
var/area/old_area = get_area(oldloc)
|
||||
oldloc.Exited(src, null)
|
||||
if(old_area)
|
||||
old_area.Exited(src, null)
|
||||
loc = null
|
||||
|
||||
/atom/movable/proc/onTransitZ(old_z,new_z)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z)
|
||||
for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
|
||||
var/atom/movable/AM = item
|
||||
AM.onTransitZ(old_z,new_z)
|
||||
|
||||
/atom/movable/proc/setMovetype(newval)
|
||||
movement_type = newval
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
|
||||
//movement_dir == 0 when stopping or any dir when trying to move
|
||||
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
|
||||
if(has_gravity(src))
|
||||
return 1
|
||||
|
||||
if(pulledby)
|
||||
return 1
|
||||
|
||||
if(throwing)
|
||||
return 1
|
||||
|
||||
if(!isturf(loc))
|
||||
return 1
|
||||
|
||||
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
|
||||
if(!loc || Process_Spacemove(0))
|
||||
inertia_dir = 0
|
||||
return 0
|
||||
|
||||
inertia_dir = direction
|
||||
if(!direction)
|
||||
return 1
|
||||
inertia_last_loc = loc
|
||||
SSspacedrift.processing[src] = src
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
set waitfor = 0
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
|
||||
@@ -610,17 +319,6 @@
|
||||
SSthrowing.currentrun[src] = TT
|
||||
TT.tick()
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
if(!buckled_mob.Move(newloc, direct))
|
||||
forceMove(buckled_mob.loc)
|
||||
last_move = buckled_mob.last_move
|
||||
inertia_dir = last_move
|
||||
buckled_mob.inertia_dir = last_move
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return FALSE
|
||||
|
||||
@@ -639,7 +337,7 @@
|
||||
|
||||
/atom/movable/CanPass(atom/movable/mover, turf/target)
|
||||
if(mover in buckled_mobs)
|
||||
return 1
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
// called when this atom is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
// File for movement procs for atom/movable
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// Here's where we rewrite how byond handles movement except slightly different
|
||||
// To be removed on step_ conversion
|
||||
// All this work to prevent a second bump
|
||||
/atom/movable/Move(atom/newloc, direct=0)
|
||||
. = FALSE
|
||||
if(!newloc || newloc == loc)
|
||||
return
|
||||
|
||||
if(!direct)
|
||||
direct = get_dir(src, newloc)
|
||||
setDir(direct)
|
||||
|
||||
if(!loc.Exit(src, newloc))
|
||||
return
|
||||
|
||||
if(!newloc.Enter(src, src.loc))
|
||||
return
|
||||
|
||||
// Past this is the point of no return
|
||||
var/atom/oldloc = loc
|
||||
var/area/oldarea = get_area(oldloc)
|
||||
var/area/newarea = get_area(newloc)
|
||||
loc = newloc
|
||||
. = TRUE
|
||||
oldloc.Exited(src, newloc)
|
||||
if(oldarea != newarea)
|
||||
oldarea.Exited(src, newloc)
|
||||
|
||||
for(var/i in oldloc)
|
||||
if(i == src) // Multi tile objects
|
||||
continue
|
||||
var/atom/movable/thing = i
|
||||
thing.Uncrossed(src)
|
||||
|
||||
newloc.Entered(src, oldloc)
|
||||
if(oldarea != newarea)
|
||||
newarea.Entered(src, oldloc)
|
||||
|
||||
for(var/i in loc)
|
||||
if(i == src) // Multi tile objects
|
||||
continue
|
||||
var/atom/movable/thing = i
|
||||
thing.Crossed(src)
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
||||
/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(!loc || !newloc)
|
||||
return FALSE
|
||||
var/atom/oldloc = loc
|
||||
|
||||
if(loc != newloc)
|
||||
if (!(direct & (direct - 1))) //Cardinal move
|
||||
. = ..()
|
||||
else //Diagonal move, split it into cardinal moves
|
||||
moving_diagonally = FIRST_DIAG_STEP
|
||||
var/first_step_dir
|
||||
// The `&& moving_diagonally` checks are so that a forceMove taking
|
||||
// place due to a Crossed, Bumped, etc. call will interrupt
|
||||
// the second half of the diagonal movement, or the second attempt
|
||||
// at a first half if step() fails because we hit something.
|
||||
if (direct & NORTH)
|
||||
if (direct & EAST)
|
||||
if (step(src, NORTH) && moving_diagonally)
|
||||
first_step_dir = NORTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if (moving_diagonally && step(src, EAST))
|
||||
first_step_dir = EAST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if (direct & WEST)
|
||||
if (step(src, NORTH) && moving_diagonally)
|
||||
first_step_dir = NORTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if (moving_diagonally && step(src, WEST))
|
||||
first_step_dir = WEST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, NORTH)
|
||||
else if (direct & SOUTH)
|
||||
if (direct & EAST)
|
||||
if (step(src, SOUTH) && moving_diagonally)
|
||||
first_step_dir = SOUTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, EAST)
|
||||
else if (moving_diagonally && step(src, EAST))
|
||||
first_step_dir = EAST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
else if (direct & WEST)
|
||||
if (step(src, SOUTH) && moving_diagonally)
|
||||
first_step_dir = SOUTH
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, WEST)
|
||||
else if (moving_diagonally && step(src, WEST))
|
||||
first_step_dir = WEST
|
||||
moving_diagonally = SECOND_DIAG_STEP
|
||||
. = step(src, SOUTH)
|
||||
if(moving_diagonally == SECOND_DIAG_STEP)
|
||||
if(!.)
|
||||
setDir(first_step_dir)
|
||||
else if (!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(direct)
|
||||
moving_diagonally = 0
|
||||
return
|
||||
|
||||
if(!loc || (loc == oldloc && oldloc != newloc))
|
||||
last_move = NONE
|
||||
return
|
||||
|
||||
if(.)
|
||||
last_move = direct
|
||||
setDir(direct)
|
||||
|
||||
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.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.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()
|
||||
|
||||
Moved(oldloc, direct)
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
|
||||
for(var/m in buckled_mobs)
|
||||
var/mob/living/buckled_mob = m
|
||||
if(!buckled_mob.Move(newloc, direct))
|
||||
forceMove(buckled_mob.loc)
|
||||
last_move = buckled_mob.last_move
|
||||
inertia_dir = last_move
|
||||
buckled_mob.inertia_dir = last_move
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
|
||||
if (!inertia_moving)
|
||||
inertia_next_move = world.time + inertia_move_delay
|
||||
newtonian_move(Dir)
|
||||
if (length(client_mobs_in_contents))
|
||||
update_parallax_contents()
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly.
|
||||
// You probably want CanPass()
|
||||
/atom/movable/Cross(atom/movable/AM)
|
||||
. = TRUE
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM)
|
||||
return CanPass(AM, AM.loc, TRUE)
|
||||
|
||||
//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called!
|
||||
/atom/movable/Crossed(atom/movable/AM, oldloc)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
|
||||
|
||||
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
|
||||
. = ..()
|
||||
if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS)
|
||||
return FALSE
|
||||
if(isturf(newloc) && !CheckExit(AM, newloc))
|
||||
return FALSE
|
||||
|
||||
/atom/movable/Uncrossed(atom/movable/AM)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM)
|
||||
|
||||
/atom/movable/Bump(atom/A)
|
||||
if(!A)
|
||||
CRASH("Bump was called with no argument.")
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
|
||||
. = ..()
|
||||
if(!QDELETED(throwing))
|
||||
throwing.hit_atom(A)
|
||||
. = TRUE
|
||||
if(QDELETED(A))
|
||||
return
|
||||
A.Bumped(src)
|
||||
|
||||
/atom/movable/proc/onTransitZ(old_z,new_z)
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z)
|
||||
for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care.
|
||||
var/atom/movable/AM = item
|
||||
AM.onTransitZ(old_z,new_z)
|
||||
|
||||
/atom/movable/proc/setMovetype(newval)
|
||||
movement_type = newval
|
||||
|
||||
///////////// FORCED MOVEMENT /////////////
|
||||
|
||||
/atom/movable/proc/forceMove(atom/destination)
|
||||
. = FALSE
|
||||
if(destination)
|
||||
. = doMove(destination)
|
||||
else
|
||||
CRASH("No valid destination passed into forceMove")
|
||||
|
||||
/atom/movable/proc/moveToNullspace()
|
||||
return doMove(null)
|
||||
|
||||
/atom/movable/proc/doMove(atom/destination)
|
||||
. = FALSE
|
||||
if(destination)
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
var/atom/oldloc = loc
|
||||
var/same_loc = oldloc == destination
|
||||
var/area/old_area = get_area(oldloc)
|
||||
var/area/destarea = get_area(destination)
|
||||
|
||||
loc = destination
|
||||
moving_diagonally = 0
|
||||
|
||||
if(!same_loc)
|
||||
if(oldloc)
|
||||
oldloc.Exited(src, destination)
|
||||
if(old_area && old_area != destarea)
|
||||
old_area.Exited(src, destination)
|
||||
for(var/atom/movable/AM in oldloc)
|
||||
AM.Uncrossed(src)
|
||||
var/turf/oldturf = get_turf(oldloc)
|
||||
var/turf/destturf = get_turf(destination)
|
||||
var/old_z = (oldturf ? oldturf.z : null)
|
||||
var/dest_z = (destturf ? destturf.z : null)
|
||||
if (old_z != dest_z)
|
||||
onTransitZ(old_z, dest_z)
|
||||
destination.Entered(src, oldloc)
|
||||
if(destarea && old_area != destarea)
|
||||
destarea.Entered(src, oldloc)
|
||||
|
||||
for(var/atom/movable/AM in destination)
|
||||
if(AM == src)
|
||||
continue
|
||||
AM.Crossed(src, oldloc)
|
||||
|
||||
Moved(oldloc, NONE, TRUE)
|
||||
. = TRUE
|
||||
|
||||
//If no destination, move the atom into nullspace (don't do this unless you know what you're doing)
|
||||
else
|
||||
. = TRUE
|
||||
if (loc)
|
||||
var/atom/oldloc = loc
|
||||
var/area/old_area = get_area(oldloc)
|
||||
oldloc.Exited(src, null)
|
||||
if(old_area)
|
||||
old_area.Exited(src, null)
|
||||
loc = null
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
|
||||
//movement_dir == 0 when stopping or any dir when trying to move
|
||||
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
|
||||
if(has_gravity(src))
|
||||
return 1
|
||||
|
||||
if(pulledby)
|
||||
return 1
|
||||
|
||||
if(throwing)
|
||||
return 1
|
||||
|
||||
if(!isturf(loc))
|
||||
return 1
|
||||
|
||||
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
|
||||
if(!loc || Process_Spacemove(0))
|
||||
inertia_dir = 0
|
||||
return 0
|
||||
|
||||
inertia_dir = direction
|
||||
if(!direction)
|
||||
return 1
|
||||
inertia_last_loc = loc
|
||||
SSspacedrift.processing[src] = src
|
||||
return 1
|
||||
@@ -54,6 +54,6 @@
|
||||
return
|
||||
var/mob/living/carbon/human/H = gangster_mind.current // we are sure the dude's human cause it's checked in attack()
|
||||
H.silent = max(H.silent, 5)
|
||||
H.Knockdown(100)
|
||||
H.DefaultCombatKnockdown(100)
|
||||
gangster_mind.add_antag_datum(/datum/antagonist/gang, gang)
|
||||
return TRUE
|
||||
@@ -185,7 +185,7 @@ Class Procs:
|
||||
A.forceMove(T)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
L.update_canmove()
|
||||
L.update_mobility()
|
||||
if(occupant)
|
||||
SEND_SIGNAL(src, COMSIG_MACHINE_EJECT_OCCUPANT, occupant)
|
||||
occupant = null
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
M.vomit(10, distance = 5)
|
||||
if(ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
M.Knockdown(60)
|
||||
M.DefaultCombatKnockdown(60)
|
||||
say("A sudden gust of powerful wind slams [M] into the floor!")
|
||||
M.take_bodypart_damage(25)
|
||||
playsound(loc, 'sound/weapons/genhit.ogg', 100, 1)
|
||||
|
||||
@@ -37,12 +37,11 @@
|
||||
dat += "[R.name] |"
|
||||
if(R.stat)
|
||||
dat += " Not Responding |"
|
||||
else if (!R.canmove)
|
||||
else if(R.locked_down)
|
||||
dat += " Locked Down |"
|
||||
else
|
||||
dat += " Operating Normally |"
|
||||
if (!R.canmove)
|
||||
else if(R.cell)
|
||||
if(R.cell)
|
||||
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
|
||||
else
|
||||
dat += " No Cell Installed |"
|
||||
@@ -62,7 +61,7 @@
|
||||
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
|
||||
else if(IsAdminGhost(user) && !R.emagged)
|
||||
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
|
||||
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.canmove ? "Lockdown" : "Release"]</i></font>)</A> "
|
||||
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.locked_down? "Lockdown" : "Release"]</i></font>)</A> "
|
||||
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
|
||||
dat += "<BR>"
|
||||
|
||||
@@ -116,14 +115,14 @@
|
||||
if(src.allowed(usr))
|
||||
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
|
||||
if(can_control(usr, R))
|
||||
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
|
||||
var/choice = input("Are you certain you wish to [R.locked_down? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
|
||||
if(choice == "Confirm" && can_control(usr, R) && !..())
|
||||
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
|
||||
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
|
||||
R.SetLockdown(!R.lockcharge)
|
||||
to_chat(R, "[!R.lockcharge ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
|
||||
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [R.locked_down? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
|
||||
log_game("[key_name(usr)] [R.locked_down? "locked down" : "released"] [key_name(R)]!")
|
||||
R.SetLockdown(!R.locked_down)
|
||||
to_chat(R, "[!R.locked_down ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
|
||||
if(R.connected_ai)
|
||||
to_chat(R.connected_ai, "[!R.lockcharge ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
|
||||
to_chat(R.connected_ai, "[!R.locked_down ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
|
||||
|
||||
else
|
||||
to_chat(usr, "<span class='danger'>Access Denied.</span>")
|
||||
|
||||
@@ -433,5 +433,5 @@
|
||||
. = ..()
|
||||
if(active)
|
||||
for(var/mob/living/M in rangers)
|
||||
if(prob(5+(allowed(M)*4)) && M.canmove)
|
||||
if(prob(5+(allowed(M)*4)) && CHECK_MOBILITY(M, MOBILITY_MOVE))
|
||||
dance(M)
|
||||
|
||||
@@ -769,7 +769,7 @@
|
||||
if(!istype(H.head, /obj/item/clothing/head/helmet))
|
||||
H.visible_message("<span class='danger'>[user] headbutts the airlock.</span>", \
|
||||
"<span class='userdanger'>You headbutt the airlock!</span>")
|
||||
H.Knockdown(100)
|
||||
H.DefaultCombatKnockdown(100)
|
||||
H.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
|
||||
else
|
||||
visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>")
|
||||
@@ -1033,7 +1033,7 @@
|
||||
if(!I.use_tool(src, user, 150, volume=50))
|
||||
to_chat(user, "<span class='warning'>You slip and [charge] detonates!</span>")
|
||||
charge.ex_act(EXPLODE_DEVASTATE)
|
||||
user.Knockdown(60)
|
||||
user.DefaultCombatKnockdown(60)
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] removes [charge] from [src].</span>", \
|
||||
"<span class='notice'>You gently pry out [charge] from [src] and unhook its wires.</span>")
|
||||
|
||||
@@ -508,7 +508,7 @@
|
||||
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
|
||||
SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
|
||||
flash_color(L, flash_color="#960000", flash_time=20)
|
||||
L.Knockdown(40)
|
||||
L.DefaultCombatKnockdown(40)
|
||||
L.throw_at(throwtarget, 5, 1)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -319,10 +319,10 @@
|
||||
else if(ishuman(L)) //For humans
|
||||
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
|
||||
L.emote("scream")
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
else if(ismonkey(L)) //For monkeys
|
||||
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
else //for simple_animals & borgs
|
||||
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
continue
|
||||
|
||||
if(L.flash_act(affect_silicon = 1))
|
||||
L.Knockdown(strength)
|
||||
L.DefaultCombatKnockdown(strength)
|
||||
flashed = TRUE
|
||||
|
||||
if(flashed)
|
||||
|
||||
@@ -90,7 +90,8 @@ Buildable meters
|
||||
set name = "Flip Pipe"
|
||||
set src in view(1)
|
||||
|
||||
if ( usr.stat || usr.restrained() || !usr.canmove )
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
|
||||
do_a_flip()
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
/obj/machinery/pipedispenser/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!anchored|| !usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
|
||||
var/mob/living/L = usr
|
||||
if(!anchored || !istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
usr << browse(null, "window=pipedispenser")
|
||||
return 1
|
||||
usr.set_machine(src)
|
||||
@@ -93,14 +94,14 @@
|
||||
|
||||
|
||||
//Allow you to drag-drop disposal pipes and transit tubes into it
|
||||
/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/usr)
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
/obj/machinery/pipedispenser/disposal/MouseDrop_T(obj/structure/pipe, mob/living/user)
|
||||
if(!istype(user) || !CHECK_MOBILITY(user, MOBILITY_USE))
|
||||
return
|
||||
|
||||
if (!istype(pipe, /obj/structure/disposalconstruct) && !istype(pipe, /obj/structure/c_transit_tube) && !istype(pipe, /obj/structure/c_transit_tube_pod))
|
||||
return
|
||||
|
||||
if (get_dist(usr, src) > 1 || get_dist(src,pipe) > 1 )
|
||||
if (get_dist(user, src) > 1 || get_dist(src,pipe) > 1 )
|
||||
return
|
||||
|
||||
if (pipe.anchored)
|
||||
|
||||
@@ -226,8 +226,7 @@
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.AdjustStun(-80)
|
||||
M.AdjustKnockdown(-80)
|
||||
M.AdjustAllImmobility(-80)
|
||||
M.AdjustUnconscious(-80)
|
||||
if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
M.SetSleeping(0)
|
||||
M.stuttering += 20
|
||||
M.adjustEarDamage(0, 30)
|
||||
M.Knockdown(60)
|
||||
M.DefaultCombatKnockdown(60)
|
||||
if(prob(30))
|
||||
M.Stun(200)
|
||||
M.Unconscious(80)
|
||||
|
||||
@@ -755,7 +755,7 @@
|
||||
AI.cancel_camera()
|
||||
AI.controlled_mech = src
|
||||
AI.remote_control = src
|
||||
AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
|
||||
AI.mobility_flags = MOBILITY_FLAGS_DEFAULT //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
|
||||
AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
|
||||
to_chat(AI, AI.can_dominate_mechs ? "<span class='announce'>Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!</span>" :\
|
||||
"<span class='notice'>You have been uploaded to a mech's onboard computer.</span>")
|
||||
@@ -927,7 +927,7 @@
|
||||
brainmob.forceMove(src) //should allow relaymove
|
||||
brainmob.reset_perspective(src)
|
||||
brainmob.remote_control = src
|
||||
brainmob.update_canmove()
|
||||
brainmob.update_mobility()
|
||||
brainmob.update_mouse_pointer()
|
||||
icon_state = initial(icon_state)
|
||||
update_icon()
|
||||
@@ -941,7 +941,6 @@
|
||||
/obj/mecha/container_resist(mob/living/user)
|
||||
go_out()
|
||||
|
||||
|
||||
/obj/mecha/Exited(atom/movable/M, atom/newloc)
|
||||
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
|
||||
go_out(TRUE, newloc)
|
||||
@@ -993,7 +992,7 @@
|
||||
L.reset_perspective()
|
||||
mmi.mecha = null
|
||||
mmi.update_icon()
|
||||
L.canmove = 0
|
||||
L.mobility_flags = NONE
|
||||
icon_state = initial(icon_state)+"-open"
|
||||
setDir(dir_in)
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
|
||||
//procs that handle the actual buckling and unbuckling
|
||||
/atom/movable/proc/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
|
||||
if(!buckled_mobs)
|
||||
buckled_mobs = list()
|
||||
LAZYINITLIST(buckled_mobs)
|
||||
|
||||
if(!istype(M))
|
||||
return FALSE
|
||||
@@ -66,7 +65,7 @@
|
||||
M.buckled = src
|
||||
M.setDir(dir)
|
||||
buckled_mobs |= M
|
||||
M.update_canmove()
|
||||
M.update_mobility()
|
||||
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
|
||||
post_buckle_mob(M)
|
||||
|
||||
@@ -85,7 +84,7 @@
|
||||
. = buckled_mob
|
||||
buckled_mob.buckled = null
|
||||
buckled_mob.anchored = initial(buckled_mob.anchored)
|
||||
buckled_mob.update_canmove()
|
||||
buckled_mob.update_mobility()
|
||||
buckled_mob.clear_alert("buckled")
|
||||
buckled_mobs -= buckled_mob
|
||||
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
|
||||
/obj/effect/anomaly/grav/proc/gravShock(mob/living/A)
|
||||
if(boing && isliving(A) && !A.stat)
|
||||
A.Knockdown(40)
|
||||
A.DefaultCombatKnockdown(40)
|
||||
var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src)))
|
||||
A.throw_at(target, 5, 1)
|
||||
boing = 0
|
||||
|
||||
@@ -104,4 +104,5 @@
|
||||
if(explosion_message)
|
||||
location.visible_message("<span class='danger'>The solution violently explodes!</span>", \
|
||||
"<span class='italics'>You hear an explosion!</span>")
|
||||
dyn_explosion(location, amount, flashing_factor)
|
||||
dyn_explosion(location, amount, flashing_factor)
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
/obj/effect/mine/stun/mineEffect(mob/living/victim)
|
||||
if(isliving(victim))
|
||||
victim.Knockdown(stun_time)
|
||||
victim.DefaultCombatKnockdown(stun_time)
|
||||
|
||||
/obj/effect/mine/kickmine
|
||||
name = "kick mine"
|
||||
|
||||
@@ -61,10 +61,11 @@
|
||||
if(AM in T.affecting)
|
||||
return
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(immobilize)
|
||||
M.canmove = 0
|
||||
ADD_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
|
||||
M.update_mobility()
|
||||
|
||||
affecting.Add(AM)
|
||||
while(AM && !stopthrow)
|
||||
@@ -98,10 +99,11 @@
|
||||
|
||||
affecting.Remove(AM)
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
if(immobilize)
|
||||
M.canmove = 1
|
||||
REMOVE_TRAIT(M, TRAIT_MOBILITY_NOMOVE, src)
|
||||
M.update_mobility()
|
||||
|
||||
/* Stops things thrown by a thrower, doesn't do anything */
|
||||
|
||||
|
||||
@@ -175,14 +175,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove)
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !isturf(loc) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
|
||||
var/turf/T = src.loc
|
||||
|
||||
src.loc = null
|
||||
|
||||
src.loc = T
|
||||
var/turf/T = loc
|
||||
loc = null
|
||||
loc = T
|
||||
|
||||
/obj/item/examine(mob/user) //This might be spammy. Remove?
|
||||
. = ..()
|
||||
@@ -544,7 +543,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
to_chat(M, "<span class='danger'>You drop what you're holding and clutch at your eyes!</span>")
|
||||
M.adjust_blurriness(10)
|
||||
M.Unconscious(20)
|
||||
M.Knockdown(40)
|
||||
M.DefaultCombatKnockdown(40)
|
||||
if (prob(eyes.damage - 10 + 1))
|
||||
M.become_blind(EYE_DAMAGE)
|
||||
to_chat(M, "<span class='danger'>You go blind!</span>")
|
||||
|
||||
@@ -856,7 +856,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
if(prob(5))//small chance for the vape to break and deal damage if it's emagged
|
||||
playsound(get_turf(src), 'sound/effects/pop_expl.ogg', 50, 0)
|
||||
M.apply_damage(20, BURN, BODY_ZONE_HEAD)
|
||||
M.Knockdown(300, 1, 0)
|
||||
M.DefaultCombatKnockdown(300, 1, 0)
|
||||
var/datum/effect_system/spark_spread/sp = new /datum/effect_system/spark_spread
|
||||
sp.set_up(5, 1, src)
|
||||
sp.start()
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
C.blind_eyes(1)
|
||||
if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS.
|
||||
C.confused = max(C.confused, 3)
|
||||
C.Knockdown(60)
|
||||
C.DefaultCombatKnockdown(60)
|
||||
if(ishuman(C) && actually_paints)
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.lip_style = "spray_face"
|
||||
|
||||
@@ -449,7 +449,7 @@
|
||||
M.visible_message("<span class='danger'>[user] zaps [M] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] zaps [M] with [src]!</span>")
|
||||
M.adjustStaminaLoss(50)
|
||||
M.Knockdown(100)
|
||||
M.DefaultCombatKnockdown(100)
|
||||
M.updatehealth() //forces health update before next life tick
|
||||
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
M.emote("gasp")
|
||||
@@ -506,7 +506,7 @@
|
||||
H.set_heartattack(TRUE)
|
||||
H.apply_damage(50, BURN, BODY_ZONE_CHEST)
|
||||
log_combat(user, H, "overloaded the heart of", defib)
|
||||
H.Knockdown(100)
|
||||
H.DefaultCombatKnockdown(100)
|
||||
H.Jitter(100)
|
||||
if(req_defib)
|
||||
defib.deductcharge(revivecost)
|
||||
|
||||
@@ -469,7 +469,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/mob/living/U = usr
|
||||
//Looking for master was kind of pointless since PDAs don't appear to have one.
|
||||
|
||||
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !href_list["close"])
|
||||
if(usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK, FALSE) && !href_list["close"])
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
@@ -757,7 +757,7 @@ GLOBAL_LIST_EMPTY(PDAs)
|
||||
var/t = stripped_input(U, "Please enter message", name)
|
||||
if (!t || toff)
|
||||
return
|
||||
if(!U.canUseTopic(src, BE_CLOSE))
|
||||
if(!U.canUseTopic(src, BE_CLOSE, FALSE, NO_TK, FALSE))
|
||||
return
|
||||
if(emped)
|
||||
t = Gibberish(t, 100)
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
//chance to actually hit the eyes depends on internal component
|
||||
if(prob(effectchance * diode.rating))
|
||||
S.flash_act(affect_silicon = 1)
|
||||
S.Knockdown(rand(100,200))
|
||||
S.DefaultCombatKnockdown(rand(100,200))
|
||||
to_chat(S, "<span class='danger'>Your sensors were overloaded by a laser!</span>")
|
||||
outmsg = "<span class='notice'>You overload [S] by shining [src] at [S.p_their()] sensors.</span>"
|
||||
else
|
||||
@@ -152,8 +152,7 @@
|
||||
if(prob(50))
|
||||
C.visible_message("<span class='notice'>[C] pounces on the light!</span>","<span class='warning'>LIGHT!</span>")
|
||||
C.Move(targloc)
|
||||
C.resting = TRUE
|
||||
C.update_canmove()
|
||||
C.set_resting(TRUE)
|
||||
else
|
||||
C.visible_message("<span class='notice'>[C] looks uninterested in your games.</span>","<span class='warning'>You spot [user] shining [src] at you. How insulting!</span>")
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
s.set_up(3, 1, L)
|
||||
s.start()
|
||||
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
@@ -192,7 +192,7 @@ Code:
|
||||
s.set_up(3, 1, L)
|
||||
s.start()
|
||||
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
|
||||
@@ -484,7 +484,8 @@ SLIME SCANNER
|
||||
set name = "Switch Verbosity"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
|
||||
mode = !mode
|
||||
|
||||
@@ -44,7 +44,7 @@ effective or pretty fucking useless.
|
||||
for(var/mob/living/carbon/human/M in urange(10, user, 1))
|
||||
if(prob(50))
|
||||
|
||||
M.Knockdown(rand(200,400))
|
||||
M.DefaultCombatKnockdown(rand(200,400))
|
||||
to_chat(M, "<span class='userdanger'>You feel a tremendous, paralyzing wave flood your mind.</span>")
|
||||
|
||||
else
|
||||
|
||||
@@ -294,7 +294,7 @@
|
||||
/obj/item/book/granter/spell/knock/recoil(mob/living/user)
|
||||
..()
|
||||
to_chat(user,"<span class='warning'>You're knocked down!</span>")
|
||||
user.Knockdown(40)
|
||||
user.DefaultCombatKnockdown(40)
|
||||
|
||||
/obj/item/book/granter/spell/barnyard
|
||||
spell = /obj/effect/proc_holder/spell/targeted/barnyardcurse
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
M.show_message("<span class='warning'>BANG</span>", MSG_AUDIBLE)
|
||||
var/distance = get_dist(get_turf(M), source)
|
||||
if(!distance || loc == M || loc == M.loc) //Stop allahu akbarring rooms with this.
|
||||
M.Knockdown(200)
|
||||
M.DefaultCombatKnockdown(200)
|
||||
M.soundbang_act(1, 200, 10, 15)
|
||||
else
|
||||
M.soundbang_act(1, max(200/max(1,distance), 60), rand(0, 5))
|
||||
@@ -41,4 +41,4 @@
|
||||
return
|
||||
var/distance = get_dist(get_turf(M), source)
|
||||
if(M.flash_act(affect_silicon = 1))
|
||||
M.Knockdown(max(200/max(1,distance), 60))
|
||||
M.DefaultCombatKnockdown(max(200/max(1,distance), 60))
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
C.update_inv_legcuffed()
|
||||
SSblackbox.record_feedback("tally", "handcuffs", 1, type)
|
||||
to_chat(C, "<span class='userdanger'>\The [src] ensnares you!</span>")
|
||||
C.Knockdown(knockdown)
|
||||
C.DefaultCombatKnockdown(knockdown)
|
||||
|
||||
/obj/item/restraints/legcuffs/bola/tactical//traitor variant
|
||||
name = "reinforced bola"
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
master.emote("scream")
|
||||
master.remove_status_effect(STATUS_EFFECT_HISGRACE)
|
||||
REMOVE_TRAIT(src, TRAIT_NODROP, HIS_GRACE_TRAIT)
|
||||
master.Knockdown(60)
|
||||
master.DefaultCombatKnockdown(60)
|
||||
master.adjustBruteLoss(master.maxHealth)
|
||||
playsound(master, 'sound/effects/splat.ogg', 100, 0)
|
||||
else
|
||||
|
||||
@@ -64,16 +64,16 @@
|
||||
else
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 40, 1)
|
||||
|
||||
/obj/item/holybeacon/proc/beacon_armor(mob/M)
|
||||
/obj/item/holybeacon/proc/beacon_armor(mob/living/L)
|
||||
var/list/holy_armor_list = typesof(/obj/item/storage/box/holy)
|
||||
var/list/display_names = list()
|
||||
for(var/V in holy_armor_list)
|
||||
var/atom/A = V
|
||||
display_names += list(initial(A.name) = A)
|
||||
|
||||
var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T || QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
|
||||
var/choice = input(L,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || QDELETED(src) || !choice || !CHECK_MOBILITY(L, MOBILITY_USE) || !in_range(L, src) || GLOB.holy_armor_type)
|
||||
return
|
||||
|
||||
var/index = display_names.Find(choice)
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
if(holy_armor_box)
|
||||
qdel(src)
|
||||
M.put_in_hands(holy_armor_box)
|
||||
L.put_in_hands(holy_armor_box)
|
||||
|
||||
/obj/item/storage/box/holy
|
||||
name = "Templar Kit"
|
||||
@@ -244,7 +244,7 @@
|
||||
if(user.mind && (user.mind.isholy) && !reskinned)
|
||||
reskin_holy_weapon(user)
|
||||
|
||||
/obj/item/nullrod/proc/reskin_holy_weapon(mob/M)
|
||||
/obj/item/nullrod/proc/reskin_holy_weapon(mob/living/L)
|
||||
if(GLOB.holy_weapon_type)
|
||||
return
|
||||
var/obj/item/holy_weapon
|
||||
@@ -255,8 +255,8 @@
|
||||
if (initial(rodtype.chaplain_spawnable))
|
||||
display_names[initial(rodtype.name)] = rodtype
|
||||
|
||||
var/choice = input(M,"What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
|
||||
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || reskinned)
|
||||
var/choice = input(L, "What theme would you like for your holy weapon?","Holy Weapon Theme") as null|anything in display_names
|
||||
if(QDELETED(src) || !choice || !in_range(L, src) || !CHECK_MOBILITY(L, MOBILITY_USE) || reskinned)
|
||||
return
|
||||
|
||||
var/A = display_names[choice] // This needs to be on a separate var as list member access is not allowed for new
|
||||
@@ -269,7 +269,7 @@
|
||||
if(holy_weapon)
|
||||
holy_weapon.reskinned = TRUE
|
||||
qdel(src)
|
||||
M.put_in_active_hand(holy_weapon)
|
||||
L.put_in_active_hand(holy_weapon)
|
||||
|
||||
/obj/item/nullrod/proc/jedi_spin(mob/living/user)
|
||||
for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH))
|
||||
@@ -674,7 +674,7 @@
|
||||
add_fingerprint(user)
|
||||
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
|
||||
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
|
||||
user.Knockdown(60)
|
||||
user.DefaultCombatKnockdown(60)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD)
|
||||
|
||||
@@ -71,8 +71,7 @@
|
||||
if(stimulant)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
L.SetStun(0)
|
||||
L.SetKnockdown(0)
|
||||
L.SetAllImmobility(0)
|
||||
L.SetSleeping(0)
|
||||
L.SetUnconscious(0)
|
||||
L.reagents.add_reagent(/datum/reagent/medicine/muscle_stimulant, CLAMP(5 - L.reagents.get_reagent_amount(/datum/reagent/medicine/muscle_stimulant), 0, 5)) //If you don't have legs or get bola'd, tough luck!
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
return
|
||||
if(message && imp_in.stat == CONSCIOUS)
|
||||
imp_in.visible_message("<span class='warning'>[imp_in] doubles over in pain!</span>")
|
||||
imp_in.Knockdown(140)
|
||||
imp_in.DefaultCombatKnockdown(140)
|
||||
|
||||
/obj/item/implant/explosive/proc/boom_goes_the_weasel()
|
||||
explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
add_fingerprint(user)
|
||||
if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
|
||||
to_chat(user, "<span class ='danger'>You club yourself over the head.</span>")
|
||||
user.Knockdown(60 * force)
|
||||
user.DefaultCombatKnockdown(60 * force)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD)
|
||||
@@ -225,7 +225,7 @@
|
||||
if(check_martial_counter(H, user))
|
||||
return
|
||||
playsound(get_turf(src), 'sound/effects/woodhit.ogg', 75, 1, -1)
|
||||
target.Knockdown(softstun_ds, TRUE, FALSE, hardstun_ds, stam_dmg)
|
||||
target.DefaultCombatKnockdown(softstun_ds, TRUE, FALSE, hardstun_ds, stam_dmg)
|
||||
log_combat(user, target, "stunned", src)
|
||||
src.add_fingerprint(user)
|
||||
target.visible_message("<span class ='danger'>[user] has knocked down [target] with [src]!</span>", \
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
if(pressureSetting >= 3 && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.visible_message("<span class='warning'>[C] is thrown down by the force of the cannon!</span>", "<span class='userdanger'>[src] slams into your shoulder, knocking you down!")
|
||||
C.Knockdown(60)
|
||||
C.DefaultCombatKnockdown(60)
|
||||
|
||||
/obj/item/pneumatic_cannon/proc/fire_items(turf/target, mob/user)
|
||||
if(fire_mode == PCANNON_FIREALL)
|
||||
|
||||
@@ -64,8 +64,7 @@
|
||||
/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustAllImmobility(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
return
|
||||
|
||||
user.do_attack_animation(M)
|
||||
M.Knockdown(100)
|
||||
M.DefaultCombatKnockdown(100)
|
||||
M.apply_effect(EFFECT_STUTTER, 5)
|
||||
|
||||
M.visible_message("<span class='danger'>[user] has prodded [M] with [src]!</span>", \
|
||||
@@ -81,8 +81,7 @@
|
||||
user.visible_message("<span class='notice'>[user] hugs [M] to make [M.p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [M] to make [M.p_them()] feel better!</span>")
|
||||
if(M.resting && !M.recoveringstam)
|
||||
M.resting = FALSE
|
||||
M.update_canmove()
|
||||
M.set_resting(FALSE, TRUE)
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] pets [M]!</span>", \
|
||||
"<span class='notice'>You pet [M]!</span>")
|
||||
@@ -100,9 +99,8 @@
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...</span>", \
|
||||
"<span class='warning'>You hug [M] firmly to make [M.p_them()] feel better! [M] looks uncomfortable...</span>")
|
||||
if(M.resting && !M.recoveringstam)
|
||||
M.resting = FALSE
|
||||
M.update_canmove()
|
||||
if(!CHECK_MOBILITY(M, MOBILITY_STAND) && !M.recoveringstam)
|
||||
M.set_resting(FALSE, TRUE)
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] bops [M] on the head!</span>", \
|
||||
"<span class='warning'>You bop [M] on the head!</span>")
|
||||
@@ -114,7 +112,6 @@
|
||||
M.electrocute_act(5, "[user]", safety = 1)
|
||||
user.visible_message("<span class='userdanger'>[user] electrocutes [M] with [user.p_their()] touch!</span>", \
|
||||
"<span class='danger'>You electrocute [M] with your touch!</span>")
|
||||
M.update_canmove()
|
||||
else
|
||||
if(!iscyborg(M))
|
||||
M.adjustFireLoss(10)
|
||||
@@ -326,7 +323,7 @@
|
||||
C.stuttering += 10
|
||||
C.Jitter(10)
|
||||
if(2)
|
||||
C.Knockdown(40)
|
||||
C.DefaultCombatKnockdown(40)
|
||||
C.confused += 10
|
||||
C.stuttering += 15
|
||||
C.Jitter(25)
|
||||
|
||||
@@ -317,8 +317,7 @@
|
||||
O.robot_suit = src
|
||||
|
||||
if(!locomotion)
|
||||
O.lockcharge = 1
|
||||
O.update_canmove()
|
||||
O.SetLockdown(TRUE)
|
||||
to_chat(O, "<span class='warning'>Error: Servo motors unresponsive.</span>")
|
||||
|
||||
else
|
||||
@@ -356,8 +355,7 @@
|
||||
forceMove(O)
|
||||
O.robot_suit = src
|
||||
if(!locomotion)
|
||||
O.lockcharge = TRUE
|
||||
O.update_canmove()
|
||||
O.SetLockdown(TRUE)
|
||||
|
||||
else if(istype(W, /obj/item/pen))
|
||||
to_chat(user, "<span class='warning'>You need to use a multitool to name [src]!</span>")
|
||||
|
||||
@@ -577,7 +577,7 @@
|
||||
return FALSE
|
||||
|
||||
R.notransform = TRUE
|
||||
var/prev_lockcharge = R.lockcharge
|
||||
var/prev_locked_down = R.locked_down
|
||||
R.SetLockdown(1)
|
||||
R.anchored = TRUE
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
@@ -587,7 +587,7 @@
|
||||
for(var/i in 1 to 4)
|
||||
playsound(R, pick('sound/items/drill_use.ogg', 'sound/items/jaws_cut.ogg', 'sound/items/jaws_pry.ogg', 'sound/items/welder.ogg', 'sound/items/ratchet.ogg'), 80, 1, -1)
|
||||
sleep(12)
|
||||
if(!prev_lockcharge)
|
||||
if(!prev_locked_down)
|
||||
R.SetLockdown(0)
|
||||
R.anchored = FALSE
|
||||
R.notransform = FALSE
|
||||
|
||||
@@ -246,7 +246,8 @@
|
||||
set name = "Activate Seed Extraction"
|
||||
set category = "Object"
|
||||
set desc = "Activate to convert your plants into plantable seeds."
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
var/mob/living/L = usr
|
||||
if(istype(L) && !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return
|
||||
for(var/obj/item/O in contents)
|
||||
seedify(O, 1)
|
||||
@@ -353,7 +354,7 @@
|
||||
|
||||
if(ishuman(M) || ismonkey(M))
|
||||
if(prob(10))
|
||||
M.Knockdown(40)
|
||||
M.DefaultCombatKnockdown(40)
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/bag/tray/update_overlays()
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
if(!disarming)
|
||||
if(knockdown)
|
||||
L.Knockdown(50, override_stamdmg = 0) //knockdown
|
||||
L.DefaultCombatKnockdown(50, override_stamdmg = 0) //knockdown
|
||||
L.adjustStaminaLoss(stunpwr)
|
||||
else
|
||||
L.drop_all_held_items() //no knockdown/stamina damage, instead disarm.
|
||||
@@ -218,7 +218,7 @@
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
user.Knockdown(stamforce*6)
|
||||
user.DefaultCombatKnockdown(stamforce*6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
deductcharge(hitcost)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
|
||||
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
|
||||
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
|
||||
user.Knockdown(stamforce * 6)
|
||||
user.DefaultCombatKnockdown(stamforce * 6)
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
|
||||
deductcharge(hitcost)
|
||||
|
||||
@@ -1078,8 +1078,13 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/toy/cards/singlecard/attack_self(mob/user)
|
||||
if(usr.stat || !ishuman(usr) || !usr.canmove || usr.restrained())
|
||||
/obj/item/toy/cards/singlecard/attack_self(mob/living/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_USE))
|
||||
return
|
||||
Flip()
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(structureclimber && structureclimber != user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
structureclimber.Knockdown(40)
|
||||
structureclimber.DefaultCombatKnockdown(40)
|
||||
structureclimber.visible_message("<span class='warning'>[structureclimber] has been knocked off [src].", "You're knocked off [src]!", "You see [structureclimber] get knocked off [src].</span>")
|
||||
|
||||
/obj/structure/ui_act(action, params)
|
||||
@@ -45,7 +45,8 @@
|
||||
if(!climbable)
|
||||
return
|
||||
if(user == O && iscarbon(O))
|
||||
if(user.canmove)
|
||||
var/mob/living/L = O
|
||||
if(CHECK_MOBILITY(L, MOBILITY_MOVE))
|
||||
climb_structure(user)
|
||||
return
|
||||
if(!istype(O, /obj/item) || user.get_active_held_item() != O)
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
user.visible_message("<span class='notice'>[user] pulls [src] out from under [poordude].</span>", "<span class='notice'>You pull [src] out from under [poordude].</span>")
|
||||
var/C = new item_chair(loc)
|
||||
user.put_in_hands(C)
|
||||
poordude.Knockdown(20)//rip in peace
|
||||
poordude.DefaultCombatKnockdown(20)//rip in peace
|
||||
user.adjustStaminaLoss(5)
|
||||
unbuckle_all_mobs(TRUE)
|
||||
qdel(src)
|
||||
@@ -377,7 +377,7 @@
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.health < C.maxHealth*0.5)
|
||||
C.Knockdown(20)
|
||||
C.DefaultCombatKnockdown(20)
|
||||
smash(user)
|
||||
|
||||
/obj/item/chair/greyscale
|
||||
|
||||
@@ -431,7 +431,7 @@
|
||||
"<span class='italics'>You hear a loud metal bang.</span>")
|
||||
var/mob/living/L = O
|
||||
if(!issilicon(L))
|
||||
L.Knockdown(40)
|
||||
L.DefaultCombatKnockdown(40)
|
||||
O.forceMove(T)
|
||||
close()
|
||||
else
|
||||
@@ -474,8 +474,9 @@
|
||||
set category = "Object"
|
||||
set name = "Toggle Open"
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained())
|
||||
return
|
||||
var/mob/living/L = usr
|
||||
if(!istype(L) || !CHECK_MOBILITY(L, MOBILITY_USE))
|
||||
return FALSE
|
||||
|
||||
if(iscarbon(usr) || issilicon(usr) || isdrone(usr))
|
||||
return attack_hand(usr)
|
||||
@@ -510,7 +511,7 @@
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
if(do_after(user,(breakout_time), target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
@@ -603,12 +604,12 @@
|
||||
step_towards(user, T2)
|
||||
T1 = get_turf(user)
|
||||
if(T1 == T2)
|
||||
user.resting = TRUE //so people can jump into crates without slamming the lid on their head
|
||||
user.set_resting(TRUE, TRUE)
|
||||
if(!close(user))
|
||||
to_chat(user, "<span class='warning'>You can't get [src] to close!</span>")
|
||||
user.resting = FALSE
|
||||
user.set_resting(FALSE, TRUE)
|
||||
return
|
||||
user.resting = FALSE
|
||||
user.set_resting(FALSE, TRUE)
|
||||
togglelock(user)
|
||||
T1.visible_message("<span class='warning'>[user] dives into [src]!</span>")
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
var/egged = 0
|
||||
var/use_mob_movespeed = FALSE //Citadel adds snowflake box handling
|
||||
|
||||
/obj/structure/closet/cardboard/relaymove(mob/user, direction)
|
||||
if(opened || move_delay || user.stat || user.IsStun() || user.IsKnockdown() || user.IsUnconscious() || !isturf(loc) || !has_gravity(loc))
|
||||
/obj/structure/closet/cardboard/relaymove(mob/living/user, direction)
|
||||
if(opened || move_delay || !CHECK_MOBILITY(user, MOBILITY_MOVE) || !isturf(loc) || !has_gravity(loc))
|
||||
return
|
||||
move_delay = TRUE
|
||||
var/oldloc = loc
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
src.visible_message(text("<span class='danger'>[M] falls free of [src]!</span>"))
|
||||
unbuckle_mob(M,force=1)
|
||||
M.emote("scream")
|
||||
M.AdjustKnockdown(20)
|
||||
M.DefaultCombatKnockdown(20)
|
||||
|
||||
/obj/structure/kitchenspike/Destroy()
|
||||
if(has_buckled_mobs())
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
/datum/song/proc/shouldStopPlaying(mob/user)
|
||||
if(instrumentObj)
|
||||
if(!user.canUseTopic(instrumentObj))
|
||||
if(!user.canUseTopic(instrumentObj, TRUE, FALSE, FALSE, FALSE))
|
||||
return TRUE
|
||||
return !instrumentObj.anchored // add special cases to stop in subclasses
|
||||
else
|
||||
@@ -220,7 +220,7 @@
|
||||
updateDialog(usr) // make sure updates when complete
|
||||
|
||||
/datum/song/Topic(href, href_list)
|
||||
if(!usr.canUseTopic(instrumentObj))
|
||||
if(!usr.canUseTopic(instrumentObj, TRUE, FALSE, FALSE, FALSE))
|
||||
usr << browse(null, "window=instrument")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
if(S.mind)
|
||||
if(petrified_mob)
|
||||
S.mind.transfer_to(petrified_mob)
|
||||
petrified_mob.Knockdown(100)
|
||||
petrified_mob.DefaultCombatKnockdown(100)
|
||||
to_chat(petrified_mob, "<span class='notice'>You slowly come back to your senses. You are in control of yourself again!</span>")
|
||||
qdel(S)
|
||||
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
|
||||
/obj/structure/table/proc/tableplace(mob/living/user, mob/living/pushed_mob)
|
||||
pushed_mob.forceMove(src.loc)
|
||||
pushed_mob.resting = TRUE
|
||||
pushed_mob.update_canmove()
|
||||
pushed_mob.set_resting(TRUE, FALSE)
|
||||
pushed_mob.visible_message("<span class='notice'>[user] places [pushed_mob] onto [src].</span>", \
|
||||
"<span class='notice'>[user] places [pushed_mob] onto [src].</span>")
|
||||
log_combat(user, pushed_mob, "placed")
|
||||
@@ -128,7 +127,7 @@
|
||||
pushed_mob.pass_flags &= ~PASSTABLE
|
||||
if(pushed_mob.loc != loc) //Something prevented the tabling
|
||||
return
|
||||
pushed_mob.Knockdown(40)
|
||||
pushed_mob.DefaultCombatKnockdown(40)
|
||||
pushed_mob.visible_message("<span class='danger'>[user] slams [pushed_mob] onto [src]!</span>", \
|
||||
"<span class='userdanger'>[user] slams you onto [src]!</span>")
|
||||
log_combat(user, pushed_mob, "tabled", null, "onto [src]")
|
||||
@@ -138,11 +137,11 @@
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
|
||||
|
||||
/obj/structure/table/shove_act(mob/living/target, mob/living/user)
|
||||
if(!target.resting)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
|
||||
if(CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_TABLE)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [src]!</span>",
|
||||
"<span class='danger'>You shove [target.name] onto \the [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.forceMove(src.loc)
|
||||
target.forceMove(loc)
|
||||
log_combat(user, target, "shoved", "onto [src] (table)")
|
||||
return TRUE
|
||||
|
||||
@@ -270,7 +269,7 @@
|
||||
debris -= AM
|
||||
if(istype(AM, /obj/item/shard))
|
||||
AM.throw_impact(L)
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
|
||||
@@ -568,23 +567,20 @@
|
||||
break
|
||||
|
||||
/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob)
|
||||
pushed_mob.forceMove(src.loc)
|
||||
pushed_mob.resting = 1
|
||||
pushed_mob.update_canmove()
|
||||
pushed_mob.forceMove(loc)
|
||||
pushed_mob.set_resting(TRUE, TRUE)
|
||||
visible_message("<span class='notice'>[user] has laid [pushed_mob] on [src].</span>")
|
||||
check_patient()
|
||||
|
||||
/obj/structure/table/optable/proc/check_patient()
|
||||
var/mob/M = locate(/mob/living/carbon/human, loc)
|
||||
if(M)
|
||||
if(M.resting)
|
||||
patient = M
|
||||
return 1
|
||||
var/mob/living/carbon/human/H = locate() in loc
|
||||
if(H)
|
||||
if(!CHECK_MOBILITY(H, MOBILITY_STAND))
|
||||
patient = H
|
||||
return TRUE
|
||||
else
|
||||
patient = null
|
||||
return 0
|
||||
|
||||
|
||||
return FALSE
|
||||
|
||||
/*
|
||||
* Racks
|
||||
@@ -644,7 +640,7 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(user.IsKnockdown() || user.resting || user.lying || user.get_num_legs() < 2)
|
||||
if(CHECK_MULTIPLE_BITFIELDS(user.mobility_flags, MOBILITY_STAND|MOBILITY_MOVE) || user.get_num_legs() < 2)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src, ATTACK_EFFECT_KICK)
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
|
||||
|
||||
//pod insertion
|
||||
/obj/structure/transit_tube/station/MouseDrop_T(obj/structure/c_transit_tube_pod/R, mob/user)
|
||||
if(!user.canmove || user.stat || user.restrained())
|
||||
/obj/structure/transit_tube/station/MouseDrop_T(obj/structure/c_transit_tube_pod/R, mob/living/user)
|
||||
if(!istype(user) || !CHECK_MOBILITY(user, MOBILITY_USE))
|
||||
return
|
||||
if (!istype(R) || get_dist(user, src) > 1 || get_dist(src,R) > 1)
|
||||
if(!istype(R) || get_dist(user, src) > 1 || get_dist(src,R) > 1)
|
||||
return
|
||||
for(var/obj/structure/transit_tube_pod/pod in loc)
|
||||
return //no fun allowed
|
||||
@@ -74,7 +74,7 @@
|
||||
pod.visible_message("<span class='warning'>[user] starts putting [GM] into the [pod]!</span>")
|
||||
if(do_after(user, 15, target = src))
|
||||
if(open_status == STATION_TUBE_OPEN && GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.has_buckled_mobs())
|
||||
GM.Knockdown(100)
|
||||
GM.DefaultCombatKnockdown(100)
|
||||
src.Bumped(GM)
|
||||
break
|
||||
else
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
/obj/structure/trap/stun/trap_effect(mob/living/L)
|
||||
L.electrocute_act(30, src, safety=1) // electrocute act does a message.
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
|
||||
/obj/structure/trap/fire
|
||||
name = "flame trap"
|
||||
@@ -92,7 +92,7 @@
|
||||
|
||||
/obj/structure/trap/fire/trap_effect(mob/living/L)
|
||||
to_chat(L, "<span class='danger'><B>Spontaneous combustion!</B></span>")
|
||||
L.Knockdown(20)
|
||||
L.DefaultCombatKnockdown(20)
|
||||
|
||||
/obj/structure/trap/fire/flare()
|
||||
..()
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
/obj/structure/trap/chill/trap_effect(mob/living/L)
|
||||
to_chat(L, "<span class='danger'><B>You're frozen solid!</B></span>")
|
||||
L.Knockdown(20)
|
||||
L.DefaultCombatKnockdown(20)
|
||||
L.adjust_bodytemperature(-300)
|
||||
L.apply_status_effect(/datum/status_effect/freon)
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
/obj/structure/trap/damage/trap_effect(mob/living/L)
|
||||
to_chat(L, "<span class='danger'><B>The ground quakes beneath your feet!</B></span>")
|
||||
L.Knockdown(100)
|
||||
L.DefaultCombatKnockdown(100)
|
||||
L.adjustBruteLoss(35)
|
||||
|
||||
/obj/structure/trap/damage/flare()
|
||||
@@ -147,7 +147,7 @@
|
||||
/obj/structure/trap/cult/trap_effect(mob/living/L)
|
||||
to_chat(L, "<span class='danger'><B>With a crack, the hostile constructs come out of hiding, stunning you!</B></span>")
|
||||
L.electrocute_act(10, src, safety = TRUE) // electrocute act does a message.
|
||||
L.Knockdown(20)
|
||||
L.DefaultCombatKnockdown(20)
|
||||
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
|
||||
new /mob/living/simple_animal/hostile/construct/proteon/hostile(loc)
|
||||
QDEL_IN(src, 30)
|
||||
QDEL_IN(src, 30)
|
||||
|
||||
@@ -529,7 +529,7 @@
|
||||
if(B.cell.charge > 0 && B.status == 1)
|
||||
flick("baton_active", src)
|
||||
var/stunforce = B.stamforce
|
||||
user.Knockdown(stunforce * 2)
|
||||
user.DefaultCombatKnockdown(stunforce * 2)
|
||||
user.stuttering = stunforce/20
|
||||
B.deductcharge(B.hitcost)
|
||||
user.visible_message("<span class='warning'>[user] shocks [user.p_them()]self while attempting to wash the active [B.name]!</span>", \
|
||||
|
||||
@@ -343,7 +343,8 @@
|
||||
set name = "Flip Windoor Assembly"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
if(usr.stat || !usr.canmove || usr.restrained())
|
||||
var/mob/living/L = usr
|
||||
if(!CHECK_MOBILITY(L, MOBILITY_PULL))
|
||||
return
|
||||
|
||||
if(facing == "l")
|
||||
@@ -354,4 +355,3 @@
|
||||
to_chat(usr, "<span class='notice'>The windoor will now slide to the left.</span>")
|
||||
|
||||
update_icon()
|
||||
return
|
||||
|
||||
@@ -272,7 +272,7 @@
|
||||
|
||||
var/olddir = C.dir
|
||||
if(!(lube & SLIDE_ICE))
|
||||
C.Knockdown(knockdown_amount)
|
||||
C.DefaultCombatKnockdown(knockdown_amount)
|
||||
C.stop_pulling()
|
||||
else
|
||||
C.Stun(20)
|
||||
|
||||
Reference in New Issue
Block a user