diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 81fb3587fd8..c3f52d7131f 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -281,7 +281,7 @@ var/list/mob/living/forced_ambiance_list = new
var/area/oldarea = L.lastarea
if((oldarea.has_gravity() == FALSE) && (newarea.has_gravity() == TRUE) && (L.m_intent == M_RUN)) // Being ready when you change areas gives you a chance to avoid falling all together.
thunk(L)
- L.update_floating(L.Check_Dense_Object())
+ L.update_floating()
L.lastarea = newarea
@@ -339,7 +339,7 @@ var/list/mob/living/forced_ambiance_list = new
thunk(M)
else
to_chat(M, SPAN_NOTICE("The sudden lack of gravity makes you feel weightless and float cluelessly."))
- M.update_floating(M.Check_Dense_Object())
+ M.update_floating()
/area/proc/thunk(mob)
if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing.
@@ -465,4 +465,4 @@ var/list/mob/living/forced_ambiance_list = new
#undef VOLUME_AMBIENCE
#undef VOLUME_AMBIENT_HUM
-#undef VOLUME_MUSIC
\ No newline at end of file
+#undef VOLUME_MUSIC
diff --git a/code/game/objects/items/weapons/tanks/jetpack.dm b/code/game/objects/items/weapons/tanks/jetpack.dm
index 01709b08665..6f938a296f5 100644
--- a/code/game/objects/items/weapons/tanks/jetpack.dm
+++ b/code/game/objects/items/weapons/tanks/jetpack.dm
@@ -38,21 +38,13 @@
gauge_icon = null
w_class = ITEMSIZE_LARGE
distribute_pressure = ONE_ATMOSPHERE*O2STANDARD
- var/datum/effect_system/ion_trail/ion_trail
+ var/ion_trail_type = /obj/effect/effect/ion_trails
var/on = 0.0
var/stabilization_on = 0
var/warned = 0
var/volume_rate = 500 //Needed for borg jetpack transfer
action_button_name = "Toggle Jetpack"
-/obj/item/tank/jetpack/Initialize()
- . = ..()
- ion_trail = new(src)
-
-/obj/item/tank/jetpack/Destroy()
- QDEL_NULL(ion_trail)
- return ..()
-
/obj/item/tank/jetpack/examine(mob/user)
. = ..()
if(air_contents.total_moles < 5)
@@ -81,10 +73,8 @@
toggle_rockets_stabilization(user, message_mobs)
if(on)
icon_state = "[icon_state]-on"
- ion_trail.start()
else
icon_state = initial(icon_state)
- ion_trail.stop()
user.update_inv_back()
user.update_action_buttons()
@@ -95,17 +85,16 @@
/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user as mob)
if(!(src.on))
- return 0
+ return FALSE
if (stabilization_on)
num *= 2//gas usage is doubled when stabilising. one burst to start moving, and one to stop
if((num < 0.005 || src.air_contents.total_moles < num))
- src.ion_trail.stop()
- return 0
+ return FALSE
if (src.air_contents.total_moles < 3 && !warned)
- warned = 1
+ warned = TRUE
playsound(user, 'sound/effects/alert.ogg', 50, 1)
to_chat(user, "The meter on \the [src] indicates you are almost out of gas and beeps loudly!")
addtimer(CALLBACK(src, .proc/reset_warning), 600)
@@ -114,7 +103,12 @@
var/allgases = G.gas[GAS_CO2] + G.gas[GAS_NITROGEN] + G.gas[GAS_OXYGEN] + G.gas[GAS_PHORON] + G.gas[GAS_HYDROGEN]
if(allgases >= 0.005)
- return 1
+ var/obj/effect/effect/ion_trails/ion_trail = new(user.loc)
+ flick("ion_fade", ion_trail)
+ ion_trail.icon_state = "blank"
+ animate(ion_trail, alpha = 0, time = 18, easing = SINE_EASING | EASE_IN)
+ QDEL_IN(ion_trail, 20)
+ return TRUE
qdel(G)
@@ -167,10 +161,8 @@
on = !on
if(on)
icon_state = "[icon_state]-on"
- ion_trail.start()
else
icon_state = initial(icon_state)
- ion_trail.stop()
to_chat(usr, SPAN_NOTICE("You toggle the thrusters [on ? "on" : "off"]."))
stabilization_on = !stabilization_on
@@ -194,21 +186,25 @@
/obj/item/tank/jetpack/rig/allow_thrust(num, mob/living/user as mob)
if(!(src.on))
- return 0
+ return FALSE
if(!istype(holder) || !holder.air_supply)
- return 0
+ return FALSE
var/obj/item/tank/pressure_vessel = holder.air_supply
if((num < 0.005 || pressure_vessel.air_contents.total_moles < num))
- src.ion_trail.stop()
- return 0
+ return FALSE
var/datum/gas_mixture/G = pressure_vessel.air_contents.remove(num)
var/allgases = G.gas[GAS_CO2] + G.gas[GAS_NITROGEN] + G.gas[GAS_OXYGEN] + G.gas[GAS_PHORON] + G.gas[GAS_HYDROGEN]
if(allgases >= 0.005)
- return 1
+ var/obj/effect/effect/ion_trails/ion_trail = new(user.loc)
+ flick("ion_fade", ion_trail)
+ ion_trail.icon_state = "blank"
+ animate(ion_trail, alpha = 0, time = 18, easing = SINE_EASING | EASE_IN)
+ QDEL_IN(ion_trail, 20)
+ return TRUE
+
qdel(G)
- return
diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm
index 1e29746eb3f..9b9137cccc3 100644
--- a/code/game/objects/structures/lattice.dm
+++ b/code/game/objects/structures/lattice.dm
@@ -31,6 +31,15 @@
for(var/obj/structure/lattice/LAT in loc)
if(LAT != src)
qdel(LAT)
+ if(isturf(loc))
+ var/turf/turf = loc
+ turf.is_hole = FALSE
+
+/obj/structure/lattice/Destroy()
+ if(isturf(loc))
+ var/turf/turf = loc
+ turf.is_hole = initial(turf.is_hole)
+ return ..()
/obj/structure/lattice/ex_act(severity)
switch(severity)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index a3183333a0c..743a7e4b2be 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -237,14 +237,20 @@ var/const/enterloopsanity = 100
var/mob/M = AM
if(!M.lastarea)
M.lastarea = get_area(M.loc)
- if(M.lastarea.has_gravity() == 0)
+
+ var/has_gravity = M.lastarea.has_gravity()
+ if(!has_gravity)
inertial_drift(M)
// Footstep SFX logic moved to human_movement.dm - Move().
- else if (type != /turf/space)
+ else if(!is_hole)
M.inertia_dir = 0
- M.make_floating(0)
+
+ if(!M.is_floating && (is_hole || !has_gravity))
+ M.update_floating()
+ else if(M.is_floating && !is_hole && has_gravity)
+ M.update_floating()
if(does_footprint && footprint_color && ishuman(AM))
var/mob/living/carbon/human/H = AM
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index f2368bd5a17..6d0f5ced4a2 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -51,6 +51,7 @@
to_chat(user, "You enable the mag-pulse traction system.")
user.update_inv_shoes() //so our mob-overlays update
user.update_action_buttons()
+ user.update_floating()
/obj/item/clothing/shoes/magboots/negates_gravity()
if(magpulse)
diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm
index 3697712fa1c..3dd56995517 100644
--- a/code/modules/clothing/spacesuits/rig/modules/utility.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm
@@ -497,12 +497,10 @@
/obj/item/rig_module/maneuvering_jets/installed()
..()
jets.holder = holder
- jets.ion_trail.bind(holder)
/obj/item/rig_module/maneuvering_jets/removed()
..()
jets.holder = null
- jets.ion_trail.bind(jets)
/obj/item/rig_module/device/paperdispenser
name = "hardsuit paper dispenser"
@@ -874,4 +872,4 @@ var/global/list/lattice_users = list()
counter--
previous_turf = T
sleep(1)
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm
index 0a3278c53ef..93fdc64a260 100644
--- a/code/modules/mob/animations.dm
+++ b/code/modules/mob/animations.dm
@@ -78,50 +78,39 @@ note dizziness decrements automatically in the mob's Life() proc.
//handles up-down floaty effect in space and zero-gravity
-/mob/var/is_floating = 0
-/mob/var/floatiness = 0
+/mob/var/is_floating = FALSE
-/mob/proc/update_floating(var/dense_object=0)
-
- if(anchored||buckled_to)
- make_floating(0)
+/mob/proc/update_floating()
+ if(anchored || buckled_to)
+ set_floating(FALSE)
return
var/turf/turf = get_turf(src)
- if(!istype(turf,/turf/space))
+ if(!turf?.is_hole)
var/area/A = turf.loc
if(istype(A) && A.has_gravity())
- make_floating(0)
- return
- else if (Check_Shoegrip())
- make_floating(0)
+ set_floating(FALSE)
return
else
- make_floating(1)
- return
+ var/shoegrip = Check_Shoegrip()
+ if(shoegrip)
+ set_floating(FALSE)
+ return
- if(dense_object && Check_Shoegrip())
- make_floating(0)
+ set_floating(TRUE)
+
+/mob/proc/set_floating(var/floating_state)
+ if(buckled_to && is_floating)
+ stop_floating()
return
- make_floating(1)
- return
-
-/mob/proc/make_floating(var/n)
- if(buckled_to)
- if(is_floating)
- stop_floating()
- return
- floatiness = n
-
- if(floatiness && !is_floating)
+ if(floating_state && !is_floating)
start_floating()
- else if(!floatiness && is_floating)
+ else if(!floating_state && is_floating)
stop_floating()
/mob/proc/start_floating()
-
- is_floating = 1
+ is_floating = TRUE
var/amplitude = 2 //maximum displacement from original position
var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4
@@ -138,7 +127,7 @@ note dizziness decrements automatically in the mob's Life() proc.
/mob/proc/stop_floating()
animate(src, pixel_y = get_standard_pixel_y(), time = 5, easing = SINE_EASING | EASE_IN) //halt animation
//reset the pixel offsets to defaults
- is_floating = 0
+ is_floating = FALSE
/atom/movable/proc/do_attack_animation(atom/A, atom/movable/weapon, var/image/attack_image, var/initial_pixel_x = 0, var/initial_pixel_y = 0)
var/pixel_x_diff = 0
@@ -198,7 +187,9 @@ note dizziness decrements automatically in the mob's Life() proc.
var/initial_pixel_x = get_standard_pixel_x()
var/initial_pixel_y = get_standard_pixel_y()
..(A, attack_item, attack_image, initial_pixel_x, initial_pixel_y)
- is_floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
+
+ if(is_floating)
+ addtimer(CALLBACK(src, .proc/start_floating), 4)
if(attack_item == FIST_ATTACK_ANIMATION) // only play the physical movement
return
@@ -270,27 +261,30 @@ note dizziness decrements automatically in the mob's Life() proc.
return
// Mob Throwing Animation
-/proc/animate_throw(atom/A)
- var/ipx = A.pixel_x
- var/ipy = A.pixel_y
+/mob/proc/animate_throw()
+ var/ipx = pixel_x
+ var/ipy = pixel_y
var/mpx = 0
var/mpy = 0
- if(A.dir & NORTH)
+ if(dir & NORTH)
mpy += 3
- else if(A.dir & SOUTH)
+ else if(dir & SOUTH)
mpy -= 3
- if(A.dir & EAST)
+ if(dir & EAST)
mpx += 3
- else if(A.dir & WEST)
+ else if(dir & WEST)
mpx -= 3
- var/x = mpx + ipx
- var/y = mpy + ipy
+ var/new_x = mpx + ipx
+ var/new_y = mpy + ipy
- animate(A, pixel_x = x, pixel_y = y, time = 0.6, easing = EASE_OUT)
+ animate(src, pixel_x = new_x, pixel_y = new_y, time = 0.6, easing = EASE_OUT)
- var/matrix/M = matrix(A.transform)
- animate(transform = turn(A.transform, (mpx - mpy) * 4), time = 0.6, easing = EASE_OUT)
+ var/matrix/M = matrix(transform)
+ animate(transform = turn(transform, (mpx - mpy) * 4), time = 0.6, easing = EASE_OUT)
animate(pixel_x = ipx, pixel_y = ipy, time = 0.6, easing = EASE_IN)
- animate(transform = M, time = 0.6, easing = EASE_IN)
\ No newline at end of file
+ animate(transform = M, time = 0.6, easing = EASE_IN)
+
+ if(is_floating)
+ addtimer(CALLBACK(src, .proc/start_floating), 2.4)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 935c13729bc..3f4f8acf0f5 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -24,7 +24,7 @@
/mob/proc/equip_to_slot_if_possible(obj/item/W as obj, slot, del_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, ignore_blocked = FALSE, assisted_equip = FALSE)
if(!istype(W))
return FALSE
- if(W.item_flags & NOMOVE) //Cannot move NOMOVE items from one inventory slot to another. Cannot do canremove here because then BSTs spawn naked.
+ if(W.item_flags & NOMOVE) //Cannot move NOMOVE items from one inventory slot to another. Cannot do canremove here because then BSTs spawn naked.
return FALSE
if(!W.mob_can_equip(src, slot, disable_warning, ignore_blocked))
@@ -398,12 +398,12 @@ var/list/slot_equipment_priority = list( \
for(var/obj/O in T)
if(!O.density) //We don't care about you.
continue
- if(O.CanPass(item, T)) //Items have CANPASS for tables/railings, allows placement. Also checks windows.
+ if(O.CanPass(item, T)) //Items have CANPASS for tables/railings, allows placement. Also checks windows.
continue
if(istype(O, /obj/structure/closet/crate)) //Placing on/in crates is fine.
continue
return TRUE //Something is stopping us. Takes off throw mode.
-
+
if(unEquip(I))
make_item_drop_sound(I)
I.forceMove(T)
@@ -431,7 +431,7 @@ var/list/slot_equipment_priority = list( \
playsound(src, 'sound/effects/throw.ogg', volume, TRUE, -1)
// Animate the mob throwing.
- animate_throw(src)
+ animate_throw()
item.throw_at(target, item.throw_range, item.throw_speed, src)
@@ -489,4 +489,4 @@ var/list/slot_equipment_priority = list( \
//When you drop an extremely heavy 406mm shell onto your foot. Oops!
/mob/living/carbon/proc/throw_fail_consequences(var/obj/item/I)
apply_damage(45, BRUTE, pick(list(BP_L_FOOT, BP_R_FOOT)), I, armor_pen = 30)
- I.throw_fail_consequences(src)
\ No newline at end of file
+ I.throw_fail_consequences(src)
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index 7b2cbaec5bf..fc5fd30d596 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -6,7 +6,7 @@
/mob/living/silicon/robot/Allow_Spacemove()
if(module)
for(var/obj/item/tank/jetpack/J in module.modules)
- if(J && J.allow_thrust(0.01))
+ if(J?.allow_thrust(0.01, src))
return TRUE
. = ..()
@@ -24,7 +24,7 @@
/mob/living/silicon/robot/Move()
. = ..()
-
+
if(client)
var/turf/B = GetAbove(get_turf(src))
if(up_hint)
@@ -41,4 +41,4 @@
var/mob/living/carbon/human/H = pulling
if(H.species.slowdown > speed)
. += H.species.slowdown - speed
- . += H.ClothesSlowdown()
\ No newline at end of file
+ . += H.ClothesSlowdown()
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 41cc339ccac..b947607a1e8 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -504,16 +504,15 @@
var/turf/T = get_turf(src)
if (!T) // nullspace so sure, have gravity.
- return 1
- else if (istype(T, /turf/space))
- return 0
+ return TRUE
+ else if(T.is_hole)
+ return FALSE
var/area/A = T.loc
-
if (!A.has_gravity() && !Check_Shoegrip())
- return 0
+ return FALSE
- return 1
+ return TRUE
/mob/proc/Check_Dense_Object() //checks for anything to push off in the vicinity. also handles magboots on gravity-less floors tiles
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index d84d1c2b4c3..fd1e34d0503 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -52,11 +52,11 @@
var/turf/start = get_turf(src)
if(!start.CanZPass(src, direction))
- to_chat(src, SPAN_WARNING("\The [start] is in the way."))
+ to_chat(src, SPAN_WARNING("\The [start.GetZPassBlocker()] is in the way."))
return FALSE
if(!destination.CanZPass(src, direction))
- to_chat(src, SPAN_WARNING("\The [destination] is in the way!"))
+ to_chat(src, SPAN_WARNING("\The [destination.GetZPassBlocker()] is in the way!"))
return FALSE
var/area/area = get_area(src)
diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/structures.dm
index 6fe864b9afe..85d23251cc5 100644
--- a/code/modules/multiz/structures.dm
+++ b/code/modules/multiz/structures.dm
@@ -158,10 +158,10 @@
if(istype(target_ladder, target_down))
direction = DOWN
if(!LAD.CanZPass(M, direction))
- to_chat(M, "\The [LAD] is blocking \the [src].")
+ to_chat(M, "\The [LAD.GetZPassBlocker()] is blocking \the [src].")
return FALSE
if(!T.CanZPass(M, direction))
- to_chat(M, "\The [T] is blocking \the [src].")
+ to_chat(M, "\The [T.GetZPassBlocker()] is blocking \the [src].")
return FALSE
for(var/atom/A in T)
if(!isliving(A))
@@ -286,4 +286,4 @@
/obj/structure/stairs/west
dir = WEST
- bound_width = 64
\ No newline at end of file
+ bound_width = 64
diff --git a/code/modules/multiz/turfs/open_space.dm b/code/modules/multiz/turfs/open_space.dm
index 693323465e6..c322a849a07 100644
--- a/code/modules/multiz/turfs/open_space.dm
+++ b/code/modules/multiz/turfs/open_space.dm
@@ -39,15 +39,24 @@
if(direction == DOWN) //on a turf above, trying to enter
return !density
+/turf/proc/GetZPassBlocker()
+ return src
+
/turf/simulated/open/CanZPass(atom/A, direction)
if(locate(/obj/structure/lattice/catwalk, src))
if(z == A.z)
if(direction == DOWN)
- return 0
+ return FALSE
else if(direction == UP)
- return 0
+ return FALSE
return 1
+/turf/simulated/open/GetZPassBlocker()
+ var/obj/structure/lattice/catwalk/catwalk = locate(/obj/structure/lattice/catwalk, src)
+ if(catwalk)
+ return catwalk
+ return src
+
/turf/space/CanZPass(atom/A, direction)
if(locate(/obj/structure/lattice/catwalk, src))
if(z == A.z)
@@ -57,6 +66,12 @@
return 0
return 1
+/turf/space/GetZPassBlocker()
+ var/obj/structure/lattice/catwalk/catwalk = locate(/obj/structure/lattice/catwalk, src)
+ if(catwalk)
+ return catwalk
+ return src
+
// Add a falling atom by default. Even if it's not an atom that can actually fall.
// SSfalling will check this on its own and remove if necessary. This is saner, as it
@@ -256,4 +271,4 @@
return t.roof_type
/turf/simulated/open/is_open()
- return TRUE
\ No newline at end of file
+ return TRUE
diff --git a/html/changelogs/geeves-hole_changes.yml b/html/changelogs/geeves-hole_changes.yml
new file mode 100644
index 00000000000..570edfb0913
--- /dev/null
+++ b/html/changelogs/geeves-hole_changes.yml
@@ -0,0 +1,10 @@
+author: Geeves
+
+delete-after: True
+
+changes:
+ - rscadd: "Putting a lattice/catwalk on an open space makes it not be a hole anymore, meaning you won't fall through it, not use jetpack fuel to traverse them, and mechs can now walk over them."
+ - rscadd: "Jetpack users will now visibly float when they're jetting over an open turf."
+ - tweak: "Jetpack ion trails now fire whenever the jetpack thrusts, not on a processing timer."
+ - bugfix: "Attacking someone or throwing someone no longer resets your floating state."
+ - bugfix: "Trying to pass through an open space with a catwalk will now report the catwalk as the blocker, instead of the open space."