diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index c542d714ca6..7e791e6adda 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -12,7 +12,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
/obj/machinery/atmospherics
anchored = 1
layer = GAS_PIPE_HIDDEN_LAYER //under wires
- plane = FLOOR_PLANE
+ plane = FLOOR_PLANE
idle_power_usage = 0
active_power_usage = 0
power_channel = ENVIRON
@@ -66,7 +66,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
if(level == 2 || !T.intact)
plane = GAME_PLANE
else
- plane = FLOOR_PLANE
+ plane = FLOOR_PLANE
/obj/machinery/atmospherics/proc/update_pipe_image()
pipe_image = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) //the 20 puts it above Byond's darkness (not its opacity view)
@@ -258,7 +258,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
if(!direction || !(direction in cardinal)) //cant go this way.
return
- if(buckled_mob == user)
+ if(user in buckled_mobs)// fixes buckle ventcrawl edgecase fuck bug
return
var/obj/machinery/atmospherics/target_move = findConnecting(direction)
diff --git a/code/ATMOSPHERICS/pipes/pipe.dm b/code/ATMOSPHERICS/pipes/pipe.dm
index ec4f6bfd7ec..038180cdd7d 100644
--- a/code/ATMOSPHERICS/pipes/pipe.dm
+++ b/code/ATMOSPHERICS/pipes/pipe.dm
@@ -8,8 +8,8 @@
var/alert_pressure = 80*ONE_ATMOSPHERE //minimum pressure before check_pressure(...) should be called
//Buckling
- can_buckle = 1
- buckle_requires_restraints = 1
+ can_buckle = TRUE
+ buckle_requires_restraints = TRUE
buckle_lying = -1
/obj/machinery/atmospherics/pipe/New()
diff --git a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
index cb7ec277f95..1f40bdae665 100644
--- a/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
+++ b/code/ATMOSPHERICS/pipes/simple/pipe_simple_he.dm
@@ -10,7 +10,7 @@
thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT
color = "#404040"
- buckle_lying = 1
+ buckle_lying = TRUE
var/icon_temperature = T20C //stop small changes in temperature causing icon refresh
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/process_atmos()
@@ -50,10 +50,12 @@
animate(src, color = rgb(h_r, h_g, h_b), time = 20, easing = SINE_EASING)
//burn any mobs buckled based on temperature
- if(buckled_mob)
+ if(has_buckled_mobs())
var/heat_limit = 1000
if(pipe_air.temperature > heat_limit + 1)
- buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, "chest")
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.apply_damage(4 * log(pipe_air.temperature - heat_limit), BURN, "chest")
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/New()
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 8ce4d64911b..d49c0ee59eb 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -557,6 +557,7 @@ so as to remain in compliance with the most up-to-date laws."
/obj/screen/alert/restrained/buckled
name = "Buckled"
desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed."
+ icon_state = "buckled"
/obj/screen/alert/restrained/handcuffed
name = "Handcuffed"
@@ -570,6 +571,15 @@ so as to remain in compliance with the most up-to-date laws."
if(isliving(usr))
var/mob/living/L = usr
return L.resist()
+
+/obj/screen/alert/restrained/buckled/Click()
+ var/mob/living/L = usr
+ if(!istype(L) || !L.can_resist())
+ return
+ L.changeNext_move(CLICK_CD_RESIST)
+ if(L.last_special <= world.time)
+ return L.resist_buckle()
+
// PRIVATE = only edit, use, or override these if you're editing the system as a whole
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index bd06e0eb13d..65e188512d5 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -139,7 +139,7 @@
if(isliving(teleatom))
var/mob/living/L = teleatom
if(L.buckled)
- L.buckled.unbuckle_mob()
+ L.buckled.unbuckle_mob(L, force = TRUE)
destarea.Entered(teleatom)
diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm
index 70825f5195e..023939c2747 100644
--- a/code/datums/spells/area_teleport.dm
+++ b/code/datums/spells/area_teleport.dm
@@ -56,7 +56,7 @@
return
if(target && target.buckled)
- target.buckled.unbuckle_mob()
+ target.buckled.unbuckle_mob(target, force = TRUE)
var/list/tempL = L
var/attempt = null
diff --git a/code/datums/spells/devil.dm b/code/datums/spells/devil.dm
index 925b54d5e3c..12e2a44a8c1 100644
--- a/code/datums/spells/devil.dm
+++ b/code/datums/spells/devil.dm
@@ -131,14 +131,6 @@
playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1)
var/obj/effect/dummy/slaughter/s_holder = new(loc)
ExtinguishMob()
- if(buckled)
- buckled.unbuckle_mob(src,force=1)
- if(has_buckled_mobs())
- unbuckle_mob()
- if(pulledby)
- pulledby.stop_pulling()
- if(pulling)
- stop_pulling()
forceMove(s_holder)
holder = s_holder
notransform = FALSE
diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm
index 72f49ad5057..9f98a481dbf 100644
--- a/code/datums/weather/weather_types/floor_is_lava.dm
+++ b/code/datums/weather/weather_types/floor_is_lava.dm
@@ -26,8 +26,10 @@
/datum/weather/floor_is_lava/weather_act(mob/living/L)
if(issilicon(L))
return
+ if(istype(L.buckled, /obj/structure/bed))
+ return
for(var/obj/structure/O in L.loc)
- if(O.density || O.buckled_mob && istype(O, /obj/structure/bed))
+ if(O.density)
return
if(L.loc.density)
return
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index cb7bc3037b2..bfb2eb1d214 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -41,6 +41,7 @@
. = ..()
/atom/movable/Destroy()
+ unbuckle_all_mobs(force = TRUE)
if(loc)
loc.handle_atom_del(src)
for(var/atom/movable/AM in contents)
@@ -109,7 +110,7 @@
log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
return
- if(pulling.anchored)
+ if(pulling.anchored || pulling.move_resist > move_force)
stop_pulling()
return
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move.
@@ -123,6 +124,7 @@
if(force < (move_resist * MOVE_FORCE_PULL_RATIO))
return FALSE
return TRUE
+
// Used in shuttle movement and AI eye stuff.
// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
/atom/movable/proc/setLoc(var/T, var/teleported=0)
@@ -200,7 +202,7 @@
src.move_speed = world.time - src.l_move_time
src.l_move_time = world.time
- if(. && buckled_mob && !handle_buckled_mob_movement(loc, direct)) //movement failed due to buckled mob
+ if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct)) //movement failed due to buckled mob
. = 0
// Called after a successful Move(). By this point, we've already moved
@@ -270,8 +272,10 @@
/mob/living/forceMove(atom/destination)
if(buckled)
addtimer(CALLBACK(src, .proc/check_buckled), 1, TIMER_UNIQUE)
- if(buckled_mob)
- addtimer(CALLBACK(buckled_mob, .proc/check_buckled), 1, TIMER_UNIQUE)
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ addtimer(CALLBACK(buckled_mob, .proc/check_buckled), 1, TIMER_UNIQUE)
if(pulling)
addtimer(CALLBACK(src, .proc/check_pull), 1, TIMER_UNIQUE)
. = ..()
@@ -423,12 +427,14 @@
return TRUE
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
- if(!buckled_mob.Move(newloc, direct))
- loc = buckled_mob.loc
- last_move = buckled_mob.last_move
- inertia_dir = last_move
- buckled_mob.inertia_dir = last_move
- return 0
+ 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)
@@ -448,7 +454,7 @@
return FALSE
/atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5)
- if(buckled_mob == mover)
+ if(mover in buckled_mobs)
return 1
return ..()
diff --git a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
index 2c34503781e..1ea0539620a 100644
--- a/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
+++ b/code/game/gamemodes/miniantags/slaughter/bloodcrawl.dm
@@ -35,8 +35,6 @@
animation.dir = dir
ExtinguishMob()
- if(buckled)
- buckled.unbuckle_mob()
if(pulling && bloodcrawl == BLOODCRAWL_EAT)
if(istype(pulling, /mob/living/))
var/mob/living/victim = pulling
@@ -50,8 +48,9 @@
kidnapped = victim
stop_pulling()
flick("jaunt",animation)
- loc = holder
- holder = holder
+
+ src.holder = holder
+ forceMove(holder)
if(kidnapped)
to_chat(src, "You begin to feast on [kidnapped]. You can not move while you are doing this.")
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index 276f8d2eb1f..1671c4a03b0 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -45,14 +45,14 @@
if(M in view_or_range(range, user, "view"))
targets += M
-
+
if(!targets.len) //doesn't waste the spell
revert_cast(user)
return
perform(targets, user = user)
return
-
+
/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets, mob/user = usr)
for(var/mob/living/carbon/human/target in targets)
@@ -139,8 +139,6 @@
target.ExtinguishMob()
var/turf/T = get_turf(target)
target.forceMove(T) //to properly move the mob out of a potential container
- if(target.buckled)
- target.buckled.unbuckle_mob()
if(target.pulledby)
target.pulledby.stop_pulling()
target.stop_pulling()
@@ -543,7 +541,7 @@
to_chat(user, "You must stand next to an APC to drain it!")
charge_counter = charge_max
return
-
+
if(target_apc.cell?.charge == 0)
to_chat(user, "APC must have a power to drain!")
charge_counter = charge_max
diff --git a/code/game/gamemodes/vampire/vampire_powers.dm b/code/game/gamemodes/vampire/vampire_powers.dm
index 7e1a375f15d..7db238533be 100644
--- a/code/game/gamemodes/vampire/vampire_powers.dm
+++ b/code/game/gamemodes/vampire/vampire_powers.dm
@@ -424,8 +424,6 @@
var/jaunt_duration = 50 //in deciseconds
/obj/effect/proc_holder/spell/vampire/self/jaunt/cast(list/targets, mob/user = usr)
- if(user.buckled)
- user.buckled.unbuckle_mob()
spawn(0)
var/mob/living/U = user
var/originalloc = get_turf(user.loc)
@@ -439,8 +437,6 @@
animation.layer = 5
animation.master = holder
U.ExtinguishMob()
- if(user.buckled)
- user.buckled.unbuckle_mob()
flick("liquify", animation)
user.forceMove(holder)
user.client.eye = holder
@@ -513,8 +509,6 @@
perform(turfs, user = user)
/obj/effect/proc_holder/spell/vampire/shadowstep/cast(list/targets, mob/user = usr)
- if(usr.buckled)
- user.buckled.unbuckle_mob()
spawn(0)
var/turf/picked = pick(targets)
@@ -522,8 +516,6 @@
return
var/mob/living/U = user
U.ExtinguishMob()
- if(user.buckled)
- user.buckled.unbuckle_mob()
var/atom/movable/overlay/animation = new /atom/movable/overlay(get_turf(user))
animation.name = user.name
animation.density = 0
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index af73a13f27c..de15a26264a 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -12,7 +12,7 @@
var/strapped = 0.0
var/obj/machinery/computer/operating/computer = null
- buckle_lying = 90
+ buckle_lying = -1
var/no_icon_updates = 0 //set this to 1 if you don't want the icons ever changing
var/list/injected_reagents = list()
var/reagent_target_amount = 1
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 8f542a2ea3c..56618164bbb 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -554,7 +554,10 @@ var/list/turret_icons
if(istype(A, /obj/vehicle))
var/obj/vehicle/T = A
- assess_and_assign(T.buckled_mob, targets, secondarytargets)
+ if(T.has_buckled_mobs())
+ for(var/m in T.buckled_mobs)
+ var/mob/living/buckled_mob = m
+ assess_and_assign(buckled_mob, targets, secondarytargets)
if(isliving(A))
var/mob/living/C = A
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index a89be1c211e..72652958e7c 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -1,80 +1,103 @@
-
-
/atom/movable
- var/can_buckle = 0
- var/buckle_lying = -1 //bed-like behaviour, forces mob.lying = buckle_lying if != -1 //except -1 actually means "rotate 90 degrees to the left" as it is used by 1*buckle_lying.
+ var/can_buckle = FALSE
+ var/buckle_lying = -1 //bed-like behaviour, forces mob.lying = buckle_lying if != -1
var/buckle_requires_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
- var/mob/living/buckled_mob = null
+ var/list/buckled_mobs = null //list()
var/buckle_offset = 0
-
+ var/max_buckled_mobs = 1
+ var/buckle_prevents_pull = FALSE
//Interaction
/atom/movable/attack_hand(mob/living/user)
. = ..()
- if(can_buckle && buckled_mob)
- return user_unbuckle_mob(user)
-
-/atom/movable/attack_robot(mob/living/user)
- . = ..()
- if(can_buckle && buckled_mob && Adjacent(user)) // attack_robot is called on all ranges, so the Adjacent check is needed
- return user_unbuckle_mob(user)
+ if(can_buckle && has_buckled_mobs())
+ if(buckled_mobs.len > 1)
+ var/unbuckled = input(user, "Who do you wish to unbuckle?", "Unbuckle Who?") as null|mob in buckled_mobs
+ if(user_unbuckle_mob(unbuckled,user))
+ return 1
+ else
+ if(user_unbuckle_mob(buckled_mobs[1], user))
+ return 1
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
- if(can_buckle && istype(M))
- return user_buckle_mob(M, user)
-
-
-//Cleanup
-/atom/movable/Destroy()
- . = ..()
- unbuckle_mob()
+ if(can_buckle && istype(M) && istype(user))
+ if(user_buckle_mob(M, user))
+ return 1
/atom/movable/proc/has_buckled_mobs()
- if(buckled_mob)
+ if(!buckled_mobs)
+ return FALSE
+ if(buckled_mobs.len)
return TRUE
- return FALSE
//procs that handle the actual buckling and unbuckling
-/atom/movable/proc/buckle_mob(mob/living/M, force = 0)
- if((!can_buckle && !force)|| !istype(M) || (M.loc != loc) || M.buckled || M.buckled_mob || buckled_mob || (buckle_requires_restraints && !M.restrained()) || M == src)
- return 0
+/atom/movable/proc/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
+ if(!buckled_mobs)
+ buckled_mobs = list()
- if((isslime(M) || isAI(M)) && !force)
+ if(!istype(M))
+ return FALSE
+
+ if(check_loc && M.loc != loc)
+ return FALSE
+
+ if((!can_buckle && !force) || M.buckled || (buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src)
+ return FALSE
+ M.buckling = src
+ if(!M.can_buckle() && !force)
if(M == usr)
- to_chat(M, "You are unable to buckle yourself to the [src]!")
+ to_chat(M, "You are unable to buckle yourself to [src]!")
else
- to_chat(usr, "You are unable to buckle [M] to the [src]!")
- return 0
+ to_chat(usr, "You are unable to buckle [M] to [src]!")
+ M.buckling = null
+ return FALSE
+ if(M.pulledby)
+ if(buckle_prevents_pull)
+ M.pulledby.stop_pulling()
+
+ if(!check_loc && M.loc != loc)
+ M.forceMove(loc)
+
+ M.buckling = null
M.buckled = src
- M.dir = dir
- buckled_mob = M
+ M.setDir(dir)
+ buckled_mobs |= M
M.update_canmove()
+ M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
post_buckle_mob(M)
- M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
- return 1
-/obj/buckle_mob(mob/living/M, force = 0)
+ SEND_SIGNAL(src, COMSIG_MOVABLE_BUCKLE, M, force)
+ return TRUE
+
+/obj/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
. = ..()
if(.)
if(burn_state == ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect
M.adjust_fire_stacks(1)
M.IgniteMob()
-/atom/movable/proc/unbuckle_mob(force = FALSE)
- if(buckled_mob && buckled_mob.buckled == src && (buckled_mob.can_unbuckle(usr) || force))
+/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
+ if(istype(buckled_mob) && buckled_mob.buckled == src && (buckled_mob.can_unbuckle() || force))
. = buckled_mob
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob.clear_alert("buckled")
- buckled_mob = null
+ buckled_mobs -= buckled_mob
+ SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
post_unbuckle_mob(.)
-//Handle any extras after buckling/unbuckling
-//Called on buckle_mob() and unbuckle_mob()
+/atom/movable/proc/unbuckle_all_mobs(force = FALSE)
+ if(!has_buckled_mobs())
+ return
+ for(var/m in buckled_mobs)
+ unbuckle_mob(m, force)
+
+//Handle any extras after buckling
+//Called on buckle_mob()
/atom/movable/proc/post_buckle_mob(mob/living/M)
return
@@ -83,36 +106,31 @@
return
//Wrapper procs that handle sanity and user feedback
-/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user)
- if(!in_range(user, src) || user.stat || user.restrained())
- return
+/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
+ if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored)
+ return FALSE
add_fingerprint(user)
-
- if(buckle_mob(M))
+ . = buckle_mob(M, check_loc = check_loc)
+ if(.)
if(M == user)
- M.visible_message(\
- "[M] buckles themself to [src].",\
+ M.visible_message("[M] buckles [M.p_them()]self to [src].",\
"You buckle yourself to [src].",\
"You hear metal clanking.")
else
- M.visible_message(\
- "[user] buckles [M] to [src]!",\
+ M.visible_message("[user] buckles [M] to [src]!",\
"[user] buckles you to [src]!",\
"You hear metal clanking.")
- return 1
-/atom/movable/proc/user_unbuckle_mob(mob/user)
- var/mob/living/M = unbuckle_mob()
+/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
+ var/mob/living/M = unbuckle_mob(buckled_mob)
if(M)
if(M != user)
- M.visible_message(\
- "[user] unbuckles [M] from [src].",\
+ M.visible_message("[user] unbuckles [M] from [src].",\
"[user] unbuckles you from [src].",\
"You hear metal clanking.")
else
- M.visible_message(\
- "[M] unbuckles themselves from [src].",\
+ M.visible_message("[M] unbuckles [M.p_them()]self from [src].",\
"You unbuckle yourself from [src].",\
"You hear metal clanking.")
add_fingerprint(user)
@@ -120,4 +138,4 @@
/mob/living/proc/check_buckled()
if(buckled && !(buckled in loc))
- buckled.unbuckle_mob(src, force=1)
+ buckled.unbuckle_mob(src, force = TRUE)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm
index 314077db68e..cef14d28796 100644
--- a/code/game/objects/items/weapons/implants/implantchair.dm
+++ b/code/game/objects/items/weapons/implants/implantchair.dm
@@ -78,7 +78,7 @@
if(!ismob(G.affecting))
return
var/mob/M = G.affecting
- if(M.buckled_mob)
+ if(M.has_buckled_mobs())
to_chat(usr, "[M] will not fit into [src] because [M.p_they()] [M.p_have()] a slime latched onto [M.p_their()] head.")
return
if(put_mob(M))
diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm
index ccee6c18feb..696d54cc3bf 100644
--- a/code/game/objects/items/weapons/scrolls.dm
+++ b/code/game/objects/items/weapons/scrolls.dm
@@ -51,7 +51,7 @@
if(!A)
return
-
+
var/area/thearea = teleportlocs[A]
if(user.stat || user.restrained())
@@ -83,7 +83,7 @@
return
if(user && user.buckled)
- user.buckled.unbuckle_mob()
+ user.buckled.unbuckle_mob(user, force = TRUE)
var/list/tempL = L
var/attempt = null
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 4a2dadffcc7..965819dd436 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -69,7 +69,7 @@
continue
if(istype(O, /obj/structure/bed)) //This is only necessary because of rollerbeds and swivel chairs.
var/obj/structure/bed/B = O
- if(B.buckled_mob)
+ if(B.has_buckled_mobs())
continue
O.forceMove(src)
itemcount++
@@ -161,7 +161,7 @@
if(C.use(15))
to_chat(user, "You rig [src].")
rigged = TRUE
- else
+ else
to_chat(user, "You need atleast 15 wires to rig [src]!")
return
else if(istype(W, /obj/item/radio/electropack))
diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm
index dcbc7c017bb..b8f0d6c5cb5 100644
--- a/code/game/objects/structures/electricchair.dm
+++ b/code/game/objects/structures/electricchair.dm
@@ -71,11 +71,12 @@
flick("echair_shock", src)
do_sparks(12, 1, src)
visible_message("The electric chair went off!", "You hear a deep sharp shock!")
- if(buckled_mob)
- buckled_mob.electrocute_act(110, src, 1)
- to_chat(buckled_mob, "You feel a deep shock course through your body!")
- spawn(1)
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
buckled_mob.electrocute_act(110, src, 1)
+ to_chat(buckled_mob, "You feel a deep shock course through your body!")
+ spawn(1)
+ buckled_mob.electrocute_act(110, src, 1)
A.power_light = light
- A.updateicon()
- return
+ A.updateicon()
\ No newline at end of file
diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm
index 30429e2ca2c..6d32aec248e 100644
--- a/code/game/objects/structures/guillotine.dm
+++ b/code/game/objects/structures/guillotine.dm
@@ -28,6 +28,10 @@
var/force_clap = FALSE //You WILL clap if I want you to
var/current_action = 0 // What's currently happening to the guillotine
+/obj/structure/guillotine/Initialize(mapload)
+ LAZYINITLIST(buckled_mobs)
+ return ..()
+
/obj/structure/guillotine/examine(mob/user)
..()
@@ -84,7 +88,7 @@
else
current_action = 0
else
- unbuckle_mob()
+ unbuckle_all_mobs()
else
blade_status = GUILLOTINE_BLADE_MOVING
icon_state = "guillotine_drop"
@@ -97,7 +101,7 @@
/obj/structure/guillotine/proc/drop_blade(mob/user)
if(has_buckled_mobs() && blade_sharpness)
- var/mob/living/carbon/human/H = buckled_mob
+ var/mob/living/carbon/human/H = buckled_mobs[1]
if(!H)
blade_status = GUILLOTINE_BLADE_DROPPED
@@ -116,7 +120,7 @@
head.droplimb()
add_attack_logs(user, H, "beheaded with [src]")
H.regenerate_icons()
- unbuckle_mob()
+ unbuckle_all_mobs()
kill_count += 1
var/blood_overlay = "bloody"
@@ -219,7 +223,7 @@
else
return ..()
-/obj/structure/guillotine/buckle_mob(mob/living/M, force = 0)
+/obj/structure/guillotine/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!anchored)
to_chat(usr, "The [src] needs to be wrenched to the floor!")
return FALSE
@@ -232,15 +236,19 @@
to_chat(usr, "You need to raise the blade before buckling someone in!")
return FALSE
- if(..())
- M.pixel_y -= GUILLOTINE_HEAD_OFFSET // Offset their body so it looks like they're in the guillotine
- M.layer += GUILLOTINE_LAYER_DIFF
+ return ..(M, force, FALSE)
-/obj/structure/guillotine/unbuckle_mob(force = 0)
- if(buckled_mob)
- buckled_mob.pixel_y += GUILLOTINE_HEAD_OFFSET // Move their body back
- buckled_mob.layer -= GUILLOTINE_LAYER_DIFF
- . = ..()
+/obj/structure/guillotine/post_buckle_mob(mob/living/M)
+ if(!ishuman(M))
+ return
+ M.pixel_y += -GUILLOTINE_HEAD_OFFSET // Offset their body so it looks like they're in the guillotine
+ M.layer += GUILLOTINE_LAYER_DIFF
+ ..()
+
+/obj/structure/guillotine/post_unbuckle_mob(mob/living/M)
+ M.pixel_y -= -GUILLOTINE_HEAD_OFFSET // Move their body back
+ M.layer -= GUILLOTINE_LAYER_DIFF
+ ..()
#undef GUILLOTINE_BLADE_MAX_SHARP
#undef GUILLOTINE_DECAP_MIN_SHARP
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 05f7f326898..e38af14ecc4 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -35,14 +35,20 @@
desc = "A spike for collecting meat from animals."
density = 1
anchored = 1
- buckle_lying = 0
- can_buckle = 1
+ buckle_lying = FALSE
+ can_buckle = TRUE
+//ATTACK HAND IGNORING PARENT RETURN VALUE
+/obj/structure/kitchenspike/attack_hand(mob/user)
+ if(has_buckled_mobs())
+ for(var/mob/living/L in buckled_mobs)
+ user_unbuckle_mob(L, user)
+ else
+ ..()
-
-/obj/structure/kitchenspike/attackby(obj/item/grab/G as obj, mob/user as mob)
+/obj/structure/kitchenspike/attackby(obj/item/grab/G, mob/user)
if(istype(G, /obj/item/crowbar))
- if(!buckled_mob)
+ if(!has_buckled_mobs())
playsound(loc, G.usesound, 100, 1)
if(do_after(user, 20 * G.toolspeed, target = src))
to_chat(user, "You pry the spikes out of the frame.")
@@ -55,11 +61,11 @@
return
if(!istype(G, /obj/item/grab) || !G.affecting)
return
- if(buckled_mob)
+ if(has_buckled_mobs())
to_chat(user, "The spike already has something on it, finish collecting its meat first!")
else
if(isliving(G.affecting))
- if(!buckled_mob)
+ if(!has_buckled_mobs())
if(do_mob(user, src, 120))
if(spike(G.affecting))
G.affecting.visible_message("[user] slams [G.affecting] onto the meat spike!", "[user] slams you onto the meat spike!", "You hear a squishy wet noise.")
@@ -68,56 +74,50 @@
to_chat(user, "You can't use that on the spike!")
return
-/obj/structure/kitchenspike/proc/spike(var/mob/living/victim)
+/obj/structure/kitchenspike/proc/spike(mob/living/victim)
if(!istype(victim))
- return
+ return FALSE
-
- if(buckled_mob) //to prevent spam/queing up attacks
- return 0
+ if(has_buckled_mobs()) //to prevent spam/queing up attacks
+ return FALSE
if(victim.buckled)
- return 0
- var/mob/living/H = victim
+ return FALSE
playsound(loc, 'sound/effects/splat.ogg', 25, 1)
- H.forceMove(loc)
- H.emote("scream")
- if(ishuman(H))
+ victim.forceMove(drop_location())
+ victim.emote("scream")
+ if(ishuman(victim))
+ var/mob/living/carbon/human/H = victim
H.add_splatter_floor()
- H.adjustBruteLoss(30)
- H.buckled = src
- H.dir = 2
- buckled_mob = H
- var/matrix/m180 = matrix()
+ victim.adjustBruteLoss(30)
+ victim.setDir(2)
+ buckle_mob(victim, force = TRUE)
+ var/matrix/m180 = matrix(victim.transform)
m180.Turn(180)
- animate(H, transform = m180, time = 3)
- H.pixel_y = H.get_standard_pixel_y_offset(180)
- return 1
-
+ animate(victim, transform = m180, time = 3)
+ victim.pixel_y = victim.get_standard_pixel_y_offset(180)
+ return TRUE
/obj/structure/kitchenspike/user_buckle_mob(mob/living/M, mob/living/user) //Don't want them getting put on the rack other than by spiking
return
-/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/carbon/human/user)
- if(buckled_mob && buckled_mob.buckled == src)
+/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/buckled_mob, mob/living/carbon/human/user)
+ if(buckled_mob)
var/mob/living/M = buckled_mob
if(M != user)
- M.visible_message(\
- "[user.name] tries to pull [M.name] free of the [src]!",\
- "[user.name] is trying to pull you off of [src], opening up fresh wounds!",\
+ M.visible_message("[user] tries to pull [M] free of [src]!",\
+ "[user] is trying to pull you off [src], opening up fresh wounds!",\
"You hear a squishy wet noise.")
if(!do_after(user, 300, target = src))
if(M && M.buckled)
- M.visible_message(\
- "[user.name] fails to free [M.name]!",\
- "[user.name] fails to pull you off of [src].")
+ M.visible_message("[user] fails to free [M]!",\
+ "[user] fails to pull you off of [src].")
return
else
- M.visible_message(\
- "[M.name] struggles to break free from the [src]!",\
- "You struggle to break free from the [src], exacerbating your wounds! (Stay still for two minutes.)",\
+ M.visible_message("[M] struggles to break free from [src]!",\
+ "You struggle to break free from [src], exacerbating your wounds! (Stay still for two minutes.)",\
"You hear a wet squishing noise..")
M.adjustBruteLoss(30)
if(!do_after(M, 1200, target = src))
@@ -126,13 +126,21 @@
return
if(!M.buckled)
return
- var/matrix/m180 = matrix(M.transform)
- m180.Turn(180)
- animate(M, transform = m180, time = 3)
- M.pixel_y = M.get_standard_pixel_y_offset(180)
- M.adjustBruteLoss(30)
- visible_message("[M] falls free of the [src]!")
- unbuckle_mob()
- M.emote("scream")
- M.AdjustWeakened(10)
+ release_mob(M)
+/obj/structure/kitchenspike/proc/release_mob(mob/living/M)
+ var/matrix/m180 = matrix(M.transform)
+ m180.Turn(180)
+ animate(M, transform = m180, time = 3)
+ M.pixel_y = M.get_standard_pixel_y_offset(180)
+ M.adjustBruteLoss(30)
+ src.visible_message(text("[M] falls free of [src]!"))
+ unbuckle_mob(M, force = TRUE)
+ M.emote("scream")
+ M.AdjustWeakened(10)
+
+/obj/structure/kitchenspike/Destroy()
+ if(has_buckled_mobs())
+ for(var/mob/living/L in buckled_mobs)
+ release_mob(L)
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index 91e2d552859..c175dca567b 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -7,12 +7,6 @@
anchored = 1
layer = 4
armor = list(melee = 100, bullet = 80, laser = 80, energy = 100, bomb = 50, bio = 100, rad = 100)
- var/list/mobs_can_pass = list(
- /mob/living/carbon/slime,
- /mob/living/simple_animal/mouse,
- /mob/living/silicon/robot/drone,
- /mob/living/simple_animal/bot/mulebot
- )
var/state = PLASTIC_FLAPS_NORMAL
/obj/structure/plasticflaps/examine(mob/user)
@@ -66,43 +60,40 @@
return prob(60)
var/obj/structure/bed/B = A
- if(istype(A, /obj/structure/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass
- return 0
+ if(istype(A, /obj/structure/bed) && (B.has_buckled_mobs() || B.density))//if it's a bed/chair and is dense or someone is buckled, it will not pass
+ return FALSE
if(istype(A, /obj/structure/closet/cardboard))
var/obj/structure/closet/cardboard/C = A
if(C.move_delay)
- return 0
+ return FALSE
- if(istype(A, /obj/vehicle)) //no vehicles
- return 0
-
- var/mob/living/M = A
- if(istype(M))
- if(M.lying)
- return ..()
- for(var/mob_type in mobs_can_pass)
- if(istype(A, mob_type))
- return ..()
- if(istype(A, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- if(H.dna.species.is_small)
- return ..()
- return 0
+ if(ismecha(A))
+ return FALSE
+ else if(isliving(A)) // You Shall Not Pass!
+ var/mob/living/M = A
+ if(isbot(A)) //Bots understand the secrets
+ return TRUE
+ if(M.buckled && istype(M.buckled, /mob/living/simple_animal/bot/mulebot)) // mulebot passenger gets a free pass.
+ return TRUE
+ if(!M.lying && !M.ventcrawler && M.mob_size != MOB_SIZE_TINY) //If your not laying down, or a ventcrawler or a small creature, no pass.
+ return FALSE
return ..()
/obj/structure/plasticflaps/CanAStarPass(ID, to_dir, caller)
- if(istype(caller, /mob/living))
- for(var/mob_type in mobs_can_pass)
- if(istype(caller, mob_type))
- return 1
+ if(isliving(caller))
+ if(isbot(caller))
+ return TRUE
var/mob/living/M = caller
- if(!M.ventcrawler && M.mob_size > MOB_SIZE_SMALL)
- return 0
- return 1
+ if(!M.ventcrawler && M.mob_size != MOB_SIZE_TINY)
+ return FALSE
+ var/atom/movable/M = caller
+ if(M && M.pulling)
+ return CanAStarPass(ID, to_dir, M.pulling)
+ return TRUE //diseases, stings, etc can pass
/obj/structure/plasticflaps/ex_act(severity)
switch(severity)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index 33fe66c0f08..d3ee6c0bece 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -14,68 +14,67 @@
return ..()
/obj/structure/bed/nest/user_unbuckle_mob(mob/living/user)
- if(buckled_mob && buckled_mob.buckled == src)
- var/mob/living/M = buckled_mob
+ if(has_buckled_mobs())
+ for(var/buck in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore
+ var/mob/living/M = buck
- if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
- unbuckle_mob()
+ if(user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
+ unbuckle_mob(M)
+ add_fingerprint(user)
+ return
+
+ if(M != user)
+ M.visible_message("[user.name] pulls [M.name] free from the sticky nest!",\
+ "[user.name] pulls you free from the gelatinous resin.",\
+ "You hear squelching...")
+ else
+ M.visible_message("[M.name] struggles to break free from the gelatinous resin!",\
+ "You struggle to break free from the gelatinous resin... (Stay still for two minutes.)",\
+ "You hear squelching...")
+ if(!do_after(M, 1200, target = src))
+ if(M && M.buckled)
+ to_chat(M, "You fail to escape \the [src]!")
+ return
+ if(!M.buckled)
+ return
+ M.visible_message("[M.name] breaks free from the gelatinous resin!",\
+ "You break free from the gelatinous resin!",\
+ "You hear squelching...")
+
+ unbuckle_mob(M)
add_fingerprint(user)
- return
-
- if(M != user)
- M.visible_message(\
- "[user.name] pulls [M.name] free from the sticky nest!",\
- "[user.name] pulls you free from the gelatinous resin.",\
- "You hear squelching...")
-
- else
- buckled_mob.visible_message(\
- "[buckled_mob.name] struggles to break free of the gelatinous resin...",\
- "You struggle to break free from the gelatinous resin... (This will take around 2 minutes and you need to stay still)",\
- "You hear squelching...")
- if(!do_after(M, 1200, target = src))
- if(M && M.buckled)
- to_chat(M, "You fail to escape \the [src]!")
- return
- if(!M.buckled)
- return
- M.visible_message(\
- "[M.name] breaks free from the gelatinous resin!",\
- "You break free from the gelatinous resin!",\
- "You hear squelching...")
- unbuckle_mob()
- add_fingerprint(user)
/obj/structure/bed/nest/user_buckle_mob(mob/living/M, mob/living/user)
- if( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) )
+ if (!ismob(M) || (get_dist(src, user) > 1) || (M.loc != loc) || user.incapacitated() || M.buckled)
return
if(M.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
return
+
if(!user.get_int_organ(/obj/item/organ/internal/xenos/plasmavessel))
return
- unbuckle_mob()
+ if(has_buckled_mobs())
+ unbuckle_all_mobs()
if(buckle_mob(M))
- M.visible_message(\
- "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\
+ M.visible_message("[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\
"[user.name] drenches you in a foul-smelling resin, trapping you in [src]!",\
"You hear squelching...")
/obj/structure/bed/nest/post_buckle_mob(mob/living/M)
- if(M == buckled_mob)
- M.pixel_y = 0
- M.pixel_x = initial(M.pixel_x) + 2
- M.layer = MOB_LAYER - 0.3
- overlays += nest_overlay
- else
- M.pixel_x = M.get_standard_pixel_x_offset(M.lying)
- M.pixel_y = M.get_standard_pixel_y_offset(M.lying)
- M.layer = initial(M.layer)
- overlays -= nest_overlay
+ M.pixel_y = 0
+ M.pixel_x = initial(M.pixel_x) + 2
+ M.layer = BELOW_MOB_LAYER
+ add_overlay(nest_overlay)
+
+/obj/structure/bed/nest/post_unbuckle_mob(mob/living/M)
+ M.pixel_x = M.get_standard_pixel_x_offset(M.lying)
+ M.pixel_y = M.get_standard_pixel_y_offset(M.lying)
+ M.layer = initial(M.layer)
+ cut_overlay(nest_overlay)
/obj/structure/bed/nest/attackby(obj/item/W as obj, mob/user as mob, params)
user.changeNext_move(CLICK_CD_MELEE)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index adbeffd600d..0802c212560 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -29,8 +29,6 @@
desc = "For prime comfort during psychiatric evaluations."
icon_state = "psychbed"
buildstackamount = 5
- can_buckle = TRUE
- buckle_lying = TRUE
/obj/structure/bed/alien
name = "resting contraption"
@@ -66,20 +64,23 @@
anchored = FALSE
comfort = 1
-/obj/structure/bed/roller/attackby(obj/item/W as obj, mob/user as mob, params)
+/obj/structure/bed/roller/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/roller_holder))
- if(buckled_mob)
- user_unbuckle_mob(user)
+ if(has_buckled_mobs())
+ if(buckled_mobs.len > 1)
+ unbuckle_all_mobs()
+ user.visible_message("[user] unbuckles all creatures from [src].")
+ else
+ user_unbuckle_mob(buckled_mobs[1], user)
else
user.visible_message("[user] collapses \the [name].", "You collapse \the [name].")
new/obj/item/roller(get_turf(src))
qdel(src)
/obj/structure/bed/roller/post_buckle_mob(mob/living/M)
- if(M == buckled_mob)
- density = TRUE
- icon_state = "up"
- M.pixel_y = initial(M.pixel_y)
+ density = TRUE
+ icon_state = "up"
+ M.pixel_y = initial(M.pixel_y)
/obj/structure/bed/roller/post_unbuckle_mob(mob/living/M)
density = FALSE
@@ -112,7 +113,7 @@
if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src)))
if(!ishuman(usr))
return
- if(buckled_mob)
+ if(has_buckled_mobs())
return 0
usr.visible_message("[usr] collapses \the [name].", "You collapse \the [name].")
new/obj/item/roller(get_turf(src))
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 8192e39b85d..cdb502a695c 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -78,19 +78,20 @@
qdel(src)
/obj/structure/chair/attack_tk(mob/user as mob)
- if(buckled_mob)
+ if(!anchored || has_buckled_mobs() || !isturf(user.loc))
..()
else
rotate()
- return
-/obj/structure/chair/proc/handle_rotation(direction) //making this into a seperate proc so office chairs can call it on Move()
+/obj/structure/chair/proc/handle_rotation(direction)
handle_layer()
- if(buckled_mob)
- buckled_mob.dir = dir
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(direction)
/obj/structure/chair/proc/handle_layer()
- if(buckled_mob && dir == NORTH)
+ if(has_buckled_mobs() && dir == NORTH)
layer = ABOVE_MOB_LAYER
else
layer = OBJ_LAYER
@@ -229,24 +230,20 @@
/obj/structure/chair/office/Bump(atom/A)
..()
- if(!buckled_mob)
+ if(!has_buckled_mobs())
return
if(propelled)
- var/mob/living/occupant = buckled_mob
- unbuckle_mob()
- occupant.throw_at(A, 3, propelled)
- occupant.apply_effect(6, STUN, 0)
- occupant.apply_effect(6, WEAKEN, 0)
- occupant.apply_effect(6, STUTTER, 0)
- playsound(src.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
- if(istype(A, /mob/living))
- var/mob/living/victim = A
- victim.apply_effect(6, STUN, 0)
- victim.apply_effect(6, WEAKEN, 0)
- victim.apply_effect(6, STUTTER, 0)
- victim.take_organ_damage(10)
- occupant.visible_message("[occupant] crashed into \the [A]!")
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ unbuckle_mob(buckled_mob)
+ buckled_mob.throw_at(A, 3, propelled)
+ buckled_mob.apply_effect(6, STUN, 0)
+ buckled_mob.apply_effect(6, WEAKEN, 0)
+ buckled_mob.apply_effect(6, STUTTER, 0)
+ buckled_mob.take_organ_damage(10)
+ playsound(loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
+ buckled_mob.visible_message("[buckled_mob] crashed into [A]!")
/obj/structure/chair/office/light
icon_state = "officechair_white"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index e4e15d191e5..a837e632692 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -11,8 +11,10 @@
overlays = null
var/image/O = image(icon = icon, icon_state = "[icon_state]_overlay", layer = FLY_LAYER, dir = src.dir)
overlays += O
- if(buckled_mob)
- buckled_mob.dir = dir
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(dir)
/obj/structure/chair/wheelchair/relaymove(mob/user, direction)
if(propelled)
@@ -27,7 +29,8 @@
var/calculated_move_delay
calculated_move_delay += 2 //wheelchairs are not infact sport bikes
- if(buckled_mob)
+ if(has_buckled_mobs())
+ var/mob/living/buckled_mob = buckled_mobs[1]
if(buckled_mob.incapacitated())
return 0
@@ -69,15 +72,15 @@
/obj/structure/chair/wheelchair/Bump(atom/A)
..()
- if(!buckled_mob)
+ if(!has_buckled_mobs())
return
-
+ var/mob/living/buckled_mob = buckled_mobs[1]
if(istype(A, /obj/machinery/door))
A.Bumped(buckled_mob)
if(propelled)
var/mob/living/occupant = buckled_mob
- unbuckle_mob()
+ unbuckle_mob(occupant)
occupant.throw_at(A, 3, propelled)
@@ -114,9 +117,10 @@
var/calculated_move_delay
calculated_move_delay = 0 //bikes are infact sport bikes
- if(buckled_mob)
+ if(has_buckled_mobs())
+ var/mob/living/buckled_mob = buckled_mobs[1]
if(buckled_mob.incapacitated())
- unbuckle_mob() //if the rider is incapacitated, unbuckle them (they can't balance so they fall off)
+ unbuckle_mob(buckled_mob) //if the rider is incapacitated, unbuckle them (they can't balance so they fall off)
return 0
var/mob/living/thedriver = user
@@ -151,4 +155,4 @@
. = 0
else
- . = 1
+ . = 1
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor/lava.dm b/code/game/turfs/simulated/floor/lava.dm
index b2c29a5ee01..e35f9e86c68 100644
--- a/code/game/turfs/simulated/floor/lava.dm
+++ b/code/game/turfs/simulated/floor/lava.dm
@@ -84,17 +84,20 @@
var/mob/living/L = thing
if(L.flying)
continue //YOU'RE FLYING OVER IT
+ var/buckle_check = L.buckling
+ if(!buckle_check)
+ buckle_check = L.buckled
+ if(isobj(buckle_check))
+ var/obj/O = buckle_check
+ if(O.resistance_flags & LAVA_PROOF)
+ continue
+ else if(isliving(buckle_check))
+ var/mob/living/live = buckle_check
+ if("lava" in live.weather_immunities)
+ continue
+
if("lava" in L.weather_immunities)
continue
- if(L.buckled)
- if(isobj(L.buckled))
- var/obj/O = L.buckled
- if(O.resistance_flags & LAVA_PROOF)
- continue
- if(isliving(L.buckled)) //Goliath riding
- var/mob/living/live = L.buckled
- if("lava" in live.weather_immunities)
- continue
L.adjustFireLoss(20)
if(L) //mobs turning into object corpses could get deleted here.
diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm
index d6e72f1505c..699cbf5f803 100644
--- a/code/modules/awaymissions/gateway.dm
+++ b/code/modules/awaymissions/gateway.dm
@@ -248,23 +248,32 @@ var/obj/machinery/gateway/centerstation/the_gateway = null
toggleoff()
-/obj/machinery/gateway/centeraway/Bumped(atom/movable/M as mob|obj)
+/obj/machinery/gateway/centeraway/Bumped(atom/movable/AM)
if(!ready)
return
if(!active)
return
- if(istype(M, /mob/living/carbon))
- if(exilecheck(M))
+ if(!stationgate || QDELETED(stationgate))
+ return
+ if(isliving(AM))
+ if(exilecheck(AM))
return
- if(istype(M, /obj))
- if(M.can_buckle && M.has_buckled_mobs())
- if(exilecheck(M.buckled_mob))
+ else
+ for(var/mob/living/L in AM.contents)
+ if(exilecheck(L))
+ atom_say("Rejecting [AM]: Exile implant detected in contained lifeform.")
return
- for(var/mob/living/carbon/F in M)
- if(exilecheck(F))
+ if(AM.has_buckled_mobs())
+ for(var/mob/living/L in AM.buckled_mobs)
+ if(exilecheck(L))
+ atom_say("Rejecting [AM]: Exile implant detected in close proximity lifeform.")
return
- M.forceMove(get_step(stationgate.loc, SOUTH))
- M.dir = SOUTH
+ AM.forceMove(get_step(stationgate.loc, SOUTH))
+ AM.setDir(SOUTH)
+ if(ismob(AM))
+ var/mob/M = AM
+ if(M.client)
+ M.client.move_delay = max(world.time + 5, M.client.move_delay)
/obj/machinery/gateway/centeraway/proc/exilecheck(var/mob/living/carbon/M)
for(var/obj/item/implant/exile/E in M)//Checking that there is an exile implant in the contents
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index 7fce23b9e4c..36c3a9de5c5 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -2050,7 +2050,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if("ghost_radio")
toggles ^= CHAT_GHOSTRADIO
-
+
if("ghost_pda")
toggles ^= CHAT_GHOSTPDA
@@ -2104,7 +2104,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
"High" = PARALLAX_HIGH,
"Insane" = PARALLAX_INSANE
)
- parallax = parallax_styles[input(user, "Pick a parallax style", "Parallax Style") as null|anything in parallax_styles]
+ parallax = parallax_styles[input(user, "Pick a parallax style", "Parallax Style") as null|anything in parallax_styles]
if(parent && parent.mob && parent.mob.hud_used)
parent.mob.hud_used.update_parallax_pref()
@@ -2189,12 +2189,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
var/obj/item/organ/external/l_foot = character.get_organ("l_foot")
var/obj/item/organ/external/r_foot = character.get_organ("r_foot")
if(!l_foot && !r_foot)
- var/obj/structure/chair/wheelchair/W = new /obj/structure/chair/wheelchair (character.loc)
- character.buckled = W
- character.update_canmove()
- W.dir = character.dir
- W.buckled_mob = character
- W.add_fingerprint(character)
+ var/obj/structure/chair/wheelchair/W = new /obj/structure/chair/wheelchair(character.loc)
+ W.buckle_mob(character, TRUE)
character.underwear = underwear
character.undershirt = undershirt
diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm
index fdd871a3448..700c88008e0 100644
--- a/code/modules/clothing/spacesuits/chronosuit.dm
+++ b/code/modules/clothing/spacesuits/chronosuit.dm
@@ -80,9 +80,7 @@
phaseanim.layer = FLY_LAYER
phaseanim.master = user
user.ExtinguishMob()
- if(user.buckled)
- user.buckled.unbuckle_mob()
- user.loc = holder
+ user.forceMove(holder)
flick("chronophase", phaseanim)
spawn(7)
if(user)
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index 1ab7fe58c2b..f654f052ab7 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -323,8 +323,6 @@
var/turf/picked = pick(turfs)
if(!isturf(picked))
return
- if(H.buckled)
- H.buckled.unbuckle_mob()
H.forceMove(picked)
return 1
return 0
diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm
index aaed5f5672c..0bd4060c831 100644
--- a/code/modules/crafting/craft.dm
+++ b/code/modules/crafting/craft.dm
@@ -268,7 +268,8 @@
/datum/personal_crafting/proc/close(mob/user)
var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main")
- ui.close()
+ if(ui)
+ ui.close()
/datum/personal_crafting/ui_data(mob/user)
var/list/data = list()
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index 58579a893e2..c7330151b00 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -455,8 +455,8 @@
master = null
mutations.Cut()
set_opacity(0)
- if(buckled_mob)
- unbuckle_mob()
+ if(has_buckled_mobs())
+ unbuckle_all_mobs(force = TRUE)
return ..()
/obj/structure/spacevine/proc/add_mutation(datum/spacevine_mutation/mutation)
@@ -639,7 +639,7 @@
SM.on_grow(src)
/obj/structure/spacevine/proc/entangle_mob()
- if(!buckled_mob && prob(25))
+ if(!has_buckled_mobs() && prob(25))
for(var/mob/living/V in loc)
entangle(V)
if(has_buckled_mobs())
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index 156a426e202..c045b8a5b88 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -108,7 +108,7 @@
icon_state = "bonfire"
density = FALSE
anchored = TRUE
- buckle_lying = 0
+ buckle_lying = FALSE
var/burning = 0
var/fire_stack_strength = 5
@@ -119,8 +119,8 @@
if(istype(W, /obj/item/stack/rods) && !can_buckle)
var/obj/item/stack/rods/R = W
R.use(1)
- can_buckle = 1
- buckle_requires_restraints = 1
+ can_buckle = TRUE
+ buckle_requires_restraints = TRUE
to_chat(user, "You add a rod to [src].")
var/image/U = image(icon='icons/obj/hydroponics/equipment.dmi',icon_state="bonfire_rod",pixel_y=16)
underlays += U
@@ -191,11 +191,10 @@
set_light(0)
STOP_PROCESSING(SSobj, src)
-/obj/structure/bonfire/buckle_mob(mob/living/M, force = 0)
+/obj/structure/bonfire/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(..())
M.pixel_y += 13
-/obj/structure/bonfire/unbuckle_mob(force=0)
- if(buckled_mob)
- buckled_mob.pixel_y -= 13
- . = ..()
+/obj/structure/bonfire/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
+ if(..())
+ buckled_mob.pixel_y -= 13
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 5ca13a616c1..de52fe192da 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -398,12 +398,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(ventcrawler)
ventcrawlerlocal = ventcrawler
- if(!ventcrawler)
- if(ishuman(src))
- var/mob/living/carbon/human/H = src
- ventcrawlerlocal = H.dna.species.ventcrawler
-
- if(!ventcrawlerlocal) return
+ if(!ventcrawlerlocal)
+ return
if(stat)
to_chat(src, "You must be conscious to do this!")
@@ -413,8 +409,11 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
to_chat(src, "You can't vent crawl while you're stunned!")
return
- if(buckled_mob)
- to_chat(src, "You can't vent crawl with [buckled_mob] on you!")
+ if(has_buckled_mobs())
+ to_chat(src, "You can't vent crawl with other creatures on you!")
+ return
+ if(buckled)
+ to_chat(src, "You can't vent crawl while buckled!")
return
if(ishuman(src))
var/mob/living/carbon/human/H = src
@@ -450,6 +449,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(!do_after(src, 45, target = src))
return
+ if(has_buckled_mobs())
+ to_chat(src, "You can't vent crawl with other creatures on you!")
+ return
+
if(buckled)
to_chat(src, "You cannot crawl into a vent while buckled to something!")
return
@@ -626,7 +629,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
else if(I == handcuffed)
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
- buckled.unbuckle_mob()
+ buckled.unbuckle_mob(src)
update_handcuffed()
else if(I == legcuffed)
legcuffed = null
@@ -934,7 +937,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
var/obj/item/W = handcuffed
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
- buckled.unbuckle_mob()
+ buckled.unbuckle_mob(src)
update_handcuffed()
if(client)
client.screen -= W
diff --git a/code/modules/mob/living/carbon/human/login.dm b/code/modules/mob/living/carbon/human/login.dm
index 2964166e68f..4cc542ae1ad 100644
--- a/code/modules/mob/living/carbon/human/login.dm
+++ b/code/modules/mob/living/carbon/human/login.dm
@@ -3,7 +3,7 @@
overlays -= image('icons/effects/effects.dmi', icon_state = "zzz_glow")
..()
- if(dna.species && dna.species.ventcrawler)
+ if(ventcrawler)
to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.")
update_pipe_vision()
return
diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm
index 10b23dcfc82..d3ce27a4704 100644
--- a/code/modules/mob/living/carbon/human/species/_species.dm
+++ b/code/modules/mob/living/carbon/human/species/_species.dm
@@ -61,7 +61,7 @@
var/punchstunthreshold = 9 //damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
var/list/default_genes = list()
- var/ventcrawler = 0 //Determines if the mob can go through the vents.
+ var/ventcrawler = VENTCRAWLER_NONE //Determines if the mob can go through the vents.
var/has_fine_manipulation = 1 // Can use small items.
var/list/allowed_consumed_mobs = list() //If a species can consume mobs, put the type of mobs it can consume here.
@@ -280,10 +280,12 @@
H.unEquip(thing)
if(H.hud_used)
H.hud_used.update_locked_slots()
+ H.ventcrawler = ventcrawler
/datum/species/proc/on_species_loss(mob/living/carbon/human/H)
if(H.butcher_results) //clear it out so we don't butcher a actual human.
H.butcher_results = null
+ H.ventcrawler = initial(H.ventcrawler)
/datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors.
return
diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm
index e8451d61cbb..4b816f7ab5d 100644
--- a/code/modules/mob/living/carbon/human/species/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/golem.dm
@@ -404,18 +404,11 @@
name = "Plastic Golem"
prefix = "Plastic"
special_names = null
+ ventcrawler = VENTCRAWLER_NUDE
golem_colour = rgb(255, 255, 255)
skinned_type = /obj/item/stack/sheet/plastic
info_text = "As a Plastic Golem, you are capable of ventcrawling if you're naked."
-/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species)
- . = ..()
- C.ventcrawler = VENTCRAWLER_NUDE
-
-/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
- . = ..()
- C.ventcrawler = initial(C.ventcrawler)
-
//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death.
/datum/species/golem/sand
name = "Sand Golem"
@@ -533,7 +526,7 @@
if(!isturf(picked))
return
if(H.buckled)
- H.buckled.unbuckle_mob()
+ H.buckled.unbuckle_mob(H, force = TRUE)
do_teleport(H, picked)
return TRUE
@@ -617,7 +610,7 @@
if(!isturf(picked))
return
if(H.buckled)
- H.buckled.unbuckle_mob()
+ H.buckled.unbuckle_mob(H, force = TRUE)
do_teleport(H, picked)
last_teleport = world.time
UpdateButtonIcon() //action icon looks unavailable
diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm
index 4bfad7b15c9..a0980256718 100644
--- a/code/modules/mob/living/carbon/human/species/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/monkey.dm
@@ -17,7 +17,7 @@
can_craft = FALSE
is_small = 1
has_fine_manipulation = 0
- ventcrawler = 1
+ ventcrawler = VENTCRAWLER_NUDE
show_ssd = 0
eyes = "blank_eyes"
death_message = "lets out a faint chimper as it collapses and stops moving..."
diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm
index 89e6393cd09..afd358ab99f 100644
--- a/code/modules/mob/living/carbon/slime/slime.dm
+++ b/code/modules/mob/living/carbon/slime/slime.dm
@@ -72,6 +72,16 @@
X.stored_slimes -= src
return ..()
+/mob/living/carbon/slime/can_unbuckle()
+ return FALSE
+
+/mob/living/carbon/slime/can_buckle()
+ return FALSE
+
+/mob/living/carbon/slime/get_mob_buckling_height(mob/seat)
+ if(..())
+ return 3
+
/mob/living/carbon/slime/regenerate_icons()
icon_state = "[colour] [is_adult ? "adult" : "baby"] slime"
overlays.len = 0
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index df222fadf47..f659b4198d1 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -446,12 +446,7 @@
on_fire = 0
suiciding = 0
if(buckled) //Unbuckle the mob and clear the alerts.
- buckled.buckled_mob = null
- buckled = null
- anchored = initial(anchored)
- update_canmove()
- clear_alert("buckled")
- post_buckle_mob(src)
+ buckled.unbuckle_mob(src, force = TRUE)
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -637,11 +632,14 @@
START RESIST PROCS
*///////////////////////
+/mob/living/can_resist()
+ return !((next_move > world.time) || incapacitated(ignore_restraints = TRUE, ignore_lying = TRUE))
+
/mob/living/verb/resist()
set name = "Resist"
set category = "IC"
- if(!isliving(src) || next_move > world.time || stat || weakened || stunned || paralysis)
+ if(!can_resist())
return
changeNext_move(CLICK_CD_RESIST)
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index f624b7ab33d..e9cfac7ae0a 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -216,6 +216,9 @@
fire_stacks += L.fire_stacks
IgniteMob()
+/mob/living/can_be_pulled(user, grab_state, force)
+ return ..() && !(buckled && buckled.buckle_prevents_pull)
+
/mob/living/water_act(volume, temperature, source, method = TOUCH)
. = ..()
adjust_fire_stacks(-(volume * 0.2))
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 023c03cd00a..9605ae186a7 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -1173,6 +1173,9 @@ var/list/ai_verbs_default = list(
to_chat(src, "You have been downloaded to a mobile storage device. Remote device connection severed.")
to_chat(user, "Transfer successful: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.")
+/mob/living/silicon/ai/can_buckle()
+ return FALSE
+
// Pass lying down or getting up to our pet human, if we're in a rig.
/mob/living/silicon/ai/lay_down()
set name = "Rest"
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index d9f1aac2757..d2e52c39197 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -124,6 +124,11 @@
securityActive2 = null
return ..()
+/mob/living/silicon/pai/can_unbuckle()
+ return FALSE
+
+/mob/living/silicon/pai/can_buckle()
+ return FALSE
/mob/living/silicon/pai/movement_delay()
. = ..()
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 1db149418c7..ef087c29b6d 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -17,7 +17,7 @@
maxHealth = 50
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
a_intent = INTENT_HARM //No swapping
- buckle_lying = 0
+ buckle_lying = FALSE
mob_size = MOB_SIZE_LARGE
radio_channel = "Supply"
@@ -372,7 +372,7 @@
if(isobj(AM))
var/obj/O = AM
- if(O.buckled_mob || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it.
+ if(O.has_buckled_mobs() || (locate(/mob) in AM)) //can't load non crates objects with mobs buckled to it or inside it.
buzz(SIGH)
return
@@ -398,19 +398,11 @@
return FALSE
/mob/living/simple_animal/bot/mulebot/post_buckle_mob(mob/living/M)
- if(M == buckled_mob) //post buckling
- M.pixel_y = initial(M.pixel_y) + 9
- if(M.layer < layer)
- M.layer = layer + 0.1
-
- else //post unbuckling
- reset_buckled_mob(M)
+ M.pixel_y = initial(M.pixel_y) + 9
+ if(M.layer < layer)
+ M.layer = layer + 0.01
/mob/living/simple_animal/bot/mulebot/post_unbuckle_mob(mob/living/M)
- . = ..()
- reset_buckled_mob(M)
-
-/mob/living/simple_animal/bot/mulebot/proc/reset_buckled_mob(mob/living/M)
load = null
M.layer = initial(M.layer)
M.pixel_y = initial(M.pixel_y)
@@ -429,12 +421,13 @@
if(ismob(load))
var/mob/M = load
M.reset_perspective(null)
- unbuckle_mob()
+ unbuckle_all_mobs()
if(load)
load.forceMove(loc)
load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer)
+ load.plane = initial(load.plane)
if(dirn)
var/turf/T = loc
var/turf/newT = get_step(T,dirn)
@@ -453,6 +446,7 @@
AM.forceMove(loc)
AM.layer = initial(AM.layer)
AM.pixel_y = initial(AM.pixel_y)
+ AM.plane = initial(AM.plane)
if(ismob(AM))
var/mob/M = AM
M.reset_perspective(null)
diff --git a/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm
index 244edaeedec..c3939e41395 100644
--- a/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm
+++ b/code/modules/mob/living/simple_animal/hostile/floorcluwne.dm
@@ -313,7 +313,7 @@
if(T.density)
forceMove(H.loc)
if(H.buckled)
- H.buckled.unbuckle_mob()
+ H.buckled.unbuckle_mob(H, force = TRUE)
manifested = TRUE
Manifest()
to_chat(H, "You feel the floor closing in on your feet!")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index c2d16069146..4e8da45a155 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -17,7 +17,7 @@
qdel(tkgrabbed_objects[I])
tkgrabbed_objects = null
if(buckled)
- buckled.unbuckle_mob()
+ buckled.unbuckle_mob(src, force = TRUE)
if(viewing_alternate_appearances)
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
AA.viewers -= src
@@ -1192,31 +1192,52 @@ var/list/slot_equipment_priority = list( \
/mob/proc/handle_ventcrawl()
return // Only living mobs can ventcrawl
-//You can buckle on mobs if you're next to them since most are dense
-/mob/buckle_mob(mob/living/M, force = 0)
+/**
+ * Buckle to another mob
+ *
+ * You can buckle on mobs if you're next to them since most are dense
+ *
+ * Turns you to face the other mob too
+ */
+/mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(M.buckled)
return 0
var/turf/T = get_turf(src)
if(M.loc != T)
var/old_density = density
- density = 0
+ density = FALSE
var/can_step = step_towards(M, T)
density = old_density
if(!can_step)
return 0
return ..()
-//Default buckling shift visual for mobs
+///Call back post buckle to a mob to offset your visual height
/mob/post_buckle_mob(mob/living/M)
- if(M == buckled_mob) //post buckling
- M.pixel_y = initial(M.pixel_y) + 9
- if(M.layer < layer)
- M.layer = layer + 0.1
- else //post unbuckling
- M.layer = initial(M.layer)
- M.pixel_y = initial(M.pixel_y)
+ var/height = M.get_mob_buckling_height(src)
+ M.pixel_y = initial(M.pixel_y) + height
+ if(M.layer < layer)
+ M.layer = layer + 0.1
-/mob/proc/can_unbuckle(mob/user)
+///Call back post unbuckle from a mob, (reset your visual height here)
+/mob/post_unbuckle_mob(mob/living/M)
+ M.layer = initial(M.layer)
+ M.pixel_y = initial(M.pixel_y)
+
+///returns the height in pixel the mob should have when buckled to another mob.
+/mob/proc/get_mob_buckling_height(mob/seat)
+ if(isliving(seat))
+ var/mob/living/L = seat
+ if(L.mob_size <= MOB_SIZE_SMALL) //being on top of a small mob doesn't put you very high.
+ return 0
+ return 9
+
+///can the mob be buckled to something by default?
+/mob/proc/can_buckle()
+ return 1
+
+///can the mob be unbuckled from something by default?
+/mob/proc/can_unbuckle()
return 1
@@ -1307,6 +1328,10 @@ var/list/slot_equipment_priority = list( \
.["Gib"] = "?_src_=vars;gib=[UID()]"
+///Can this mob resist (default FALSE)
+/mob/proc/can_resist()
+ return FALSE //overridden in living.dm
+
/mob/proc/spin(spintime, speed)
set waitfor = 0
var/D = dir
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index b378705becb..c4d4ef24ed6 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -74,7 +74,11 @@
var/a_intent = INTENT_HELP//Living
var/m_intent = MOVE_INTENT_RUN//Living
var/lastKnownIP = null
+ /// movable atoms buckled to this mob
var/atom/movable/buckled = null//Living
+ /// movable atom we are buckled to
+ var/atom/movable/buckling
+
var/obj/item/l_hand = null//Living
var/obj/item/r_hand = null//Living
var/obj/item/back = null//Human/Monkey
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 7f78f58eb72..c45ff96df34 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -8,13 +8,13 @@
if(mover.checkpass(PASSMOB))
return 1
if(buckled == mover)
- return 1
+ return TRUE
if(ismob(mover))
var/mob/moving_mob = mover
if((other_mobs && moving_mob.other_mobs))
- return 1
- if(mover == buckled_mob)
- return 1
+ return TRUE
+ if(mover in buckled_mobs)
+ return TRUE
return (!mover.density || !density || lying)
@@ -362,10 +362,14 @@
/mob/proc/Move_Pulled(atom/A)
if(!canmove || restrained() || !pulling)
return
- if(pulling.anchored)
- return
- if(!pulling.Adjacent(src))
+ if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
+ stop_pulling()
return
+ if(isliving(pulling))
+ var/mob/living/L = pulling
+ if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it
+ stop_pulling()
+ return
if(A == loc && pulling.density)
return
if(!Process_Spacemove(get_dir(pulling.loc, A)))
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 2889a68c75b..785c03b13a1 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -92,17 +92,17 @@
potion_action.target = src
potion_action.Grant(user)
actions += potion_action
-
+
if(hotkey_help)
hotkey_help.target = src
hotkey_help.Grant(user)
actions += hotkey_help
- RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl)
- RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt)
- RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift)
- RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift)
- RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl)
+ RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL, .proc/XenoSlimeClickCtrl)
+ RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT, .proc/XenoSlimeClickAlt)
+ RegisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT, .proc/XenoSlimeClickShift)
+ RegisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT, .proc/XenoTurfClickShift)
+ RegisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL, .proc/XenoTurfClickCtrl)
RegisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL, .proc/XenoMonkeyClickCtrl)
if(!connected_recycler)
@@ -112,12 +112,12 @@
connected_recycler.connected += src
/obj/machinery/computer/camera_advanced/xenobio/remove_eye_control(mob/living/user)
- UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL)
- UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT)
- UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT)
- UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT)
- UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL)
- UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL)
+ UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_CTRL)
+ UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_ALT)
+ UnregisterSignal(user, COMSIG_XENO_SLIME_CLICK_SHIFT)
+ UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_SHIFT)
+ UnregisterSignal(user, COMSIG_XENO_TURF_CLICK_CTRL)
+ UnregisterSignal(user, COMSIG_XENO_MONKEY_CLICK_CTRL)
..()
/obj/machinery/computer/camera_advanced/xenobio/attack_hand(mob/user)
@@ -197,7 +197,7 @@
break
if(!S.ckey)
if(S.buckled)
- S.buckled.unbuckle_mob()
+ S.buckled.unbuckle_mob(S, force = TRUE)
S.Feedstop()
S.visible_message("[S] vanishes in a flash of light!")
S.forceMove(X)
@@ -240,7 +240,7 @@
var/mob/camera/aiEye/remote/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
var/obj/machinery/monkey_recycler/recycler = X.connected_recycler
-
+
if(!recycler)
to_chat(owner, "There is no connected monkey recycler. Use a multitool to link one.")
return
@@ -335,8 +335,9 @@
..()
//Pick up monkey
-/mob/living/carbon/monkey/CtrlClick(mob/user)
- SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src)
+/mob/living/carbon/human/CtrlClick(mob/user)
+ if(issmall(src))
+ SEND_SIGNAL(user, COMSIG_XENO_MONKEY_CLICK_CTRL, src)
..()
// Scans slime
@@ -379,7 +380,7 @@
return
if(!S.ckey)
if(S.buckled)
- S.buckled.unbuckle_mob()
+ S.buckled.unbuckle_mob(S, force = TRUE)
S.Feedstop()
S.visible_message("[S] vanishes in a flash of light!")
S.forceMove(X)
@@ -419,7 +420,7 @@
to_chat(user, "[X] now has [X.monkeys] monkeys left.")
//Pick up monkey
-/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/monkey/M)
+/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/human/M)
if(!cameranet.checkTurfVis(M.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
diff --git a/code/modules/ruins/lavalandruin_code/fountain_hall.dm b/code/modules/ruins/lavalandruin_code/fountain_hall.dm
index 3de758ac0c9..75e2b8d9aa3 100644
--- a/code/modules/ruins/lavalandruin_code/fountain_hall.dm
+++ b/code/modules/ruins/lavalandruin_code/fountain_hall.dm
@@ -12,7 +12,7 @@
return
if(!has_buckled_mobs())
return
- var/mob/living/L = buckled_mob
+ var/mob/living/L = locate() in buckled_mobs
if(!L)
return
to_chat(user, "You attempt to sacrifice [L] by invoking the sacrificial ritual.")
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index 8c96837e9d5..783f8203857 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -594,7 +594,7 @@
if(ismob(AM))
var/mob/M = AM
if(M.buckled)
- M.buckled.unbuckle_mob(M, 1)
+ M.buckled.unbuckle_mob(M, force = TRUE)
if(isliving(AM))
var/mob/living/L = AM
L.stop_pulling()
diff --git a/code/modules/vehicle/ambulance.dm b/code/modules/vehicle/ambulance.dm
index 102b8895bf6..f10f9d9769c 100644
--- a/code/modules/vehicle/ambulance.dm
+++ b/code/modules/vehicle/ambulance.dm
@@ -58,8 +58,8 @@
AA.Remove(M)
/obj/vehicle/ambulance/post_unbuckle_mob(mob/living/M)
- . = ..()
AA.Remove(M)
+ return ..()
/obj/item/key/ambulance
name = "ambulance key"
@@ -69,20 +69,22 @@
/obj/vehicle/ambulance/handle_vehicle_offsets()
..()
- if(buckled_mob)
- switch(buckled_mob.dir)
- if(SOUTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = 7
- if(WEST)
- buckled_mob.pixel_x = 13
- buckled_mob.pixel_y = 7
- if(NORTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = 4
- if(EAST)
- buckled_mob.pixel_x = -13
- buckled_mob.pixel_y = 7
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ switch(buckled_mob.dir)
+ if(SOUTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = 7
+ if(WEST)
+ buckled_mob.pixel_x = 13
+ buckled_mob.pixel_y = 7
+ if(NORTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = 4
+ if(EAST)
+ buckled_mob.pixel_x = -13
+ buckled_mob.pixel_y = 7
/obj/vehicle/ambulance/Move(newloc, Dir)
var/oldloc = loc
@@ -92,8 +94,10 @@
if(bed && get_dist(oldloc, loc) <= 2)
bed.Move(oldloc)
bed.dir = Dir
- if(bed.buckled_mob)
- bed.buckled_mob.dir = Dir
+ if(bed.has_buckled_mobs())
+ for(var/m in bed.buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(Dir)
/obj/structure/bed/amb_trolley
name = "ambulance train trolley"
diff --git a/code/modules/vehicle/atv.dm b/code/modules/vehicle/atv.dm
index a67310c8874..a78791fddea 100644
--- a/code/modules/vehicle/atv.dm
+++ b/code/modules/vehicle/atv.dm
@@ -16,10 +16,13 @@
atvcover.layer = MOB_LAYER + 0.1
/obj/vehicle/atv/post_buckle_mob(mob/living/M)
- if(buckled_mob)
- overlays += atvcover
- else
- overlays -= atvcover
+ add_overlay(atvcover)
+ return ..()
+
+/obj/vehicle/atv/post_unbuckle_mob(mob/living/M)
+ if(!has_buckled_mobs())
+ cut_overlay(atvcover)
+ return ..()
/obj/vehicle/atv/handle_vehicle_layer()
if(dir == SOUTH)
diff --git a/code/modules/vehicle/janicart.dm b/code/modules/vehicle/janicart.dm
index 8ee2d71443a..0f4382c92d1 100644
--- a/code/modules/vehicle/janicart.dm
+++ b/code/modules/vehicle/janicart.dm
@@ -10,20 +10,22 @@
/obj/vehicle/janicart/handle_vehicle_offsets()
..()
- if(buckled_mob)
- switch(buckled_mob.dir)
- if(NORTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = 4
- if(EAST)
- buckled_mob.pixel_x = -12
- buckled_mob.pixel_y = 7
- if(SOUTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = 7
- if(WEST)
- buckled_mob.pixel_x = 12
- buckled_mob.pixel_y = 7
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ switch(buckled_mob.dir)
+ if(NORTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = 4
+ if(EAST)
+ buckled_mob.pixel_x = -12
+ buckled_mob.pixel_y = 7
+ if(SOUTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = 7
+ if(WEST)
+ buckled_mob.pixel_x = 12
+ buckled_mob.pixel_y = 7
/obj/item/key/janitor
diff --git a/code/modules/vehicle/motorcycle.dm b/code/modules/vehicle/motorcycle.dm
index 3bcf98f2164..a79f8e3fa12 100644
--- a/code/modules/vehicle/motorcycle.dm
+++ b/code/modules/vehicle/motorcycle.dm
@@ -16,11 +16,14 @@
bikecover.layer = MOB_LAYER + 0.1
-obj/vehicle/motorcycle/post_buckle_mob(mob/living/M)
- if(buckled_mob)
- overlays += bikecover
- else
- overlays -= bikecover
+/obj/vehicle/motorcycle/post_buckle_mob(mob/living/M)
+ add_overlay(bikecover)
+ return ..()
+
+/obj/vehicle/motorcycle/post_unbuckle_mob(mob/living/M)
+ if(!has_buckled_mobs())
+ cut_overlay(bikecover)
+ return ..()
/obj/vehicle/motorcycle/handle_vehicle_layer()
diff --git a/code/modules/vehicle/speedbike.dm b/code/modules/vehicle/speedbike.dm
index ac57e65b2e6..e1efe63bcbd 100644
--- a/code/modules/vehicle/speedbike.dm
+++ b/code/modules/vehicle/speedbike.dm
@@ -15,7 +15,7 @@
overlays += overlay
/obj/vehicle/space/speedbike/Move(newloc,move_dir)
- if(buckled_mob)
+ if(has_buckled_mobs())
new /obj/effect/temp_visual/dir_setting/speedbike_trail(loc)
. = ..()
@@ -29,21 +29,23 @@
pixel_y = 0
/obj/vehicle/space/speedbike/handle_vehicle_offsets()
- if(buckled_mob)
- buckled_mob.dir = dir
- switch(dir)
- if(NORTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = -8
- if(SOUTH)
- buckled_mob.pixel_x = 0
- buckled_mob.pixel_y = 4
- if(EAST)
- buckled_mob.pixel_x = -10
- buckled_mob.pixel_y = 5
- if(WEST)
- buckled_mob.pixel_x = 10
- buckled_mob.pixel_y = 5
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(dir)
+ switch(dir)
+ if(NORTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = -8
+ if(SOUTH)
+ buckled_mob.pixel_x = 0
+ buckled_mob.pixel_y = 4
+ if(EAST)
+ buckled_mob.pixel_x = -10
+ buckled_mob.pixel_y = 5
+ if(WEST)
+ buckled_mob.pixel_x = 10
+ buckled_mob.pixel_y = 5
/obj/vehicle/space/speedbike/red
icon_state = "speedbike_red"
diff --git a/code/modules/vehicle/sportscar.dm b/code/modules/vehicle/sportscar.dm
index 04ba5bdd2f5..f52f4b77a92 100644
--- a/code/modules/vehicle/sportscar.dm
+++ b/code/modules/vehicle/sportscar.dm
@@ -15,29 +15,33 @@
carcover = image("icons/vehicles/sportscar.dmi", "sportscar_cover")
carcover.layer = MOB_LAYER + 0.1
-
/obj/vehicle/car/post_buckle_mob(mob/living/M)
- if(buckled_mob)
- overlays += carcover
- else
- overlays -= carcover
+ add_overlay(carcover)
+ return ..()
+
+/obj/vehicle/car/post_unbuckle_mob(mob/living/M)
+ if(!has_buckled_mobs())
+ cut_overlay(carcover)
+ return ..()
/obj/vehicle/car/handle_vehicle_offsets()
..()
- if(buckled_mob)
- switch(buckled_mob.dir)
- if(NORTH)
- buckled_mob.pixel_x = 2
- buckled_mob.pixel_y = 20
- if(EAST)
- buckled_mob.pixel_x = 20
- buckled_mob.pixel_y = 23
- if(SOUTH)
- buckled_mob.pixel_x = 20
- buckled_mob.pixel_y = 27
- if(WEST)
- buckled_mob.pixel_x = 34
- buckled_mob.pixel_y = 10
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ switch(buckled_mob.dir)
+ if(NORTH)
+ buckled_mob.pixel_x = 2
+ buckled_mob.pixel_y = 20
+ if(EAST)
+ buckled_mob.pixel_x = 20
+ buckled_mob.pixel_y = 23
+ if(SOUTH)
+ buckled_mob.pixel_x = 20
+ buckled_mob.pixel_y = 27
+ if(WEST)
+ buckled_mob.pixel_x = 34
+ buckled_mob.pixel_y = 10
/obj/vehicle/car/handle_vehicle_layer()
diff --git a/code/modules/vehicle/vehicle.dm b/code/modules/vehicle/vehicle.dm
index fc2ea3b4600..9b3a747b7ff 100644
--- a/code/modules/vehicle/vehicle.dm
+++ b/code/modules/vehicle/vehicle.dm
@@ -6,14 +6,14 @@
icon_state = "scooter"
density = 1
anchored = 0
- can_buckle = 1
- buckle_lying = 0
+ can_buckle = TRUE
+ buckle_lying = FALSE
armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0)
var/keytype = null //item typepath, if non-null an item of this type is needed in your hands to drive this vehicle
var/next_vehicle_move = 0 //used for move delays
var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower
var/auto_door_open = TRUE
- var/needs_gravity = 0//To allow non-space vehicles to move in no gravity or not, mostly for adminbus
+ var/needs_gravity = 0 //To allow non-space vehicles to move in no gravity or not, mostly for adminbus
//Pixels
var/generic_pixel_x = 0 //All dirs show this pixel_x for the driver
var/generic_pixel_y = 0 //All dirs shwo this pixel_y for the driver
@@ -37,25 +37,26 @@
//if they differ between directions, otherwise use the
//generic variables
/obj/vehicle/proc/handle_vehicle_offsets()
- if(buckled_mob)
- buckled_mob.dir = dir
- buckled_mob.pixel_x = generic_pixel_x
- buckled_mob.pixel_y = generic_pixel_y
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.setDir(dir)
+ buckled_mob.pixel_x = generic_pixel_x
+ buckled_mob.pixel_y = generic_pixel_y
/obj/vehicle/update_icon()
return
-
//KEYS
/obj/vehicle/proc/keycheck(mob/user)
if(keytype)
if(istype(user.l_hand, keytype) || istype(user.r_hand, keytype))
- return 1
+ return TRUE
else
- return 1
- return 0
+ return TRUE
+ return FALSE
/obj/item/key
name = "key"
@@ -66,8 +67,8 @@
//BUCKLE HOOKS
-/obj/vehicle/unbuckle_mob(force = 0)
- if(buckled_mob)
+/obj/vehicle/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
+ if(istype(buckled_mob))
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
. = ..()
@@ -80,38 +81,45 @@
if(A.density)
if(A != src && A != M)
return
- M.loc = get_turf(src)
+ M.forceMove(get_turf(src))
..()
handle_vehicle_offsets()
-
/obj/vehicle/bullet_act(obj/item/projectile/Proj)
- if(buckled_mob)
- buckled_mob.bullet_act(Proj)
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.bullet_act(Proj)
//MOVEMENT
/obj/vehicle/relaymove(mob/user, direction)
if(user.incapacitated())
- unbuckle_mob()
+ unbuckle_mob(user)
+ return
+ if(world.time < next_vehicle_move)
+ return
+ next_vehicle_move = world.time + vehicle_move_delay
if(keycheck(user))
- if(!Process_Spacemove(direction) || world.time < next_vehicle_move || !isturf(loc)) return
- next_vehicle_move = world.time + vehicle_move_delay
-
+ if(!Process_Spacemove(direction) || !isturf(loc))
+ return
step(src, direction)
- if(buckled_mob)
- if(buckled_mob.loc != loc)
- buckled_mob.buckled = null //Temporary, so Move() succeeds.
- buckled_mob.buckled = src //Restoring
+ if(has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ if(buckled_mob.loc != loc)
+ buckled_mob.buckled = null //Temporary, so Move() succeeds.
+ buckled_mob.buckled = src //Restoring
- if(istype(src.loc, /turf/simulated))
- var/turf/simulated/T = src.loc
+ if(issimulatedturf(loc))
+ var/turf/simulated/T = loc
if(T.wet == TURF_WET_LUBE) //Lube! Fall off!
playsound(src, 'sound/misc/slip.ogg', 50, 1, -3)
- buckled_mob.Stun(7)
- buckled_mob.Weaken(7)
- unbuckle_mob()
+ for(var/m in buckled_mobs)
+ var/mob/living/buckled_mob = m
+ buckled_mob.Weaken(5)
+ unbuckle_all_mobs()
step(src, dir)
handle_vehicle_layer()
@@ -121,7 +129,7 @@
/obj/vehicle/Move(NewLoc,Dir=0,step_x=0,step_y=0)
- ..()
+ . = ..()
handle_vehicle_layer()
handle_vehicle_offsets()
@@ -133,11 +141,12 @@
/obj/vehicle/Bump(atom/movable/M)
if(!spaceworthy && isspaceturf(get_turf(src)))
- return 0
+ return FALSE
. = ..()
if(auto_door_open)
- if(istype(M, /obj/machinery/door) && buckled_mob)
- M.Bumped(buckled_mob)
+ if(istype(M, /obj/machinery/door) && has_buckled_mobs())
+ for(var/m in buckled_mobs)
+ M.Bumped(m)
/obj/vehicle/proc/RunOver(var/mob/living/carbon/human/H)
return //write specifics for different vehicles
@@ -145,19 +154,19 @@
/obj/vehicle/Process_Spacemove(direction)
if(has_gravity(src))
- return 1
+ return TRUE
- if(pulledby && pulledby != buckled_mob) // no pulling the vehicle you're driving through space!
- return 1
+ if(pulledby && (pulledby.loc != loc))
+ return TRUE
if(needs_gravity)
- return 1
+ return TRUE
- return 0
+ return FALSE
/obj/vehicle/space
pressure_resistance = INFINITY
spaceworthy = TRUE
/obj/vehicle/space/Process_Spacemove(direction)
- return 1
+ return TRUE
\ No newline at end of file
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 2fe2c7cd21c..367a42a6c79 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ