diff --git a/_maps/map_files/LayeniaStation/LayeniaStation.dmm b/_maps/map_files/LayeniaStation/LayeniaStation.dmm
index bc5414030..6bd14f8f9 100644
--- a/_maps/map_files/LayeniaStation/LayeniaStation.dmm
+++ b/_maps/map_files/LayeniaStation/LayeniaStation.dmm
@@ -2941,7 +2941,6 @@
icon_state = "1-2"
},
/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/maintenance/solars/starboard/fore)
"aiI" = (
@@ -7020,8 +7019,8 @@
/turf/open/floor/plasteel,
/area/maintenance/disposal/incinerator)
"aRt" = (
-/obj/machinery/power/grounding_rod{
- anchored = 1
+/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{
+ name = "air scrubber"
},
/turf/open/floor/plasteel/dark,
/area/engine/tether)
@@ -10933,15 +10932,11 @@
/turf/open/floor/plating/layenia,
/area/layenia/cloudlayer)
"bxU" = (
-/obj/machinery/light{
- dir = 1;
- pixel_y = 16
- },
-/obj/machinery/power/grounding_rod{
- anchored = 1
- },
-/obj/machinery/power/grounding_rod{
- anchored = 1
+/obj/effect/decal/cleanable/cobweb,
+/obj/effect/turf_decal/loading_area{
+ dir = 8;
+ icon_state = "half_stairs_darkfull";
+ name = "dark steps"
},
/turf/open/floor/plasteel/dark,
/area/engine/tether)
@@ -19217,6 +19212,11 @@
dir = 4;
name = "scrubbers pipe"
},
+/obj/effect/turf_decal/loading_area{
+ dir = 5;
+ icon_state = "steel_panel";
+ name = "steel pannel"
+ },
/turf/open/floor/plasteel/dark{
icon_state = "darkfull_plate"
},
@@ -42989,8 +42989,7 @@
},
/area/chapel/main)
"gQR" = (
-/obj/machinery/safety_tether,
-/turf/open/floor/engine,
+/turf/open/floor/carpet/kinaris,
/area/engine/tether)
"gQT" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -58849,7 +58848,13 @@
/turf/open/floor/carpet,
/area/crew_quarters/dorms)
"jgm" = (
-/turf/open/floor/engine,
+/obj/structure/railing/handrail,
+/obj/effect/turf_decal/loading_area{
+ dir = 10;
+ icon_state = "steel_panel";
+ name = "steel pannel"
+ },
+/turf/open/floor/plasteel/dark,
/area/engine/tether)
"jgz" = (
/obj/structure/cable{
@@ -59817,7 +59822,6 @@
name = "Atmospherics External Access";
req_access_txt = "24"
},
-/obj/structure/fans/tiny,
/turf/open/floor/plating,
/area/maintenance/theatre)
"jnp" = (
@@ -62508,7 +62512,6 @@
dir = 10;
name = "air supply pipe"
},
-/obj/item/paper/fluff/safety_tether,
/turf/open/floor/plasteel/dark{
dir = 1;
icon_state = "darkfull_plate"
@@ -72108,9 +72111,13 @@
/turf/closed/wall/r_wall,
/area/ai_monitored/turret_protected/aisat_interior)
"lgU" = (
-/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer1{
- name = "air scrubber"
+/obj/machinery/power/grounding_rod{
+ anchored = 1
},
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer1{
+ name = "scrubbers pipe"
+ },
+/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel/dark,
/area/engine/tether)
"lgW" = (
@@ -80162,6 +80169,11 @@
/obj/effect/turf_decal/arrows,
/turf/open/floor/plasteel,
/area/hallway/primary/port/fore)
+"mwH" = (
+/obj/structure/grille,
+/obj/structure/window/plasma/fulltile,
+/turf/open/floor/plating,
+/area/engine/tether)
"mwM" = (
/obj/structure/flora/crystal/small/pile{
icon_state = "crystals4"
@@ -87827,6 +87839,10 @@
},
/turf/open/floor/plasteel/layenia,
/area/layenia)
+"nAF" = (
+/obj/item/paper/fluff/safety_tether,
+/turf/open/floor/carpet/kinaris,
+/area/engine/tether)
"nAJ" = (
/obj/machinery/light{
dir = 8;
@@ -91780,17 +91796,6 @@
"ofn" = (
/turf/closed/wall,
/area/storage/D)
-"ofu" = (
-/obj/machinery/door/airlock/external{
- name = "Port Docking Bay 1"
- },
-/obj/effect/mapping_helpers/airlock/cyclelink_helper,
-/obj/effect/turf_decal/delivery,
-/obj/structure/fans/tiny,
-/turf/open/floor/plasteel/dark{
- icon_state = "darkfull_whole_alt"
- },
-/area/hallway/secondary/entry/upper)
"ofE" = (
/obj/structure/closet/l3closet/scientist,
/obj/effect/turf_decal/stripes/line{
@@ -100338,10 +100343,6 @@
},
/turf/open/floor/plating/layenia,
/area/layenia/cloudlayer)
-"pkn" = (
-/obj/item/paper/fluff/safety_tether,
-/turf/open/floor/plasteel/dark,
-/area/engine/tether)
"pko" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{
dir = 8;
@@ -101582,6 +101583,10 @@
},
/turf/open/floor/plasteel,
/area/security/main/upper)
+"ptb" = (
+/obj/machinery/safety_tether,
+/turf/open/floor/carpet/kinaris,
+/area/engine/tether)
"ptc" = (
/obj/effect/turf_decal/tile/brown{
dir = 1
@@ -103854,6 +103859,12 @@
/obj/structure/cable{
icon_state = "2-4"
},
+/obj/effect/turf_decal/loading_area{
+ dir = 5;
+ icon_state = "steel_panel";
+ name = "steel pannel"
+ },
+/obj/effect/turf_decal/caution/stand_clear,
/turf/open/floor/plasteel/dark{
icon_state = "darkfull_trim"
},
@@ -104159,6 +104170,10 @@
/turf/open/floor/plasteel/dark,
/area/security/brig/upper)
"pLi" = (
+/obj/machinery/power/grounding_rod{
+ anchored = 1
+ },
+/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel/dark,
/area/engine/tether)
"pLj" = (
@@ -109018,6 +109033,12 @@
name = "tile"
},
/area/hallway/primary/aft)
+"qwN" = (
+/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{
+ name = "air vent"
+ },
+/turf/open/floor/plasteel/dark,
+/area/engine/tether)
"qwP" = (
/obj/machinery/power/apc{
areastring = "/area/security/checkpoint/auxiliary";
@@ -129644,12 +129665,17 @@
/turf/open/floor/circuit/telecomms/mainframe,
/area/tcommsat/server)
"tlH" = (
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{
dir = 8;
name = "air supply pipe"
},
-/obj/structure/cable{
- icon_state = "4-8"
+/obj/effect/turf_decal/loading_area{
+ dir = 5;
+ icon_state = "steel_panel";
+ name = "steel pannel"
},
/turf/open/floor/plasteel/dark{
icon_state = "darkfull_plate"
@@ -131230,8 +131256,10 @@
dir = 1;
pixel_y = 16
},
-/obj/machinery/power/grounding_rod{
- anchored = 1
+/obj/effect/turf_decal/loading_area{
+ dir = 4;
+ icon_state = "half_stairs_darkfull";
+ name = "dark steps"
},
/turf/open/floor/plasteel/dark,
/area/engine/tether)
@@ -140981,9 +141009,13 @@
/turf/closed/wall,
/area/medical/genetics)
"uPI" = (
-/obj/machinery/atmospherics/components/unary/vent_pump/on/layer3{
- name = "air vent"
+/obj/machinery/power/grounding_rod{
+ anchored = 1
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{
+ name = "air supply pipe"
+ },
+/obj/effect/turf_decal/delivery,
/turf/open/floor/plasteel/dark,
/area/engine/tether)
"uPP" = (
@@ -144746,7 +144778,6 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 1
},
-/obj/structure/fans/tiny,
/turf/open/floor/plasteel/dark{
icon_state = "darkfull_whole_alt"
},
@@ -153466,7 +153497,6 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 8
},
-/obj/structure/fans/tiny,
/turf/open/floor/plating/layenia,
/area/maintenance/department/engine/upper)
"wAM" = (
@@ -158924,10 +158954,6 @@
/obj/machinery/light{
pixel_y = -1
},
-/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{
- dir = 9;
- name = "air supply pipe"
- },
/obj/machinery/power/apc/highcap/five_k{
areastring = "/area/engine/tether";
dir = 4;
@@ -158937,6 +158963,10 @@
/obj/structure/cable{
icon_state = "0-8"
},
+/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer3{
+ dir = 9;
+ name = "air supply pipe"
+ },
/turf/open/floor/plasteel/dark{
icon_state = "darkfull_plate"
},
@@ -206646,9 +206676,9 @@ ykt
wWR
woc
woc
-woc
-woc
-woc
+mwH
+mwH
+mwH
woc
woc
wAU
@@ -207158,11 +207188,11 @@ ejD
xdO
ykt
wWR
-woc
+mwH
jgm
-jgm
-jgm
-pkn
+gQR
+gQR
+nAF
cZp
woc
tgZ
@@ -207415,11 +207445,11 @@ ejD
xdO
ykt
wWR
-woc
+mwH
jgm
gQR
-jgm
-pLi
+ptb
+gQR
pIP
vct
fJb
@@ -207672,11 +207702,11 @@ ejD
xdO
ykt
wWR
-woc
+mwH
jgm
-jgm
-jgm
-pLi
+gQR
+gQR
+gQR
tlH
woc
jJn
@@ -207932,7 +207962,7 @@ wWR
woc
txg
pLi
-aRt
+qwN
uPI
xqo
woc
@@ -252198,7 +252228,7 @@ vka
vka
vka
prt
-ofu
+dvT
rFp
vKI
tGx
diff --git a/hyperstation/code/game/machinery/safety_tether.dm b/hyperstation/code/game/machinery/safety_tether.dm
index 1955d7599..9a7b27e69 100644
--- a/hyperstation/code/game/machinery/safety_tether.dm
+++ b/hyperstation/code/game/machinery/safety_tether.dm
@@ -72,10 +72,22 @@
power_channel = EQUIP
idle_power_usage = 1000
var/teleport_power_draw = 900000 //Uses about a fourth of the upgraded power cell plus default in APCs
- var/tesla_power_ratio = 0.75 //ratio of its actual power draw to the tesla it creates
+ var/tesla_power_ratio = 0.75 //Ratio of its actual power draw to the tesla it creates
critical_machine = TRUE //If this machine is critical to station operation and should have the area be excempted from power failures.
+ //Area types we're allowed to teleport players to. Set up in initialize.
+ var/list/allowed_area_types/*= typecacheof(list(/area/maintenance)) */
+ var/list/blacklisted_areas /*= typecacheof(list(/area)) */
+ var/list/whitelisted_areas /*= typecacheof(list(/area)) */
+ var/list/allowed_areas
+
+ //Whitelist and blacklist of types to not dump players into walls or chasms. Set up in initialize.
+ //Separate check each time for dense objects in way when getRandomTurf called, since no GLOB list of unblocked turfs maintained
+ var/list/turf/allowed_turf_types
+ var/list/turf/disallowed_turf_types
+ var/list/allowed_turfs
+
var/internal_radio = TRUE
var/obj/item/radio/radio
@@ -95,10 +107,24 @@
radio.canhear_range = 0
radio.recalculateChannels()
+ //Setting up the lists for valid teleportation areas
+ allowed_area_types = typecacheof(list(/area/maintenance))
+ //blacklisted_areas = typecacheof(list(/area/))
+ //whitelisted_areas = typecacheof(list(/area/))
+
+ //Set up the list of allowed areas based on our three categories
+ allowed_areas = make_associative(allowed_area_types - blacklisted_areas + whitelisted_areas)
+
+ //Don't dump players into walls or chasms
+ allowed_turf_types = typecacheof(list(/turf/open))
+ disallowed_turf_types = typecacheof(list(/turf/open/chasm))
+
+ allowed_turfs = make_associative(allowed_turf_types - disallowed_turf_types)
+
//ensures light is properly centered around the tether. Removes lighting system's pixel approximation that breaks it.
light_source = get_turf(src)
update_icon()
- power_change() //Here to start lights on ititialization.
+ power_change(TRUE) //Here to start lights on ititialization.
/obj/machinery/safety_tether/Destroy()
QDEL_NULL(radio)
@@ -121,23 +147,50 @@
/obj/machinery/safety_tether/examine(mob/user)
. = ..()
- if(is_operational())
- . += "The safety tether's currently protecting the station."
- else
- . += "The safety tether's offline."
+ var/operating = is_operational()
+ . += "The safety tether's [operating ? "on" : "off"]line."
/obj/machinery/safety_tether/attack_ai(mob/user)
return examine(user)
+
+//Procedure to find a random area to teleport a mob to
+/obj/machinery/safety_tether/proc/findRandomTurf()
+
+ //Pick an area
+ var/area/selected_area = safepick(typecache_filter_list(GLOB.sortedAreas,allowed_areas))
+
+ //Compile a list of turfs to pick from
+ var/list/unblocked_turfs = typecache_filter_list(get_area_turfs(selected_area),allowed_turfs)
+
+ //Check if there's objects with density like machines, doors, or windows in the way, removed from pick list if so
+ for(var/turf/T in unblocked_turfs)
+ if(is_blocked_turf(T))
+ unblocked_turfs -= T
+
+ //Pick a specific turf from our list and return it
+ return safepick(unblocked_turfs)
+
+
//Returns true if teleport is successful, false otherwise
/obj/machinery/safety_tether/proc/bungee_teleport(mob/living/M)
- if(ismovableatom(M) && is_operational() != 0 && do_teleport(M, get_turf(src), channel = TELEPORT_CHANNEL_BLUESPACE))
+ //Teleports the player to a random safe location
+ var/turf/Target_Turf = findRandomTurf() //
+ if(!Target_Turf)
+ Target_Turf = get_turf(src)
+
+ if(ismovableatom(M) && is_operational() != 0 && do_teleport(M, Target_Turf, channel = TELEPORT_CHANNEL_BLUESPACE))
use_power(teleport_power_draw)
//Style points
playsound(src, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 5)
+
+ //For if the player is teleported to maintenance or wherever else
+ if(get_turf(src) != Target_Turf)
+ playsound(M, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 5)
+
// TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES
tesla_zap(src, 3, teleport_power_draw * tesla_power_ratio, TESLA_MOB_DAMAGE | FALSE | TESLA_MOB_STUN | FALSE) //Set to zap harmlessly but in a way that looks cool
@@ -187,10 +240,12 @@
M.blood_volume -= BLOOD_VOLUME_NORMAL * M.blood_ratio * bleed_ratio
src.visible_message("[src] spits out [M] and viscera!")
- if(internal_radio)
- //Area name gotten just in case the locale of it's moved from engineering when mapmaking.
- var/area/A = get_area(get_turf(src))
+ //Radio in the teleportation
+ if(radio && internal_radio)
+
+ //Get the name of the area we teleported the player to
+ var/area/A = get_area(Target_Turf)
var/area_name = A.name
SPEAKMEDICAL("The safety tether's caught the would-be crater [M] at the [area_name].")
@@ -207,10 +262,12 @@
S.apply_damage_type(damage = rand(silicon_burn_min, silicon_burn_max), damagetype = BURN)
src.visible_message("[src] spits out [M] and oily, smoking circuits!")
- if(internal_radio)
- //Area name gotten just in case the locale of it's moved from engineering when mapmaking.
- var/area/A = get_area(get_turf(src))
+ //Radio in the teleportation
+ if(radio && internal_radio)
+
+ //Get the name of the area we teleported the player to
+ var/area/A = get_area(Target_Turf)
var/area_name = A.name
SPEAKSCIENCE("The safety tether's caught the would-be crater [M] at the [area_name].")
@@ -221,14 +278,16 @@
return FALSE
//Updates machine icon and lighting every time power in the area changes
-/obj/machinery/safety_tether/power_change()
+/obj/machinery/safety_tether/power_change(var/initializing = FALSE)
. = ..()
if(light_source)
if(stat & NOPOWER)
- SPEAKCOMMON("The Safety Tether's shut down from a lack of power.")
+ if(!initializing && radio && internal_radio) //If called while initializing results in a null error.
+ SPEAKCOMMON("The Safety Tether's shut down from a lack of power.")
light_source.set_light(0)
else
- SPEAKCOMMON("The Safety Tether is back online.")
+ if(!initializing && radio && internal_radio)
+ SPEAKCOMMON("The Safety Tether is back online.")
light_source.set_light(brightness_on, light_power, light_color)
update_icon()