Files
Bubberstation/code/modules/mapping/mapping_helpers.dm
MrMelbert 16d2571e3f [MDB Ignore] Air alarms of surgical rooms (robotics, medical) start with scrubbers set to filter nitrous oxide (#90558)
## About The Pull Request

- Primary Surgical Theaters
- Secondary Surgical Theaters
- Robotics Surgical Theaters

Now all start the game with their scrubbers set to scrub nitrous oxide
from the air, and expanded range active

## Why It's Good For The Game

Using anesthetic is annoying because it griefs all of medbay. By having
scrubbers start to filter nitrous, people should feel less worried about
griefing all of medbay without needing to call over engineering first.

An alternative to this could be adding a full ventilator machine to
medical which they use to hook people up to anesthetic. Said ventilator
would have an exhaust tank which collects breaths.

## Changelog

🆑 Melbert
add: Air alarms of surgical rooms (Robotics, Medical) start with
scrubbers set to filter Nitrous Oxide
/🆑
2025-04-29 17:51:10 -06:00

1499 lines
53 KiB
Plaintext

//Landmarks and other helpers which speed up the mapping process and reduce the number of unique instances/subtypes of items/turf/ect
/obj/effect/baseturf_helper //Set the baseturfs of every turf in the /area/ it is placed.
name = "baseturf editor"
icon = 'icons/effects/mapping_helpers.dmi'
icon_state = ""
/// Replacing a specific turf
var/list/baseturf_to_replace
/// The desired bottom turf
var/baseturf
plane = POINT_PLANE
/obj/effect/baseturf_helper/Initialize(mapload)
. = ..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/baseturf_helper/LateInitialize()
if(!baseturf_to_replace)
baseturf_to_replace = typecacheof(list(/turf/open/space,/turf/baseturf_bottom))
else if(!length(baseturf_to_replace))
baseturf_to_replace = list(baseturf_to_replace = TRUE)
else if(baseturf_to_replace[baseturf_to_replace[1]] != TRUE) // It's not associative
var/list/formatted = list()
for(var/i in baseturf_to_replace)
formatted[i] = TRUE
baseturf_to_replace = formatted
var/area/our_area = get_area(src)
for(var/i in get_area_turfs(our_area, z))
replace_baseturf(i)
qdel(src)
/// Replaces all the requested baseturfs (usually space/baseturfbottom) with the desired baseturf. Skips if its already there
/obj/effect/baseturf_helper/proc/replace_baseturf(turf/thing)
thing.remove_baseturfs_from_typecache(baseturf_to_replace)
if(length(thing.baseturfs))
var/turf/tile = thing.baseturfs[1]
if(tile == baseturf)
return
thing.place_on_bottom(baseturf)
/obj/effect/baseturf_helper/space
name = "space baseturf editor"
baseturf = /turf/open/space
/obj/effect/baseturf_helper/asteroid
name = "asteroid baseturf editor"
baseturf = /turf/open/misc/asteroid
/obj/effect/baseturf_helper/asteroid/airless
name = "asteroid airless baseturf editor"
baseturf = /turf/open/misc/asteroid/airless
/obj/effect/baseturf_helper/asteroid/basalt
name = "asteroid basalt baseturf editor"
baseturf = /turf/open/misc/asteroid/basalt
/obj/effect/baseturf_helper/asteroid/snow
name = "asteroid snow baseturf editor"
baseturf = /turf/open/misc/asteroid/snow
/obj/effect/baseturf_helper/asteroid/moon
name = "lunar sand baseturf editor"
baseturf = /turf/open/misc/asteroid/moon
/obj/effect/baseturf_helper/beach/sand
name = "beach sand baseturf editor"
baseturf = /turf/open/misc/beach/sand
/obj/effect/baseturf_helper/beach/water
name = "water baseturf editor"
baseturf = /turf/open/water/beach
/obj/effect/baseturf_helper/lava
name = "lava baseturf editor"
baseturf = /turf/open/lava/smooth
/obj/effect/baseturf_helper/lava_land/surface
name = "lavaland baseturf editor"
baseturf = /turf/open/lava/smooth/lava_land_surface
/obj/effect/baseturf_helper/reinforced_plating
name = "reinforced plating baseturf editor"
baseturf = /turf/open/floor/plating/reinforced
baseturf_to_replace = list(/turf/open/floor/plating)
/obj/effect/baseturf_helper/reinforced_plating/replace_baseturf(turf/thing)
if(istype(thing, /turf/open/floor/plating))
return //Plates should not be placed under other plates
thing.stack_ontop_of_baseturf(/turf/open/floor/plating, baseturf)
//This applies the reinforced plating to the above Z level for every tile in the area where this is placed
/obj/effect/baseturf_helper/reinforced_plating/ceiling
name = "reinforced ceiling plating baseturf editor"
/obj/effect/baseturf_helper/reinforced_plating/ceiling/replace_baseturf(turf/thing)
var/turf/ceiling = get_step_multiz(thing, UP)
if(isnull(ceiling))
CRASH("baseturf helper is attempting to modify the Z level above but there is no Z level above it.")
if(isspaceturf(ceiling) || istype(ceiling, /turf/open/openspace))
return
return ..(ceiling)
///Used for marking mapping errors. These should only be created by cases explicitly caught by unit tests, and should NEVER actually appear in production.
/obj/effect/mapping_error
name = "I AM ERROR"
desc = "IF YOU SEE ME, YELL AT A MAPPER!!!"
icon = 'icons/effects/mapping_helpers.dmi'
icon_state = "mapping_error"
/obj/effect/mapping_helpers
icon = 'icons/effects/mapping_helpers.dmi'
icon_state = ""
anchored = TRUE
// Unless otherwise specified, layer above everything
layer = ABOVE_ALL_MOB_LAYER
var/late = FALSE
/obj/effect/mapping_helpers/Initialize(mapload)
..()
return late ? INITIALIZE_HINT_LATELOAD : INITIALIZE_HINT_QDEL
//airlock helpers
/obj/effect/mapping_helpers/airlock
layer = DOOR_HELPER_LAYER
late = TRUE
/// If TRUE we will apply to every windoor in the loc if we can't find an airlock.
var/apply_to_windoors = FALSE
/obj/effect/mapping_helpers/airlock/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
if(!airlock)
if(apply_to_windoors)
var/any_found = FALSE
for(var/obj/machinery/door/window/windoor in loc)
payload(windoor)
any_found = TRUE
if(!any_found)
log_mapping("[src] failed to find an airlock at [AREACOORD(src)], AND no windoors were found.")
return
log_mapping("[src] failed to find an airlock at [AREACOORD(src)]")
return
payload(airlock)
/obj/effect/mapping_helpers/airlock/LateInitialize()
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
if(!airlock)
qdel(src)
return
if(airlock.cyclelinkeddir)
airlock.cyclelinkairlock()
if(airlock.closeOtherId)
airlock.update_other_id()
if(airlock.abandoned)
var/outcome = rand(1,100)
switch(outcome)
if(1 to 9)
var/turf/here = get_turf(src)
for(var/turf/closed/T in range(2, src))
here.place_on_top(T.type)
qdel(airlock)
qdel(src)
return
here.place_on_top(/turf/closed/wall)
qdel(airlock)
qdel(src)
return
if(9 to 11)
airlock.lights = FALSE
// These do not use airlock.bolt() because we want to pretend it was always locked. That means no sound effects.
airlock.locked = TRUE
if(12 to 15)
airlock.locked = TRUE
if(16 to 23)
airlock.welded = TRUE
if(24 to 30)
airlock.set_panel_open(TRUE)
if(airlock.cutAiWire)
airlock.wires.cut(WIRE_AI)
if(airlock.autoname)
airlock.name = get_area_name(src, TRUE)
airlock.update_appearance()
qdel(src)
/obj/effect/mapping_helpers/airlock/proc/payload(obj/machinery/door/airlock/payload)
return
/obj/effect/mapping_helpers/airlock/cyclelink_helper
name = "airlock cyclelink helper"
icon_state = "airlock_cyclelink_helper"
/obj/effect/mapping_helpers/airlock/cyclelink_helper/payload(obj/machinery/door/airlock/airlock)
if(airlock.cyclelinkeddir)
log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!")
else
airlock.cyclelinkeddir = dir
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi
name = "airlock multi-cyclelink helper"
icon_state = "airlock_multicyclelink_helper"
var/cycle_id
/obj/effect/mapping_helpers/airlock/cyclelink_helper_multi/payload(obj/machinery/door/airlock/airlock)
if(airlock.closeOtherId)
log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] closeOtherId, but it's already set!")
else if(!cycle_id)
log_mapping("[src] at [AREACOORD(src)] doesn't have a cycle_id to assign to [airlock]!")
else
airlock.closeOtherId = cycle_id
/obj/effect/mapping_helpers/airlock/locked
name = "airlock lock helper"
icon_state = "airlock_locked_helper"
/obj/effect/mapping_helpers/airlock/locked/payload(obj/machinery/door/airlock/airlock)
if(airlock.locked)
log_mapping("[src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!")
else
// Used instead of bolt so that we can pretend it was always locked, i.e. no sound effects on init.
airlock.locked = TRUE
/obj/effect/mapping_helpers/airlock/unres
name = "airlock unrestricted side helper"
icon_state = "airlock_unres_helper"
/obj/effect/mapping_helpers/airlock/unres/payload(obj/machinery/door/airlock/airlock)
airlock.unres_sides ^= dir
airlock.unres_sensor = TRUE
/obj/effect/mapping_helpers/airlock/abandoned
name = "airlock abandoned helper"
icon_state = "airlock_abandoned"
/obj/effect/mapping_helpers/airlock/abandoned/payload(obj/machinery/door/airlock/airlock)
if(airlock.abandoned)
log_mapping("[src] at [AREACOORD(src)] tried to make [airlock] abandoned but it's already abandoned!")
else
airlock.abandoned = TRUE
/obj/effect/mapping_helpers/airlock/welded
name = "airlock welded helper"
icon_state = "airlock_welded"
/obj/effect/mapping_helpers/airlock/welded/payload(obj/machinery/door/airlock/airlock)
if(airlock.welded)
log_mapping("[src] at [AREACOORD(src)] tried to make [airlock] welded but it's already welded closed!")
airlock.welded = TRUE
/obj/effect/mapping_helpers/airlock/cutaiwire
name = "airlock cut ai wire helper"
icon_state = "airlock_cutaiwire"
/obj/effect/mapping_helpers/airlock/cutaiwire/payload(obj/machinery/door/airlock/airlock)
if(airlock.cutAiWire)
log_mapping("[src] at [AREACOORD(src)] tried to cut the ai wire on [airlock] but it's already cut!")
else
airlock.cutAiWire = TRUE
/obj/effect/mapping_helpers/airlock/autoname
name = "airlock autoname helper"
icon_state = "airlock_autoname"
/obj/effect/mapping_helpers/airlock/autoname/payload(obj/machinery/door/airlock/airlock)
if(airlock.autoname)
log_mapping("[src] at [AREACOORD(src)] tried to autoname the [airlock] but it's already autonamed!")
else
airlock.autoname = TRUE
/obj/effect/mapping_helpers/airlock/inaccessible
name = "airlock inaccessible helper"
icon_state = "airlock_inaccessible"
/obj/effect/mapping_helpers/airlock/inaccessible/payload(obj/machinery/door/airlock/airlock)
if(airlock.req_one_access != null)
log_mapping("[src] at [AREACOORD(src)] tried to set req_access, but req__one_access was already set!")
else
airlock.req_access += list(ACCESS_INACCESSIBLE)
/obj/effect/mapping_helpers/airlock/red_alert_access
name = "airlock red alert access helper"
icon_state = "airlock_red_alert_access"
apply_to_windoors = TRUE
/obj/effect/mapping_helpers/airlock/red_alert_access/payload(obj/machinery/door/airlock)
airlock.red_alert_access = TRUE
//air alarm helpers
/obj/effect/mapping_helpers/airalarm
desc = "You shouldn't see this. Report it please."
late = TRUE
/obj/effect/mapping_helpers/airalarm/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
var/obj/machinery/airalarm/target = locate(/obj/machinery/airalarm) in loc
if(isnull(target))
var/area/target_area = get_area(src)
log_mapping("[src] failed to find an air alarm at [AREACOORD(src)] ([target_area.type]).")
else
payload(target)
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/airalarm/LateInitialize()
var/obj/machinery/airalarm/target = locate(/obj/machinery/airalarm) in loc
if(isnull(target))
qdel(src)
return
if(target.unlocked)
target.unlock()
if(target.tlv_cold_room)
target.set_tlv_cold_room()
if(target.tlv_kitchen)
target.set_tlv_kitchen()
if(target.tlv_no_checks)
target.set_tlv_no_checks()
if(target.tlv_no_checks + target.tlv_cold_room + target.tlv_kitchen > 1)
CRASH("Tried to apply incompatible air alarm threshold helpers!")
if(target.syndicate_access)
target.give_syndicate_access()
if(target.away_general_access)
target.give_away_general_access()
if(target.engine_access)
target.give_engine_access()
if(target.mixingchamber_access)
target.give_mixingchamber_access()
if(target.all_access)
target.give_all_access()
if(target.syndicate_access + target.away_general_access + target.engine_access + target.mixingchamber_access + target.all_access > 1)
CRASH("Tried to combine incompatible air alarm access helpers!")
target.update_appearance()
qdel(src)
/obj/effect/mapping_helpers/airalarm/proc/payload(obj/machinery/airalarm/target)
return
/obj/effect/mapping_helpers/airalarm/unlocked
name = "airalarm unlocked interface helper"
icon_state = "airalarm_unlocked_interface_helper"
/obj/effect/mapping_helpers/airalarm/unlocked/payload(obj/machinery/airalarm/target)
if(target.unlocked)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to unlock the [target] but it's already unlocked!")
target.unlocked = TRUE
/obj/effect/mapping_helpers/airalarm/syndicate_access
name = "airalarm syndicate access helper"
icon_state = "airalarm_syndicate_access_helper"
/obj/effect/mapping_helpers/airalarm/syndicate_access/payload(obj/machinery/airalarm/target)
if(target.syndicate_access)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s access to syndicate but it's already changed!")
target.syndicate_access = TRUE
/obj/effect/mapping_helpers/airalarm/away_general_access
name = "airalarm away access helper"
icon_state = "airalarm_away_general_access_helper"
/obj/effect/mapping_helpers/airalarm/away_general_access/payload(obj/machinery/airalarm/target)
if(target.away_general_access)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s access to away_general but it's already changed!")
target.away_general_access = TRUE
/obj/effect/mapping_helpers/airalarm/engine_access
name = "airalarm engine access helper"
icon_state = "airalarm_engine_access_helper"
/obj/effect/mapping_helpers/airalarm/engine_access/payload(obj/machinery/airalarm/target)
if(target.engine_access)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s access to engine_access but it's already changed!")
target.engine_access = TRUE
/obj/effect/mapping_helpers/airalarm/mixingchamber_access
name = "airalarm mixingchamber access helper"
icon_state = "airalarm_mixingchamber_access_helper"
/obj/effect/mapping_helpers/airalarm/mixingchamber_access/payload(obj/machinery/airalarm/target)
if(target.mixingchamber_access)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s access to mixingchamber_access but it's already changed!")
target.mixingchamber_access = TRUE
/obj/effect/mapping_helpers/airalarm/all_access
name = "airalarm all access helper"
icon_state = "airalarm_all_access_helper"
/obj/effect/mapping_helpers/airalarm/all_access/payload(obj/machinery/airalarm/target)
if(target.all_access)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s access to all_access but it's already changed!")
target.all_access = TRUE
/obj/effect/mapping_helpers/airalarm/tlv_cold_room
name = "airalarm cold room tlv helper"
icon_state = "airalarm_tlv_cold_room_helper"
/obj/effect/mapping_helpers/airalarm/tlv_cold_room/payload(obj/machinery/airalarm/target)
if(target.tlv_cold_room)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s tlv to cold_room but it's already changed!")
target.tlv_cold_room = TRUE
/obj/effect/mapping_helpers/airalarm/tlv_kitchen
name = "airalarm kitchen tlv helper"
icon_state = "airalarm_tlv_kitchen_helper"
/obj/effect/mapping_helpers/airalarm/tlv_kitchen/payload(obj/machinery/airalarm/target)
if(target.tlv_kitchen)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s tlv to kitchen but it's already changed!")
target.tlv_kitchen = TRUE
/obj/effect/mapping_helpers/airalarm/tlv_no_checks
name = "airalarm no checks tlv helper"
icon_state = "airalarm_tlv_no_checks_helper"
/obj/effect/mapping_helpers/airalarm/tlv_no_checks/payload(obj/machinery/airalarm/target)
if(target.tlv_no_checks)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to adjust [target]'s tlv to no_checks but it's already changed!")
target.tlv_no_checks = TRUE
/obj/effect/mapping_helpers/airalarm/link
name = "airalarm link helper"
icon_state = "airalarm_link_helper"
late = TRUE
var/chamber_id = ""
var/allow_link_change = FALSE
/obj/effect/mapping_helpers/airalarm/link/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
/obj/effect/mapping_helpers/airalarm/link/LateInitialize(mapload)
var/obj/machinery/airalarm/alarm = locate(/obj/machinery/airalarm) in loc
if(!isnull(alarm))
alarm.air_sensor_chamber_id = chamber_id
alarm.allow_link_change = allow_link_change
alarm.setup_chamber_link()
else
log_mapping("[src] failed to find air alarm at [AREACOORD(src)].")
qdel(src)
/obj/effect/mapping_helpers/airalarm/surgery
name = "airalarm surgery helper"
icon_state = "airalarm_surgery_helper"
/obj/effect/mapping_helpers/airalarm/surgery/LateInitialize()
var/obj/machinery/airalarm/target = locate() in loc
for(var/obj/machinery/atmospherics/components/unary/vent_scrubber/scrubber as anything in target?.my_area?.air_scrubbers)
scrubber.filter_types |= /datum/gas/nitrous_oxide
scrubber.set_widenet(TRUE)
return ..()
//apc helpers
/obj/effect/mapping_helpers/apc
desc = "You shouldn't see this. Report it please."
late = TRUE
/obj/effect/mapping_helpers/apc/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
var/obj/machinery/power/apc/target = locate(/obj/machinery/power/apc) in loc
if(isnull(target))
var/area/target_area = get_area(src)
log_mapping("[src] failed to find an apc at [AREACOORD(src)] ([target_area.type]).")
else
payload(target)
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/apc/LateInitialize()
var/obj/machinery/power/apc/target = locate(/obj/machinery/power/apc) in loc
if(isnull(target))
qdel(src)
return
if(target.cut_AI_wire)
target.wires.cut(WIRE_AI)
if(target.cell_5k)
target.install_cell_5k()
if(target.cell_10k)
target.install_cell_10k()
if(target.unlocked)
target.unlock()
if(target.syndicate_access)
target.give_syndicate_access()
if(target.away_general_access)
target.give_away_general_access()
if(target.no_charge)
target.set_no_charge()
if(target.full_charge)
target.set_full_charge()
if(target.cell_5k && target.cell_10k)
CRASH("Tried to combine non-combinable cell_5k and cell_10k APC helpers!")
if(target.syndicate_access && target.away_general_access)
CRASH("Tried to combine non-combinable syndicate_access and away_general_access APC helpers!")
if(target.no_charge && target.full_charge)
CRASH("Tried to combine non-combinable no_charge and full_charge APC helpers!")
target.update_appearance()
qdel(src)
/obj/effect/mapping_helpers/apc/proc/payload(obj/machinery/power/apc/target)
return
/obj/effect/mapping_helpers/apc/cut_AI_wire
name = "apc AI wire mended helper"
icon_state = "apc_cut_AIwire_helper"
/obj/effect/mapping_helpers/apc/cut_AI_wire/payload(obj/machinery/power/apc/target)
if(target.cut_AI_wire)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to mend the AI wire on the [target] but it's already cut!")
target.cut_AI_wire = TRUE
/obj/effect/mapping_helpers/apc/cell_5k
name = "apc 5k cell helper"
icon_state = "apc_5k_cell_helper"
/obj/effect/mapping_helpers/apc/cell_5k/payload(obj/machinery/power/apc/target)
if(target.cell_5k)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to change [target]'s cell to cell_5k but it's already changed!")
target.cell_5k = TRUE
/obj/effect/mapping_helpers/apc/cell_10k
name = "apc 10k cell helper"
icon_state = "apc_10k_cell_helper"
/obj/effect/mapping_helpers/apc/cell_10k/payload(obj/machinery/power/apc/target)
if(target.cell_10k)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to change [target]'s cell to cell_10k but it's already changed!")
target.cell_10k = TRUE
/obj/effect/mapping_helpers/apc/syndicate_access
name = "apc syndicate access helper"
icon_state = "apc_syndicate_access_helper"
/obj/effect/mapping_helpers/apc/syndicate_access/payload(obj/machinery/power/apc/target)
if(target.syndicate_access)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to adjust [target]'s access to syndicate but it's already changed!")
target.syndicate_access = TRUE
/obj/effect/mapping_helpers/apc/away_general_access
name = "apc away access helper"
icon_state = "apc_away_general_access_helper"
/obj/effect/mapping_helpers/apc/away_general_access/payload(obj/machinery/power/apc/target)
if(target.away_general_access)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to adjust [target]'s access to away_general but it's already changed!")
target.away_general_access = TRUE
/obj/effect/mapping_helpers/apc/unlocked
name = "apc unlocked interface helper"
icon_state = "apc_unlocked_interface_helper"
/obj/effect/mapping_helpers/apc/unlocked/payload(obj/machinery/power/apc/target)
if(target.unlocked)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to unlock the [target] but it's already unlocked!")
target.unlocked = TRUE
/obj/effect/mapping_helpers/apc/no_charge
name = "apc no charge helper"
icon_state = "apc_no_charge_helper"
/obj/effect/mapping_helpers/apc/no_charge/payload(obj/machinery/power/apc/target)
if(target.no_charge)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to set [target]'s charge to 0 but it's already at 0!")
target.no_charge = TRUE
/obj/effect/mapping_helpers/apc/full_charge
name = "apc full charge helper"
icon_state = "apc_full_charge_helper"
/obj/effect/mapping_helpers/apc/full_charge/payload(obj/machinery/power/apc/target)
if(target.full_charge)
var/area/apc_area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(apc_area.type)] tried to set [target]'s charge to 100 but it's already at 100!")
target.full_charge = TRUE
//Used to turn off lights with lightswitch in areas.
/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch
name = "area turned off lights helper"
icon_state = "lights_off"
/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/turn_off_lights_with_lightswitch/LateInitialize()
var/area/needed_area = get_area(src)
if(!needed_area.lightswitch)
stack_trace("[src] at [AREACOORD(src)] [(needed_area.type)] tried to turn lights off but they are already off!")
var/obj/machinery/light_switch/light_switch = locate(/obj/machinery/light_switch) in needed_area
if(!light_switch)
CRASH("Trying to turn off lights with lightswitch in area without lightswitches. In [(needed_area.type)] to be precise.")
light_switch.set_lights(FALSE)
qdel(src)
//needs to do its thing before spawn_rivers() is called
INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
/obj/effect/mapping_helpers/no_lava
icon_state = "no_lava"
/obj/effect/mapping_helpers/no_lava/Initialize(mapload)
. = ..()
var/turf/T = get_turf(src)
T.turf_flags |= NO_LAVA_GEN
INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_atoms_ontop)
/obj/effect/mapping_helpers/no_atoms_ontop
icon_state = "no_atoms_ontop"
/obj/effect/mapping_helpers/no_atoms_ontop/Initialize(mapload)
. = ..()
var/turf/loc_turf = get_turf(src)
loc_turf.turf_flags |= TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES
///Helpers used for injecting stuff into atoms on the map.
/obj/effect/mapping_helpers/atom_injector
name = "Atom Injector"
icon_state = "injector"
late = TRUE
///Will inject into all fitting the criteria if false, otherwise first found.
var/first_match_only = TRUE
///Will inject into atoms of this type.
var/target_type
///Will inject into atoms with this name.
var/target_name
//Late init so everything is likely ready and loaded (no warranty)
/obj/effect/mapping_helpers/atom_injector/LateInitialize()
if(!check_validity())
return
var/turf/target_turf = get_turf(src)
var/matches_found = 0
for(var/atom/atom_on_turf as anything in target_turf.get_all_contents())
if(atom_on_turf == src)
continue
if(target_name && atom_on_turf.name != target_name)
continue
if(target_type && !istype(atom_on_turf, target_type))
continue
inject(atom_on_turf)
matches_found++
if(first_match_only)
qdel(src)
return
if(!matches_found)
stack_trace(generate_stack_trace())
qdel(src)
///Checks if whatever we are trying to inject with is valid
/obj/effect/mapping_helpers/atom_injector/proc/check_validity()
return TRUE
///Injects our stuff into the atom
/obj/effect/mapping_helpers/atom_injector/proc/inject(atom/target)
return
///Generates text for our stack trace
/obj/effect/mapping_helpers/atom_injector/proc/generate_stack_trace()
. = "[name] found no targets at ([x], [y], [z]). First Match Only: [first_match_only ? "true" : "false"] target type: [target_type] | target name: [target_name]"
/obj/effect/mapping_helpers/atom_injector/obj_flag
name = "Obj Flag Injector"
icon_state = "objflag_helper"
var/inject_flags = NONE
/obj/effect/mapping_helpers/atom_injector/obj_flag/inject(atom/target)
if(!isobj(target))
return
var/obj/obj_target = target
obj_target.obj_flags |= inject_flags
///This helper applies components to things on the map directly.
/obj/effect/mapping_helpers/atom_injector/component_injector
name = "Component Injector"
icon_state = "component"
///Typepath of the component.
var/component_type
///Arguments for the component.
var/list/component_args = list()
/obj/effect/mapping_helpers/atom_injector/component_injector/check_validity()
if(!ispath(component_type, /datum/component))
CRASH("Wrong component type in [type] - [component_type] is not a component")
return TRUE
/obj/effect/mapping_helpers/atom_injector/component_injector/inject(atom/target)
var/arguments = list(component_type)
arguments += component_args
target._AddComponent(arguments)
/obj/effect/mapping_helpers/atom_injector/component_injector/generate_stack_trace()
. = ..()
. += " | component type: [component_type] | component arguments: [list2params(component_args)]"
///This helper applies elements to things on the map directly.
/obj/effect/mapping_helpers/atom_injector/element_injector
name = "Element Injector"
icon_state = "element"
///Typepath of the element.
var/element_type
///Arguments for the element.
var/list/element_args = list()
/obj/effect/mapping_helpers/atom_injector/element_injector/check_validity()
if(!ispath(element_type, /datum/element))
CRASH("Wrong element type in [type] - [element_type] is not a element")
return TRUE
/obj/effect/mapping_helpers/atom_injector/element_injector/inject(atom/target)
var/arguments = list(element_type)
arguments += element_args
target._AddElement(arguments)
/obj/effect/mapping_helpers/atom_injector/element_injector/generate_stack_trace()
. = ..()
. += " | element type: [element_type] | element arguments: [list2params(element_args)]"
///This helper applies traits to things on the map directly.
/obj/effect/mapping_helpers/atom_injector/trait_injector
name = "Trait Injector"
icon_state = "trait"
///Name of the trait, in the lower-case text (NOT the upper-case define) form.
var/trait_name
/obj/effect/mapping_helpers/atom_injector/trait_injector/check_validity()
if(!istext(trait_name))
CRASH("Wrong trait in [type] - [trait_name] is not a trait")
if(!GLOB.global_trait_name_map)
GLOB.global_trait_name_map = generate_global_trait_name_map()
if(!GLOB.global_trait_name_map.Find(trait_name))
stack_trace("Possibly wrong trait in [type] - [trait_name] is not a trait in the global trait list")
return TRUE
/obj/effect/mapping_helpers/atom_injector/trait_injector/inject(atom/target)
ADD_TRAIT(target, trait_name, MAPPING_HELPER_TRAIT)
/obj/effect/mapping_helpers/atom_injector/trait_injector/generate_stack_trace()
. = ..()
. += " | trait name: [trait_name]"
///This helper applies dynamic human icons to things on the map
/obj/effect/mapping_helpers/atom_injector/human_icon_injector
name = "Human Icon Injector"
icon_state = "icon"
/// Path of the outfit we give the human.
var/outfit_path
/// Path of the species we give the human.
var/species_path = /datum/species/human
/// Path of the mob spawner we base the human off of.
var/mob_spawn_path
/// Path of the right hand item we give the human.
var/r_hand = NO_REPLACE
/// Path of the left hand item we give the human.
var/l_hand = NO_REPLACE
/// Which slots on the mob should be bloody?
var/bloody_slots = NONE
/// Do we draw more than one frame for the mob?
var/animated = TRUE
/obj/effect/mapping_helpers/atom_injector/human_icon_injector/check_validity()
if(!ispath(species_path, /datum/species))
CRASH("Wrong species path in [type] - [species_path] is not a species")
if(outfit_path && !ispath(outfit_path, /datum/outfit))
CRASH("Wrong outfit path in [type] - [species_path] is not an outfit")
if(mob_spawn_path && !ispath(mob_spawn_path, /obj/effect/mob_spawn))
CRASH("Wrong mob spawn path in [type] - [mob_spawn_path] is not a mob spawner")
if(l_hand && !ispath(l_hand, /obj/item))
CRASH("Wrong left hand item path in [type] - [l_hand] is not an item")
if(r_hand && !ispath(r_hand, /obj/item))
CRASH("Wrong left hand item path in [type] - [r_hand] is not an item")
return TRUE
/obj/effect/mapping_helpers/atom_injector/human_icon_injector/inject(atom/target)
apply_dynamic_human_appearance(target, outfit_path, species_path, mob_spawn_path, r_hand, l_hand, bloody_slots, animated)
/obj/effect/mapping_helpers/atom_injector/human_icon_injector/generate_stack_trace()
. = ..()
. += " | outfit path: [outfit_path] | species path: [species_path] | mob spawner path: [mob_spawn_path] | right/left hand path: [r_hand]/[l_hand]"
///Fetches an external dmi and applies to the target object
/obj/effect/mapping_helpers/atom_injector/custom_icon
name = "Custom Icon Injector"
icon_state = "icon"
///This is the var that will be set with the fetched icon. In case you want to set some secondary icon sheets like inhands and such.
var/target_variable = "icon"
///This should return raw dmi in response to http get request. For example: "https://github.com/tgstation/SS13-sprites/raw/master/mob/medu.dmi?raw=true"
var/icon_url
///The icon file we fetched from the http get request.
var/icon_file
/obj/effect/mapping_helpers/atom_injector/custom_icon/check_validity()
var/static/icon_cache = list()
var/static/query_in_progress = FALSE //We're using a single tmp file so keep it linear.
if(query_in_progress)
UNTIL(!query_in_progress)
if(icon_cache[icon_url])
icon_file = icon_cache[icon_url]
return TRUE
log_asset("Custom Icon Helper fetching dmi from: [icon_url]")
var/datum/http_request/request = new()
var/file_name = "tmp/custom_map_icon.dmi"
request.prepare(RUSTG_HTTP_METHOD_GET, icon_url, "", "", file_name)
query_in_progress = TRUE
request.begin_async()
UNTIL(request.is_complete())
var/datum/http_response/response = request.into_response()
if(response.errored || response.status_code != 200)
query_in_progress = FALSE
CRASH("Failed to fetch mapped custom icon from url [icon_url], code: [response.status_code], error: [response.error]")
var/icon/new_icon = new(file_name)
icon_cache[icon_url] = new_icon
query_in_progress = FALSE
icon_file = new_icon
return TRUE
/obj/effect/mapping_helpers/atom_injector/custom_icon/inject(atom/target)
if(IsAdminAdvancedProcCall())
return
target.vars[target_variable] = icon_file
/obj/effect/mapping_helpers/atom_injector/custom_icon/generate_stack_trace()
. = ..()
. += " | target variable: [target_variable] | icon url: [icon_url]"
///Fetches an external sound and applies to the target object
/obj/effect/mapping_helpers/atom_injector/custom_sound
name = "Custom Sound Injector"
icon_state = "sound"
///This is the var that will be set with the fetched sound.
var/target_variable = "hitsound"
///This should return raw sound in response to http get request. For example: "https://github.com/tgstation/tgstation/blob/master/sound/misc/bang.ogg?raw=true"
var/sound_url
///The sound file we fetched from the http get request.
var/sound_file
/obj/effect/mapping_helpers/atom_injector/custom_sound/check_validity()
var/static/sound_cache = list()
var/static/query_in_progress = FALSE //We're using a single tmp file so keep it linear.
if(query_in_progress)
UNTIL(!query_in_progress)
if(sound_cache[sound_url])
sound_file = sound_cache[sound_url]
return TRUE
log_asset("Custom Sound Helper fetching sound from: [sound_url]")
var/datum/http_request/request = new()
var/file_name = "tmp/custom_map_sound.ogg"
request.prepare(RUSTG_HTTP_METHOD_GET, sound_url, "", "", file_name)
query_in_progress = TRUE
request.begin_async()
UNTIL(request.is_complete())
var/datum/http_response/response = request.into_response()
if(response.errored || response.status_code != 200)
query_in_progress = FALSE
CRASH("Failed to fetch mapped custom sound from url [sound_url], code: [response.status_code], error: [response.error]")
var/sound/new_sound = new(file_name)
sound_cache[sound_url] = new_sound
query_in_progress = FALSE
sound_file = new_sound
return TRUE
/obj/effect/mapping_helpers/atom_injector/custom_sound/inject(atom/target)
if(IsAdminAdvancedProcCall())
return
target.vars[target_variable] = sound_file
/obj/effect/mapping_helpers/atom_injector/custom_sound/generate_stack_trace()
. = ..()
. += " | target variable: [target_variable] | sound url: [sound_url]"
/obj/effect/mapping_helpers/dead_body_placer
name = "Dead Body placer"
late = TRUE
icon_state = "deadbodyplacer"
///if TRUE, was spawned out of mapload.
var/admin_spawned
///number of bodies to spawn
var/bodycount = 3
/// Corpse type we spawn thats always human
var/datum/corpse_damage_class/morgue_body_class = /datum/corpse_damage_class/station/morgue
/obj/effect/mapping_helpers/dead_body_placer/Initialize(mapload)
. = ..()
if(mapload)
return
admin_spawned = TRUE
/obj/effect/mapping_helpers/dead_body_placer/LateInitialize()
var/area/morgue_area = get_area(src)
var/list/obj/structure/bodycontainer/morgue/trays = list()
for (var/list/zlevel_turfs as anything in morgue_area.get_zlevel_turf_lists())
for(var/turf/area_turf as anything in zlevel_turfs)
var/obj/structure/bodycontainer/morgue/morgue_tray = locate() in area_turf
if(isnull(morgue_tray) || !morgue_tray.beeper || morgue_tray.connected.loc != morgue_tray)
continue
trays += morgue_tray
var/numtrays = length(trays)
if(numtrays == 0)
if(admin_spawned)
message_admins("[src] spawned at [ADMIN_VERBOSEJMP(src)] failed to find a closed morgue to spawn a body!")
else
log_mapping("[src] at [x],[y] could not find any morgues.")
return
var/reuse_trays = (numtrays < bodycount) //are we going to spawn more trays than bodies?
for (var/i in 1 to bodycount)
var/obj/structure/bodycontainer/morgue/morgue_tray = reuse_trays ? pick(trays) : pick_n_take(trays)
var/obj/structure/closet/body_bag/body_bag = new(morgue_tray.loc)
var/mob/living/carbon/human/new_human = GLOB.lost_crew_manager.create_lost_crew(revivable = FALSE, forced_class = morgue_body_class)
body_bag.insert(new_human, TRUE)
body_bag.close()
body_bag.handle_tag("[new_human.real_name][new_human.dna?.species ? " - [new_human.dna.species.name]" : " - Human"]")
body_bag.forceMove(morgue_tray)
morgue_tray.update_appearance()
qdel(src)
//On Ian's birthday, the hop's office is decorated.
/obj/effect/mapping_helpers/ianbirthday
name = "Ian's Bday Helper"
late = TRUE
icon_state = "iansbdayhelper"
/// How many clusters of balloons to spawn.
var/balloon_clusters = 2
/// if TRUE, we give a map log warning if we can't find Ian's dogbed.
var/map_warning = TRUE
/obj/effect/mapping_helpers/ianbirthday/LateInitialize()
if(check_holidays(IAN_HOLIDAY))
birthday()
qdel(src)
/obj/effect/mapping_helpers/ianbirthday/proc/birthday()
var/area/celebration_area = get_area(src)
var/list/table_turfs = list()
var/list/open_turfs = list()
var/turf/dogbed_turf
for (var/list/zlevel_turfs as anything in celebration_area.get_zlevel_turf_lists())
for(var/turf/area_turf as anything in zlevel_turfs)
if(locate(/obj/structure/table/reinforced) in area_turf)
table_turfs += area_turf
if(locate(/obj/structure/bed/dogbed/ian) in area_turf)
dogbed_turf = area_turf
if(isopenturf(area_turf))
new /obj/effect/decal/cleanable/confetti(area_turf)
open_turfs += area_turf
if(isnull(dogbed_turf) && map_warning)
log_mapping("[src] in [celebration_area] could not find Ian's dogbed.")
else
new /obj/item/toy/balloon/corgi(dogbed_turf)
var/turf/food_turf = length(table_turfs) ? pick(table_turfs) : dogbed_turf
new /obj/item/knife/kitchen(food_turf)
var/obj/item/food/cake/birthday/iancake = new(food_turf)
iancake.desc = "Happy birthday, Ian!"
if(!length(open_turfs))
return
//some balloons! this picks an open turf and pops a few balloons in and around that turf, yay.
for(var/i in 1 to balloon_clusters)
var/turf/clusterspot = pick_n_take(open_turfs)
new /obj/item/toy/balloon(clusterspot)
var/balloons_left_to_give = 3 //the amount of balloons around the cluster
var/list/dirs_to_balloon = GLOB.cardinals.Copy()
while(balloons_left_to_give > 0)
balloons_left_to_give--
var/chosen_dir = pick_n_take(dirs_to_balloon)
var/turf/balloonstep = get_step(clusterspot, chosen_dir)
var/placed = FALSE
if(isopenturf(balloonstep))
var/obj/item/toy/balloon/B = new(balloonstep)//this clumps the cluster together
placed = TRUE
if(chosen_dir == NORTH)
B.pixel_y -= 10
if(chosen_dir == SOUTH)
B.pixel_y += 10
if(chosen_dir == EAST)
B.pixel_x -= 10
if(chosen_dir == WEST)
B.pixel_x += 10
if(!placed)
new /obj/item/toy/balloon(clusterspot)
//remind me to add wall decor!
/obj/effect/mapping_helpers/ianbirthday/admin//so admins may birthday any room
name = "generic birthday setup"
icon_state = "bdayhelper"
map_warning = FALSE
/obj/effect/mapping_helpers/ianbirthday/admin/LateInitialize()
birthday()
qdel(src)
//Ian, like most dogs, loves a good new years eve party.
/obj/effect/mapping_helpers/iannewyear
name = "Ian's New Years Helper"
late = TRUE
icon_state = "iansnewyrshelper"
/obj/effect/mapping_helpers/iannewyear/LateInitialize()
if(check_holidays(NEW_YEAR))
fireworks()
qdel(src)
/obj/effect/mapping_helpers/iannewyear/proc/fireworks()
var/area/celebration_area = get_area(src)
var/list/table_turfs = list()
var/turf/dogbed_turf
for (var/list/zlevel_turfs as anything in celebration_area.get_zlevel_turf_lists())
for(var/turf/area_turf as anything in zlevel_turfs)
if(locate(/obj/structure/table/reinforced) in area_turf)
table_turfs += area_turf
if(locate(/obj/structure/bed/dogbed/ian) in area_turf)
dogbed_turf = area_turf
if(isnull(dogbed_turf))
log_mapping("[src] in [celebration_area] could not find Ian's dogbed.")
return
new /obj/item/clothing/head/costume/festive(dogbed_turf)
var/obj/item/reagent_containers/cup/glass/bottle/champagne/iandrink = new(dogbed_turf)
iandrink.name = "dog champagne"
iandrink.pixel_y += 8
iandrink.pixel_x += 8
var/turf/fireworks_turf = length(table_turfs) ? pick(table_turfs) : dogbed_turf
var/obj/item/storage/box/matches/matchbox = new(fireworks_turf)
matchbox.pixel_y += 8
matchbox.pixel_x -= 3
new /obj/item/storage/box/fireworks/dangerous(fireworks_turf) //dangerous version for extra holiday memes.
//lets mappers place notes on airlocks with custom info or a pre-made note from a path
/obj/effect/mapping_helpers/airlock_note_placer
name = "Airlock Note Placer"
late = TRUE
icon_state = "airlocknoteplacer"
var/note_info //for writing out custom notes without creating an extra paper subtype
var/note_name //custom note name
var/note_path //if you already have something wrote up in a paper subtype, put the path here
/obj/effect/mapping_helpers/airlock_note_placer/LateInitialize()
var/turf/turf = get_turf(src)
if(note_path && !ispath(note_path, /obj/item/paper)) //don't put non-paper in the paper slot thank you
log_mapping("[src] at [x],[y] had an improper note_path path, could not place paper note.")
qdel(src)
return
if(locate(/obj/machinery/door/airlock) in turf)
var/obj/machinery/door/airlock/found_airlock = locate(/obj/machinery/door/airlock) in turf
if(note_path)
found_airlock.note = note_path
found_airlock.update_appearance()
qdel(src)
return
if(note_info)
var/obj/item/paper/paper = new /obj/item/paper(src)
if(note_name)
paper.name = note_name
paper.add_raw_text("[note_info]")
paper.update_appearance()
found_airlock.note = paper
paper.forceMove(found_airlock)
found_airlock.update_appearance()
qdel(src)
return
log_mapping("[src] at [x],[y] had no note_path or note_info, cannot place paper note.")
qdel(src)
return
log_mapping("[src] at [x],[y] could not find an airlock on current turf, cannot place paper note.")
qdel(src)
/**
* ## trapdoor placer!
*
* This places an unlinked trapdoor in the tile its on (so someone with a remote needs to link it up first)
* Pre-mapped trapdoors (unlike player-made ones) are not conspicuous by default so nothing stands out with them
* Admins may spawn this in the round for additional trapdoors if they so desire
* if YOU want to learn more about trapdoors, read about the component at trapdoor.dm
* note: this is not a turf subtype because the trapdoor needs the type of the turf to turn back into
*/
/obj/effect/mapping_helpers/trapdoor_placer
name = "trapdoor placer"
icon_state = "trapdoor"
late = TRUE
/obj/effect/mapping_helpers/trapdoor_placer/LateInitialize()
var/turf/component_target = get_turf(src)
component_target.AddComponent(/datum/component/trapdoor, starts_open = FALSE, conspicuous = FALSE)
qdel(src)
/obj/effect/mapping_helpers/ztrait_injector
name = "ztrait injector"
icon_state = "ztrait"
late = TRUE
/// List of traits to add to this Z-level.
var/list/traits_to_add = list()
/obj/effect/mapping_helpers/ztrait_injector/LateInitialize()
var/datum/space_level/level = SSmapping.z_list[z]
if(!level || !length(traits_to_add))
return
level.traits |= traits_to_add
SSweather.update_z_level(level) //in case of someone adding a weather for the level, we want SSweather to update for that
/obj/effect/mapping_helpers/circuit_spawner
name = "circuit spawner"
icon_state = "circuit"
/// The shell for the circuit.
var/atom/movable/circuit_shell
/// Capacity of the shell.
var/shell_capacity = SHELL_CAPACITY_VERY_LARGE
/// The url for the json. Example: "https://pastebin.com/raw/eH7VnP9d"
var/json_url
/obj/effect/mapping_helpers/circuit_spawner/Initialize(mapload)
. = ..()
INVOKE_ASYNC(src, PROC_REF(spawn_circuit))
/obj/effect/mapping_helpers/circuit_spawner/proc/spawn_circuit()
var/list/errors = list()
var/obj/item/integrated_circuit/loaded/new_circuit = new(loc)
var/json_data = load_data()
new_circuit.load_circuit_data(json_data, errors)
if(!circuit_shell)
return
circuit_shell = new(loc)
var/datum/component/shell/shell_component = circuit_shell.GetComponent(/datum/component/shell)
if(shell_component)
shell_component.shell_flags |= SHELL_FLAG_CIRCUIT_UNMODIFIABLE|SHELL_FLAG_CIRCUIT_UNREMOVABLE
shell_component.attach_circuit(new_circuit)
else
shell_component = circuit_shell.AddComponent(/datum/component/shell, \
capacity = shell_capacity, \
shell_flags = SHELL_FLAG_CIRCUIT_UNMODIFIABLE|SHELL_FLAG_CIRCUIT_UNREMOVABLE, \
starting_circuit = new_circuit, \
)
/obj/effect/mapping_helpers/circuit_spawner/proc/load_data()
var/static/json_cache = list()
var/static/query_in_progress = FALSE //We're using a single tmp file so keep it linear.
if(query_in_progress)
UNTIL(!query_in_progress)
if(json_cache[json_url])
return json_cache[json_url]
log_asset("Circuit Spawner fetching json from: [json_url]")
var/datum/http_request/request = new()
request.prepare(RUSTG_HTTP_METHOD_GET, json_url, "")
query_in_progress = TRUE
request.begin_async()
UNTIL(request.is_complete())
var/datum/http_response/response = request.into_response()
if(response.errored || response.status_code != 200)
query_in_progress = FALSE
CRASH("Failed to fetch mapped custom json from url [json_url], code: [response.status_code], error: [response.error]")
var/json_data = response.body
json_cache[json_url] = json_data
query_in_progress = FALSE
return json_data
/obj/effect/mapping_helpers/broken_floor
name = "broken floor"
icon = 'icons/turf/damaged.dmi'
icon_state = "damaged1"
layer = ABOVE_NORMAL_TURF_LAYER
late = TRUE
/obj/effect/mapping_helpers/broken_floor/LateInitialize()
var/turf/open/floor/floor = get_turf(src)
floor.break_tile()
qdel(src)
/obj/effect/mapping_helpers/burnt_floor
name = "burnt floor"
icon = 'icons/turf/damaged.dmi'
icon_state = "floorscorched1"
layer = ABOVE_NORMAL_TURF_LAYER
late = TRUE
/obj/effect/mapping_helpers/burnt_floor/LateInitialize()
var/turf/open/floor/floor = get_turf(src)
floor.burn_tile()
qdel(src)
///Applies BROKEN flag to the first found machine on a tile
/obj/effect/mapping_helpers/broken_machine
name = "broken machine helper"
icon_state = "broken_machine"
late = TRUE
/obj/effect/mapping_helpers/broken_machine/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
var/obj/machinery/target = locate(/obj/machinery) in loc
if(isnull(target))
var/area/target_area = get_area(src)
log_mapping("[src] failed to find a machine at [AREACOORD(src)] ([target_area.type]).")
else
payload(target)
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/broken_machine/LateInitialize()
var/obj/machinery/target = locate(/obj/machinery) in loc
if(isnull(target))
qdel(src)
return
target.update_appearance()
qdel(src)
/obj/effect/mapping_helpers/broken_machine/proc/payload(obj/machinery/airalarm/target)
if(target.machine_stat & BROKEN)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to break [target] but it's already broken!")
target.set_machine_stat(target.machine_stat | BROKEN)
///Deals random damage to the first window found on a tile to appear cracked
/obj/effect/mapping_helpers/damaged_window
name = "damaged window helper"
icon_state = "damaged_window"
late = TRUE
/// Minimum roll of integrity damage in percents needed to show cracks
var/integrity_damage_min = 0.25
/// Maximum roll of integrity damage in percents needed to show cracks
var/integrity_damage_max = 0.85
/obj/effect/mapping_helpers/damaged_window/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/damaged_window/LateInitialize()
var/obj/structure/window/target = locate(/obj/structure/window) in loc
if(isnull(target))
var/area/target_area = get_area(src)
log_mapping("[src] failed to find a window at [AREACOORD(src)] ([target_area.type]).")
qdel(src)
return
else
payload(target)
target.update_appearance()
qdel(src)
/obj/effect/mapping_helpers/damaged_window/proc/payload(obj/structure/window/target)
if(target.get_integrity() < target.max_integrity)
var/area/area = get_area(target)
log_mapping("[src] at [AREACOORD(src)] [(area.type)] tried to damage [target] but it's already damaged!")
target.take_damage(rand(target.max_integrity * integrity_damage_min, target.max_integrity * integrity_damage_max))
//requests console helpers
/obj/effect/mapping_helpers/requests_console
desc = "You shouldn't see this. Report it please."
late = TRUE
/obj/effect/mapping_helpers/requests_console/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/requests_console/LateInitialize()
var/obj/machinery/airalarm/target = locate(/obj/machinery/requests_console) in loc
if(isnull(target))
var/area/target_area = get_area(src)
log_mapping("[src] failed to find a requests console at [AREACOORD(src)] ([target_area.type]).")
else
payload(target)
qdel(src)
/// Fills out the request console's variables
/obj/effect/mapping_helpers/requests_console/proc/payload(obj/machinery/requests_console/console)
return
/obj/effect/mapping_helpers/requests_console/announcement
name = "request console announcement helper"
icon_state = "requests_console_announcement_helper"
/obj/effect/mapping_helpers/requests_console/announcement/payload(obj/machinery/requests_console/console)
console.can_send_announcements = TRUE
/obj/effect/mapping_helpers/requests_console/assistance
name = "request console assistance requestable helper"
icon_state = "requests_console_assistance_helper"
/obj/effect/mapping_helpers/requests_console/assistance/payload(obj/machinery/requests_console/console)
GLOB.req_console_assistance |= console.department
/obj/effect/mapping_helpers/requests_console/supplies
name = "request console supplies requestable helper"
icon_state = "requests_console_supplies_helper"
/obj/effect/mapping_helpers/requests_console/supplies/payload(obj/machinery/requests_console/console)
GLOB.req_console_supplies |= console.department
/obj/effect/mapping_helpers/requests_console/information
name = "request console information relayable helper"
icon_state = "requests_console_information_helper"
/obj/effect/mapping_helpers/requests_console/information/payload(obj/machinery/requests_console/console)
GLOB.req_console_information |= console.department
/obj/effect/mapping_helpers/requests_console/ore_update
name = "request console ore update helper"
icon_state = "requests_console_ore_update_helper"
/obj/effect/mapping_helpers/requests_console/ore_update/payload(obj/machinery/requests_console/console)
console.receive_ore_updates = TRUE
/obj/effect/mapping_helpers/engraving
name = "engraving helper"
icon = 'icons/turf/wall_overlays.dmi'
icon_state = "engraving2"
late = TRUE
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/mapping_helpers/engraving/Initialize(mapload)
. = ..()
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/engraving/LateInitialize()
var/turf/closed/engraved_wall = get_turf(src)
if(!isclosedturf(engraved_wall) || !SSpersistence.saved_engravings.len || HAS_TRAIT(engraved_wall, TRAIT_NOT_ENGRAVABLE))
qdel(src)
return
var/engraving = pick_n_take(SSpersistence.saved_engravings)
if(!islist(engraving))
stack_trace("something's wrong with the engraving data! one of the saved engravings wasn't a list!")
qdel(src)
return
engraved_wall.AddComponent(/datum/component/engraved, engraving["story"], FALSE, engraving["story_value"])
qdel(src)
/// Apply to a wall (or floor, technically) to ensure it is instantly destroyed by any explosion, even if usually invulnerable
/obj/effect/mapping_helpers/bombable_wall
name = "bombable wall helper"
icon = 'icons/turf/overlays.dmi'
icon_state = "explodable"
/obj/effect/mapping_helpers/bombable_wall/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return
var/turf/our_turf = get_turf(src) // In case a locker ate us or something
our_turf.AddElement(/datum/element/bombable_turf)
return INITIALIZE_HINT_QDEL
/// this helper buckles all mobs on the tile to the first buckleable object
/obj/effect/mapping_helpers/mob_buckler
name = "Buckle Mob"
icon_state = "buckle"
late = TRUE
///whether we force a buckle
var/force_buckle = FALSE
/obj/effect/mapping_helpers/mob_buckler/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
return INITIALIZE_HINT_LATELOAD
/obj/effect/mapping_helpers/mob_buckler/LateInitialize()
var/atom/movable/buckle_to
var/list/mobs = list()
for(var/atom/movable/possible_buckle as anything in loc)
if(isnull(buckle_to) && possible_buckle.can_buckle)
buckle_to = possible_buckle
continue
if(isliving(possible_buckle))
mobs += possible_buckle
if(isnull(buckle_to))
log_mapping("[type] at [x] [y] [z] did not find anything to buckle to")
qdel(src)
return
for(var/mob/living/mob as anything in mobs)
buckle_to.buckle_mob(mob, force = force_buckle)
qdel(src)
///Basic mob flag helpers for things like deleting on death.
/obj/effect/mapping_helpers/basic_mob_flags
name = "Basic mob flags helper"
desc = "Used to apply basic_mob_flags to basic mobs on the same turf."
late = TRUE
///The basic mob flag that we're adding to all basic mobs on the turf.
var/flag_to_give
/obj/effect/mapping_helpers/basic_mob_flags/Initialize(mapload)
. = ..()
if(!mapload)
log_mapping("[src] spawned outside of mapload!")
return INITIALIZE_HINT_QDEL
/obj/effect/mapping_helpers/basic_mob_flags/LateInitialize()
var/had_any_mobs = FALSE
for(var/mob/living/basic/basic_mobs in loc)
had_any_mobs = TRUE
basic_mobs.basic_mob_flags |= flag_to_give
if(!had_any_mobs)
CRASH("[src] called on a turf without any basic mobs.")
qdel(src)
/obj/effect/mapping_helpers/basic_mob_flags/del_on_death
name = "Basic mob del on death flag helper"
icon_state = "basic_mob_del_on_death"
flag_to_give = DEL_ON_DEATH
/obj/effect/mapping_helpers/basic_mob_flags/flip_on_death
name = "Basic mob flip on death flag helper"
icon_state = "basic_mob_flip_on_death"
flag_to_give = FLIP_ON_DEATH
/obj/effect/mapping_helpers/basic_mob_flags/remain_dense_while_dead
name = "Basic mob remain dense while dead flag helper"
icon_state = "basic_mob_remain_dense_while_dead"
flag_to_give = REMAIN_DENSE_WHILE_DEAD
/obj/effect/mapping_helpers/basic_mob_flags/flammable_mob
name = "Basic mob flammable flag helper"
icon_state = "basic_mob_flammable"
flag_to_give = FLAMMABLE_MOB
/obj/effect/mapping_helpers/basic_mob_flags/immune_to_fists
name = "Basic mob immune to fists flag helper"
icon_state = "basic_mob_immune_to_fists"
flag_to_give = IMMUNE_TO_FISTS
/obj/effect/mapping_helpers/basic_mob_flags/immune_to_getting_wet
name = "Basic mob immune to getting wet flag helper"
icon_state = "basic_mob_immune_to_getting_wet"
flag_to_give = IMMUNE_TO_GETTING_WET