diff --git a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
index 9f2bf05b62..b6414d2704 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm
@@ -1,4 +1,4 @@
-//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
+//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE
"aa" = (
/turf/template_noop,
/area/template_noop)
@@ -848,7 +848,7 @@
},
/area/lavaland/surface/outdoors/explored)
"gX" = (
-/turf/open/chasm/straight_down/lava_land_surface,
+/turf/open/chasm/lavaland,
/area/lavaland/surface/outdoors/explored)
"hY" = (
/obj/machinery/light,
diff --git a/_maps/shuttles/emergency_clown.dmm b/_maps/shuttles/emergency_clown.dmm
index 61dd05607e..96bd21e8b7 100644
--- a/_maps/shuttles/emergency_clown.dmm
+++ b/_maps/shuttles/emergency_clown.dmm
@@ -110,7 +110,7 @@
/turf/closed/wall/mineral/titanium,
/area/shuttle/escape)
"au" = (
-/turf/open/chasm/straight_down/lava_land_surface/normal_air,
+/turf/open/chasm,
/area/shuttle/escape)
"av" = (
/obj/machinery/light{
diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm
index 7c61613c41..728fdc431e 100644
--- a/code/datums/components/archaeology.dm
+++ b/code/datums/components/archaeology.dm
@@ -1,5 +1,5 @@
/datum/component/archaeology
- dupe_type = COMPONENT_DUPE_UNIQUE
+ dupe_mode = COMPONENT_DUPE_UNIQUE
var/list/archdrops
var/prob2drop
var/dug
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
new file mode 100644
index 0000000000..27bf9ab29a
--- /dev/null
+++ b/code/datums/components/chasm.dm
@@ -0,0 +1,132 @@
+// Used by /turf/open/chasm and subtypes to implement the "dropping" mechanic
+/datum/component/chasm
+ var/turf/target_turf
+ var/fall_message = "GAH! Ah... where are you?"
+ var/oblivion_message = "You stumble and stare into the abyss before you. It stares back, and you fall into the enveloping dark."
+
+ var/static/list/falling_atoms = list() // Atoms currently falling into chasms
+ var/static/list/forbidden_types = typecacheof(list(
+ /obj/singularity,
+ /obj/structure/lattice,
+ /obj/structure/stone_tile,
+ /obj/item/projectile,
+ /obj/effect/portal,
+ /obj/effect/abstract,
+ /obj/effect/temp_visual,
+ /obj/effect/light_emitter/tendril,
+ /obj/effect/collapse))
+
+/datum/component/chasm/Initialize(turf/target)
+ RegisterSignal(list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered)
+ target_turf = target
+ START_PROCESSING(SSobj, src) // process on create, in case stuff is still there
+
+/datum/component/chasm/proc/Entered(atom/movable/AM)
+ START_PROCESSING(SSobj, src)
+ drop_stuff(AM)
+
+/datum/component/chasm/process()
+ if (!drop_stuff())
+ STOP_PROCESSING(SSobj, src)
+
+/datum/component/chasm/proc/is_safe()
+ //if anything matching this typecache is found in the chasm, we don't drop things
+ var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
+
+ var/atom/parent = src.parent
+ var/list/found_safeties = typecache_filter_list(parent.contents, chasm_safeties_typecache)
+ for(var/obj/structure/stone_tile/S in found_safeties)
+ if(S.fallen)
+ LAZYREMOVE(found_safeties, S)
+ return LAZYLEN(found_safeties)
+
+/datum/component/chasm/proc/drop_stuff(AM)
+ . = 0
+ if (is_safe())
+ return FALSE
+
+ var/atom/parent = src.parent
+ var/to_check = AM ? list(AM) : parent.contents
+ for (var/thing in to_check)
+ if (droppable(thing))
+ . = 1
+ INVOKE_ASYNC(src, .proc/drop, thing)
+
+/datum/component/chasm/proc/droppable(atom/movable/AM)
+ // avoid an infinite loop, but allow falling a large distance
+ if(falling_atoms[AM] && falling_atoms[AM] > 30)
+ return FALSE
+ if(!isliving(AM) && !isobj(AM))
+ return FALSE
+ if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || AM.floating)
+ return FALSE
+ //Flies right over the chasm
+ if(isliving(AM))
+ var/mob/M = AM
+ if(M.is_flying())
+ return FALSE
+ if(ishuman(AM))
+ var/mob/living/carbon/human/H = AM
+ if(istype(H.belt, /obj/item/device/wormhole_jaunter))
+ var/obj/item/device/wormhole_jaunter/J = H.belt
+ //To freak out any bystanders
+ H.visible_message("[H] falls into [parent]!")
+ J.chasm_react(H)
+ return FALSE
+ return TRUE
+
+/datum/component/chasm/proc/drop(atom/movable/AM)
+ //Make sure the item is still there after our sleep
+ if(!AM || QDELETED(AM))
+ return
+ falling_atoms[AM] = (falling_atoms[AM] || 0) + 1
+ var/turf/T = target_turf
+
+ if(T)
+ // send to the turf below
+ AM.visible_message("[AM] falls into [parent]!", "[fall_message]")
+ T.visible_message("[AM] falls from above!")
+ AM.forceMove(T)
+ if(isliving(AM))
+ var/mob/living/L = AM
+ L.Knockdown(100)
+ L.adjustBruteLoss(30)
+ falling_atoms -= AM
+
+ else
+ // send to oblivion
+ AM.visible_message("[AM] falls into [parent]!", "[oblivion_message]")
+ if (isliving(AM))
+ var/mob/living/L = AM
+ L.notransform = TRUE
+ L.Stun(200)
+ L.resting = TRUE
+
+ var/oldtransform = AM.transform
+ var/oldcolor = AM.color
+ var/oldalpha = AM.alpha
+ animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10)
+ for(var/i in 1 to 5)
+ //Make sure the item is still there after our sleep
+ if(!AM || QDELETED(AM))
+ return
+ AM.pixel_y--
+ sleep(2)
+
+ //Make sure the item is still there after our sleep
+ if(!AM || QDELETED(AM))
+ return
+
+ if(iscyborg(AM))
+ var/mob/living/silicon/robot/S = AM
+ qdel(S.mmi)
+
+ falling_atoms -= AM
+ qdel(AM)
+ if(AM && !QDELETED(AM)) //It's indestructible
+ var/atom/parent = src.parent
+ parent.visible_message("[parent] spits out [AM]!")
+ AM.alpha = oldalpha
+ AM.color = oldcolor
+ AM.transform = oldtransform
+ AM.throw_at(get_edge_target_turf(parent,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 2411e7757e..3f45d5e127 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -1,20 +1,25 @@
-
-//////////////CHASM//////////////////
-
+// Base chasm, defaults to oblivion but can be overridden
/turf/open/chasm
name = "chasm"
desc = "Watch your step."
baseturf = /turf/open/chasm
smooth = SMOOTH_TRUE | SMOOTH_BORDER | SMOOTH_MORE
- icon = 'icons/turf/floors/Chasms.dmi'
+ icon = 'icons/turf/floors/chasms.dmi'
icon_state = "smooth"
canSmoothWith = list(/turf/open/floor/fakepit, /turf/open/chasm)
density = TRUE //This will prevent hostile mobs from pathing into chasms, while the canpass override will still let it function like an open turf
- var/static/list/falling_atoms = list() //Atoms currently falling into the chasm
- var/static/list/forbidden_types = typecacheof(list(/obj/effect/portal, /obj/singularity, /obj/structure/stone_tile, /obj/item/projectile, /obj/effect/abstract, /obj/effect/temp_visual, /obj/effect/light_emitter/tendril, /obj/effect/collapse))
- var/drop_x = 1
- var/drop_y = 1
- var/drop_z = 1
+
+/turf/open/chasm/Initialize()
+ . = ..()
+ AddComponent(/datum/component/chasm, null)
+
+/turf/open/chasm/proc/set_target(turf/target)
+ GET_COMPONENT(chasm_component, /datum/component/chasm)
+ chasm_component.target_turf = target
+
+/turf/open/chasm/proc/drop(atom/movable/AM)
+ GET_COMPONENT(chasm_component, /datum/component/chasm)
+ chasm_component.drop(AM)
/turf/open/chasm/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0)
return
@@ -22,15 +27,6 @@
/turf/open/chasm/MakeDry(wet_setting = TURF_WET_WATER)
return
-/turf/open/chasm/Entered(atom/movable/AM)
- ..()
- START_PROCESSING(SSobj, src)
- drop_stuff(AM)
-
-/turf/open/chasm/process()
- if(!drop_stuff())
- STOP_PROCESSING(SSobj, src)
-
/turf/open/chasm/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
underlay_appearance.icon = 'icons/turf/floors.dmi'
underlay_appearance.icon_state = "basalt"
@@ -45,7 +41,8 @@
if(R.use(1))
to_chat(user, "You construct a lattice.")
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
- ReplaceWithLattice()
+ // Create a lattice, without reverting to our baseturf
+ new /obj/structure/lattice(src)
else
to_chat(user, "You need one rod to build a lattice.")
return
@@ -57,154 +54,51 @@
qdel(L)
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
to_chat(user, "You build a floor.")
- ChangeTurf(/turf/open/floor/plating)
+ // Create a floor, which has this chasm underneath it
+ ChangeTurf(/turf/open/floor/plating, type)
else
to_chat(user, "You need one floor tile to build a floor!")
else
to_chat(user, "The plating is going to need some support! Place metal rods first.")
-/turf/open/chasm/proc/is_safe()
- //if anything matching this typecache is found in the chasm, we don't drop things
- var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile))
- var/list/found_safeties = typecache_filter_list(contents, chasm_safeties_typecache)
- for(var/obj/structure/stone_tile/S in found_safeties)
- if(S.fallen)
- LAZYREMOVE(found_safeties, S)
- return LAZYLEN(found_safeties)
-
-/turf/open/chasm/proc/drop_stuff(AM)
- . = 0
- if(is_safe())
- return FALSE
- var/thing_to_check = src
- if(AM)
- thing_to_check = list(AM)
- for(var/thing in thing_to_check)
- if(droppable(thing))
- . = 1
- INVOKE_ASYNC(src, .proc/drop, thing)
-
-/turf/open/chasm/proc/droppable(atom/movable/AM)
- if(falling_atoms[AM])
- return FALSE
- if(!isliving(AM) && !isobj(AM))
- return FALSE
- if(is_type_in_typecache(AM, forbidden_types) || AM.throwing)
- return FALSE
- //Flies right over the chasm
- if(isliving(AM))
- var/mob/M = AM
- if(M.is_flying())
- return FALSE
- if(ishuman(AM))
- var/mob/living/carbon/human/H = AM
- if(istype(H.belt, /obj/item/device/wormhole_jaunter))
- var/obj/item/device/wormhole_jaunter/J = H.belt
- //To freak out any bystanders
- visible_message("[H] falls into [src]!")
- J.chasm_react(H)
- return FALSE
- return TRUE
+/turf/open/chasm/CanPass(atom/movable/mover, turf/target)
+ return 1
-/turf/open/chasm/proc/drop(atom/movable/AM)
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
- falling_atoms[AM] = TRUE
- var/turf/T = locate(drop_x, drop_y, drop_z)
- if(T)
- AM.visible_message("[AM] falls into [src]!", "GAH! Ah... where are you?")
- T.visible_message("[AM] falls from above!")
- AM.forceMove(T)
- if(isliving(AM))
- var/mob/living/L = AM
- L.Knockdown(100)
- L.adjustBruteLoss(30)
- falling_atoms -= AM
-
+// Naive "down" which just subtracts a z-level
+/turf/open/chasm/straight_down
+ baseturf = /turf/open/chasm/straight_down
/turf/open/chasm/straight_down/Initialize()
. = ..()
- drop_x = x
- drop_y = y
- drop_z = z - 1
- var/turf/T = locate(drop_x, drop_y, drop_z)
- T.visible_message("The ceiling gives way!")
- playsound(T, 'sound/effects/break_stone.ogg', 50, 1)
+ set_target(locate(x, y, z - 1))
-/turf/open/chasm/straight_down/lava_land_surface
+// Chasms for Lavaland, with planetary atmos and lava glow
+/turf/open/chasm/lavaland
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
- baseturf = /turf/open/chasm/straight_down/lava_land_surface
+ baseturf = /turf/open/chasm/lavaland
light_range = 1.9 //slightly less range than lava
light_power = 0.65 //less bright, too
light_color = LIGHT_COLOR_LAVA //let's just say you're falling into lava, that makes sense right
-/turf/open/chasm/straight_down/lava_land_surface/drop(atom/movable/AM)
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
- falling_atoms[AM] = TRUE
- AM.visible_message("[AM] falls into [src]!", "You stumble and stare into an abyss before you. It stares back, and you fall \
- into the enveloping dark.")
- if(isliving(AM))
- var/mob/living/L = AM
- L.notransform = TRUE
- L.Stun(200)
- L.resting = TRUE
- var/oldtransform = AM.transform
- var/oldcolor = AM.color
- var/oldalpha = AM.alpha
- animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10)
- for(var/i in 1 to 5)
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
- AM.pixel_y--
- sleep(2)
-
- //Make sure the item is still there after our sleep
- if(!AM || QDELETED(AM))
- return
-
- if(iscyborg(AM))
- var/mob/living/silicon/robot/S = AM
- qdel(S.mmi)
-
- falling_atoms -= AM
-
- qdel(AM)
-
- if(AM && !QDELETED(AM)) //It's indestructible
- visible_message("[src] spits out the [AM]!")
- AM.alpha = oldalpha
- AM.color = oldcolor
- AM.transform = oldtransform
- AM.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
-
-/turf/open/chasm/straight_down/lava_land_surface/normal_air
- initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
-
-
-
-/turf/open/chasm/CanPass(atom/movable/mover, turf/target)
- return 1
-
-//Jungle
+// Chasms for the jungle, with planetary atmos and a different icon
/turf/open/chasm/jungle
icon = 'icons/turf/floors/junglechasm.dmi'
- planetary_atmos = TRUE
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+ planetary_atmos = TRUE
+ baseturf = /turf/open/chasm/jungle
/turf/open/chasm/jungle/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
underlay_appearance.icon = 'icons/turf/floors.dmi'
underlay_appearance.icon_state = "dirt"
return TRUE
-/turf/open/chasm/straight_down/jungle
- icon = 'icons/turf/floors/junglechasm.dmi'
- planetary_atmos = TRUE
- initial_gas_mix = LAVALAND_DEFAULT_ATMOS
+/turf/open/chasm/jungle/straight_down
+ baseturf = /turf/open/chasm/jungle/straight_down
+
+/turf/open/chasm/jungle/straight_down/Initialize(mapload)
+ . = ..()
+ set_target(locate(x, y, z - 1))
diff --git a/code/game/turfs/simulated/floor/plating/dirt.dm b/code/game/turfs/simulated/floor/plating/dirt.dm
index 3795150b2e..3a02935657 100644
--- a/code/game/turfs/simulated/floor/plating/dirt.dm
+++ b/code/game/turfs/simulated/floor/plating/dirt.dm
@@ -3,7 +3,7 @@
desc = "Upon closer examination, it's still dirt."
icon = 'icons/turf/floors.dmi'
icon_state = "dirt"
- baseturf = /turf/open/chasm/straight_down/jungle
+ baseturf = /turf/open/chasm/jungle/straight_down
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
attachment_holes = FALSE
diff --git a/code/game/turfs/simulated/lava.dm b/code/game/turfs/simulated/lava.dm
index 1f1ea76168..d5dbd79ff5 100644
--- a/code/game/turfs/simulated/lava.dm
+++ b/code/game/turfs/simulated/lava.dm
@@ -137,7 +137,7 @@
/turf/open/lava/smooth/lava_land_surface
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
- baseturf = /turf/open/chasm/straight_down/lava_land_surface
+ baseturf = /turf/open/chasm/lavaland
/turf/open/lava/smooth/airless
initial_gas_mix = "TEMP=2.7"
diff --git a/code/game/turfs/simulated/water.dm b/code/game/turfs/simulated/water.dm
index d73c5f98c2..c67fdc83a1 100644
--- a/code/game/turfs/simulated/water.dm
+++ b/code/game/turfs/simulated/water.dm
@@ -3,7 +3,7 @@
desc = "Shallow water."
icon = 'icons/turf/floors.dmi'
icon_state = "riverwater"
- baseturf = /turf/open/chasm/straight_down/lava_land_surface
+ baseturf = /turf/open/chasm/lavaland
initial_gas_mix = LAVALAND_DEFAULT_ATMOS
planetary_atmos = TRUE
slowdown = 1
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
index b579437796..923c34fef2 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm
@@ -97,5 +97,5 @@
visible_message("The tendril falls inward, the ground around it widening into a yawning chasm!")
for(var/turf/T in range(2,src))
if(!T.density)
- T.TerraformTurf(/turf/open/chasm/straight_down/lava_land_surface)
+ T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland)
qdel(src)
diff --git a/code/modules/ruins/objects_and_mobs/sin_ruins.dm b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
index f00c90bb25..3924d29e91 100644
--- a/code/modules/ruins/objects_and_mobs/sin_ruins.dm
+++ b/code/modules/ruins/objects_and_mobs/sin_ruins.dm
@@ -102,7 +102,7 @@
"Perfect. Much better! Now nobody will be able to resist yo-")
var/turf/T = get_turf(user)
T.ChangeTurf(/turf/open/chasm/straight_down)
- var/turf/open/chasm/straight_down/C = T
+ var/turf/open/chasm/C = T
C.drop(user)
//can't be bothered to do sloth right now, will make later
diff --git a/tgstation.dme b/tgstation.dme
index f30fcdd8f8..bbbd444d7d 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -330,6 +330,7 @@
#include "code\datums\antagonists\wizard.dm"
#include "code\datums\components\_component.dm"
#include "code\datums\components\archaeology.dm"
+#include "code\datums\components\chasm.dm"
#include "code\datums\components\decal.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\material_container.dm"