mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Blueprint Revamp.
This commit is contained in:
@@ -94,6 +94,13 @@
|
|||||||
assign_uid()
|
assign_uid()
|
||||||
id_tag = num2text(uid)
|
id_tag = num2text(uid)
|
||||||
|
|
||||||
|
/obj/machinery/atmospherics/unary/vent_pump/proc/update_area()
|
||||||
|
initial_loc = get_area(loc)
|
||||||
|
area_uid = "\ref[initial_loc]"
|
||||||
|
assign_uid()
|
||||||
|
id_tag = num2text(uid)
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_pump/Destroy()
|
/obj/machinery/atmospherics/unary/vent_pump/Destroy()
|
||||||
unregister_radio(src, frequency)
|
unregister_radio(src, frequency)
|
||||||
if(initial_loc)
|
if(initial_loc)
|
||||||
|
|||||||
@@ -43,6 +43,12 @@
|
|||||||
assign_uid()
|
assign_uid()
|
||||||
id_tag = num2text(uid)
|
id_tag = num2text(uid)
|
||||||
|
|
||||||
|
/obj/machinery/atmospherics/unary/vent_scrubber/proc/update_area()
|
||||||
|
initial_loc = get_area(loc)
|
||||||
|
area_uid = "\ref[initial_loc]"
|
||||||
|
assign_uid()
|
||||||
|
id_tag = num2text(uid)
|
||||||
|
|
||||||
/obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
|
/obj/machinery/atmospherics/unary/vent_scrubber/Destroy()
|
||||||
unregister_radio(src, frequency)
|
unregister_radio(src, frequency)
|
||||||
if(initial_loc)
|
if(initial_loc)
|
||||||
|
|||||||
@@ -28,3 +28,12 @@
|
|||||||
#define OUTDOORS_NO 0 // Ditto.
|
#define OUTDOORS_NO 0 // Ditto.
|
||||||
#define OUTDOORS_AREA -1 // If a turf has this, it will defer to the area's settings on init.
|
#define OUTDOORS_AREA -1 // If a turf has this, it will defer to the area's settings on init.
|
||||||
// Note that after init, it will be either YES or NO.
|
// Note that after init, it will be either YES or NO.
|
||||||
|
|
||||||
|
//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a
|
||||||
|
///Returns a list of turf in a square
|
||||||
|
|
||||||
|
#define RECT_TURFS(H_RADIUS, V_RADIUS, CENTER) \
|
||||||
|
block( \
|
||||||
|
locate(max(CENTER.x-(H_RADIUS),1), max(CENTER.y-(V_RADIUS),1), CENTER.z), \
|
||||||
|
locate(min(CENTER.x+(H_RADIUS),world.maxx), min(CENTER.y+(V_RADIUS),world.maxy), CENTER.z) \
|
||||||
|
)
|
||||||
@@ -2,7 +2,8 @@ GLOBAL_LIST_INIT(speech_toppings, list("|" = "i", "+" = "b", "_" = "u"))
|
|||||||
GLOBAL_LIST_EMPTY(meteor_list)
|
GLOBAL_LIST_EMPTY(meteor_list)
|
||||||
|
|
||||||
/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc.
|
/// List of wire colors for each object type of that round. One for airlocks, one for vendors, etc.
|
||||||
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
|
GLOBAL_LIST_EMPTY(wire_color_directory) // This is an associative list with the `holder_type` as the key, and a list of colors as the value.
|
||||||
|
GLOBAL_LIST_EMPTY(wire_name_directory) // This is an associative list
|
||||||
|
|
||||||
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
|
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
|
||||||
GLOBAL_LIST_EMPTY(tagger_locations)
|
GLOBAL_LIST_EMPTY(tagger_locations)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ var/global/list/item_vore_blacklist = list(
|
|||||||
/obj/item/weapon/gun,
|
/obj/item/weapon/gun,
|
||||||
/obj/item/weapon/pinpointer,
|
/obj/item/weapon/pinpointer,
|
||||||
/obj/item/clothing/shoes/magboots,
|
/obj/item/clothing/shoes/magboots,
|
||||||
/obj/item/blueprints,
|
/obj/item/areaeditor/blueprints,
|
||||||
/obj/item/clothing/head/helmet/space,
|
/obj/item/clothing/head/helmet/space,
|
||||||
/obj/item/weapon/disk/nuclear,
|
/obj/item/weapon/disk/nuclear,
|
||||||
/obj/item/clothing/suit/storage/hooded/wintercoat/roiz)
|
/obj/item/clothing/suit/storage/hooded/wintercoat/roiz)
|
||||||
@@ -850,3 +850,98 @@ var/global/list/xenobio_rainbow_extracts = list(
|
|||||||
/obj/item/slime_extract/emerald = 3,
|
/obj/item/slime_extract/emerald = 3,
|
||||||
/obj/item/slime_extract/light_pink = 1,
|
/obj/item/slime_extract/light_pink = 1,
|
||||||
/obj/item/slime_extract/rainbow = 1)
|
/obj/item/slime_extract/rainbow = 1)
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
|
||||||
|
|
||||||
|
// AREA GENERATION AND BLUEPRINT STUFF BELOW HERE
|
||||||
|
// typecacheof(list) and list() are two completely separate things, don't break!
|
||||||
|
|
||||||
|
// WHATEVER YOU DO, DO NOT LEAVE THE LAST THING IN THE LIST BELOW HAVE A COMMA OR EVERYTHING EVER WILL BREAK
|
||||||
|
// ENSURE THE LAST AREA OR TURF LISTED IS SIMPLY "/area/clownhideout" AND NOT "/area/clownhideout," OR YOU WILL IMMEDIATELY DIE
|
||||||
|
|
||||||
|
// These lists are, obviously, unfinished.
|
||||||
|
|
||||||
|
// ALLOWING BUILDING IN AN AREA:
|
||||||
|
// If you want someone to be able to build a new area in a place, add the area to the 'BUILDABLE_AREA_TYPES' and 'blacklisted_areas'
|
||||||
|
// BUILDABLE_AREA_TYPES means they can build an area there. The blacklisted_areas means they CAN NOT EXPAND that area. No making space bigger!
|
||||||
|
|
||||||
|
// DISALLOW BUILDING/AREA MANIPULATION IN AN AREA (OR A TURF TYPE):
|
||||||
|
// Likewise, if you want someone to never ever EVER be able to do anything area generation/expansion related to an area
|
||||||
|
// Then add it to SPECIALS and area_or_turf_fail_types
|
||||||
|
|
||||||
|
// If you want someone to
|
||||||
|
var/global/list/BUILDABLE_AREA_TYPES = list(
|
||||||
|
/area/space,
|
||||||
|
/area/mine,
|
||||||
|
// /area/surface/outside, //SC
|
||||||
|
// /area/surface/cave, //SC
|
||||||
|
/area/tether/surfacebase/outside,
|
||||||
|
/area/groundbase/unexplored/outdoors,
|
||||||
|
/area/maintenance/groundbase/level1,
|
||||||
|
/area/submap/groundbase/wilderness,
|
||||||
|
/area/groundbase/mining,
|
||||||
|
/area/offmap/aerostat/surface,
|
||||||
|
/area/tether_away/beach,
|
||||||
|
/area/tether_away/cave,
|
||||||
|
)
|
||||||
|
|
||||||
|
var/static/list/blacklisted_areas = typecacheof(list(
|
||||||
|
/area/space,
|
||||||
|
/area/mine,
|
||||||
|
// /area/surface/outside, //SC
|
||||||
|
// /area/surface/cave, //SC
|
||||||
|
//TETHER STUFF BELOW THIS
|
||||||
|
/area/tether/surfacebase/outside,
|
||||||
|
//GROUNDBASE STUFF BELOW THIS
|
||||||
|
/area/groundbase/unexplored/outdoors,
|
||||||
|
/area/maintenance/groundbase/level1,
|
||||||
|
/area/submap/groundbase/wilderness,
|
||||||
|
/area/groundbase/mining,
|
||||||
|
/area/offmap/aerostat/surface,
|
||||||
|
/area/tether_away/beach,
|
||||||
|
/area/tether_away/cave
|
||||||
|
))
|
||||||
|
|
||||||
|
var/global/list/SPECIALS = list(
|
||||||
|
/turf/space,
|
||||||
|
/area/shuttle,
|
||||||
|
/area/admin,
|
||||||
|
/area/arrival,
|
||||||
|
/area/centcom,
|
||||||
|
/area/asteroid,
|
||||||
|
/area/tdome,
|
||||||
|
/area/syndicate_station,
|
||||||
|
/area/wizard_station,
|
||||||
|
/area/prison,
|
||||||
|
/area/holodeck,
|
||||||
|
/area/turbolift,
|
||||||
|
/area/tether/elevator,
|
||||||
|
/turf/unsimulated/wall/planetary,
|
||||||
|
/area/submap/virgo2,
|
||||||
|
/area/submap/event,
|
||||||
|
/area/submap/casino_event
|
||||||
|
// /area/derelict //commented out, all hail derelict-rebuilders!
|
||||||
|
)
|
||||||
|
|
||||||
|
var/global/list/area_or_turf_fail_types = typecacheof(list(
|
||||||
|
/turf/space,
|
||||||
|
/area/shuttle,
|
||||||
|
/area/admin,
|
||||||
|
/area/arrival,
|
||||||
|
/area/centcom,
|
||||||
|
/area/asteroid,
|
||||||
|
/area/tdome,
|
||||||
|
/area/syndicate_station,
|
||||||
|
/area/wizard_station,
|
||||||
|
/area/prison,
|
||||||
|
/area/holodeck,
|
||||||
|
/turf/simulated/wall/elevator,
|
||||||
|
/area/turbolift,
|
||||||
|
/area/tether/elevator,
|
||||||
|
/turf/unsimulated/wall/planetary,
|
||||||
|
/area/submap/virgo2,
|
||||||
|
/area/submap/event,
|
||||||
|
/area/submap/casino_event
|
||||||
|
))
|
||||||
|
>>>>>>> 420957ffec... Merge pull request #13828 from Cameron653/BUILDABLE_SHUTTLES
|
||||||
|
|||||||
@@ -643,6 +643,20 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
|||||||
for(var/turf/T in N) turfs += T
|
for(var/turf/T in N) turfs += T
|
||||||
return turfs
|
return turfs
|
||||||
|
|
||||||
|
|
||||||
|
//Takes: An instance of the area.
|
||||||
|
//Returns: A list of all turfs in that area.
|
||||||
|
//Side note: I don't know why this was never a thing. Did everyone just ignore the Blueprint item?! - C.L.
|
||||||
|
/proc/get_current_area_turfs(var/area/checked_area)
|
||||||
|
if(!checked_area)
|
||||||
|
return null
|
||||||
|
|
||||||
|
var/list/turfs = new/list()
|
||||||
|
for(var/turf/counted_turfs in checked_area.contents) //Cheap. Efficient. Lovely.
|
||||||
|
turfs += counted_turfs
|
||||||
|
return turfs
|
||||||
|
|
||||||
|
|
||||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||||
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
|
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
|
||||||
/proc/get_area_all_atoms(var/areatype)
|
/proc/get_area_all_atoms(var/areatype)
|
||||||
@@ -659,6 +673,18 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
|||||||
atoms += A
|
atoms += A
|
||||||
return atoms
|
return atoms
|
||||||
|
|
||||||
|
|
||||||
|
//Takes: Area as an instance of the area.
|
||||||
|
//Returns: A list of all atoms (objs, turfs, mobs) in the selected area.
|
||||||
|
/proc/get_current_area_atoms(var/area/checked_area)
|
||||||
|
if(!checked_area)
|
||||||
|
return null
|
||||||
|
|
||||||
|
var/list/atoms = new/list()
|
||||||
|
for(var/atom/A in checked_area.contents)
|
||||||
|
atoms += A
|
||||||
|
return atoms
|
||||||
|
|
||||||
/datum/coords //Simple datum for storing coordinates.
|
/datum/coords //Simple datum for storing coordinates.
|
||||||
var/x_pos = null
|
var/x_pos = null
|
||||||
var/y_pos = null
|
var/y_pos = null
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
if(!GLOB.wire_color_directory[holder_type])
|
if(!GLOB.wire_color_directory[holder_type])
|
||||||
randomize()
|
randomize()
|
||||||
GLOB.wire_color_directory[holder_type] = colors
|
GLOB.wire_color_directory[holder_type] = colors
|
||||||
|
GLOB.wire_name_directory[holder_type] = proper_name
|
||||||
else
|
else
|
||||||
colors = GLOB.wire_color_directory[holder_type]
|
colors = GLOB.wire_color_directory[holder_type]
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
var/block_suit_sensors = FALSE //If mob size is limited in the area.
|
var/block_suit_sensors = FALSE //If mob size is limited in the area.
|
||||||
var/turf/ceiling_type
|
var/turf/ceiling_type
|
||||||
|
|
||||||
|
// Size of the area in open turfs, only calculated for indoors areas.
|
||||||
|
var/areasize = 0
|
||||||
|
|
||||||
/area/Entered(var/atom/movable/AM, oldLoc)
|
/area/Entered(var/atom/movable/AM, oldLoc)
|
||||||
. = ..()
|
. = ..()
|
||||||
if(enter_message && isliving(AM))
|
if(enter_message && isliving(AM))
|
||||||
@@ -29,3 +32,41 @@
|
|||||||
var/turf/TA = GetAbove(T)
|
var/turf/TA = GetAbove(T)
|
||||||
if(isopenspace(TA))
|
if(isopenspace(TA))
|
||||||
TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE)
|
TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup an area (with the given name)
|
||||||
|
*
|
||||||
|
* Sets the area name, sets all status var's to false and adds the area to the sorted area list
|
||||||
|
* //NOTE: Virgo does not have a sorted area list.
|
||||||
|
*/
|
||||||
|
/area/proc/setup(a_name)
|
||||||
|
name = a_name
|
||||||
|
power_equip = FALSE
|
||||||
|
power_light = FALSE
|
||||||
|
power_environ = FALSE
|
||||||
|
always_unpowered = FALSE
|
||||||
|
update_areasize()
|
||||||
|
|
||||||
|
/area/proc/update_areasize()
|
||||||
|
if(outdoors)
|
||||||
|
return FALSE
|
||||||
|
areasize = 0
|
||||||
|
for(var/turf/simulated/floor/T in contents)
|
||||||
|
areasize++
|
||||||
|
|
||||||
|
/proc/rename_area(a, new_name)
|
||||||
|
var/area/A = get_area(a)
|
||||||
|
var/prevname = "[A.name]"
|
||||||
|
set_area_machinery(A, new_name, prevname)
|
||||||
|
A.name = new_name
|
||||||
|
A.update_areasize()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/area/proc/power_check()
|
||||||
|
if(!requires_power || !apc)
|
||||||
|
power_light = 0
|
||||||
|
power_equip = 0
|
||||||
|
power_environ = 0
|
||||||
|
power_change() // all machines set to current power level, also updates lighting icon
|
||||||
|
if(no_spoilers)
|
||||||
|
set_spoiler_obfuscation(TRUE)
|
||||||
@@ -749,7 +749,7 @@ datum
|
|||||||
|
|
||||||
|
|
||||||
blueprints
|
blueprints
|
||||||
steal_target = /obj/item/blueprints
|
steal_target = /obj/item/areaeditor/blueprints
|
||||||
explanation_text = "Steal the station's blueprints."
|
explanation_text = "Steal the station's blueprints."
|
||||||
weight = 20
|
weight = 20
|
||||||
|
|
||||||
|
|||||||
@@ -431,7 +431,7 @@ var/global/list/all_objectives = list()
|
|||||||
"a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain,
|
"a site manager's jumpsuit" = /obj/item/clothing/under/rank/captain,
|
||||||
"a functional AI" = /obj/item/device/aicard,
|
"a functional AI" = /obj/item/device/aicard,
|
||||||
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
|
"a pair of magboots" = /obj/item/clothing/shoes/magboots,
|
||||||
"the station blueprints" = /obj/item/blueprints,
|
"the station blueprints" = /obj/item/areaeditor/blueprints,
|
||||||
"a nasa voidsuit" = /obj/item/clothing/suit/space/void,
|
"a nasa voidsuit" = /obj/item/clothing/suit/space/void,
|
||||||
"28 moles of phoron (full tank)" = /obj/item/weapon/tank,
|
"28 moles of phoron (full tank)" = /obj/item/weapon/tank,
|
||||||
"a sample of slime extract" = /obj/item/slime_extract,
|
"a sample of slime extract" = /obj/item/slime_extract,
|
||||||
|
|||||||
@@ -154,6 +154,12 @@
|
|||||||
|
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
|
/obj/machinery/alarm/proc/update_area()
|
||||||
|
alarm_area = get_area(src)
|
||||||
|
area_uid = "\ref[alarm_area]"
|
||||||
|
if(name == "alarm")
|
||||||
|
name = "[alarm_area.name] Air Alarm"
|
||||||
|
|
||||||
/obj/machinery/alarm/Initialize()
|
/obj/machinery/alarm/Initialize()
|
||||||
. = ..()
|
. = ..()
|
||||||
set_frequency(frequency)
|
set_frequency(frequency)
|
||||||
@@ -540,9 +546,9 @@
|
|||||||
|
|
||||||
var/list/list/environment_data = list()
|
var/list/list/environment_data = list()
|
||||||
data["environment_data"] = environment_data
|
data["environment_data"] = environment_data
|
||||||
|
|
||||||
DECLARE_TLV_VALUES
|
DECLARE_TLV_VALUES
|
||||||
|
|
||||||
var/pressure = environment.return_pressure()
|
var/pressure = environment.return_pressure()
|
||||||
LOAD_TLV_VALUES(TLV["pressure"], pressure)
|
LOAD_TLV_VALUES(TLV["pressure"], pressure)
|
||||||
environment_data.Add(list(list(
|
environment_data.Add(list(list(
|
||||||
@@ -551,7 +557,7 @@
|
|||||||
"unit" = "kPa",
|
"unit" = "kPa",
|
||||||
"danger_level" = TEST_TLV_VALUES
|
"danger_level" = TEST_TLV_VALUES
|
||||||
)))
|
)))
|
||||||
|
|
||||||
var/temperature = environment.temperature
|
var/temperature = environment.temperature
|
||||||
LOAD_TLV_VALUES(TLV["temperature"], temperature)
|
LOAD_TLV_VALUES(TLV["temperature"], temperature)
|
||||||
environment_data.Add(list(list(
|
environment_data.Add(list(list(
|
||||||
@@ -573,7 +579,7 @@
|
|||||||
"unit" = "%",
|
"unit" = "%",
|
||||||
"danger_level" = TEST_TLV_VALUES
|
"danger_level" = TEST_TLV_VALUES
|
||||||
)))
|
)))
|
||||||
|
|
||||||
if(!locked || issilicon(user) || data["remoteUser"])
|
if(!locked || issilicon(user) || data["remoteUser"])
|
||||||
var/list/list/vents = list()
|
var/list/list/vents = list()
|
||||||
data["vents"] = vents
|
data["vents"] = vents
|
||||||
@@ -595,7 +601,7 @@
|
|||||||
"extdefault"= (info["external"] == ONE_ATMOSPHERE),
|
"extdefault"= (info["external"] == ONE_ATMOSPHERE),
|
||||||
"intdefault"= (info["internal"] == 0),
|
"intdefault"= (info["internal"] == 0),
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
||||||
var/list/list/scrubbers = list()
|
var/list/list/scrubbers = list()
|
||||||
data["scrubbers"] = scrubbers
|
data["scrubbers"] = scrubbers
|
||||||
@@ -622,7 +628,7 @@
|
|||||||
data["scrubbers"] = scrubbers
|
data["scrubbers"] = scrubbers
|
||||||
|
|
||||||
data["mode"] = mode
|
data["mode"] = mode
|
||||||
|
|
||||||
var/list/list/modes = list()
|
var/list/list/modes = list()
|
||||||
data["modes"] = modes
|
data["modes"] = modes
|
||||||
modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)
|
modes[++modes.len] = list("name" = "Filtering - Scrubs out contaminants", "mode" = AALARM_MODE_SCRUBBING, "selected" = mode == AALARM_MODE_SCRUBBING, "danger" = 0)
|
||||||
@@ -682,7 +688,7 @@
|
|||||||
else
|
else
|
||||||
target_temperature = input_temperature + T0C
|
target_temperature = input_temperature + T0C
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
// Account for remote users here.
|
// Account for remote users here.
|
||||||
// Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey
|
// Yes, this is kinda snowflaky; however, I would argue it would be far more snowflakey
|
||||||
// to include "custom hrefs" and all the other bullshit that nano states have just for the
|
// to include "custom hrefs" and all the other bullshit that nano states have just for the
|
||||||
|
|||||||
940
code/game/objects/items/blueprints_vr.dm
Normal file
940
code/game/objects/items/blueprints_vr.dm
Normal file
@@ -0,0 +1,940 @@
|
|||||||
|
#define BP_MAX_ROOM_SIZE 300
|
||||||
|
|
||||||
|
// WARNING: ESOTERIC BULLSHIT INSIDE OF THIS FILE.
|
||||||
|
// This is a port of /tg/'s blueprints that also have Virgo modifications as well.
|
||||||
|
// However it is heavily modified and lacking the 't-ray' scanner functionality that /TG/ has. We have our own t-rays after all.
|
||||||
|
// This works and uses a bunch of really odd hacks and trickery to get it to all function.
|
||||||
|
// If you're looking at this a few years from now and going 'What the hell were they thinking' just know that this was the best we had at the time.
|
||||||
|
|
||||||
|
// Now that I've scared away half the people looking at this file, here's the relevant info:
|
||||||
|
|
||||||
|
// Banning areas: Go to global_lists_vr, jump to the BUILDABLE_AREA_TYPES and read the comments left there.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// These areas are defined here so they can be blacklisted in global_lists_vr
|
||||||
|
/area/tether/elevator
|
||||||
|
|
||||||
|
name = "Tether Elevator"
|
||||||
|
|
||||||
|
/area/tether/surfacebase/outside
|
||||||
|
name = "Outside - Surface"
|
||||||
|
|
||||||
|
/area/groundbase/unexplored/outdoors
|
||||||
|
name = "\improper Rascal's Pass"
|
||||||
|
|
||||||
|
/area/groundbase/mining
|
||||||
|
name = "Mining"
|
||||||
|
|
||||||
|
/area/groundbase/unexplored/rock
|
||||||
|
name = "\improper Rascal's Pass"
|
||||||
|
|
||||||
|
/area/maintenance/groundbase/level1
|
||||||
|
name = "Groundbase Level One Maint"
|
||||||
|
|
||||||
|
/area/submap/groundbase/wilderness
|
||||||
|
name = "Groundbase Wilderness"
|
||||||
|
|
||||||
|
/area/offmap/aerostat/surface
|
||||||
|
name = "Aerostat Surface"
|
||||||
|
|
||||||
|
/area/tether_away/beach
|
||||||
|
name = "\improper Away Mission - Virgo 4 Beach"
|
||||||
|
|
||||||
|
/area/tether_away/cave
|
||||||
|
name = "Tether Away Cave"
|
||||||
|
|
||||||
|
/area/offmap/aerostat/surface
|
||||||
|
|
||||||
|
name = "Aerostat Surface"
|
||||||
|
|
||||||
|
/area/submap/virgo2
|
||||||
|
name = "Submap Area"
|
||||||
|
|
||||||
|
/area/submap/casino_event
|
||||||
|
name = "\improper Space Casino"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TG blueprints.
|
||||||
|
#define AREA_ERRNONE 0
|
||||||
|
#define AREA_STATION 1
|
||||||
|
#define AREA_SPACE 2
|
||||||
|
#define AREA_SPECIAL 3
|
||||||
|
|
||||||
|
/obj/item/areaeditor
|
||||||
|
name = "area modification item"
|
||||||
|
icon = 'icons/obj/items.dmi'
|
||||||
|
icon_state = "blueprints"
|
||||||
|
attack_verb = list("attacked", "bapped", "hit")
|
||||||
|
in_use = FALSE
|
||||||
|
preserve_item = 1
|
||||||
|
var/uses_charges = 0 // If the area editor has limited uses.
|
||||||
|
var/initial_charges = 10
|
||||||
|
var/charges = 10 // The amount of uses the area editor has.
|
||||||
|
var/station_master = 1 // If the areaeditor can add charges to others.
|
||||||
|
var/wire_schematics = 0 // If the areaeditor can see wires.
|
||||||
|
var/can_override = 0 // If you want the areaeditor to override the 'Don't make a new area where one already exists' logic. Only given to CE blueprints.
|
||||||
|
|
||||||
|
var/can_create_areas_in = AREA_SPACE // Must be standing in space to create
|
||||||
|
var/can_create_areas_into = AREA_SPACE // New areas will only overwrite space area turfs.
|
||||||
|
var/can_expand_areas_in = AREA_STATION // Must be standing in station to expand
|
||||||
|
var/can_expand_areas_into = AREA_SPACE // Can expand station areas only into space.
|
||||||
|
var/can_rename_areas_in = AREA_STATION // Only station areas can be reanamed
|
||||||
|
|
||||||
|
|
||||||
|
var/const/ROOM_ERR_LOLWAT = 0 // Don't touch these three consts or BYOND will literally tear out your throat
|
||||||
|
var/const/ROOM_ERR_SPACE = -1
|
||||||
|
var/const/ROOM_ERR_TOOLARGE = -2
|
||||||
|
var/const/ROOM_ERR_FORBIDDEN = -3
|
||||||
|
|
||||||
|
var/list/areaColor_turfs = list()
|
||||||
|
var/legend = 0 //If viewing wires or not.
|
||||||
|
|
||||||
|
/obj/item/areaeditor/examine(mob/user)
|
||||||
|
. =..()
|
||||||
|
if(uses_charges && !isnull(charges))
|
||||||
|
. += "There appears to be enough space for a total of [charges] more changes!"
|
||||||
|
if(!charges)
|
||||||
|
. += "There seems to be no more room for any more edits!"
|
||||||
|
|
||||||
|
/obj/item/areaeditor/attackby(obj/item/W, mob/user, params)
|
||||||
|
if(uses_charges && (charges < initial_charges) && istype(W, /obj/item/areaeditor)) //Do we have a reason to add charges? And is it something that COULD add charges?
|
||||||
|
var/missing_charges = initial_charges-charges
|
||||||
|
var/obj/item/areaeditor/blueprint = W
|
||||||
|
if(blueprint.station_master) //Master can refill.
|
||||||
|
charges = initial_charges
|
||||||
|
to_chat(user, span_notice("You add some more writing material to the [src] with the [blueprint]!"))
|
||||||
|
return
|
||||||
|
else if(blueprint.uses_charges && blueprint.charges) //Getting from another with limited charges.
|
||||||
|
var/to_add = tgui_input_number(user, "How many charges do you want to add to the [src]?", "[blueprint]", missing_charges)
|
||||||
|
if(!isnull(to_add) && blueprint.charges >= to_add)
|
||||||
|
to_chat(user, span_notice("You add some more writing material to the [src] with the [blueprint]!"))
|
||||||
|
blueprint.charges -= to_add
|
||||||
|
charges += to_add
|
||||||
|
return
|
||||||
|
|
||||||
|
else
|
||||||
|
to_chat(user, span_notice("You decide not to add any more material to the [src]"))
|
||||||
|
return
|
||||||
|
else if(!blueprint.uses_charges || !blueprint.charges) // The item it's being hit by doesn't use charges OR doesn't have any charges.
|
||||||
|
to_chat(user, span_warning("You can't add find any suitable material to add from the [blueprint]!"))
|
||||||
|
else
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/item/areaeditor/attack_self(mob/user) //Convert this to TGUI some time.
|
||||||
|
add_fingerprint(user)
|
||||||
|
. = "<BODY><HTML><head><title>[src]</title></head> \
|
||||||
|
<h2>[station_name()] [src.name]</h2>"
|
||||||
|
switch(get_area_type())
|
||||||
|
if(AREA_SPACE)
|
||||||
|
. += "<p>According to the [src.name], you are now in an unclaimed territory.</p>"
|
||||||
|
if(AREA_SPECIAL)
|
||||||
|
. += "<p>This place is not noted on the [src.name].</p>"
|
||||||
|
return //If we're in a special area, no modifying.
|
||||||
|
if(!uses_charges || (uses_charges && charges)) //No charges OR it has charges available.
|
||||||
|
. += "<p><a href='?src=[REF(src)];create_area=1'>Create or modify an existing area (3x3 space) (1 Charge)</a></p>"
|
||||||
|
. += "<p><a href='?src=[REF(src)];create_area_whole=1'>Create new area or merge two areas. (Whole Room.) (5 Charges)</a></p>"
|
||||||
|
. += "There is a note on the corner of the [src.name]: Use 3x3 for fine-tuning and including walls into your area!"
|
||||||
|
if(uses_charges)
|
||||||
|
if(!charges) //We're out!
|
||||||
|
. += "Your [src.name] has been completely filled! You would need to get some extra blueprint paper from the CE's blueprints to expand further!"
|
||||||
|
else
|
||||||
|
. += "Your [src.name] seems like it has enough room for [charges] more edits!"
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/Topic(href, href_list)
|
||||||
|
if(..())
|
||||||
|
return TRUE
|
||||||
|
if ((usr.restrained() || usr.stat || usr.get_active_hand() != src))
|
||||||
|
return
|
||||||
|
if(href_list["create_area"])
|
||||||
|
if(in_use)
|
||||||
|
return
|
||||||
|
var/area/A = get_area(usr)
|
||||||
|
if(A.flags & BLUE_SHIELDED)
|
||||||
|
to_chat(usr, span_warning("You cannot edit restricted areas."))
|
||||||
|
return
|
||||||
|
in_use = TRUE
|
||||||
|
create_area(usr, src)
|
||||||
|
in_use = FALSE
|
||||||
|
if(href_list["create_area_whole"])
|
||||||
|
if(in_use)
|
||||||
|
return
|
||||||
|
in_use = TRUE
|
||||||
|
var/area/A = create_area_whole(usr, src)
|
||||||
|
if(A && (A.flags & BLUE_SHIELDED))
|
||||||
|
to_chat(usr, span_warning("You cannot edit restricted areas."))
|
||||||
|
in_use = FALSE
|
||||||
|
return
|
||||||
|
in_use = FALSE
|
||||||
|
updateUsrDialog()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Station Wire Tool.
|
||||||
|
/obj/item/wire_reader //Not really a blueprint, but it's included here as such.
|
||||||
|
name = "wire schematics"
|
||||||
|
desc = "A blueprint detailing the various internal wiring of machinery around the station."
|
||||||
|
icon = 'icons/obj/items.dmi'
|
||||||
|
icon_state = "blueprints"
|
||||||
|
attack_verb = list("attacked", "bapped", "hit")
|
||||||
|
preserve_item = 1
|
||||||
|
var/legend = 1
|
||||||
|
|
||||||
|
/obj/item/wire_reader/attack_self(mob/user) //Convert this to TGUI some time.
|
||||||
|
add_fingerprint(user)
|
||||||
|
. = "<BODY><HTML><head><title>[src]</title></head> \
|
||||||
|
<h2>[station_name()] [src.name]</h2>"
|
||||||
|
if(legend == TRUE)
|
||||||
|
. += view_station_wire_devices(user);
|
||||||
|
else
|
||||||
|
//legend is a wireset
|
||||||
|
. += "<a href='?src=[REF(src)];view_legend=1'><< Back</a>"
|
||||||
|
. += view_station_wire_set(user, legend)
|
||||||
|
|
||||||
|
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
|
||||||
|
popup.set_content(.)
|
||||||
|
popup.open()
|
||||||
|
onclose(user, "blueprints")
|
||||||
|
|
||||||
|
/obj/item/wire_reader/Topic(href, href_list)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
if(href_list["view_wireset"])
|
||||||
|
legend = href_list["view_wireset"];
|
||||||
|
if(href_list["view_legend"])
|
||||||
|
legend = TRUE
|
||||||
|
attack_self(usr)
|
||||||
|
|
||||||
|
/obj/item/wire_reader/proc/view_station_wire_devices(mob/user)
|
||||||
|
var/message = "<br>You examine the wire legend.<br>"
|
||||||
|
for(var/wireset in GLOB.wire_color_directory)
|
||||||
|
//if(istype(wireset,/datum/wires/grid_checker))//Uncomment this in if you want the grid checker minigame to not be revealed here.
|
||||||
|
// continue
|
||||||
|
message += "<br><a href='?src=[REF(src)];view_wireset=[wireset]'>[GLOB.wire_name_directory[wireset]]</a>"
|
||||||
|
message += "</p>"
|
||||||
|
return message
|
||||||
|
|
||||||
|
/obj/item/wire_reader/proc/view_station_wire_set(mob/user, wireset)
|
||||||
|
//for some reason you can't use wireset directly as a derefencer so this is the next best :/
|
||||||
|
for(var/device in GLOB.wire_color_directory)
|
||||||
|
if("[device]" == wireset) //I know... don't change it...
|
||||||
|
var/message = "<p><b>[GLOB.wire_name_directory[device]]:</b>"
|
||||||
|
for(var/Col in GLOB.wire_color_directory[device])
|
||||||
|
var/wire_name = GLOB.wire_color_directory[device][Col]
|
||||||
|
if(!findtext(wire_name, WIRE_DUD_PREFIX)) //don't show duds
|
||||||
|
message += "<p><span style='color: [Col]'>[Col]</span>: [wire_name]</p>"
|
||||||
|
message += "</p>"
|
||||||
|
return message
|
||||||
|
return ""
|
||||||
|
|
||||||
|
//Station blueprints!!!
|
||||||
|
/obj/item/areaeditor/blueprints
|
||||||
|
name = "station blueprints"
|
||||||
|
desc = "Blueprints of the station. There is a \"Classified\" stamp and several coffee stains on it."
|
||||||
|
//var/list/image/showing = list() //For viewing pipes. Unused.
|
||||||
|
//var/client/viewing //For viewing pipes. Unused.
|
||||||
|
can_override = 1 //In case there is a reason for building in a non-blacklisted, non-buildable area.
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/engineers
|
||||||
|
name = "writing blueprints"
|
||||||
|
desc = "A piece of paper that allows for expansion of the station and creaiton of new areas. There is a \"For Official Use Only\" stamp on it. NOT to be mistaken with the staion blueprints."
|
||||||
|
station_master = 0
|
||||||
|
uses_charges = 1
|
||||||
|
can_override = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/Destroy()
|
||||||
|
//clear_viewer()
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/attack_self(mob/user)
|
||||||
|
. = ..()
|
||||||
|
var/area/A = get_area(user)
|
||||||
|
if(!legend)
|
||||||
|
if(get_area_type() == AREA_STATION)
|
||||||
|
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
|
||||||
|
. += "<p><a href='?src=[REF(src)];edit_area=1'>Change area name</a></p>" //You can change the name without charges.
|
||||||
|
if(wire_schematics)
|
||||||
|
. += "<p><a href='?src=[REF(src)];view_legend=1'>View wire colour legend</a></p>"
|
||||||
|
else
|
||||||
|
if(legend == TRUE)
|
||||||
|
. += "<a href='?src=[REF(src)];exit_legend=1'><< Back</a>"
|
||||||
|
. += view_wire_devices(user);
|
||||||
|
else
|
||||||
|
//legend is a wireset
|
||||||
|
. += "<a href='?src=[REF(src)];view_legend=1'><< Back</a>"
|
||||||
|
. += view_wire_set(user, legend)
|
||||||
|
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
|
||||||
|
popup.set_content(.)
|
||||||
|
popup.open()
|
||||||
|
onclose(user, "blueprints")
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/Topic(href, href_list)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
if(href_list["edit_area"])
|
||||||
|
if(get_area_type()!=AREA_STATION)
|
||||||
|
return
|
||||||
|
if(in_use)
|
||||||
|
return
|
||||||
|
in_use = TRUE
|
||||||
|
edit_area()
|
||||||
|
in_use = FALSE
|
||||||
|
if(href_list["exit_legend"])
|
||||||
|
legend = FALSE;
|
||||||
|
if(href_list["view_legend"])
|
||||||
|
if(wire_schematics) //No href hacks allow for you, my friend!
|
||||||
|
legend = TRUE;
|
||||||
|
if(href_list["view_wireset"])
|
||||||
|
if(wire_schematics) //No href hacks allow for you, my friend!
|
||||||
|
legend = href_list["view_wireset"];
|
||||||
|
attack_self(usr)
|
||||||
|
|
||||||
|
|
||||||
|
//Code for viewing pipes or whatnot. Think t-ray scanner.
|
||||||
|
//Code for viewing pipes or whatnot. Think t-ray scanner.
|
||||||
|
//Code for viewing pipes or whatnot. Think t-ray scanner.
|
||||||
|
/*
|
||||||
|
/obj/item/areaeditor/blueprints/proc/get_images(turf/central_turf, viewsize)
|
||||||
|
. = list()
|
||||||
|
var/list/dimensions = getviewsize(viewsize)
|
||||||
|
var/horizontal_radius = dimensions[1] / 2
|
||||||
|
var/vertical_radius = dimensions[2] / 2
|
||||||
|
for(var/turf/nearby_turf as anything in RECT_TURFS(horizontal_radius, vertical_radius, central_turf))
|
||||||
|
if(nearby_turf.blueprint_data)
|
||||||
|
. += nearby_turf.blueprint_data
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
/obj/item/areaeditor/blueprints/proc/set_viewer(mob/user, message = "")
|
||||||
|
if(user?.client)
|
||||||
|
if(viewing)
|
||||||
|
clear_viewer()
|
||||||
|
viewing = user.client
|
||||||
|
showing = get_images(get_turf(viewing.eye || user), viewing.view)
|
||||||
|
viewing.images |= showing
|
||||||
|
if(message)
|
||||||
|
to_chat(user, message)
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
/obj/item/areaeditor/blueprints/proc/clear_viewer(mob/user, message = "")
|
||||||
|
if(viewing)
|
||||||
|
viewing.images -= showing
|
||||||
|
viewing = null
|
||||||
|
showing.Cut()
|
||||||
|
if(message)
|
||||||
|
to_chat(user, message)
|
||||||
|
*/
|
||||||
|
/obj/item/areaeditor/blueprints/dropped(mob/user)
|
||||||
|
..()
|
||||||
|
//clear_viewer()
|
||||||
|
if(areaColor_turfs.len)
|
||||||
|
seeAreaColors_remove()
|
||||||
|
legend = FALSE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/proc/get_area_type(area/A)
|
||||||
|
if (!A)
|
||||||
|
A = get_area(usr)
|
||||||
|
if(A.outdoors)
|
||||||
|
return AREA_SPACE
|
||||||
|
|
||||||
|
for (var/type in BUILDABLE_AREA_TYPES)
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return AREA_SPACE
|
||||||
|
|
||||||
|
for (var/type in SPECIALS)
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return AREA_SPECIAL
|
||||||
|
return AREA_STATION
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/proc/view_wire_devices(mob/user)
|
||||||
|
var/message = "<br>You examine the wire legend.<br>"
|
||||||
|
for(var/wireset in GLOB.wire_color_directory)
|
||||||
|
//if(istype(wireset,/datum/wires/grid_checker))//Uncomment this in if you want the grid checker minigame to not be revealed here.
|
||||||
|
// continue
|
||||||
|
message += "<br><a href='?src=[REF(src)];view_wireset=[wireset]'>[GLOB.wire_name_directory[wireset]]</a>"
|
||||||
|
message += "</p>"
|
||||||
|
return message
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/proc/view_wire_set(mob/user, wireset)
|
||||||
|
//for some reason you can't use wireset directly as a derefencer so this is the next best :/
|
||||||
|
for(var/device in GLOB.wire_color_directory)
|
||||||
|
if("[device]" == wireset) //I know... don't change it...
|
||||||
|
var/message = "<p><b>[GLOB.wire_name_directory[device]]:</b>"
|
||||||
|
for(var/Col in GLOB.wire_color_directory[device])
|
||||||
|
var/wire_name = GLOB.wire_color_directory[device][Col]
|
||||||
|
if(!findtext(wire_name, WIRE_DUD_PREFIX)) //don't show duds
|
||||||
|
message += "<p><span style='color: [Col]'>[Col]</span>: [wire_name]</p>"
|
||||||
|
message += "</p>"
|
||||||
|
return message
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/proc/edit_area()
|
||||||
|
var/area/A = get_area(usr)
|
||||||
|
var/prevname = "[A.name]"
|
||||||
|
var/str = tgui_input_text(usr, "New area name", "Area Creation", max_length = MAX_NAME_LEN)
|
||||||
|
str = sanitize(str,MAX_NAME_LEN)
|
||||||
|
if(!str || !length(str) || str==prevname) //cancel
|
||||||
|
return
|
||||||
|
if(length(str) > 50)
|
||||||
|
to_chat(usr, span_warning("The given name is too long. The area's name is unchanged."))
|
||||||
|
return
|
||||||
|
|
||||||
|
rename_area(A, str)
|
||||||
|
|
||||||
|
to_chat(usr, span_notice("You rename the '[prevname]' to '[str]'."))
|
||||||
|
log_and_message_admins("has changed the area '[prevname]' title to '[str]'.")
|
||||||
|
A.update_areasize()
|
||||||
|
interact()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
//Blueprint Subtypes
|
||||||
|
|
||||||
|
/obj/item/areaeditor/blueprints/cyborg
|
||||||
|
name = "station schematics"
|
||||||
|
desc = "A digital copy of the station blueprints stored in your memory."
|
||||||
|
|
||||||
|
|
||||||
|
/proc/set_area_machinery(area/area, title, oldtitle)
|
||||||
|
if(!oldtitle) // or replacetext goes to infinite loop
|
||||||
|
return
|
||||||
|
for(var/obj/machinery/alarm/airpanel in area)
|
||||||
|
airpanel.name = replacetext(airpanel.name,oldtitle,title)
|
||||||
|
airpanel.update_area()
|
||||||
|
for(var/obj/machinery/power/apc/apcpanel in area)
|
||||||
|
apcpanel.name = replacetext(apcpanel.name,oldtitle,title)
|
||||||
|
apcpanel.update_area() //DECIDE IF THIS IS WANTED OR NOT. This can mean that the APC will overwrite the current APC the area being expanded has since areas cant have multiple APCs.
|
||||||
|
for(var/obj/machinery/atmospherics/unary/vent_scrubber/scrubber in area)
|
||||||
|
scrubber.name = replacetext(scrubber.name,oldtitle,title)
|
||||||
|
scrubber.update_area()
|
||||||
|
for(var/obj/machinery/atmospherics/unary/vent_pump/vent in area)
|
||||||
|
vent.name = replacetext(vent.name,oldtitle,title)
|
||||||
|
vent.update_area()
|
||||||
|
for(var/obj/machinery/door/door in area)
|
||||||
|
door.name = replacetext(door.name,oldtitle,title)
|
||||||
|
for(var/obj/machinery/firealarm/firepanel in area)
|
||||||
|
firepanel.name = replacetext(firepanel.name,oldtitle,title)
|
||||||
|
area.update_areasize()
|
||||||
|
//TODO: much much more. Unnamed airlocks, cameras, etc.
|
||||||
|
|
||||||
|
/proc/detect_room(turf/origin, list/break_if_found, max_size=INFINITY)
|
||||||
|
if(origin.blocks_air)
|
||||||
|
return list(origin)
|
||||||
|
|
||||||
|
. = list()
|
||||||
|
var/list/checked_turfs = list()
|
||||||
|
var/list/found_turfs = list(origin)
|
||||||
|
while(length(found_turfs))
|
||||||
|
var/turf/sourceT = found_turfs[1]
|
||||||
|
found_turfs.Cut(1, 2)
|
||||||
|
var/dir_flags = checked_turfs[sourceT]
|
||||||
|
for(var/dir in GLOB.alldirs)
|
||||||
|
if(length(.) > max_size)
|
||||||
|
return
|
||||||
|
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
|
||||||
|
continue
|
||||||
|
var/turf/checkT = get_step(sourceT, dir)
|
||||||
|
if(!checkT)
|
||||||
|
continue
|
||||||
|
|
||||||
|
checked_turfs[sourceT] |= dir
|
||||||
|
checked_turfs[checkT] |= turn(dir, 180)
|
||||||
|
.[sourceT] |= dir
|
||||||
|
.[checkT] |= turn(dir, 180)
|
||||||
|
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
//The below checks to make sure air can pass between the two turfs. If not, it can't be added to the area.
|
||||||
|
//This means walls can not be added to an area. The turf must first be added and then the wall.
|
||||||
|
//UNCOMMENT THIS IF YOU WANT THE BLUEPRINTS TO NOT ADD WALLS TO AN AREA.
|
||||||
|
//I personally think adding walls to an area is a big deal, so this is commented out.
|
||||||
|
|
||||||
|
//BEGIN ESOTERIC BULLSHIT
|
||||||
|
//log_debug("Origin: [origin.c_airblock(checkT)] SourceT: [sourceT.c_airblock(checkT)] 0=NB 1=AB 2=ZB, 3=B")
|
||||||
|
/*
|
||||||
|
if(origin.c_airblock(checkT)) //If everything breaks and it doesn't want to work, turn on the above debug and check this line. C.L. 0 = not blocked.
|
||||||
|
continue
|
||||||
|
*/
|
||||||
|
//END ESOTERIC BULLSHIT
|
||||||
|
|
||||||
|
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
|
||||||
|
if(found_turfs.len)
|
||||||
|
found_turfs += origin //If this isn't done, it just adds the 8 tiles around the user.
|
||||||
|
return found_turfs
|
||||||
|
|
||||||
|
/proc/create_area(mob/creator, var/obj/item/areaeditor/AO)
|
||||||
|
if(AO && istype(AO,/obj/item/areaeditor))
|
||||||
|
if(AO.uses_charges && AO.charges < 1)
|
||||||
|
to_chat(creator, span_warning("You need more paper before you can even think of editing this area!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2)
|
||||||
|
if(!turfs)
|
||||||
|
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
|
||||||
|
return
|
||||||
|
if(length(turfs) > BP_MAX_ROOM_SIZE)
|
||||||
|
to_chat(creator, span_warning("The room you're in is too big. It is [length(turfs) >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((length(turfs) / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed."))
|
||||||
|
return
|
||||||
|
var/list/areas = list("New Area" = /area)
|
||||||
|
var/annoy_admins = 0
|
||||||
|
|
||||||
|
for(var/i in 1 to length(turfs))
|
||||||
|
var/area/place = get_area(turfs[i])
|
||||||
|
if(blacklisted_areas[place.type])
|
||||||
|
continue
|
||||||
|
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
|
||||||
|
continue // No expanding powerless rooms etc
|
||||||
|
areas[place.name] = place
|
||||||
|
|
||||||
|
var/area_choice = tgui_input_list(creator, "Choose an area to expand or make a new area", "Area Expansion", areas)
|
||||||
|
if(isnull(area_choice))
|
||||||
|
to_chat(creator, span_warning("No choice selected. No adjustments made."))
|
||||||
|
return
|
||||||
|
area_choice = areas[area_choice]
|
||||||
|
|
||||||
|
var/area/newA
|
||||||
|
var/area/oldA = get_area(get_turf(creator))
|
||||||
|
if(!isarea(area_choice))
|
||||||
|
var/str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN)
|
||||||
|
str = sanitize(str,MAX_NAME_LEN)
|
||||||
|
if(!str || !length(str)) //cancel
|
||||||
|
return
|
||||||
|
if(length(str) > 50)
|
||||||
|
to_chat(creator, "<span class='warning'>Name too long.</span>")
|
||||||
|
return
|
||||||
|
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
|
||||||
|
if(A.name == str)
|
||||||
|
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
|
||||||
|
return
|
||||||
|
annoy_admins = 1 //They just made a new area entirely.
|
||||||
|
newA = new area_choice
|
||||||
|
newA.setup(str)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
else
|
||||||
|
newA = area_choice
|
||||||
|
|
||||||
|
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
|
||||||
|
var/turf/thing = turfs[i]
|
||||||
|
newA.contents += thing
|
||||||
|
thing.change_area(oldA, newA)
|
||||||
|
|
||||||
|
|
||||||
|
set_area_machinery(newA, newA.name, oldA.name)// Change the name and area defines of all the machinery to the correct area.
|
||||||
|
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
|
||||||
|
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
|
||||||
|
if(annoy_admins)
|
||||||
|
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
|
||||||
|
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
|
||||||
|
if(AO && istype(AO,/obj/item/areaeditor))
|
||||||
|
if(AO.uses_charges)
|
||||||
|
AO.charges -= 1
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// USED FOR VARIANT ROOM CREATION.
|
||||||
|
// OLD CODE. DON'T TOUCH OR 100 RABID SQUIRRELS WILL DEVOUR YOU.
|
||||||
|
// I say old code, but it truly isn't. It's a bastardization of the new create_area code and the old create_area code.
|
||||||
|
// In essence, it does a few things: Ensure no blacklisted areas are nearby, get the nearby areas (to allow merging), and allow you to make a whole near area.
|
||||||
|
/obj/item/areaeditor/proc/create_area_whole(mob/creator, var/override = 0) //Gets the entire enclosed space and makes a new area out of it. Can overwrite old areas.
|
||||||
|
if(uses_charges && charges < 5)
|
||||||
|
to_chat(creator, span_warning("You need more paper before you can even think of editing this area!"))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/res = detect_room_ex(get_turf(creator), can_create_areas_into, area_or_turf_fail_types)
|
||||||
|
if(!res)
|
||||||
|
to_chat(creator, span_warning("There is an area forbidden from being edited here! Use the fine-tune area creator! (3x3)"))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!istype(res,/list))
|
||||||
|
switch(res)
|
||||||
|
if(ROOM_ERR_SPACE)
|
||||||
|
to_chat(creator, "<span class='warning'>The new area must be completely airtight!</span>")
|
||||||
|
return
|
||||||
|
if(ROOM_ERR_TOOLARGE)
|
||||||
|
to_chat(creator, "<span class='warning'>The new area too large!</span>")
|
||||||
|
return
|
||||||
|
if(ROOM_ERR_FORBIDDEN)
|
||||||
|
to_chat(creator, "<span class='warning'>There is an area forbidden from being edited here!</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(creator, "<span class='warning'>Error! Please notify administration!</span>")
|
||||||
|
return
|
||||||
|
var/list/turf/turfs = res
|
||||||
|
|
||||||
|
var/list/areas = list("New Area" = /area) //The list of areas surrounding the user.
|
||||||
|
var/area/newA //The new area
|
||||||
|
var/area/oldA = get_area(get_turf(creator)) //The old area (area currently standing in)
|
||||||
|
var/str //What the new area is named.
|
||||||
|
var/can_make_new_area = 1 //If they can make a new area here or not.
|
||||||
|
|
||||||
|
var/list/nearby_turfs_to_check = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2) //Get the nearby areas.
|
||||||
|
|
||||||
|
if(!nearby_turfs_to_check)
|
||||||
|
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
|
||||||
|
return
|
||||||
|
if(length(turfs) > BP_MAX_ROOM_SIZE)
|
||||||
|
to_chat(creator, span_warning("The room you're in is too big. It is [length(turfs) >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((length(turfs) / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed."))
|
||||||
|
return
|
||||||
|
|
||||||
|
for(var/i in 1 to length(nearby_turfs_to_check))
|
||||||
|
var/area/place = get_area(nearby_turfs_to_check[i])
|
||||||
|
if(blacklisted_areas[place.type])
|
||||||
|
if(!creator.lastarea != place) //Stops them from merging a blacklisted area to make it larger. Allows them to merge a blacklisted area into an allowed area. (Expansion!)
|
||||||
|
continue
|
||||||
|
if(!BUILDABLE_AREA_TYPES[place.type]) //TODOTODOTODO
|
||||||
|
can_make_new_area = 0
|
||||||
|
if(!place.requires_power || (place.flags & BLUE_SHIELDED))
|
||||||
|
continue // No expanding powerless rooms etc
|
||||||
|
areas[place.name] = place
|
||||||
|
|
||||||
|
//They can select an area they want to turn their current area into.
|
||||||
|
var/area_choice = tgui_input_list(creator, "What area do you want to turn the area YOU ARE CURRENTLY STANDING IN to? Or do you want to make a new area?", "Area Expansion", areas)
|
||||||
|
if(isnull(area_choice)) //They pressed cancel.
|
||||||
|
to_chat(creator, "<span class='warning'>No changes made.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
area_choice = areas[area_choice]
|
||||||
|
|
||||||
|
|
||||||
|
if(!isarea(area_choice)) //They chose "New Area"
|
||||||
|
if(!can_make_new_area && !can_override)
|
||||||
|
to_chat(creator, "<span class='warning'>Making a new area here would be meaningless. Renaming it would be a better option.</span>")
|
||||||
|
return
|
||||||
|
str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN)
|
||||||
|
str = sanitize(str,MAX_NAME_LEN)
|
||||||
|
if(!str || !length(str)) //cancel
|
||||||
|
return
|
||||||
|
if(length(str) > 50)
|
||||||
|
to_chat(creator, "<span class='warning'>Name too long.</span>")
|
||||||
|
return
|
||||||
|
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
|
||||||
|
if(A.name == str)
|
||||||
|
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/confirm = tgui_alert(creator, "Are you sure you want to change [oldA.name] into a new area named [str]?", "READ CAREFULLY", list("No", "Yes"))
|
||||||
|
if(confirm == "No")
|
||||||
|
to_chat(creator, "<span class='warning'>No changes made.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
newA = new area_choice
|
||||||
|
newA.setup(str)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
else
|
||||||
|
var/confirm = tgui_alert(creator, "Are you sure you want to change [oldA.name] into [area_choice]?", "READ CAREFULLY", list("No", "Yes"))
|
||||||
|
if(confirm == "No")
|
||||||
|
to_chat(creator, "<span class='warning'>No changes made.</span>")
|
||||||
|
return
|
||||||
|
newA = area_choice //They selected to turn the area they're standing on into the selected area.
|
||||||
|
|
||||||
|
if(str) //New area, new name.
|
||||||
|
newA.setup(str)
|
||||||
|
else
|
||||||
|
newA.setup(newA.name)
|
||||||
|
|
||||||
|
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
|
||||||
|
var/turf/thing = turfs[i]
|
||||||
|
newA.contents += thing
|
||||||
|
thing.change_area(oldA, newA)
|
||||||
|
|
||||||
|
move_turfs_to_area(turfs, newA)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
set_area_machinery(newA, newA.name, oldA.name)
|
||||||
|
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
|
||||||
|
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
|
||||||
|
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
|
||||||
|
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
|
||||||
|
charges -= 5
|
||||||
|
|
||||||
|
spawn(5)
|
||||||
|
interact()
|
||||||
|
return
|
||||||
|
|
||||||
|
/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A)
|
||||||
|
for(var/T in turfs)
|
||||||
|
ChangeArea(T, A)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/item/areaeditor/proc/detect_room_ex(var/turf/first, var/allowedAreas = AREA_SPACE, var/list/forbiddenAreas = list(), var/visual)
|
||||||
|
if(!istype(first))
|
||||||
|
return ROOM_ERR_LOLWAT
|
||||||
|
if(!visual && forbiddenAreas[first.loc.type] || forbiddenAreas[first.type]) //Is the area of the starting turf a banned area? Is the turf a banned area?
|
||||||
|
return ROOM_ERR_FORBIDDEN
|
||||||
|
var/list/turf/found = new
|
||||||
|
var/list/turf/pending = list(first)
|
||||||
|
while(pending.len)
|
||||||
|
if (found.len+pending.len > BP_MAX_ROOM_SIZE)
|
||||||
|
return ROOM_ERR_TOOLARGE
|
||||||
|
var/turf/T = pending[1] //why byond havent list::pop()?
|
||||||
|
pending -= T
|
||||||
|
for (var/dir in cardinal)
|
||||||
|
var/turf/NT = get_step(T,dir)
|
||||||
|
if (!isturf(NT) || (NT in found) || (NT in pending))
|
||||||
|
continue
|
||||||
|
if(!visual && forbiddenAreas[NT.loc.type])
|
||||||
|
return ROOM_ERR_FORBIDDEN
|
||||||
|
// We ask ZAS to determine if its airtight. Thats what matters anyway right?
|
||||||
|
if(air_master.air_blocked(T, NT))
|
||||||
|
// Okay thats the edge of the room
|
||||||
|
if(get_area_type(NT.loc) == AREA_SPACE && air_master.air_blocked(NT, NT))
|
||||||
|
found += NT // So we include walls/doors not already in any area
|
||||||
|
continue
|
||||||
|
if (istype(NT, /turf/space))
|
||||||
|
return ROOM_ERR_SPACE //omg hull breach we all going to die here
|
||||||
|
if (istype(NT, /turf/simulated/shuttle))
|
||||||
|
return ROOM_ERR_SPACE // Unsure why this, but was in old code. Trusting for now.
|
||||||
|
if (NT.loc != first.loc && !(get_area_type(NT.loc) & allowedAreas))
|
||||||
|
// Edge of a protected area. Lets stop here...
|
||||||
|
continue
|
||||||
|
if (!istype(NT, /turf/simulated))
|
||||||
|
// Great, unsimulated... eh, just stop searching here
|
||||||
|
continue
|
||||||
|
// Okay, NT looks promising, lets continue the search there!
|
||||||
|
pending += NT
|
||||||
|
found += T
|
||||||
|
// end while
|
||||||
|
return found
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Nice verbs for the engineer to see where areas start/end.
|
||||||
|
|
||||||
|
/obj/item/areaeditor/verb/seeRoomColors()
|
||||||
|
set src in usr
|
||||||
|
set category = "Blueprints"
|
||||||
|
set name = "Show Room Colors"
|
||||||
|
|
||||||
|
// If standing somewhere we can expand from, use expand perms, otherwise create
|
||||||
|
var/canOverwrite = (get_area_type() & can_expand_areas_in) ? can_expand_areas_into : can_create_areas_into
|
||||||
|
var/res = detect_room_ex(get_turf(usr), canOverwrite, visual = 1)
|
||||||
|
if(!istype(res, /list))
|
||||||
|
switch(res)
|
||||||
|
if(ROOM_ERR_SPACE)
|
||||||
|
to_chat(usr, "<span class='warning'>The new area must be completely airtight!</span>")
|
||||||
|
return
|
||||||
|
if(ROOM_ERR_TOOLARGE)
|
||||||
|
to_chat(usr, "<span class='warning'>The new area too large!</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(usr, "<span class='danger'>Error! Please notify administration!</span>")
|
||||||
|
return
|
||||||
|
// Okay we got a room, lets color it
|
||||||
|
seeAreaColors_remove()
|
||||||
|
var/icon/green = new('icons/misc/debug_group.dmi', "green")
|
||||||
|
for(var/turf/T in res)
|
||||||
|
usr << image(green, T, "blueprints", TURF_LAYER)
|
||||||
|
areaColor_turfs += T
|
||||||
|
to_chat(usr, "<span class='notice'>The space covered by the new area is highlighted in green.</span>")
|
||||||
|
|
||||||
|
/obj/item/areaeditor/verb/seeAreaColors()
|
||||||
|
set src in usr
|
||||||
|
set category = "Blueprints"
|
||||||
|
set name = "Show Area Colors"
|
||||||
|
|
||||||
|
// Remove any existing
|
||||||
|
seeAreaColors_remove()
|
||||||
|
|
||||||
|
to_chat(usr, "<span class='notice'>\The [src] shows nearby areas in different colors.</span>")
|
||||||
|
var/i = 0
|
||||||
|
for(var/area/A in range(usr))
|
||||||
|
if(get_area_type(A) == AREA_SPACE)
|
||||||
|
continue // Don't overlay all of space!
|
||||||
|
var/icon/areaColor = new('icons/misc/debug_rebuild.dmi', "[++i]")
|
||||||
|
to_chat(usr, "- [A] as [i]")
|
||||||
|
for(var/turf/T in A.contents)
|
||||||
|
usr << image(areaColor, T, "blueprints", TURF_LAYER)
|
||||||
|
areaColor_turfs += T
|
||||||
|
|
||||||
|
/obj/item/areaeditor/verb/seeAreaColors_remove()
|
||||||
|
set src in usr
|
||||||
|
set category = "Blueprints"
|
||||||
|
set name = "Remove Area Colors"
|
||||||
|
|
||||||
|
areaColor_turfs.Cut()
|
||||||
|
if(usr.client.images.len)
|
||||||
|
for(var/image/i in usr.client.images)
|
||||||
|
if(i.icon_state == "blueprints")
|
||||||
|
usr.client.images.Remove(i)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//GLOBAL VERB FOR PAPER TO ENABLE ANYONE TO MAKE AN AREA IN BUILDABLE AREAS.
|
||||||
|
//THIS IS 70 TILES. ANYTHING LARGER SHOULD USE ACTUAL BLUEPRINTS.
|
||||||
|
|
||||||
|
/obj/item/weapon/paper
|
||||||
|
var/created_area = 0
|
||||||
|
var/area_cooldown = 0
|
||||||
|
|
||||||
|
/obj/item/weapon/paper/verb/create_area()
|
||||||
|
set name = "Create Area"
|
||||||
|
set category = "Object"
|
||||||
|
set src in usr
|
||||||
|
|
||||||
|
if(created_area)
|
||||||
|
to_chat(usr, "<span class='warning'>This paper has already been used to create an area.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(usr.stat || world.time < area_cooldown)
|
||||||
|
to_chat(usr, "<span class='warning'>You recently used this paper to try to create an area. Wait one minute before using it again.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
area_cooldown = world.time + 600 //Anti spam.
|
||||||
|
|
||||||
|
create_new_area(usr)
|
||||||
|
add_fingerprint(usr)
|
||||||
|
return
|
||||||
|
|
||||||
|
/proc/get_new_area_type(area/A) //1 = can build in. 0 = can not build in.
|
||||||
|
if (!A)
|
||||||
|
A = get_area(usr)
|
||||||
|
if(A.outdoors) //ALWAYS able to build outdoors. This means if it's missed in BUILDABLE_AREA_TYPES it's fine.
|
||||||
|
return 1
|
||||||
|
|
||||||
|
for (var/type in BUILDABLE_AREA_TYPES) //This works well.
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return 1
|
||||||
|
|
||||||
|
for (var/type in SPECIALS)
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return 0
|
||||||
|
return 0 //If it's not a buildable area, don't let them build in it.
|
||||||
|
|
||||||
|
|
||||||
|
/proc/detect_new_area(var/turf/first, var/user) //Heavily simplified version for creating an area yourself.
|
||||||
|
if(!istype(first)) //Not on a turf.
|
||||||
|
to_chat(usr, "<span class='warning'You can not create a room here.</span>")
|
||||||
|
return
|
||||||
|
if(get_new_area_type(first.loc) == 1) //Are they in an area they can build? I tried to do this BUILDABLE_AREA_TYPES[first.loc.type] but it refused.
|
||||||
|
var/list/turf/found = new
|
||||||
|
var/list/turf/pending = list(first)
|
||||||
|
while(pending.len)
|
||||||
|
if (found.len+pending.len > 70)
|
||||||
|
return 1 //TOOLARGE
|
||||||
|
var/turf/T = pending[1]
|
||||||
|
pending -= T
|
||||||
|
for (var/dir in cardinal)
|
||||||
|
var/turf/NT = get_step(T,dir)
|
||||||
|
if (!isturf(NT) || (NT in found) || (NT in pending))
|
||||||
|
continue
|
||||||
|
if(!get_new_area_type(NT.loc) == 1) //The contains somewhere that is NOT a buildable area.
|
||||||
|
return 3 //NOT A BUILDABLE AREA
|
||||||
|
|
||||||
|
if(air_master.air_blocked(T, NT)) //Is the room airtight?
|
||||||
|
// Okay thats the edge of the room
|
||||||
|
if(get_new_area_type(NT.loc) == 1 && air_master.air_blocked(NT, NT))
|
||||||
|
found += NT // So we include walls/doors not already in any area
|
||||||
|
continue
|
||||||
|
if (istype(NT, /turf/space))
|
||||||
|
return 2 //SPACE
|
||||||
|
if (istype(NT, /turf/simulated/shuttle))
|
||||||
|
return 2 //SPACE
|
||||||
|
if (NT.loc != first.loc && !(get_new_area_type(NT.loc) & 1))
|
||||||
|
// Edge of a protected area. Lets stop here...
|
||||||
|
continue
|
||||||
|
if (!istype(NT, /turf/simulated))
|
||||||
|
// Great, unsimulated... eh, just stop searching here
|
||||||
|
continue
|
||||||
|
// Okay, NT looks promising, lets continue the search there!
|
||||||
|
pending += NT
|
||||||
|
found += T
|
||||||
|
// end while
|
||||||
|
return found
|
||||||
|
else
|
||||||
|
return 3
|
||||||
|
|
||||||
|
/proc/create_new_area(mob/creator) //Heavily simplified version of the blueprint version.
|
||||||
|
var/res = detect_new_area(get_turf(creator), creator)
|
||||||
|
if(!res)
|
||||||
|
to_chat(creator, span_warning("Something went wrong."))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!istype(res,/list))
|
||||||
|
switch(res)
|
||||||
|
if(1)
|
||||||
|
to_chat(creator, "<span class='warning'>The new area too large! You can only have an area that is up to 70 tiles.</span>")
|
||||||
|
return
|
||||||
|
if(2)
|
||||||
|
to_chat(creator, "<span class='warning'>The new area must be completely airtight and not be part of a shuttle!</span>")
|
||||||
|
return
|
||||||
|
if(3)
|
||||||
|
to_chat(creator, "<span class='warning'>There is an area not permitted to be built in somewhere in the room!</span>")
|
||||||
|
return
|
||||||
|
else
|
||||||
|
to_chat(creator, "<span class='warning'>Error! Please notify administration!</span>")
|
||||||
|
return
|
||||||
|
var/list/turf/turfs = res
|
||||||
|
|
||||||
|
var/area/newA //The new area
|
||||||
|
var/area/oldA = get_area(get_turf(creator)) //The old area (area currently standing in)
|
||||||
|
var/str //What the new area is named.
|
||||||
|
|
||||||
|
var/list/nearby_turfs_to_check = detect_room(get_turf(creator), area_or_turf_fail_types, 70) //Get the nearby areas.
|
||||||
|
|
||||||
|
if(!nearby_turfs_to_check)
|
||||||
|
to_chat(creator, span_warning("The new area must have a floor and not a part of a shuttle."))
|
||||||
|
return
|
||||||
|
if(length(turfs) > 70) //Sanity
|
||||||
|
to_chat(creator, span_warning("The room you're in is too big. It can only be 70 tiles in size, excluding walls."))
|
||||||
|
return
|
||||||
|
|
||||||
|
//They can select an area they want to turn their current area into.
|
||||||
|
str = sanitizeSafe(tgui_input_text(usr, "What would you like to name the area?", "Area Name", null, MAX_NAME_LEN), MAX_NAME_LEN)
|
||||||
|
if(isnull(str)) //They pressed cancel.
|
||||||
|
to_chat(creator, "<span class='warning'>No new area made. Cancelling.</span>")
|
||||||
|
return
|
||||||
|
if(!str || !length(str)) //sanity
|
||||||
|
to_chat(creator, "<span class='warning'>No new area made. Cancelling.</span>")
|
||||||
|
return
|
||||||
|
if(length(str) > MAX_NAME_LEN)
|
||||||
|
to_chat(creator, "<span class='warning'>Name too long.</span>")
|
||||||
|
return
|
||||||
|
for(var/area/A in world) //Check to make sure we're not making a duplicate name. Sanity.
|
||||||
|
if(A.name == str)
|
||||||
|
to_chat(creator, "<span class='warning'>An area in the world alreay has this name.</span>")
|
||||||
|
return
|
||||||
|
newA = new /area
|
||||||
|
newA.setup(str)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
newA.setup(str)
|
||||||
|
|
||||||
|
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
|
||||||
|
var/turf/thing = turfs[i]
|
||||||
|
newA.contents += thing
|
||||||
|
thing.change_area(oldA, newA)
|
||||||
|
|
||||||
|
move_turfs_to_area(turfs, newA)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
set_area_machinery(newA, newA.name, oldA.name)
|
||||||
|
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
|
||||||
|
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
|
||||||
|
message_admins("[key_name(creator, creator.client)] just made a new area called [newA.name] ](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>) at ([creator.x],[creator.y],[creator.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[creator.x];Y=[creator.y];Z=[creator.z]'>JMP</a>)",0,1)
|
||||||
|
log_game("[key_name(creator, creator.client)] just made a new area called [newA.name]")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
#undef BP_MAX_ROOM_SIZE
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
starts_with = list(
|
starts_with = list(
|
||||||
/obj/item/clothing/accessory/storage/brown_vest,
|
/obj/item/clothing/accessory/storage/brown_vest,
|
||||||
/obj/item/blueprints,
|
/obj/item/areaeditor/blueprints,
|
||||||
|
/obj/item/wire_reader,
|
||||||
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
|
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
|
||||||
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
|
///obj/item/clamp, //VOREStation Removal: without leaks those are pointless,
|
||||||
/obj/item/clothing/under/rank/chief_engineer,
|
/obj/item/clothing/under/rank/chief_engineer,
|
||||||
@@ -100,7 +101,8 @@
|
|||||||
/obj/item/clothing/shoes/boots/winter/engineering,
|
/obj/item/clothing/shoes/boots/winter/engineering,
|
||||||
/obj/item/weapon/tank/emergency/oxygen/engi,
|
/obj/item/weapon/tank/emergency/oxygen/engi,
|
||||||
/obj/item/weapon/storage/belt/utility, //VOREStation Add
|
/obj/item/weapon/storage/belt/utility, //VOREStation Add
|
||||||
/obj/item/weapon/reagent_containers/spray/windowsealant) //VOREStation Add
|
/obj/item/weapon/reagent_containers/spray/windowsealant, //VOREStation Add
|
||||||
|
/obj/item/areaeditor/blueprints/engineers) //VOREStation Add
|
||||||
|
|
||||||
/obj/structure/closet/secure_closet/engineering_personal/Initialize()
|
/obj/structure/closet/secure_closet/engineering_personal/Initialize()
|
||||||
if(prob(50))
|
if(prob(50))
|
||||||
|
|||||||
@@ -128,7 +128,7 @@
|
|||||||
to_chat(usr, "<span class='notice'>***********************************************************<br>\
|
to_chat(usr, "<span class='notice'>***********************************************************<br>\
|
||||||
Left Mouse Button on turf = Select as point A<br>\
|
Left Mouse Button on turf = Select as point A<br>\
|
||||||
Right Mouse Button on turf = Select as point B<br>\
|
Right Mouse Button on turf = Select as point B<br>\
|
||||||
Right Mouse Button on buildmode button = Change floor/wall type<br>\
|
Right Mouse Button on buildmode button = Change floor/wall type/area name<br>\
|
||||||
***********************************************************</span>")
|
***********************************************************</span>")
|
||||||
|
|
||||||
if(BUILDMODE_LADDER)
|
if(BUILDMODE_LADDER)
|
||||||
@@ -226,6 +226,8 @@
|
|||||||
var/floor_holder = /turf/simulated/floor/plating
|
var/floor_holder = /turf/simulated/floor/plating
|
||||||
var/turf/coordA = null
|
var/turf/coordA = null
|
||||||
var/turf/coordB = null
|
var/turf/coordB = null
|
||||||
|
var/area_enabled = 0
|
||||||
|
var/area_name = "New Area"
|
||||||
|
|
||||||
var/new_light_color = "#FFFFFF"
|
var/new_light_color = "#FFFFFF"
|
||||||
var/new_light_range = 3
|
var/new_light_range = 3
|
||||||
@@ -275,6 +277,18 @@
|
|||||||
master.buildmode.valueholder = tgui_input_list(usr,"Enter variable value:", "Value", world)
|
master.buildmode.valueholder = tgui_input_list(usr,"Enter variable value:", "Value", world)
|
||||||
|
|
||||||
if(BUILDMODE_ROOM)
|
if(BUILDMODE_ROOM)
|
||||||
|
var/area_choice = tgui_alert(usr, "Would you like to generate a new area as well?","Room Builder", list("No", "Yes"))
|
||||||
|
switch(area_choice)
|
||||||
|
if("No")
|
||||||
|
area_enabled = 0
|
||||||
|
if("Yes")
|
||||||
|
area_enabled = 1
|
||||||
|
area_name = tgui_input_text(usr, "New area name", "Room Buildmode", max_length = MAX_NAME_LEN)
|
||||||
|
if(isnull(area_name))
|
||||||
|
to_chat(usr, "<span class='notice'>You must enter a non-null name.</span>")
|
||||||
|
area_enabled = 0
|
||||||
|
return
|
||||||
|
area_name = sanitize(area_name,MAX_NAME_LEN)
|
||||||
var/choice = tgui_alert(usr, "Would you like to change the floor or wall holders?","Room Builder", list("Floor", "Wall"))
|
var/choice = tgui_alert(usr, "Would you like to change the floor or wall holders?","Room Builder", list("Floor", "Wall"))
|
||||||
switch(choice)
|
switch(choice)
|
||||||
if("Floor")
|
if("Floor")
|
||||||
@@ -411,13 +425,19 @@
|
|||||||
to_chat(user, "<span class='notice'>Defined [object] ([object.type]) as point B.</span>")
|
to_chat(user, "<span class='notice'>Defined [object] ([object.type]) as point B.</span>")
|
||||||
|
|
||||||
if(holder.buildmode.coordA && holder.buildmode.coordB)
|
if(holder.buildmode.coordA && holder.buildmode.coordB)
|
||||||
|
if(isnull(holder.buildmode.area_name))
|
||||||
|
to_chat(user, "<span class='notice'>ERROR: Insert area name before use.</span>")
|
||||||
|
holder.buildmode.coordA = null
|
||||||
|
holder.buildmode.coordB = null
|
||||||
|
return
|
||||||
to_chat(user, "<span class='notice'>A and B set, creating rectangle.</span>")
|
to_chat(user, "<span class='notice'>A and B set, creating rectangle.</span>")
|
||||||
holder.buildmode.make_rectangle(
|
holder.buildmode.make_rectangle(
|
||||||
holder.buildmode.coordA,
|
holder.buildmode.coordA,
|
||||||
holder.buildmode.coordB,
|
holder.buildmode.coordB,
|
||||||
holder.buildmode.wall_holder,
|
holder.buildmode.wall_holder,
|
||||||
holder.buildmode.floor_holder
|
holder.buildmode.floor_holder,
|
||||||
)
|
holder.buildmode.area_enabled,
|
||||||
|
holder.buildmode.area_name)
|
||||||
holder.buildmode.coordA = null
|
holder.buildmode.coordA = null
|
||||||
holder.buildmode.coordB = null
|
holder.buildmode.coordB = null
|
||||||
|
|
||||||
@@ -651,7 +671,7 @@
|
|||||||
result = default_path
|
result = default_path
|
||||||
return result
|
return result
|
||||||
|
|
||||||
/obj/effect/bmode/buildmode/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type)
|
/obj/effect/bmode/buildmode/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type, var/area_enabled, var/area_name)
|
||||||
if(!A || !B) // No coords
|
if(!A || !B) // No coords
|
||||||
return
|
return
|
||||||
if(A.z != B.z) // Not same z-level
|
if(A.z != B.z) // Not same z-level
|
||||||
@@ -685,6 +705,10 @@
|
|||||||
var/high_bound_x = lower_left_corner.x + abs(width)
|
var/high_bound_x = lower_left_corner.x + abs(width)
|
||||||
var/high_bound_y = lower_left_corner.y + abs(height)
|
var/high_bound_y = lower_left_corner.y + abs(height)
|
||||||
|
|
||||||
|
var/origin_x = lower_left_corner.x + round((abs(width)/2))
|
||||||
|
var/origin_y = lower_left_corner.y + round((abs(height)/2))
|
||||||
|
var/turf/origin
|
||||||
|
|
||||||
for(var/i = low_bound_x, i <= high_bound_x, i++)
|
for(var/i = low_bound_x, i <= high_bound_x, i++)
|
||||||
for(var/j = low_bound_y, j <= high_bound_y, j++)
|
for(var/j = low_bound_y, j <= high_bound_y, j++)
|
||||||
var/turf/T = locate(i, j, z_level)
|
var/turf/T = locate(i, j, z_level)
|
||||||
@@ -693,11 +717,91 @@
|
|||||||
T.ChangeTurf(wall_type)
|
T.ChangeTurf(wall_type)
|
||||||
else
|
else
|
||||||
new wall_type(T)
|
new wall_type(T)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
if(T.x == origin_x && T.y == origin_y) //Get the middle of the square.
|
||||||
|
origin = T
|
||||||
if(isturf(floor_type))
|
if(isturf(floor_type))
|
||||||
T.ChangeTurf(floor_type)
|
T.ChangeTurf(floor_type)
|
||||||
else
|
else
|
||||||
new floor_type(T)
|
new floor_type(T)
|
||||||
|
if(area_enabled) //Let's try not to make a new area unless you got walls and a floor.
|
||||||
|
create_buildmode_area(area_name, origin) //Generates a new area.
|
||||||
|
|
||||||
|
/proc/create_buildmode_area(var/area_name, var/turf/origin)
|
||||||
|
var/turfs = detect_room_buildmode(origin)
|
||||||
|
|
||||||
|
var/area/newA
|
||||||
|
var/area/oldA = get_area(origin)
|
||||||
|
var/str = area_name
|
||||||
|
str = sanitize(str,MAX_NAME_LEN)
|
||||||
|
if(!str || !length(str)) //cancel
|
||||||
|
return
|
||||||
|
newA = new /area/buildmode
|
||||||
|
newA.dynamic_lighting = FALSE // Without this it's pitch black if you build anywhere but space.
|
||||||
|
newA.luminosity = TRUE // Without this it's pitch black if you build anywhere but space.
|
||||||
|
newA.setup(str)
|
||||||
|
newA.has_gravity = oldA.has_gravity
|
||||||
|
|
||||||
|
for(var/i in 1 to length(turfs)) //Fix lighting. Praise the lord.
|
||||||
|
var/turf/thing = turfs[i]
|
||||||
|
newA.contents += thing
|
||||||
|
thing.change_area(oldA, newA)
|
||||||
|
|
||||||
|
set_area_machinery(newA, newA.name, oldA.name)// Change the name and area defines of all the machinery to the correct area.
|
||||||
|
oldA.power_check() //Simply makes the area turn the power off if you nicked an APC from it.
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/proc/detect_room_buildmode(var/turf/first, var/allowedAreas = AREA_SPACE)
|
||||||
|
if(!istype(first))
|
||||||
|
return
|
||||||
|
var/list/turf/found = new
|
||||||
|
var/list/turf/pending = list(first)
|
||||||
|
while(pending.len)
|
||||||
|
var/turf/T = pending[1]
|
||||||
|
pending -= T
|
||||||
|
for (var/dir in cardinal)
|
||||||
|
var/turf/NT = get_step(T,dir)
|
||||||
|
if (!isturf(NT) || (NT in found) || (NT in pending))
|
||||||
|
continue
|
||||||
|
// We ask ZAS to determine if its airtight. Thats what matters anyway right?
|
||||||
|
if(air_master.air_blocked(T, NT))
|
||||||
|
// Okay thats the edge of the room
|
||||||
|
if(get_area_type_buildmode(NT.loc) == AREA_SPACE && air_master.air_blocked(NT, NT))
|
||||||
|
found += NT // So we include walls/doors not already in any area
|
||||||
|
continue
|
||||||
|
if (istype(NT, /turf/space))
|
||||||
|
return //omg hull breach we all going to die here
|
||||||
|
if (istype(NT, /turf/simulated/shuttle))
|
||||||
|
return // Unsure why this, but was in old code. Trusting for now.
|
||||||
|
if (NT.loc != first.loc && !(get_area_type_buildmode(NT.loc) & allowedAreas))
|
||||||
|
// Edge of a protected area. Lets stop here...
|
||||||
|
continue
|
||||||
|
if (!istype(NT, /turf/simulated))
|
||||||
|
// Great, unsimulated... eh, just stop searching here
|
||||||
|
continue
|
||||||
|
// Okay, NT looks promising, lets continue the search there!
|
||||||
|
pending += NT
|
||||||
|
found += T
|
||||||
|
// end while
|
||||||
|
return found
|
||||||
|
|
||||||
|
/proc/get_area_type_buildmode(area/A)
|
||||||
|
if(A.outdoors)
|
||||||
|
return AREA_SPACE
|
||||||
|
|
||||||
|
for (var/type in BUILDABLE_AREA_TYPES)
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return AREA_SPACE
|
||||||
|
|
||||||
|
for (var/type in SPECIALS)
|
||||||
|
if ( istype(A,type) )
|
||||||
|
return AREA_SPECIAL
|
||||||
|
return AREA_STATION
|
||||||
|
|
||||||
|
/area/buildmode
|
||||||
|
dynamic_lighting = FALSE
|
||||||
|
luminosity = FALSE
|
||||||
|
|
||||||
#undef BUILDMODE_BASIC
|
#undef BUILDMODE_BASIC
|
||||||
#undef BUILDMODE_ADVANCED
|
#undef BUILDMODE_ADVANCED
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
|
|||||||
/obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/captain,\
|
/obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/captain,\
|
||||||
/obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
|
/obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
|
||||||
/obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\
|
/obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\
|
||||||
/obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/weapon/disk/nuclear,\
|
/obj/item/clothing/shoes/magboots, /obj/item/areaeditor/blueprints, /obj/item/weapon/disk/nuclear,\
|
||||||
/obj/item/clothing/suit/space/void, /obj/item/weapon/tank)
|
/obj/item/clothing/suit/space/void, /obj/item/weapon/tank)
|
||||||
|
|
||||||
/proc/fake_attack(var/mob/living/target)
|
/proc/fake_attack(var/mob/living/target)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
to_chat(user, "<span class='warning'>[comp] is already in a shuttle.</span>")
|
to_chat(user, "<span class='warning'>[comp] is already in a shuttle.</span>")
|
||||||
return
|
return
|
||||||
// Count turfs in the area
|
// Count turfs in the area
|
||||||
var/list/turfs = get_area_turfs(my_area)
|
var/list/turfs = get_current_area_turfs(my_area)
|
||||||
if(turfs.len > max_area_turfs)
|
if(turfs.len > max_area_turfs)
|
||||||
to_chat(user, "<span class='warning'>The new shuttle area is too large.</span>")
|
to_chat(user, "<span class='warning'>The new shuttle area is too large.</span>")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
return FALSE
|
return FALSE
|
||||||
/obj/item/weapon/pinpointer/digest_act(var/atom/movable/item_storage = null)
|
/obj/item/weapon/pinpointer/digest_act(var/atom/movable/item_storage = null)
|
||||||
return FALSE
|
return FALSE
|
||||||
/obj/item/blueprints/digest_act(var/atom/movable/item_storage = null)
|
/obj/item/areaeditor/blueprints/digest_act(var/atom/movable/item_storage = null)
|
||||||
return FALSE
|
return FALSE
|
||||||
/obj/item/weapon/disk/nuclear/digest_act(var/atom/movable/item_storage = null)
|
/obj/item/weapon/disk/nuclear/digest_act(var/atom/movable/item_storage = null)
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|||||||
@@ -1216,7 +1216,7 @@
|
|||||||
#include "code\game\objects\items\antag_spawners.dm"
|
#include "code\game\objects\items\antag_spawners.dm"
|
||||||
#include "code\game\objects\items\apc_frame.dm"
|
#include "code\game\objects\items\apc_frame.dm"
|
||||||
#include "code\game\objects\items\bells.dm"
|
#include "code\game\objects\items\bells.dm"
|
||||||
#include "code\game\objects\items\blueprints.dm"
|
#include "code\game\objects\items\blueprints_vr.dm"
|
||||||
#include "code\game\objects\items\bodybag.dm"
|
#include "code\game\objects\items\bodybag.dm"
|
||||||
#include "code\game\objects\items\contraband.dm"
|
#include "code\game\objects\items\contraband.dm"
|
||||||
#include "code\game\objects\items\contraband_vr.dm"
|
#include "code\game\objects\items\contraband_vr.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user