mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-31 00:59:16 +01:00
Refactor move/click code
This commit is contained in:
@@ -54,4 +54,4 @@
|
||||
//---------------
|
||||
//#define isturf(D) istype(D, /turf) //Built in
|
||||
#define isopenspace(A) istype(A, /turf/simulated/open)
|
||||
#define isspace(A) istype(A, /turf/space)
|
||||
#define isspace(A) istype(A, /turf/space)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#define DS2TICKS(DS) ((DS)/world.tick_lag) // Convert deciseconds to ticks
|
||||
#define TICKS2DS(T) ((T) TICKS) // Convert ticks to deciseconds
|
||||
#define DS2NEARESTTICK(DS) TICKS2DS(-round(-(DS2TICKS(DS))))
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
|
||||
+7
-12
@@ -23,9 +23,10 @@
|
||||
|
||||
|
||||
/mob/living/silicon/ai/ClickOn(var/atom/A, params)
|
||||
if(world.time <= next_click)
|
||||
if(!checkClickCooldown())
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
setClickCooldown(1)
|
||||
|
||||
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
|
||||
build_click(src, client.buildmode, params, A)
|
||||
@@ -34,6 +35,9 @@
|
||||
if(stat)
|
||||
return
|
||||
|
||||
if(control_disabled)
|
||||
return
|
||||
|
||||
var/list/modifiers = params2list(params)
|
||||
if(modifiers["shift"] && modifiers["ctrl"])
|
||||
CtrlShiftClickOn(A)
|
||||
@@ -44,27 +48,18 @@
|
||||
if(modifiers["shift"])
|
||||
ShiftClickOn(A)
|
||||
return
|
||||
if(modifiers["alt"]) // alt and alt-gr (rightalt)
|
||||
if(modifiers["alt"])
|
||||
AltClickOn(A)
|
||||
return
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(control_disabled || !canClick())
|
||||
return
|
||||
|
||||
if(aiCamera.in_camera_mode)
|
||||
aiCamera.camera_mode_off()
|
||||
aiCamera.captureimage(A, usr)
|
||||
return
|
||||
|
||||
/*
|
||||
AI restrained() currently does nothing
|
||||
if(restrained())
|
||||
RestrainedClickOn(A)
|
||||
else
|
||||
*/
|
||||
A.add_hiddenprint(src)
|
||||
A.attack_ai(src)
|
||||
|
||||
|
||||
+7
-10
@@ -38,10 +38,10 @@
|
||||
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
|
||||
*/
|
||||
/mob/proc/ClickOn(var/atom/A, var/params)
|
||||
if(world.time <= next_click) // Hard check, before anything else, to avoid crashing
|
||||
if(!checkClickCooldown()) // Hard check, before anything else, to avoid crashing
|
||||
return
|
||||
|
||||
next_click = world.time + 1
|
||||
setClickCooldown(1)
|
||||
|
||||
if(client && client.buildmode)
|
||||
build_click(src, client.buildmode, params, A)
|
||||
@@ -69,9 +69,6 @@
|
||||
|
||||
face_atom(A) // change direction to face what you clicked on
|
||||
|
||||
if(!canClick()) // in the year 2000...
|
||||
return
|
||||
|
||||
if(istype(loc, /obj/mecha))
|
||||
if(!locate(/turf) in list(A, A.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
@@ -143,12 +140,12 @@
|
||||
return 1
|
||||
|
||||
/mob/proc/setClickCooldown(var/timeout)
|
||||
next_move = max(world.time + timeout, next_move)
|
||||
next_click = max(world.time + timeout, next_click)
|
||||
|
||||
/mob/proc/canClick()
|
||||
if(config.no_click_cooldown || next_move <= world.time)
|
||||
return 1
|
||||
return 0
|
||||
/mob/proc/checkClickCooldown()
|
||||
if(next_click > world.time && !config.no_click_cooldown)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
// Default behavior: ignore double clicks, the second click that makes the doubleclick call already calls for a normal click
|
||||
/mob/proc/DblClickOn(var/atom/A, var/params)
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
*/
|
||||
|
||||
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
|
||||
if(world.time <= next_click)
|
||||
if(!checkClickCooldown())
|
||||
return
|
||||
next_click = world.time + 1
|
||||
|
||||
setClickCooldown(1)
|
||||
|
||||
if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked
|
||||
build_click(src, client.buildmode, params, A)
|
||||
@@ -35,9 +36,6 @@
|
||||
if(stat || lockdown || weakened || stunned || paralysis)
|
||||
return
|
||||
|
||||
if(!canClick())
|
||||
return
|
||||
|
||||
face_atom(A) // change direction to face what you clicked on
|
||||
|
||||
if(aiCamera && aiCamera.in_camera_mode)
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
if(modifiers["shift"])
|
||||
moved = 0
|
||||
return 1
|
||||
if(usr.next_move >= world.time) // Is this needed ?
|
||||
if(!usr.checkClickCooldown())
|
||||
return
|
||||
owner.Trigger()
|
||||
return 1
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
/obj/screen/item_action/Click()
|
||||
if(!usr || !owner)
|
||||
return 1
|
||||
if(!usr.canClick())
|
||||
if(!usr.checkClickCooldown())
|
||||
return
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.stunned || usr.lying)
|
||||
@@ -114,7 +114,7 @@
|
||||
name = "storage"
|
||||
|
||||
/obj/screen/storage/Click()
|
||||
if(!usr.canClick())
|
||||
if(!usr.checkClickCooldown())
|
||||
return 1
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
@@ -559,7 +559,7 @@
|
||||
/obj/screen/inventory/Click()
|
||||
// At this point in client Click() code we have passed the 1/10 sec check and little else
|
||||
// We don't even know if it's a middle click
|
||||
if(!usr.canClick())
|
||||
if(!usr.checkClickCooldown())
|
||||
return 1
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if(client.buildmode)
|
||||
build_click(src, client.buildmode, params, A)
|
||||
return
|
||||
if(!canClick()) return
|
||||
if(!checkClickCooldown()) return
|
||||
setClickCooldown(4)
|
||||
// You are responsible for checking config.ghost_interaction when you override this function
|
||||
// Not all of them require checking, see below
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
return loc == card
|
||||
|
||||
/mob/living/proc/HardsuitClickOn(var/atom/A, var/alert_ai = 0)
|
||||
if(!can_use_rig() || !canClick())
|
||||
if(!can_use_rig() || !checkClickCooldown())
|
||||
return 0
|
||||
var/obj/item/weapon/rig/rig = get_rig()
|
||||
if(istype(rig) && !rig.offline && rig.selected_module)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/datum/riding
|
||||
var/next_vehicle_move = 0 // Used for move delays
|
||||
var/vehicle_move_delay = 2 // Tick delay between movements, lower = faster, higher = slower
|
||||
var/vehicle_move_delay = 2 // Decisecond delay between movements, lower = faster, higher = slower
|
||||
var/keytype = null // Can give this a type to require the rider to hold the item type inhand to move the ridden atom.
|
||||
var/nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs.
|
||||
var/key_name = "the keys" // What the 'keys' for the thing being rided on would be called.
|
||||
@@ -97,11 +97,13 @@
|
||||
|
||||
if(world.time < next_vehicle_move)
|
||||
return
|
||||
|
||||
next_vehicle_move = world.time + vehicle_move_delay
|
||||
|
||||
if(keycheck(user))
|
||||
if(!Process_Spacemove(direction) || !isturf(ridden.loc))
|
||||
return
|
||||
ridden.Move(get_step(ridden, direction))
|
||||
ridden.Move(get_step(ridden, direction), direction, vehicle_move_delay)
|
||||
|
||||
handle_vehicle_layer()
|
||||
handle_vehicle_offsets()
|
||||
|
||||
@@ -59,22 +59,11 @@
|
||||
var/damage = 0.0
|
||||
var/range = 10.0
|
||||
|
||||
|
||||
/obj/effect/list_container
|
||||
name = "list container"
|
||||
|
||||
/obj/effect/list_container/mobl
|
||||
name = "mobl"
|
||||
var/master = null
|
||||
|
||||
var/list/container = list( )
|
||||
|
||||
/obj/effect/projection
|
||||
name = "Projection"
|
||||
desc = "This looks like a projection of something."
|
||||
anchored = 1.0
|
||||
|
||||
|
||||
/obj/effect/shut_controller
|
||||
name = "shut controller"
|
||||
var/moving = null
|
||||
@@ -114,12 +103,5 @@
|
||||
user.drop_item()
|
||||
src.throw_at(target, throw_range, throw_speed, user)
|
||||
|
||||
/obj/effect/stop
|
||||
var/victim = null
|
||||
icon_state = "empty"
|
||||
name = "Geas"
|
||||
desc = "You can't resist."
|
||||
// name = ""
|
||||
|
||||
/obj/effect/spawner
|
||||
name = "object spawner"
|
||||
|
||||
+37
-11
@@ -1,7 +1,8 @@
|
||||
/atom/movable
|
||||
layer = OBJ_LAYER
|
||||
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
||||
var/last_move = null
|
||||
glide_size = 8
|
||||
var/last_move = null //The direction the atom last moved
|
||||
var/anchored = 0
|
||||
// var/elevation = 2 - not used anywhere
|
||||
var/moving_diagonally
|
||||
@@ -20,6 +21,7 @@
|
||||
var/icon_rotation = 0 // Used to rotate icons in update_transform()
|
||||
var/old_x = 0
|
||||
var/old_y = 0
|
||||
var/datum/riding/riding_datum = null
|
||||
var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P)
|
||||
var/movement_type = NONE
|
||||
|
||||
@@ -51,7 +53,7 @@
|
||||
return ..()
|
||||
|
||||
////////////////////////////////////////
|
||||
/atom/movable/Move(atom/newloc, direct = 0)
|
||||
/atom/movable/Move(atom/newloc, direct = 0, movetime)
|
||||
// Didn't pass enough info
|
||||
if(!loc || !newloc)
|
||||
return FALSE
|
||||
@@ -90,6 +92,7 @@
|
||||
var/dest_z = get_z(newloc)
|
||||
|
||||
// Do The Move
|
||||
glide_for(movetime)
|
||||
loc = newloc
|
||||
. = TRUE
|
||||
|
||||
@@ -131,6 +134,7 @@
|
||||
// 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.
|
||||
glide_for(movetime)
|
||||
if (direct & NORTH)
|
||||
if (direct & EAST)
|
||||
if (step(src, NORTH) && moving_diagonally)
|
||||
@@ -183,7 +187,7 @@
|
||||
|
||||
// If we moved, call Moved() on ourselves
|
||||
if(.)
|
||||
Moved(oldloc, direct, FALSE)
|
||||
Moved(oldloc, direct, FALSE, movetime)
|
||||
|
||||
// Update timers/cooldown stuff
|
||||
move_speed = world.time - l_move_time
|
||||
@@ -191,14 +195,26 @@
|
||||
last_move = direct // The direction you last moved
|
||||
// set_dir(direct) //Don't think this is necessary
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE, movetime)
|
||||
// Handle any buckled mobs on this movable
|
||||
if(has_buckled_mobs())
|
||||
handle_buckled_mob_movement(oldloc,direct)
|
||||
|
||||
//Called after a successful Move(). By this point, we've already moved
|
||||
/atom/movable/proc/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
handle_buckled_mob_movement(old_loc, direction, movetime)
|
||||
if(riding_datum)
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
return TRUE
|
||||
|
||||
/atom/movable/set_dir(newdir)
|
||||
. = ..(newdir)
|
||||
if(riding_datum)
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
|
||||
/atom/movable/relaymove(mob/user, direction)
|
||||
. = ..()
|
||||
if(riding_datum)
|
||||
riding_datum.handle_ride(user, direction)
|
||||
|
||||
// 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)
|
||||
@@ -232,17 +248,17 @@
|
||||
A.Bumped(src)
|
||||
A.last_bumped = world.time
|
||||
|
||||
/atom/movable/proc/forceMove(atom/destination)
|
||||
/atom/movable/proc/forceMove(atom/destination, direction, movetime)
|
||||
. = FALSE
|
||||
if(destination)
|
||||
. = doMove(destination)
|
||||
. = doMove(destination, direction, movetime)
|
||||
else
|
||||
CRASH("No valid destination passed into forceMove")
|
||||
|
||||
/atom/movable/proc/moveToNullspace()
|
||||
return doMove(null)
|
||||
|
||||
/atom/movable/proc/doMove(atom/destination)
|
||||
/atom/movable/proc/doMove(atom/destination, direction, movetime)
|
||||
var/atom/oldloc = loc
|
||||
var/area/old_area = get_area(oldloc)
|
||||
var/same_loc = oldloc == destination
|
||||
@@ -251,7 +267,8 @@
|
||||
var/area/destarea = get_area(destination)
|
||||
|
||||
// Do The Move
|
||||
last_move = 0
|
||||
glide_for(movetime)
|
||||
last_move = isnull(direction) ? 0 : direction
|
||||
loc = destination
|
||||
|
||||
// Unset this in case it was set in some other proc. We're no longer moving diagonally for sure.
|
||||
@@ -329,6 +346,15 @@
|
||||
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/glide_for(movetime)
|
||||
if(movetime)
|
||||
glide_size = WORLD_ICON_SIZE/max(DS2TICKS(movetime), 1)
|
||||
spawn(movetime)
|
||||
glide_size = initial(glide_size)
|
||||
else
|
||||
glide_size = initial(glide_size)
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
//called when src is thrown into hit_atom
|
||||
|
||||
@@ -151,12 +151,13 @@
|
||||
add_fingerprint(user)
|
||||
return M
|
||||
|
||||
/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct)
|
||||
/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct, movetime)
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/L = A
|
||||
L.forceMove(loc, direct)
|
||||
L.last_move = last_move
|
||||
L.inertia_dir = last_move
|
||||
if(!L.Move(loc, direct, movetime))
|
||||
L.forceMove(loc, direct, movetime)
|
||||
L.last_move = last_move
|
||||
L.inertia_dir = last_move
|
||||
|
||||
if(!buckle_dir)
|
||||
L.set_dir(dir)
|
||||
|
||||
@@ -636,6 +636,11 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
//Looking through a scope or binoculars should /not/ improve your periphereal vision. Still, increase viewsize a tiny bit so that sniping isn't as restricted to NSEW
|
||||
/obj/item/var/ignore_visor_zoom_restriction = FALSE
|
||||
|
||||
/obj/item/on_loc_moved(var/oldloc)
|
||||
. = ..()
|
||||
if(zoom)
|
||||
zoom() // aka unzoom
|
||||
|
||||
/obj/item/proc/zoom(var/tileoffset = 14,var/viewsize = 9) //tileoffset is client view offset in the direction the user is facing. viewsize is how far out this thing zooms. 7 is normal view
|
||||
|
||||
var/devicename
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
anchored = 0
|
||||
|
||||
can_buckle = 1
|
||||
buckle_movable = 1
|
||||
buckle_lying = 0
|
||||
buckle_dir = SOUTH
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
var/glass = 0 // 0 = glass can be installed. -1 = glass can't be installed. 1 = glass is already installed. Text = mineral plating is installed instead.
|
||||
var/created_name = null
|
||||
|
||||
New()
|
||||
update_state()
|
||||
/obj/structure/door_assembly/New()
|
||||
update_state()
|
||||
|
||||
/obj/structure/door_assembly/door_assembly_com
|
||||
base_icon_state = "com"
|
||||
@@ -136,23 +136,23 @@
|
||||
airlock_type = "/multi_tile/glass"
|
||||
glass = -1 //To prevent bugs in deconstruction process.
|
||||
|
||||
New()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
bound_height = world.icon_size
|
||||
else
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
update_state()
|
||||
/obj/structure/door_assembly/multi_tile/New()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
bound_height = world.icon_size
|
||||
else
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
update_state()
|
||||
|
||||
Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
bound_height = world.icon_size
|
||||
else
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
/obj/structure/door_assembly/multi_tile/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(dir in list(EAST, WEST))
|
||||
bound_width = width * world.icon_size
|
||||
bound_height = world.icon_size
|
||||
else
|
||||
bound_width = world.icon_size
|
||||
bound_height = width * world.icon_size
|
||||
|
||||
/obj/structure/door_assembly/proc/rename_door(mob/living/user)
|
||||
var/t = sanitizeSafe(input(user, "Enter the name for the windoor.", src.name, src.created_name), MAX_NAME_LEN)
|
||||
|
||||
@@ -158,6 +158,20 @@
|
||||
else
|
||||
unbuckle_mob()
|
||||
|
||||
/obj/structure/bed/chair/office/handle_buckled_mob_movement(atom/new_loc, direction, movetime)
|
||||
for(var/A in buckled_mobs)
|
||||
var/mob/living/occupant = A
|
||||
occupant.buckled = null
|
||||
occupant.Move(loc, direction, movetime)
|
||||
occupant.buckled = src
|
||||
if (occupant && (loc != occupant.loc))
|
||||
if (propelled)
|
||||
for (var/mob/O in src.loc)
|
||||
if (O != occupant)
|
||||
Bump(O)
|
||||
else
|
||||
unbuckle_mob()
|
||||
|
||||
/obj/structure/bed/chair/office/Bump(atom/A)
|
||||
..()
|
||||
if(!has_buckled_mobs()) return
|
||||
|
||||
@@ -8,45 +8,45 @@
|
||||
w_class = ITEMSIZE_HUGE
|
||||
var/obj/item/target/pinned_target // the current pinned target
|
||||
|
||||
Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
// Move the pinned target along with the stake
|
||||
if(pinned_target in view(3, src))
|
||||
pinned_target.forceMove(loc)
|
||||
/obj/structure/target_stake/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
// Move the pinned target along with the stake
|
||||
if(pinned_target in view(3, src))
|
||||
pinned_target.forceMove(loc)
|
||||
|
||||
else // Sanity check: if the pinned target can't be found in immediate view
|
||||
pinned_target = null
|
||||
density = 1
|
||||
else // Sanity check: if the pinned target can't be found in immediate view
|
||||
pinned_target = null
|
||||
density = 1
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
// Putting objects on the stake. Most importantly, targets
|
||||
if(pinned_target)
|
||||
return // get rid of that pinned target first!
|
||||
/obj/structure/target_stake/attackby(obj/item/W as obj, mob/user as mob)
|
||||
// Putting objects on the stake. Most importantly, targets
|
||||
if(pinned_target)
|
||||
return // get rid of that pinned target first!
|
||||
|
||||
if(istype(W, /obj/item/target))
|
||||
density = 0
|
||||
W.density = 1
|
||||
user.remove_from_mob(W)
|
||||
W.loc = loc
|
||||
W.layer = ABOVE_JUNK_LAYER
|
||||
pinned_target = W
|
||||
to_chat(user, "You slide the target into the stake.")
|
||||
return
|
||||
if(istype(W, /obj/item/target))
|
||||
density = 0
|
||||
W.density = 1
|
||||
user.remove_from_mob(W)
|
||||
W.loc = loc
|
||||
W.layer = ABOVE_JUNK_LAYER
|
||||
pinned_target = W
|
||||
to_chat(user, "You slide the target into the stake.")
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
// taking pinned targets off!
|
||||
if(pinned_target)
|
||||
density = 1
|
||||
pinned_target.density = 0
|
||||
pinned_target.layer = OBJ_LAYER
|
||||
/obj/structure/target_stake/attack_hand(mob/user as mob)
|
||||
// taking pinned targets off!
|
||||
if(pinned_target)
|
||||
density = 1
|
||||
pinned_target.density = 0
|
||||
pinned_target.layer = OBJ_LAYER
|
||||
|
||||
pinned_target.loc = user.loc
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(pinned_target)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
else
|
||||
pinned_target.loc = get_turf(user)
|
||||
pinned_target.loc = user.loc
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(pinned_target)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
else
|
||||
pinned_target.loc = get_turf(user)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
|
||||
pinned_target = null
|
||||
pinned_target = null
|
||||
|
||||
@@ -157,17 +157,12 @@ var/const/enterloopsanity = 100
|
||||
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
if(!M.lastarea)
|
||||
M.lastarea = get_area(M.loc)
|
||||
if(M.lastarea.has_gravity == 0)
|
||||
if(M.lastarea?.has_gravity == 0)
|
||||
inertial_drift(M)
|
||||
else if(!is_space())
|
||||
M.inertia_dir = 0
|
||||
M.make_floating(0)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
L.handle_footstep(src)
|
||||
..()
|
||||
|
||||
var/objects = 0
|
||||
if(A && (A.flags & PROXMOVE))
|
||||
for(var/atom/movable/thing in range(1))
|
||||
|
||||
@@ -56,18 +56,12 @@
|
||||
return
|
||||
|
||||
BSACooldown = 1
|
||||
spawn(50)
|
||||
BSACooldown = 0
|
||||
VARSET_IN(global, BSACooldown, FALSE, 5 SECONDS)
|
||||
|
||||
to_chat(target,"You've been hit by bluespace artillery!")
|
||||
log_and_message_admins("[key_name(target)] has been hit by Bluespace Artillery fired by [key_name(user ? user : usr)]")
|
||||
|
||||
var/obj/effect/stop/S
|
||||
S = new /obj/effect/stop
|
||||
S.victim = target
|
||||
S.loc = target.loc
|
||||
spawn(20)
|
||||
qdel(S)
|
||||
target.setMoveCooldown(2 SECONDS)
|
||||
|
||||
var/turf/simulated/floor/T = get_turf(target)
|
||||
if(istype(T))
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_mob/IAttack(atom/A)
|
||||
if(!canClick()) // Still on cooldown from a "click".
|
||||
if(!checkClickCooldown()) // Still on cooldown from a "click".
|
||||
return ATTACK_ON_COOLDOWN
|
||||
return attack_target(A) // This will set click cooldown.
|
||||
|
||||
/mob/living/carbon/human/IAttack(atom/A)
|
||||
if(!canClick()) // Still on cooldown from a "click".
|
||||
if(!checkClickCooldown()) // Still on cooldown from a "click".
|
||||
return FALSE
|
||||
return ClickOn(A) // Except this is an actual fake "click".
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_mob/IRangedAttack(atom/A)
|
||||
if(!canClick()) // Still on cooldown from a "click".
|
||||
if(!checkClickCooldown()) // Still on cooldown from a "click".
|
||||
return ATTACK_ON_COOLDOWN
|
||||
return shoot_target(A)
|
||||
|
||||
@@ -74,30 +74,27 @@
|
||||
// Respects move cooldowns as if it had a client.
|
||||
// Also tries to avoid being superdumb with moving into certain tiles (unless that's desired).
|
||||
/mob/living/proc/IMove(turf/newloc, safety = TRUE)
|
||||
if(check_move_cooldown())
|
||||
// if(!newdir)
|
||||
// newdir = get_dir(get_turf(src), newloc)
|
||||
if(!checkMoveCooldown())
|
||||
return MOVEMENT_ON_COOLDOWN
|
||||
|
||||
// Check to make sure moving to newloc won't actually kill us. e.g. we're a slime and trying to walk onto water.
|
||||
if(istype(newloc))
|
||||
if(safety && !newloc.is_safe_to_enter(src))
|
||||
return MOVEMENT_FAILED
|
||||
|
||||
// Move()ing to another tile successfully returns 32 because BYOND. Would rather deal with TRUE/FALSE-esque terms.
|
||||
// Note that moving to the same tile will be 'successful'.
|
||||
var/turf/old_T = get_turf(src)
|
||||
|
||||
// An adjacency check to avoid mobs phasing diagonally past windows.
|
||||
// This might be better in general movement code but I'm too scared to add it, and most things don't move diagonally anyways.
|
||||
if(!old_T.Adjacent(newloc))
|
||||
// Check to make sure moving to newloc won't actually kill us. e.g. we're a slime and trying to walk onto water.
|
||||
if(istype(newloc))
|
||||
if(safety && !newloc.is_safe_to_enter(src))
|
||||
return MOVEMENT_FAILED
|
||||
|
||||
. = SelfMove(newloc) ? MOVEMENT_SUCCESSFUL : MOVEMENT_FAILED
|
||||
if(. == MOVEMENT_SUCCESSFUL)
|
||||
set_dir(get_dir(old_T, newloc))
|
||||
// Apply movement delay.
|
||||
// Player movement has more factors but its all in the client and fixing that would be its own project.
|
||||
setMoveCooldown(movement_delay())
|
||||
return
|
||||
// Move()ing to another tile successfully returns 32 because BYOND. Would rather deal with TRUE/FALSE-esque terms.
|
||||
// Note that moving to the same tile will be 'successful'.
|
||||
var/turf/old_T = get_turf(src)
|
||||
|
||||
. = MOVEMENT_ON_COOLDOWN // To avoid superfast mobs that aren't meant to be superfast. Is actually -1.
|
||||
// An adjacency check to avoid mobs phasing diagonally past windows.
|
||||
// This might be better in general movement code but I'm too scared to add it, and most things don't move diagonally anyways.
|
||||
if(!old_T.Adjacent(newloc))
|
||||
return MOVEMENT_FAILED
|
||||
|
||||
. = SelfMove(newloc) ? MOVEMENT_SUCCESSFUL : MOVEMENT_FAILED
|
||||
if(. == MOVEMENT_SUCCESSFUL)
|
||||
set_dir(get_dir(old_T, newloc))
|
||||
// Apply movement delay.
|
||||
// Player movement has more factors but its all in the client and fixing that would be its own project.
|
||||
setMoveCooldown(movement_delay())
|
||||
return
|
||||
@@ -18,7 +18,6 @@
|
||||
//OTHER//
|
||||
/////////
|
||||
var/datum/preferences/prefs = null
|
||||
//var/move_delay = 1
|
||||
var/moving = null
|
||||
var/adminobs = null
|
||||
var/area = null
|
||||
|
||||
@@ -995,14 +995,6 @@
|
||||
if(wearer.transforming || !wearer.canmove)
|
||||
return
|
||||
|
||||
if(locate(/obj/effect/stop/, wearer.loc))
|
||||
for(var/obj/effect/stop/S in wearer.loc)
|
||||
if(S.victim == wearer)
|
||||
return
|
||||
|
||||
if(!wearer.lastarea)
|
||||
wearer.lastarea = get_area(wearer.loc)
|
||||
|
||||
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
|
||||
if(!wearer.Process_Spacemove(0))
|
||||
return 0
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
|
||||
/mob/living/carbon/Moved(atom/old_loc, direction, forced = FALSE)
|
||||
. = ..()
|
||||
if(src.nutrition && src.stat != DEAD)
|
||||
adjust_nutrition(-DEFAULT_HUNGER_FACTOR / 10)
|
||||
if(src.m_intent == "run")
|
||||
if(src.nutrition && src.stat != 2)
|
||||
adjust_nutrition(-DEFAULT_HUNGER_FACTOR / 10)
|
||||
if(src.m_intent == "run")
|
||||
adjust_nutrition(-DEFAULT_HUNGER_FACTOR / 10)
|
||||
|
||||
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
@@ -400,3 +400,4 @@
|
||||
if(does_not_breathe)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -1374,7 +1374,7 @@
|
||||
set desc = "Pop a joint back into place. Extremely painful."
|
||||
set src in view(1)
|
||||
|
||||
if(!isliving(usr) || !usr.canClick())
|
||||
if(!isliving(usr) || !usr.checkClickCooldown())
|
||||
return
|
||||
|
||||
usr.setClickCooldown(20)
|
||||
@@ -1612,3 +1612,32 @@
|
||||
|
||||
msg += get_display_species()
|
||||
return msg
|
||||
|
||||
/mob/living/carbon/human/pull_damage()
|
||||
if(((health - halloss) <= config.health_threshold_softcrit))
|
||||
for(var/name in organs_by_name)
|
||||
var/obj/item/organ/external/e = organs_by_name[name]
|
||||
if(!e)
|
||||
continue
|
||||
if((e.status & ORGAN_BROKEN && (!e.splinted || (e.splinted in e.contents && prob(30))) || e.status & ORGAN_BLEEDING) && (getBruteLoss() + getFireLoss() >= 100))
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
// Drag damage is handled in a parent
|
||||
/mob/living/carbon/human/dragged(var/mob/living/dragger, var/oldloc)
|
||||
if(prob(getBruteLoss() * 200 / maxHealth))
|
||||
var/bloodtrail = 1
|
||||
if(species?.flags & NO_BLOOD)
|
||||
bloodtrail = 0
|
||||
else
|
||||
var/blood_volume = round((vessel.get_reagent_amount("blood")/species.blood_volume)*100)
|
||||
if(blood_volume < BLOOD_VOLUME_SURVIVE)
|
||||
bloodtrail = 0 //Most of it's gone already, just leave it be
|
||||
else
|
||||
vessel.remove_reagent("blood", 1)
|
||||
if(bloodtrail)
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/T = loc
|
||||
T.add_blood(src)
|
||||
. = ..()
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay(oldloc, direct)
|
||||
|
||||
var/tally = 0
|
||||
. = ..()
|
||||
|
||||
if(species.slowdown)
|
||||
tally = species.slowdown
|
||||
. = species.slowdown
|
||||
|
||||
if (istype(loc, /turf/space)) return -1 // It's hard to be slowed down in space by... anything
|
||||
|
||||
@@ -19,54 +19,54 @@
|
||||
if(!isnull(M.haste) && M.haste == TRUE)
|
||||
return HUMAN_LOWEST_SLOWDOWN // Returning -1 will actually result in a slowdown for Teshari.
|
||||
if(!isnull(M.slowdown))
|
||||
tally += M.slowdown
|
||||
. += M.slowdown
|
||||
|
||||
var/health_deficiency = (getMaxHealth() - health)
|
||||
if(health_deficiency >= 40) tally += (health_deficiency / 25)
|
||||
if(health_deficiency >= 40) . += (health_deficiency / 25)
|
||||
|
||||
if(can_feel_pain())
|
||||
if(halloss >= 10) tally += (halloss / 10) //halloss shouldn't slow you down if you can't even feel it
|
||||
if(halloss >= 10) . += (halloss / 10) //halloss shouldn't slow you down if you can't even feel it
|
||||
|
||||
var/hungry = (MAX_NUTRITION - nutrition) / 5
|
||||
if (hungry >= 70) tally += hungry/50
|
||||
if (hungry >= 70) . += hungry/50
|
||||
|
||||
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
|
||||
for(var/organ_name in list(BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM))
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || E.is_stump())
|
||||
tally += 4
|
||||
. += 4
|
||||
else if(E.splinted && E.splinted.loc != E)
|
||||
tally += 0.5
|
||||
. += 0.5
|
||||
else if(E.status & ORGAN_BROKEN)
|
||||
tally += 1.5
|
||||
. += 1.5
|
||||
else
|
||||
for(var/organ_name in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT))
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || E.is_stump())
|
||||
tally += 4
|
||||
. += 4
|
||||
else if(E.splinted && E.splinted.loc != E)
|
||||
tally += 0.5
|
||||
. += 0.5
|
||||
else if(E.status & ORGAN_BROKEN)
|
||||
tally += 1.5
|
||||
. += 1.5
|
||||
|
||||
if(shock_stage >= 10) tally += 3
|
||||
if(shock_stage >= 10) . += 3
|
||||
|
||||
if(aiming && aiming.aiming_at) tally += 5 // Iron sights make you slower, it's a well-known fact.
|
||||
if(aiming && aiming.aiming_at) . += 5 // Iron sights make you slower, it's a well-known fact.
|
||||
|
||||
if(FAT in src.mutations)
|
||||
tally += 1.5
|
||||
. += 1.5
|
||||
|
||||
if (bodytemperature < species.cold_level_1)
|
||||
tally += (species.cold_level_1 - bodytemperature) / 10 * 1.75
|
||||
. += (species.cold_level_1 - bodytemperature) / 10 * 1.75
|
||||
|
||||
tally += max(2 * stance_damage, 0) //damaged/missing feet or legs is slow
|
||||
. += max(2 * stance_damage, 0) //damaged/missing feet or legs is slow
|
||||
|
||||
if(mRun in mutations)
|
||||
tally = 0
|
||||
. = 0
|
||||
|
||||
// Turf related slowdown
|
||||
var/turf/T = get_turf(src)
|
||||
tally += calculate_turf_slowdown(T, direct)
|
||||
. += calculate_turf_slowdown(T, direct)
|
||||
|
||||
// Item related slowdown.
|
||||
var/item_tally = calculate_item_encumbrance()
|
||||
@@ -83,19 +83,19 @@
|
||||
|
||||
item_tally *= species.item_slowdown_mod
|
||||
|
||||
tally += item_tally
|
||||
. += item_tally
|
||||
|
||||
if(CE_SLOWDOWN in chem_effects)
|
||||
if (tally >= 0 )
|
||||
tally = (tally + tally/4) //Add a quarter of penalties on top.
|
||||
tally += chem_effects[CE_SLOWDOWN]
|
||||
if (. >= 0 )
|
||||
. *= 1.25 //Add a quarter of penalties on top.
|
||||
. += chem_effects[CE_SLOWDOWN]
|
||||
|
||||
if(CE_SPEEDBOOST in chem_effects)
|
||||
if (tally >= 0) // cut any penalties in half
|
||||
tally = tally/2
|
||||
tally -= chem_effects[CE_SPEEDBOOST] // give 'em a buff on top.
|
||||
if (. >= 0) // cut any penalties in half
|
||||
. *= 0.5
|
||||
. -= chem_effects[CE_SPEEDBOOST] // give 'em a buff on top.
|
||||
|
||||
return max(HUMAN_LOWEST_SLOWDOWN, tally+config.human_delay) // Minimum return should be the same as force_max_speed
|
||||
. = max(HUMAN_LOWEST_SLOWDOWN, . + config.human_delay) // Minimum return should be the same as force_max_speed
|
||||
|
||||
// This calculates the amount of slowdown to receive from items worn. This does NOT include species modifiers.
|
||||
// It is in a seperate place to avoid an infinite loop situation with dragging mobs dragging each other.
|
||||
@@ -204,6 +204,8 @@
|
||||
|
||||
// Handle footstep sounds
|
||||
/mob/living/carbon/human/handle_footstep(var/turf/T)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(is_incorporeal())
|
||||
return
|
||||
if(!config.footstep_volume || !T.footstep_sounds || !T.footstep_sounds.len)
|
||||
|
||||
@@ -127,49 +127,37 @@
|
||||
onclose(user, "mob[name]")
|
||||
return
|
||||
|
||||
/mob/living/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
|
||||
if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) )))
|
||||
if (!( L ))
|
||||
return null
|
||||
else
|
||||
return L.container
|
||||
else
|
||||
if (!( L ))
|
||||
L = new /obj/effect/list_container/mobl( null )
|
||||
L.container += src
|
||||
L.master = src
|
||||
if (istype(l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = l_hand
|
||||
if (!( L.container.Find(G.affecting) ))
|
||||
L.container += G.affecting
|
||||
if (G.affecting)
|
||||
G.affecting.ret_grab(L, 1)
|
||||
if (istype(r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = r_hand
|
||||
if (!( L.container.Find(G.affecting) ))
|
||||
L.container += G.affecting
|
||||
if (G.affecting)
|
||||
G.affecting.ret_grab(L, 1)
|
||||
if (!( flag ))
|
||||
if (L.master == src)
|
||||
var/list/temp = list( )
|
||||
temp += L.container
|
||||
//L = null
|
||||
qdel(L)
|
||||
return temp
|
||||
else
|
||||
return L.container
|
||||
return
|
||||
/mob/living/ret_grab(var/list/L, var/mobchain_limit = 5)
|
||||
// We're the first!
|
||||
if(!L)
|
||||
L = list()
|
||||
|
||||
// Lefty grab!
|
||||
if (istype(l_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = l_hand
|
||||
L |= G.affecting
|
||||
if(mobchain_limit-- > 0)
|
||||
G.affecting?.ret_grab(L, mobchain_limit) // Recurse! They can update the list. It's the same instance as ours.
|
||||
|
||||
// Righty grab!
|
||||
if (istype(r_hand, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = r_hand
|
||||
L |= G.affecting
|
||||
if(mobchain_limit-- > 0)
|
||||
G.affecting?.ret_grab(L, mobchain_limit) // Same as lefty!
|
||||
|
||||
// On all but the one not called by us, this will just be ignored. Oh well!
|
||||
return L
|
||||
|
||||
/mob/living/mode()
|
||||
set name = "Activate Held Object"
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
|
||||
if(world.time <= next_click) // This isn't really a 'click' but it'll work for our purposes.
|
||||
if(!checkClickCooldown())
|
||||
return
|
||||
|
||||
next_click = world.time + 1
|
||||
|
||||
setClickCooldown(1)
|
||||
|
||||
if(istype(loc,/obj/mecha)) return
|
||||
|
||||
|
||||
@@ -735,116 +735,65 @@ default behaviour is:
|
||||
|
||||
return
|
||||
|
||||
/mob/living/Move(a, b, flag)
|
||||
if (buckled && buckled.loc != a) //not updating position
|
||||
if(istype(buckled, /mob)) //If you're buckled to a mob, a la slime things, keep on rolling.
|
||||
return buckled.Move(a, b)
|
||||
else //Otherwise, no running around for you.
|
||||
// Almost all of this handles pulling movables behind us
|
||||
/mob/living/Move(atom/newloc, direct, movetime)
|
||||
if(buckled && buckled.loc != newloc) //not updating position
|
||||
if(!buckled.anchored && buckled.buckle_movable)
|
||||
return buckled.Move(newloc, direct)
|
||||
else
|
||||
return 0
|
||||
|
||||
if (restrained())
|
||||
var/atom/movable/pullee = pulling
|
||||
// Prior to our move it's already too far away
|
||||
if(pullee && get_dist(src, pullee) > 1)
|
||||
stop_pulling()
|
||||
// Shenanigans! Pullee closed into locker for eg.
|
||||
if(pullee && !isturf(pullee.loc) && pullee.loc != loc)
|
||||
stop_pulling()
|
||||
// Can't pull with no hands
|
||||
if(restrained())
|
||||
stop_pulling()
|
||||
|
||||
// Will move our mob (probably)
|
||||
. = ..() // Moved() called at this point if successful
|
||||
|
||||
var/t7 = 1
|
||||
if (restrained())
|
||||
for(var/mob/living/M in range(src, 1))
|
||||
if ((M.pulling == src && M.stat == 0 && !( M.restrained() )))
|
||||
t7 = null
|
||||
if ((t7 && (pulling && ((get_dist(src, pulling) <= 1 || pulling.loc == loc) && (client && client.moving)))))
|
||||
var/turf/T = loc
|
||||
. = ..()
|
||||
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //seperated from our puller and not in the middle of a diagonal move
|
||||
pulledby.stop_pulling()
|
||||
|
||||
if (pulling && pulling.loc)
|
||||
if(!( isturf(pulling.loc) ))
|
||||
stop_pulling()
|
||||
return
|
||||
if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
/////
|
||||
if(pulling && pulling.anchored)
|
||||
/mob/living/proc/dragged(var/mob/living/dragger, var/oldloc)
|
||||
var/area/A = get_area(src)
|
||||
if(lying && !buckled && pull_damage() && A.has_gravity && (prob(getBruteLoss() * 200 / maxHealth)))
|
||||
adjustBruteLoss(2)
|
||||
visible_message("<span class='danger'>\The [src]'s [isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
|
||||
|
||||
/mob/living/Moved(var/atom/oldloc, direct, forced, movetime)
|
||||
. = ..()
|
||||
handle_footstep(loc)
|
||||
|
||||
if(pulling) // we were pulling a thing and didn't lose it during our move.
|
||||
if(pulling.anchored || !isturf(pulling.loc))
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
if (!restrained())
|
||||
var/diag = get_dir(src, pulling)
|
||||
if ((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if ((get_dist(src, pulling) > 1 || diag))
|
||||
if (isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
var/atom/movable/t = M.pulling
|
||||
M.stop_pulling()
|
||||
var/pull_dir = get_dir(src, pulling)
|
||||
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position
|
||||
// If it is too far away or across z-levels from old location, stop pulling.
|
||||
if(get_dist(pulling.loc, oldloc) > 1 || pulling.loc.z != oldloc?.z)
|
||||
stop_pulling()
|
||||
return
|
||||
|
||||
if(!istype(M.loc, /turf/space))
|
||||
var/area/A = get_area(M)
|
||||
if(A.has_gravity)
|
||||
//this is the gay blood on floor shit -- Added back -- Skie
|
||||
if (M.lying && (prob(M.getBruteLoss() / 6)))
|
||||
var/bloodtrail = 1 //Checks if it's possible to even spill blood
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.flags & NO_BLOOD)
|
||||
bloodtrail = 0
|
||||
else
|
||||
var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100)
|
||||
if(blood_volume < BLOOD_VOLUME_SURVIVE)
|
||||
bloodtrail = 0 //Most of it's gone already, just leave it be
|
||||
else
|
||||
H.vessel.remove_reagent("blood", 1)
|
||||
if(bloodtrail)
|
||||
var/turf/location = M.loc
|
||||
if(istype(location, /turf/simulated))
|
||||
location.add_blood(M)
|
||||
//pull damage with injured people
|
||||
if(prob(25))
|
||||
M.adjustBruteLoss(1)
|
||||
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state worsens": "wounds open more"] from being dragged!</span>")
|
||||
if(M.pull_damage())
|
||||
if(prob(25))
|
||||
M.adjustBruteLoss(2)
|
||||
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
|
||||
var/turf/location = M.loc
|
||||
if (istype(location, /turf/simulated))
|
||||
var/bloodtrail = 1 //Checks if it's possible to even spill blood
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.flags & NO_BLOOD)
|
||||
bloodtrail = 0
|
||||
else
|
||||
var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100)
|
||||
if(blood_volume < BLOOD_VOLUME_SURVIVE)
|
||||
bloodtrail = 0 //Most of it's gone already, just leave it be
|
||||
else
|
||||
H.vessel.remove_reagent("blood", 1)
|
||||
if(bloodtrail)
|
||||
if(istype(location, /turf/simulated))
|
||||
location.add_blood(M)
|
||||
// living might take damage from drags
|
||||
if(isliving(pulling))
|
||||
var/mob/living/M = pulling
|
||||
M.dragged(src, oldloc)
|
||||
|
||||
if(get_dist(pulling.loc, T) > 1 || pulling.loc.z != T.z)
|
||||
M.stop_pulling()
|
||||
else
|
||||
step(pulling, get_dir(pulling.loc, T))
|
||||
if(t)
|
||||
M.start_pulling(t)
|
||||
else
|
||||
if (pulling)
|
||||
if (istype(pulling, /obj/structure/window))
|
||||
var/obj/structure/window/W = pulling
|
||||
if(W.is_fulltile())
|
||||
for(var/obj/structure/window/win in get_step(pulling,get_dir(pulling.loc, T)))
|
||||
stop_pulling()
|
||||
pulling.Move(oldloc, 0, movetime) // the pullee tries to reach our previous position
|
||||
if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up
|
||||
stop_pulling()
|
||||
|
||||
if(get_dist(pulling.loc, T) > 1 || pulling.loc.z != T.z) // This is needed or else pulled objects can't get pushed away.
|
||||
stop_pulling()
|
||||
else
|
||||
step(pulling, get_dir(pulling.loc, T))
|
||||
else
|
||||
stop_pulling()
|
||||
. = ..()
|
||||
|
||||
if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
/mob/living/proc/handle_footstep(turf/T)
|
||||
return FALSE
|
||||
@@ -853,7 +802,7 @@ default behaviour is:
|
||||
set name = "Resist"
|
||||
set category = "IC"
|
||||
|
||||
if(!incapacitated(INCAPACITATION_KNOCKOUT) && canClick())
|
||||
if(!incapacitated(INCAPACITATION_KNOCKOUT) && checkClickCooldown())
|
||||
setClickCooldown(20)
|
||||
resist_grab()
|
||||
if(!weakened)
|
||||
@@ -1239,9 +1188,7 @@ default behaviour is:
|
||||
//actually throw it!
|
||||
src.visible_message("<span class='warning'>[src] has thrown [item].</span>")
|
||||
|
||||
if(!src.lastarea)
|
||||
src.lastarea = get_area(src.loc)
|
||||
if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
|
||||
if((isspace(src.loc)) || (src.lastarea?.has_gravity == 0))
|
||||
src.inertia_dir = get_dir(target, src)
|
||||
step(src, inertia_dir)
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
|
||||
return (!mover.density || !density || lying)
|
||||
|
||||
/mob/living/SelfMove(turf/n, direct)
|
||||
/mob/CanZASPass(turf/T, is_zone)
|
||||
return ATMOS_PASS_YES
|
||||
|
||||
/mob/living/SelfMove(turf/n, direct, movetime)
|
||||
// If on walk intent, don't willingly step into hazardous tiles.
|
||||
// Unless the walker is confused.
|
||||
if(m_intent == "walk" && confused <= 0)
|
||||
|
||||
@@ -909,10 +909,10 @@
|
||||
set category = "IC"
|
||||
set src = usr
|
||||
|
||||
if(world.time <= next_click) // Hard check, before anything else, to avoid crashing
|
||||
if(!checkClickCooldown())
|
||||
return
|
||||
|
||||
next_click = world.time + 1
|
||||
setClickCooldown(1)
|
||||
|
||||
var/obj/item/W = get_active_hand()
|
||||
if (W)
|
||||
|
||||
@@ -15,17 +15,17 @@
|
||||
|
||||
//No longer needed, but I'll leave it here incase we plan to re-use it.
|
||||
/mob/living/silicon/robot/movement_delay()
|
||||
var/tally = 0 //Incase I need to add stuff other than "speed" later
|
||||
. = ..()
|
||||
|
||||
tally = speed
|
||||
. += speed
|
||||
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
|
||||
tally-=3
|
||||
. -= 3
|
||||
|
||||
return tally+config.robot_delay
|
||||
. += config.robot_delay
|
||||
|
||||
// NEW: Use power while moving.
|
||||
/mob/living/silicon/robot/SelfMove(turf/n, direct)
|
||||
/mob/living/silicon/robot/SelfMove(turf/n, direct, movetime)
|
||||
if (!is_component_functioning("actuator"))
|
||||
return 0
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
. = ..()
|
||||
to_chat(src,"<b>You are \the [src].</b> [player_msg]")
|
||||
|
||||
/mob/living/simple_mob/SelfMove(turf/n, direct)
|
||||
/mob/living/simple_mob/SelfMove(turf/n, direct, movetime)
|
||||
var/turf/old_turf = get_turf(src)
|
||||
var/old_dir = dir
|
||||
. = ..()
|
||||
@@ -212,9 +212,9 @@
|
||||
return ..()
|
||||
*/
|
||||
/mob/living/simple_mob/movement_delay()
|
||||
var/tally = 0 //Incase I need to add stuff other than "speed" later
|
||||
. = ..()
|
||||
|
||||
tally = movement_cooldown
|
||||
. += movement_cooldown
|
||||
|
||||
if(force_max_speed)
|
||||
return -3
|
||||
@@ -223,25 +223,25 @@
|
||||
if(!isnull(M.haste) && M.haste == TRUE)
|
||||
return -3
|
||||
if(!isnull(M.slowdown))
|
||||
tally += M.slowdown
|
||||
. += M.slowdown
|
||||
|
||||
// Turf related slowdown
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && T.movement_cost && !hovering) // Flying mobs ignore turf-based slowdown. Aquatic mobs ignore water slowdown, and can gain bonus speed in it.
|
||||
if(istype(T,/turf/simulated/floor/water) && aquatic_movement)
|
||||
tally -= aquatic_movement - 1
|
||||
. -= aquatic_movement - 1
|
||||
else
|
||||
tally += T.movement_cost
|
||||
. += T.movement_cost
|
||||
|
||||
if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
|
||||
if(tally <= 0)
|
||||
tally = 1
|
||||
tally *= purge
|
||||
if(. <= 0)
|
||||
. = 1
|
||||
. *= purge
|
||||
|
||||
if(m_intent == "walk")
|
||||
tally *= 1.5
|
||||
. *= 1.5
|
||||
|
||||
return tally+config.animal_delay
|
||||
. += config.animal_delay
|
||||
|
||||
|
||||
/mob/living/simple_mob/Stat()
|
||||
|
||||
+16
-13
@@ -45,6 +45,7 @@
|
||||
dead_mob_list += src
|
||||
else
|
||||
living_mob_list += src
|
||||
lastarea = get_area(src)
|
||||
update_transform() // Some mobs may start bigger or smaller than normal.
|
||||
return ..()
|
||||
|
||||
@@ -139,7 +140,18 @@
|
||||
return 0
|
||||
|
||||
/mob/proc/movement_delay(oldloc, direct)
|
||||
return 0
|
||||
. = 0
|
||||
if(locate(/obj/item/weapon/grab) in src)
|
||||
. += 7
|
||||
|
||||
// Movespeed delay based on movement mode
|
||||
switch(m_intent)
|
||||
if("run")
|
||||
if(drowsyness > 0)
|
||||
. += 6
|
||||
. += config.run_speed
|
||||
if("walk")
|
||||
. += config.walk_speed
|
||||
|
||||
/mob/proc/Life()
|
||||
// if(organStructure)
|
||||
@@ -507,15 +519,6 @@
|
||||
|
||||
|
||||
/mob/proc/pull_damage()
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.health - H.halloss <= config.health_threshold_softcrit)
|
||||
for(var/name in H.organs_by_name)
|
||||
var/obj/item/organ/external/e = H.organs_by_name[name]
|
||||
if(e && H.lying)
|
||||
if((e.status & ORGAN_BROKEN && (!e.splinted || (e.splinted && e.splinted in e.contents && prob(30))) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100))
|
||||
return 1
|
||||
break
|
||||
return 0
|
||||
|
||||
/mob/MouseDrop(mob/M as mob)
|
||||
@@ -737,12 +740,12 @@
|
||||
|
||||
|
||||
/mob/proc/facedir(var/ndir)
|
||||
if(!canface() || (client && (client.moving || (world.time < move_delay))))
|
||||
if(!canface() || (client && (client.moving || !checkMoveCooldown())))
|
||||
return 0
|
||||
set_dir(ndir)
|
||||
if(buckled && buckled.buckle_movable)
|
||||
buckled.set_dir(ndir)
|
||||
move_delay += movement_delay()
|
||||
setMoveCooldown(movement_delay())
|
||||
return 1
|
||||
|
||||
|
||||
@@ -905,7 +908,7 @@ mob/proc/yank_out_object()
|
||||
set desc = "Remove an embedded item at the cost of bleeding and pain."
|
||||
set src in view(1)
|
||||
|
||||
if(!isliving(usr) || !usr.canClick())
|
||||
if(!isliving(usr) || !usr.checkClickCooldown())
|
||||
return
|
||||
usr.setClickCooldown(20)
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
var/datum/mind/mind
|
||||
|
||||
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
|
||||
var/move_delay = null // For movement speed delays.
|
||||
var/next_move = null // For click delay, despite the misleading name.
|
||||
var/next_move = null // world.time when mob is next allowed to self-move.
|
||||
|
||||
//Not in use yet
|
||||
var/obj/effect/organstructure/organStructure = null
|
||||
|
||||
@@ -231,8 +231,6 @@
|
||||
return
|
||||
if(state == GRAB_UPGRADING)
|
||||
return
|
||||
if(!assailant.canClick())
|
||||
return
|
||||
if(world.time < (last_action + UPGRADE_COOLDOWN))
|
||||
return
|
||||
if(!assailant.canmove || assailant.lying)
|
||||
|
||||
+160
-160
@@ -1,8 +1,8 @@
|
||||
/mob/proc/setMoveCooldown(var/timeout)
|
||||
move_delay = max(world.time + timeout, move_delay)
|
||||
next_move = max(world.time + timeout, next_move)
|
||||
|
||||
/mob/proc/check_move_cooldown()
|
||||
if(world.time < src.move_delay)
|
||||
/mob/proc/checkMoveCooldown()
|
||||
if(world.time < next_move)
|
||||
return FALSE // Need to wait more.
|
||||
return TRUE
|
||||
|
||||
@@ -108,201 +108,201 @@
|
||||
mob.control_object.forceMove(get_step(mob.control_object,direct))
|
||||
return
|
||||
|
||||
|
||||
// NB: This is called for 'self movement', not for being pulled or things like that, which COULD be the case for /mob/Move
|
||||
// But to be honest, A LOT OF THIS CODE should be in /mob/Move
|
||||
/client/Move(n, direct)
|
||||
//if(!mob) // Clients cannot have a null mob, as enforced by byond
|
||||
// return // Moved here to avoid nullrefs below
|
||||
// Prevents a double-datum lookup each time this is referenced
|
||||
// May seem dumb, but it's faster to look up a var on my_mob than dereferencing mob on client, then dereferencing the var on that mob
|
||||
// Having it in a var here means it's more available to look up things on. It won't speed up that second dereference, though.
|
||||
var/mob/my_mob = mob
|
||||
|
||||
if(mob.control_object) Move_object(direct)
|
||||
// Nothing to do in nullspace
|
||||
if(!my_mob.loc)
|
||||
return
|
||||
|
||||
if(mob.incorporeal_move && isobserver(mob))
|
||||
// Used many times below, faster reference.
|
||||
var/atom/loc = my_mob.loc
|
||||
|
||||
// We're controlling an object which is SOMEHOW DIFFERENT FROM AN EYE??
|
||||
if(my_mob.control_object)
|
||||
Move_object(direct)
|
||||
|
||||
// Ghosty mob movement
|
||||
if(my_mob.incorporeal_move && isobserver(my_mob))
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
|
||||
if(moving) return 0
|
||||
// We're in the middle of another move we've already decided to do
|
||||
if(moving)
|
||||
return 0
|
||||
|
||||
if(!mob.check_move_cooldown())
|
||||
// We're still cooling down from the last move
|
||||
if(!my_mob.checkMoveCooldown())
|
||||
return
|
||||
|
||||
if(locate(/obj/effect/stop/, mob.loc))
|
||||
for(var/obj/effect/stop/S in mob.loc)
|
||||
if(S.victim == mob)
|
||||
return
|
||||
|
||||
if(mob.stat==DEAD && isliving(mob) && !mob.forbid_seeing_deadchat)
|
||||
mob.ghostize()
|
||||
// If dead and we try to move in our mob, it leaves our body
|
||||
if(my_mob.stat == DEAD && isliving(my_mob) && !my_mob.forbid_seeing_deadchat)
|
||||
my_mob.ghostize()
|
||||
return
|
||||
|
||||
// handle possible Eye movement
|
||||
if(mob.eyeobj)
|
||||
return mob.EyeMove(n,direct)
|
||||
// If we have an eyeobj, it moves instead
|
||||
if(my_mob.eyeobj)
|
||||
return my_mob.EyeMove(n,direct)
|
||||
|
||||
if(mob.transforming) return//This is sota the goto stop mobs from moving var
|
||||
// This is sota the goto stop mobs from moving var (for some reason)
|
||||
if(my_mob.transforming)
|
||||
return
|
||||
|
||||
if(isliving(mob))
|
||||
var/mob/living/L = mob
|
||||
if(isliving(my_mob))
|
||||
var/mob/living/L = my_mob
|
||||
if(L.incorporeal_move)//Move though walls
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
if(mob.client)
|
||||
if(mob.client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
||||
for(var/obj/item/item in mob.contents)
|
||||
if(item.zoom)
|
||||
item.zoom()
|
||||
break
|
||||
/*
|
||||
if(locate(/obj/item/weapon/gun/energy/sniperrifle, mob.contents)) // If mob moves while zoomed in with sniper rifle, unzoom them.
|
||||
var/obj/item/weapon/gun/energy/sniperrifle/s = locate() in mob
|
||||
if(s.zoom)
|
||||
s.zoom()
|
||||
if(locate(/obj/item/device/binoculars, mob.contents)) // If mob moves while zoomed in with binoculars, unzoom them.
|
||||
var/obj/item/device/binoculars/b = locate() in mob
|
||||
if(b.zoom)
|
||||
b.zoom()
|
||||
*/
|
||||
/* TODO observer unzoom
|
||||
if(view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
||||
for(var/obj/item/item in mob.contents)
|
||||
if(item.zoom)
|
||||
item.zoom()
|
||||
break
|
||||
*/
|
||||
|
||||
if(Process_Grab()) return
|
||||
|
||||
if(!mob.canmove)
|
||||
if(Process_Grab())
|
||||
return
|
||||
|
||||
//Relaymove could handle it
|
||||
if(mob.machine)
|
||||
var/result = mob.machine.relaymove(mob, direct)
|
||||
// Can't move
|
||||
if(!my_mob.canmove)
|
||||
return
|
||||
|
||||
// Relaymove could handle it
|
||||
if(my_mob.machine)
|
||||
var/result = my_mob.machine.relaymove(my_mob, direct)
|
||||
if(result)
|
||||
return result
|
||||
|
||||
if(!mob.lastarea)
|
||||
mob.lastarea = get_area(mob.loc)
|
||||
|
||||
if((istype(mob.loc, /turf/space)) || (mob.lastarea.has_gravity == 0))
|
||||
if(!mob.Process_Spacemove(0)) return 0
|
||||
|
||||
if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved
|
||||
var/atom/O = mob.loc
|
||||
return O.relaymove(mob, direct)
|
||||
|
||||
if(isturf(mob.loc))
|
||||
|
||||
if(mob.restrained())//Why being pulled while cuffed prevents you from moving
|
||||
for(var/mob/M in range(mob, 1))
|
||||
if(M.pulling == mob)
|
||||
if(!M.restrained() && M.stat == 0 && M.canmove && mob.Adjacent(M))
|
||||
to_chat(src, "<font color='blue'>You're restrained! You can't move!</font>")
|
||||
return 0
|
||||
else
|
||||
M.stop_pulling()
|
||||
|
||||
if(mob.pinned.len)
|
||||
to_chat(src, "<font color='blue'>You're pinned to a wall by [mob.pinned[1]]!</font>")
|
||||
// Can't control ourselves when drifting
|
||||
if(isspace(loc) || my_mob.lastarea?.has_gravity == 0)
|
||||
if(!my_mob.Process_Spacemove(0))
|
||||
return 0
|
||||
|
||||
mob.move_delay = world.time//set move delay
|
||||
// Inside an object, tell it we moved
|
||||
if(isobj(loc) || ismob(loc))
|
||||
return loc.relaymove(my_mob, direct)
|
||||
|
||||
switch(mob.m_intent)
|
||||
if("run")
|
||||
if(mob.drowsyness > 0)
|
||||
mob.move_delay += 6
|
||||
mob.move_delay += config.run_speed
|
||||
if("walk")
|
||||
mob.move_delay += config.walk_speed
|
||||
mob.move_delay += mob.movement_delay(n, direct)
|
||||
// Can't move unless you're in the world somewhere
|
||||
if(!isturf(loc))
|
||||
return
|
||||
|
||||
if(istype(mob.buckled, /obj/vehicle))
|
||||
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
|
||||
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
|
||||
mob.move_delay = world.time
|
||||
//drunk driving
|
||||
if(mob.confused && prob(20)) //vehicles tend to keep moving in the same direction
|
||||
direct = turn(direct, pick(90, -90))
|
||||
return mob.buckled.relaymove(mob,direct)
|
||||
|
||||
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
||||
if(istype(mob.loc, /turf/space))
|
||||
return // No wheelchair driving in space
|
||||
if(istype(mob.pulledby, /obj/structure/bed/chair/wheelchair))
|
||||
return mob.pulledby.relaymove(mob, direct)
|
||||
else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
if(ishuman(mob))
|
||||
var/mob/living/carbon/human/driver = mob
|
||||
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
|
||||
if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump()))
|
||||
return // No hands to drive your chair? Tough luck!
|
||||
//drunk wheelchair driving
|
||||
else if(mob.confused)
|
||||
switch(mob.m_intent)
|
||||
if("run")
|
||||
if(prob(50)) direct = turn(direct, pick(90, -90))
|
||||
if("walk")
|
||||
if(prob(25)) direct = turn(direct, pick(90, -90))
|
||||
mob.move_delay += 2
|
||||
return mob.buckled.relaymove(mob,direct)
|
||||
|
||||
//We are now going to move
|
||||
moving = 1
|
||||
//Something with pulling things
|
||||
if(locate(/obj/item/weapon/grab, mob))
|
||||
mob.move_delay = max(mob.move_delay, world.time + 7)
|
||||
var/list/L = mob.ret_grab()
|
||||
if(istype(L, /list))
|
||||
if(L.len == 2)
|
||||
L -= mob
|
||||
var/mob/M = L[1]
|
||||
if(M)
|
||||
if ((get_dist(mob, M) <= 1 || M.loc == mob.loc))
|
||||
var/turf/T = mob.loc
|
||||
. = ..()
|
||||
if (isturf(M.loc))
|
||||
var/diag = get_dir(mob, M)
|
||||
if ((diag - 1) & diag)
|
||||
else
|
||||
diag = null
|
||||
if ((get_dist(mob, M) > 1 || diag))
|
||||
step(M, get_dir(M.loc, T))
|
||||
// Why being pulled while cuffed prevents you from moving
|
||||
if(my_mob.restrained())
|
||||
for(var/mob/M in range(my_mob, 1))
|
||||
if(M.pulling == my_mob)
|
||||
if(!M.restrained() && M.stat == 0 && M.canmove && my_mob.Adjacent(M))
|
||||
to_chat(src, "<font color='blue'>You're restrained! You can't move!</font>")
|
||||
return 0
|
||||
else
|
||||
for(var/mob/M in L)
|
||||
M.other_mobs = 1
|
||||
if(mob != M)
|
||||
M.animate_movement = 3
|
||||
for(var/mob/M in L)
|
||||
spawn( 0 )
|
||||
step(M, direct)
|
||||
return
|
||||
spawn( 1 )
|
||||
M.other_mobs = null
|
||||
M.animate_movement = 2
|
||||
return
|
||||
M.stop_pulling()
|
||||
|
||||
else
|
||||
if(mob.confused)
|
||||
switch(mob.m_intent)
|
||||
if(my_mob.pinned.len)
|
||||
to_chat(src, "<font color='blue'>You're pinned to a wall by [my_mob.pinned[1]]!</font>")
|
||||
return 0
|
||||
|
||||
if(istype(my_mob.buckled, /obj/vehicle) || ismob(my_mob.buckled))
|
||||
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
|
||||
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
|
||||
my_mob.next_move = world.time
|
||||
//drunk driving
|
||||
if(my_mob.confused && prob(20)) //vehicles tend to keep moving in the same direction
|
||||
direct = turn(direct, pick(90, -90))
|
||||
if(ismob(my_mob.buckled))
|
||||
var/mob/M = my_mob.buckled
|
||||
if(M.next_move > my_mob.next_move) // Don't let piggyback riders move their mob IN ADDITION TO the mob moving
|
||||
return
|
||||
return my_mob.buckled.relaymove(my_mob,direct)
|
||||
|
||||
if(my_mob.pulledby || my_mob.buckled) // Wheelchair driving!
|
||||
if(isspace(loc))
|
||||
return // No wheelchair driving in space
|
||||
if(istype(my_mob.pulledby, /obj/structure/bed/chair/wheelchair))
|
||||
my_mob.setMoveCooldown(3)
|
||||
return my_mob.pulledby.relaymove(my_mob, direct)
|
||||
else if(istype(my_mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
if(ishuman(my_mob))
|
||||
var/mob/living/carbon/human/driver = my_mob
|
||||
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
|
||||
if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump()))
|
||||
return // No hands to drive your chair? Tough luck!
|
||||
//drunk wheelchair driving
|
||||
else if(my_mob.confused)
|
||||
switch(my_mob.m_intent)
|
||||
if("run")
|
||||
if(prob(75))
|
||||
if(prob(50))
|
||||
direct = turn(direct, pick(90, -90))
|
||||
n = get_step(mob, direct)
|
||||
if("walk")
|
||||
if(prob(25))
|
||||
direct = turn(direct, pick(90, -90))
|
||||
n = get_step(mob, direct)
|
||||
. = mob.SelfMove(n, direct)
|
||||
my_mob.setMoveCooldown(3)
|
||||
return my_mob.buckled.relaymove(my_mob,direct)
|
||||
|
||||
for (var/obj/item/weapon/grab/G in mob)
|
||||
if (G.state == GRAB_NECK)
|
||||
mob.set_dir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
for (var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
// We are now going to move
|
||||
moving = 1
|
||||
var/total_delay = my_mob.movement_delay(n, direct)
|
||||
var/pre_move_loc = loc
|
||||
|
||||
moving = 0
|
||||
// Confused direction randomization
|
||||
if(my_mob.confused)
|
||||
switch(my_mob.m_intent)
|
||||
if("run")
|
||||
if(prob(75))
|
||||
direct = turn(direct, pick(90, -90))
|
||||
n = get_step(my_mob, direct)
|
||||
if("walk")
|
||||
if(prob(25))
|
||||
direct = turn(direct, pick(90, -90))
|
||||
n = get_step(my_mob, direct)
|
||||
|
||||
total_delay = DS2NEARESTTICK(total_delay) //Rounded to the next tick in equivalent ds
|
||||
my_mob.setMoveCooldown(total_delay)
|
||||
. = my_mob.SelfMove(n, direct, total_delay)
|
||||
|
||||
return .
|
||||
// If we have a grab
|
||||
var/list/grablist = my_mob.ret_grab()
|
||||
if(grablist.len)
|
||||
grablist -= my_mob // Just in case we're in a circular grab chain
|
||||
|
||||
// It's just us and another person
|
||||
if(grablist.len == 1)
|
||||
var/mob/M = grablist[1]
|
||||
if(!my_mob.Adjacent(M)) //Oh no, we moved away
|
||||
M.Move(pre_move_loc, get_dir(M, pre_move_loc), total_delay) //Have them step towards where we were
|
||||
|
||||
// It's a grab chain
|
||||
else
|
||||
for(var/mob/M in grablist)
|
||||
my_mob.other_mobs = 1
|
||||
M.other_mobs = 1 //Has something to do with people being able or unable to pass a chain of mobs
|
||||
|
||||
//Ugly!
|
||||
spawn(0) //Step
|
||||
M.Move(pre_move_loc, get_dir(M, pre_move_loc), total_delay)
|
||||
spawn(1) //Unstep
|
||||
M.other_mobs = null
|
||||
spawn(1) //Unset
|
||||
my_mob.other_mobs = null
|
||||
|
||||
return
|
||||
|
||||
/mob/proc/SelfMove(turf/n, direct)
|
||||
return Move(n, direct)
|
||||
// Update all the grabs!
|
||||
for (var/obj/item/weapon/grab/G in my_mob)
|
||||
if (G.state == GRAB_NECK)
|
||||
mob.set_dir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
for (var/obj/item/weapon/grab/G in my_mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
// We're not in the middle of a move anymore
|
||||
moving = 0
|
||||
|
||||
/mob/proc/SelfMove(turf/n, direct, movetime)
|
||||
return Move(n, direct, movetime)
|
||||
|
||||
///Process_Incorpmove
|
||||
///Called by client/Move()
|
||||
|
||||
@@ -497,8 +497,6 @@
|
||||
if(!new_character)
|
||||
new_character = new(T)
|
||||
|
||||
new_character.lastarea = get_area(T)
|
||||
|
||||
if(ticker.random_players)
|
||||
new_character.gender = pick(MALE, FEMALE)
|
||||
client.prefs.real_name = random_name(new_character.gender)
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
A.forceMove(target)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.pulling)
|
||||
if(L.pulling && !L.pulling.anchored)
|
||||
L.pulling.forceMove(target)
|
||||
|
||||
/obj/structure/stairs/proc/upperStep(var/turf/T)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return
|
||||
if(perm && (target_permissions & perm))
|
||||
return
|
||||
if(!owner.canClick())
|
||||
if(!owner.checkClickCooldown())
|
||||
return
|
||||
owner.setClickCooldown(5) // Spam prevention, essentially.
|
||||
if(owner.a_intent == I_HELP && owner.is_preference_enabled(/datum/client_preference/safefiring))
|
||||
|
||||
@@ -42,8 +42,6 @@
|
||||
var/load_offset_y = 0 //pixel_y offset for item overlay
|
||||
var/mob_offset_y = 0 //pixel_y offset for mob overlay
|
||||
|
||||
var/datum/riding/riding_datum = null
|
||||
|
||||
//-------------------------------------------
|
||||
// Standard procs
|
||||
//-------------------------------------------
|
||||
@@ -66,54 +64,29 @@
|
||||
|
||||
/obj/vehicle/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
|
||||
. = ..(buckled_mob, force)
|
||||
buckled_mob.update_water()
|
||||
buckled_mob?.update_water()
|
||||
if(riding_datum)
|
||||
riding_datum.restore_position(buckled_mob)
|
||||
riding_datum.handle_vehicle_offsets() // So the person in back goes to the front.
|
||||
|
||||
/obj/vehicle/set_dir(newdir)
|
||||
..(newdir)
|
||||
if(riding_datum)
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
/obj/vehicle/Move(var/newloc, var/direction, var/movetime)
|
||||
if(world.time < l_move_time + move_delay) //This AND the riding datum move speed limit?
|
||||
return
|
||||
|
||||
//MOVEMENT
|
||||
/obj/vehicle/relaymove(mob/user, direction)
|
||||
if(riding_datum)
|
||||
riding_datum.handle_ride(user, direction)
|
||||
if(mechanical && on && powered && cell.charge < charge_use)
|
||||
turn_off()
|
||||
return
|
||||
|
||||
/obj/vehicle/Moved()
|
||||
. = ..()
|
||||
if(riding_datum)
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_offsets()
|
||||
|
||||
/obj/vehicle/Move()
|
||||
if(world.time > l_move_time + move_delay)
|
||||
var/old_loc = get_turf(src)
|
||||
if(mechanical && on && powered && cell.charge < charge_use)
|
||||
turn_off()
|
||||
if(mechanical && on && powered)
|
||||
cell.use(charge_use)
|
||||
|
||||
var/init_anc = anchored
|
||||
anchored = 0
|
||||
if(!..())
|
||||
anchored = init_anc
|
||||
return 0
|
||||
|
||||
set_dir(get_dir(old_loc, loc))
|
||||
anchored = init_anc
|
||||
|
||||
if(mechanical && on && powered)
|
||||
cell.use(charge_use)
|
||||
|
||||
//Dummy loads do not have to be moved as they are just an overlay
|
||||
//See load_object() proc in cargo_trains.dm for an example
|
||||
if(load && !istype(load, /datum/vehicle_dummy_load))
|
||||
load.forceMove(loc)
|
||||
load.set_dir(dir)
|
||||
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
//Dummy loads do not have to be moved as they are just an overlay
|
||||
//See load_object() proc in cargo_trains.dm for an example
|
||||
//Also mobs are buckled to the vehicle and get moved in atom/movable/Move's call to take care of that
|
||||
if(load && !(load in buckled_mobs) && !istype(load, /datum/vehicle_dummy_load))
|
||||
load.forceMove(loc)
|
||||
|
||||
/obj/vehicle/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/hand_labeler))
|
||||
|
||||
Reference in New Issue
Block a user