mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
Blueprints Rework (#18947)
Reworks blueprints to use an eye component for area selection and changing. Blueprints will now work on whichever overmap site they spawn on if overmap is enabled, though currently they have only been added to the Horizon. Adds shuttle-modifying blueprints for altering shuttle areas and exoplanet outpost blueprints for creating areas on exoplanets. A set of outpost blueprints and a lockbox containing blueprints for the Horizon's shuttles have been added to the CE's locker. Moves eye creation to a component. Ported from: https://github.com/NebulaSS13/Nebula/pull/465 https://github.com/NebulaSS13/Nebula/pull/564 https://github.com/NebulaSS13/Nebula/pull/3046
This commit is contained in:
@@ -1,275 +1,151 @@
|
||||
/obj/item/blueprints
|
||||
name = "station blueprints"
|
||||
name = "blueprints"
|
||||
desc = "Blueprints of the station. There is a \"Classified\" stamp and several coffee stains on it."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon = 'icons/obj/item/tools/blueprints.dmi'
|
||||
icon_state = "blueprints"
|
||||
attack_verb = list("attacked", "bapped", "hit")
|
||||
var/datum/wires/airlock/blueprint/airlock_wires
|
||||
var/datum/wires/vending/blueprint/vending_wires
|
||||
|
||||
var/const/AREA_ERRNONE = 0
|
||||
var/const/AREA_STATION = 1
|
||||
var/const/AREA_SPACE = 2
|
||||
var/const/AREA_SPECIAL = 3
|
||||
|
||||
var/const/BORDER_ERROR = 0
|
||||
var/const/BORDER_NONE = 1
|
||||
var/const/BORDER_BETWEEN = 2
|
||||
var/const/BORDER_2NDTILE = 3
|
||||
var/const/BORDER_SPACE = 4
|
||||
|
||||
var/const/ROOM_ERR_LOLWAT = 0
|
||||
var/const/ROOM_ERR_SPACE = -1
|
||||
var/const/ROOM_ERR_TOOLARGE = -2
|
||||
|
||||
var/list/active_blueprints
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/list/valid_z_levels = list()
|
||||
var/area_prefix
|
||||
|
||||
/obj/item/blueprints/Initialize(mapload, ...)
|
||||
. = ..()
|
||||
airlock_wires = new(src)
|
||||
vending_wires = new(src)
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/item/blueprints/LateInitialize()
|
||||
. = ..()
|
||||
desc = "Blueprints of the [station_name()]. There is a \"Classified\" stamp and several coffee stains on it."
|
||||
if(set_valid_z_levels())
|
||||
create_blueprint_component()
|
||||
|
||||
/obj/item/blueprints/attack_self(mob/user)
|
||||
if(use_check_and_message(user, USE_DISALLOW_SILICONS))
|
||||
return
|
||||
add_fingerprint(user)
|
||||
interact()
|
||||
|
||||
/obj/item/blueprints/equipped(var/mob/user, var/slot)
|
||||
. = ..()
|
||||
if(slot == slot_l_hand || slot == slot_r_hand)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
LAZYINITLIST(active_blueprints)
|
||||
|
||||
/obj/item/blueprints/dropped(mob/user)
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
if(user.client)
|
||||
for(var/thing in active_blueprints)
|
||||
user.client.images -= thing
|
||||
LAZYCLEARLIST(active_blueprints)
|
||||
|
||||
/obj/item/blueprints/process()
|
||||
var/mob/user = loc
|
||||
if(!istype(user))
|
||||
return PROCESS_KILL
|
||||
|
||||
var/turf/origin_turf = get_turf(src)
|
||||
|
||||
var/list/new_prints = list()
|
||||
for(var/turf/T as anything in RANGE_TURFS(world.view, origin_turf))
|
||||
for(var/image/I as anything in T.blueprints)
|
||||
new_prints += I
|
||||
|
||||
var/list/update_remove = active_blueprints - new_prints
|
||||
active_blueprints = new_prints - update_remove
|
||||
|
||||
for(var/thing in update_remove)
|
||||
user.client.images -= thing
|
||||
|
||||
for(var/thing in active_blueprints)
|
||||
user.client.images += thing
|
||||
|
||||
/obj/item/blueprints/Topic(href, href_list)
|
||||
..()
|
||||
if(use_check_and_message(usr, USE_DISALLOW_SILICONS) || usr.get_active_hand() != src)
|
||||
return
|
||||
if(!href_list["action"])
|
||||
add_fingerprint(user)
|
||||
var/datum/component/eye/blueprints = GetComponent(/datum/component/eye)
|
||||
if(!(user.z in valid_z_levels))
|
||||
to_chat(user, SPAN_WARNING("The markings on this are entirely irrelevant to your whereabouts!"))
|
||||
return
|
||||
switch(href_list["action"])
|
||||
if ("create_area")
|
||||
if(get_area_type() != AREA_SPACE)
|
||||
interact()
|
||||
return
|
||||
create_area()
|
||||
if ("edit_area")
|
||||
if (get_area_type()!=AREA_STATION)
|
||||
interact()
|
||||
return
|
||||
edit_area()
|
||||
if("airlock_wires")
|
||||
airlock_wires.get_wire_diagram(usr)
|
||||
if("vending_wires")
|
||||
vending_wires.get_wire_diagram(usr)
|
||||
if(blueprints)
|
||||
if(blueprints.look(user, get_look_args())) // Abandon all peripheral vision, ye who enter here.
|
||||
to_chat(user, SPAN_NOTICE("You start peering closely at \the [src]"))
|
||||
return
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("You couldn't get a good look at \the [src]. Maybe someone else is using it?"))
|
||||
return
|
||||
to_chat(user, SPAN_WARNING("The markings on this are useless!"))
|
||||
|
||||
/obj/item/blueprints/interact()
|
||||
var/area/A = get_area(src)
|
||||
var/text = {"<HTML><head><title>[src]</title></head><BODY>
|
||||
<h2>[station_name()] blueprints</h2>
|
||||
<small>Property of [SSatlas.current_map.company_name]. For heads of staff only. Store in high-secure storage.</small><hr>
|
||||
"}
|
||||
switch (get_area_type())
|
||||
if (AREA_SPACE)
|
||||
text += {"
|
||||
<p>According the blueprints, you are now in <b>outer space</b>. Hold your breath.</p>
|
||||
<p><a href='?src=\ref[src];action=create_area'>Mark this place as new area.</a></p>
|
||||
"}
|
||||
if (AREA_STATION)
|
||||
text += {"
|
||||
<p>According the blueprints, you are now in <b>\"[A.name]\"</b>.</p>
|
||||
<p>You may <a href='?src=\ref[src];action=edit_area'>
|
||||
move an amendment</a> to the drawing.</p>
|
||||
"}
|
||||
if (AREA_SPECIAL)
|
||||
text += {"
|
||||
<p>This place isn't noted on the blueprint.</p>
|
||||
"}
|
||||
/obj/item/blueprints/proc/set_valid_z_levels()
|
||||
if(SSatlas.current_map.use_overmap)
|
||||
var/obj/effect/overmap/visitable/sector/S = GLOB.map_sectors["[GET_Z(src)]"]
|
||||
if(!S) //Blueprints are useless now, but keep them around for fluff
|
||||
desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
|
||||
return FALSE
|
||||
name += " - [S.name]"
|
||||
desc = "Blueprints of \the [S.name]. There is a \"Classified\" stamp and several coffee stains on it."
|
||||
valid_z_levels += S.map_z
|
||||
area_prefix = S.name
|
||||
return TRUE
|
||||
desc = "Blueprints of the [station_name()]. There is a \"Classified\" stamp and several coffee stains on it."
|
||||
area_prefix = station_name()
|
||||
valid_z_levels = SSatlas.current_map.station_levels
|
||||
|
||||
text += "<br><a href='?src=\ref[src];action=airlock_wires'>View Airlock Wire Schema</a><br>"
|
||||
text += "<br><a href='?src=\ref[src];action=vending_wires'>View Vending Machine Wire Schema</a><br>"
|
||||
/obj/item/blueprints/proc/create_blueprint_component() //So that subtypes can override
|
||||
AddComponent(/datum/component/eye/blueprints)
|
||||
|
||||
text += "</BODY></HTML>"
|
||||
/obj/item/blueprints/proc/get_look_args() // ditto
|
||||
return list(valid_z_levels, area_prefix)
|
||||
|
||||
var/datum/browser/blueprints_win = new(usr, "blueprints", capitalize_first_letters(name))
|
||||
blueprints_win.set_content(text)
|
||||
blueprints_win.open()
|
||||
//Blueprints for building exoplanet outposts
|
||||
/obj/item/blueprints/outpost
|
||||
name = "outpost blueprints"
|
||||
icon_state = "blueprints2"
|
||||
|
||||
/obj/item/blueprints/proc/get_area_type(var/area/A = get_area(src))
|
||||
if(istype(A, /area/space) || istype(A, /area/mine/unexplored))
|
||||
return AREA_SPACE
|
||||
var/list/SPECIALS = list(
|
||||
/area/shuttle,
|
||||
/area/centcom,
|
||||
/area/tdome,
|
||||
/area/antag
|
||||
/obj/item/blueprints/outpost/attack_self(mob/user)
|
||||
var/obj/effect/overmap/visitable/sector/S = GLOB.map_sectors["[GET_Z(user)]"]
|
||||
area_prefix = S.name
|
||||
. = ..()
|
||||
|
||||
/obj/item/blueprints/outpost/set_valid_z_levels()
|
||||
if(!SSatlas.current_map.use_overmap)
|
||||
desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
|
||||
return FALSE
|
||||
desc = "Blueprints for the daring souls wanting to establish a planetary outpost. Has some sketchy looking stains and what appears to be bite holes."
|
||||
var/area/overmap/map = global.map_overmap
|
||||
for(var/obj/effect/overmap/visitable/sector/exoplanet/E in map)
|
||||
valid_z_levels += E.map_z
|
||||
return TRUE
|
||||
|
||||
/obj/item/blueprints/shuttle
|
||||
desc_info = "These blueprints can be used to modify a shuttle. In order to be used, the shuttle must be located on its \"Open Space\" z-level. Newly-created areas will be automatically added to the shuttle. If all shuttle areas are removed, the shuttle will be destroyed!"
|
||||
///Name of the blueprints' linked shuttle. Mapped-in versions should have this preset, or be mapped into the shuttle area itself.
|
||||
var/shuttle_name
|
||||
///The actual overmap shuttle type, for setting on preset blueprints.
|
||||
var/obj/effect/overmap/visitable/ship/landable/shuttle_type
|
||||
|
||||
/obj/item/blueprints/shuttle/set_valid_z_levels()
|
||||
if(SSatlas.current_map.use_overmap)
|
||||
var/area/A = get_area(src)
|
||||
|
||||
if(!shuttle_type)
|
||||
for(var/obj/effect/overmap/visitable/ship/landable/landable in SSshuttle.ships)
|
||||
var/datum/shuttle/shuttle = SSshuttle.shuttles[landable.shuttle]
|
||||
if(shuttle && (A in shuttle.shuttle_area))
|
||||
shuttle_type = landable
|
||||
break
|
||||
else
|
||||
var/obj/effect/overmap/visitable/ship/landable/S = SSshuttle.ship_by_type(shuttle_type)
|
||||
shuttle_type = S
|
||||
|
||||
if(istype(shuttle_type) && !isnull(shuttle_type))
|
||||
if(isnull(shuttle_name))
|
||||
shuttle_name = shuttle_type.shuttle
|
||||
update_linked_name(shuttle_type, null, shuttle_type.name)
|
||||
RegisterSignal(shuttle_type, COMSIG_QDELETING, PROC_REF(on_shuttle_destroy))
|
||||
RegisterSignal(shuttle_type, COMSIG_BASENAME_SETNAME, PROC_REF(update_linked_name))
|
||||
valid_z_levels += shuttle_type.map_z
|
||||
area_prefix = shuttle_type.name
|
||||
return TRUE
|
||||
// The blueprints are useless now, but keep them around for fluff.
|
||||
desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
|
||||
return FALSE
|
||||
|
||||
/obj/item/blueprints/shuttle/proc/update_linked_name(atom/namee, old_name, new_name)
|
||||
name = "\improper [new_name] blueprints"
|
||||
desc = "Blueprints of \the [new_name]. There are several coffee stains on it."
|
||||
area_prefix = new_name
|
||||
|
||||
/obj/item/blueprints/shuttle/proc/on_shuttle_destroy(datum/destroyed)
|
||||
UnregisterSignal(destroyed, COMSIG_QDELETING)
|
||||
UnregisterSignal(destroyed, COMSIG_BASENAME_SETNAME)
|
||||
name = initial(name)
|
||||
desc = "Some dusty old blueprints. The markings are old, and seem entirely irrelevant for your wherabouts."
|
||||
valid_z_levels = list()
|
||||
area_prefix = null
|
||||
|
||||
/obj/item/blueprints/shuttle/create_blueprint_component()
|
||||
AddComponent(/datum/component/eye/blueprints/shuttle)
|
||||
|
||||
/obj/item/blueprints/shuttle/get_look_args()
|
||||
return list(valid_z_levels, area_prefix, shuttle_name)
|
||||
|
||||
/obj/item/blueprints/shuttle/intrepid
|
||||
shuttle_name = "Intrepid"
|
||||
shuttle_type = /obj/effect/overmap/visitable/ship/landable/intrepid
|
||||
|
||||
/obj/item/blueprints/shuttle/mining_shuttle
|
||||
shuttle_name = "Spark"
|
||||
shuttle_type = /obj/effect/overmap/visitable/ship/landable/mining_shuttle
|
||||
|
||||
/obj/item/blueprints/shuttle/canary
|
||||
shuttle_name = "Canary"
|
||||
shuttle_type = /obj/effect/overmap/visitable/ship/landable/canary
|
||||
|
||||
/obj/item/storage/lockbox/shuttle_blueprints //Blueprints for modifying the Horizon's shuttles.
|
||||
name = "shuttle blueprints lockbox"
|
||||
req_access = list(ACCESS_CE)
|
||||
starts_with = list(
|
||||
/obj/item/blueprints/shuttle/intrepid = 1,
|
||||
/obj/item/blueprints/shuttle/mining_shuttle = 1,
|
||||
/obj/item/blueprints/shuttle/canary = 1
|
||||
)
|
||||
for (var/type in SPECIALS)
|
||||
if ( istype(A,type) )
|
||||
return AREA_SPECIAL
|
||||
return AREA_STATION
|
||||
|
||||
/obj/item/blueprints/proc/create_area()
|
||||
var/res = detect_room(get_turf(usr))
|
||||
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='warning'>Error! Please notify administration!</span>")
|
||||
return
|
||||
var/list/turf/turfs = res
|
||||
var/str = sanitizeSafe(input("New area name:","Blueprint Editing", ""), MAX_NAME_LEN)
|
||||
if(!str || !length(str)) //cancel
|
||||
return
|
||||
if(length(str) > 50)
|
||||
to_chat(usr, "<span class='warning'>Name too long.</span>")
|
||||
return
|
||||
var/area/A = new
|
||||
A.name = str
|
||||
A.power_equip = 0
|
||||
A.power_light = 0
|
||||
A.power_environ = 0
|
||||
A.always_unpowered = 0
|
||||
move_turfs_to_area(turfs, A)
|
||||
|
||||
A.always_unpowered = 0
|
||||
|
||||
sorted_add_area(A)
|
||||
|
||||
addtimer(CALLBACK(src, PROC_REF(interact)), 5)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/blueprints/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A)
|
||||
A.contents.Add(turfs)
|
||||
//oldarea.contents.Remove(usr.loc) // not needed
|
||||
//T.forceMove(A) //error: cannot change constant value
|
||||
|
||||
|
||||
/obj/item/blueprints/proc/edit_area()
|
||||
var/area/A = get_area(src)
|
||||
var/prevname = "[A.name]"
|
||||
var/str = sanitizeSafe(input("New area name:","Blueprint Editing", prevname), MAX_NAME_LEN)
|
||||
if(!str || !length(str) || str==prevname) //cancel
|
||||
return
|
||||
if(length(str) > 50)
|
||||
to_chat(usr, "<span class='warning'>Text too long.</span>")
|
||||
return
|
||||
INVOKE_ASYNC(src, PROC_REF(set_area_machinery_title), A, str, prevname)
|
||||
A.name = str
|
||||
sortTim(GLOB.all_areas, GLOBAL_PROC_REF(cmp_text_asc))
|
||||
to_chat(usr, "<span class='notice'>You set the area '[prevname]' title to '[str]'.</span>")
|
||||
interact()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/item/blueprints/proc/set_area_machinery_title(var/area/A,var/title,var/oldtitle)
|
||||
if (!oldtitle) // or replacetext goes to infinite loop
|
||||
return
|
||||
|
||||
var/static/list/types_to_rename = list(
|
||||
/obj/machinery/alarm,
|
||||
/obj/machinery/power/apc,
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber,
|
||||
/obj/machinery/atmospherics/unary/vent_pump,
|
||||
/obj/machinery/door
|
||||
)
|
||||
|
||||
for(var/obj/machinery/M in A)
|
||||
if (is_type_in_list(M, types_to_rename))
|
||||
M.name = replacetext(M.name, oldtitle, title)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
/obj/item/blueprints/proc/check_tile_is_border(var/turf/T2,var/dir)
|
||||
if (istype(T2, /turf/space) || istype(T2, /turf/unsimulated/floor/asteroid))
|
||||
return BORDER_SPACE //omg hull breach we all going to die here
|
||||
if (get_area_type(T2.loc)!=AREA_SPACE)
|
||||
return BORDER_BETWEEN
|
||||
if (istype(T2, /turf/simulated/wall))
|
||||
return BORDER_2NDTILE
|
||||
if (!istype(T2, /turf/simulated))
|
||||
return BORDER_BETWEEN
|
||||
|
||||
for (var/obj/structure/window/W in T2)
|
||||
if(turn(dir,180) == W.dir)
|
||||
return BORDER_BETWEEN
|
||||
if (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST))
|
||||
return BORDER_2NDTILE
|
||||
for(var/obj/machinery/door/window/D in T2)
|
||||
if(turn(dir,180) == D.dir)
|
||||
return BORDER_BETWEEN
|
||||
if (locate(/obj/machinery/door) in T2)
|
||||
return BORDER_2NDTILE
|
||||
|
||||
return BORDER_NONE
|
||||
|
||||
/obj/item/blueprints/proc/detect_room(var/turf/first)
|
||||
var/list/turf/found = new
|
||||
var/list/turf/pending = list(first)
|
||||
while(pending.len)
|
||||
if (found.len+pending.len > 300)
|
||||
return ROOM_ERR_TOOLARGE
|
||||
var/turf/T = pending[1] //why byond havent list::pop()?
|
||||
pending -= T
|
||||
for (var/dir in GLOB.cardinal)
|
||||
var/skip = 0
|
||||
for (var/obj/structure/window/W in T)
|
||||
if(dir == W.dir || (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST)))
|
||||
skip = 1; break
|
||||
if (skip) continue
|
||||
for(var/obj/machinery/door/window/D in T)
|
||||
if(dir == D.dir)
|
||||
skip = 1; break
|
||||
if (skip) continue
|
||||
|
||||
var/turf/NT = get_step(T,dir)
|
||||
if (!isturf(NT) || (NT in found) || (NT in pending))
|
||||
continue
|
||||
|
||||
var/tile_is_border = check_tile_is_border(NT,dir)
|
||||
if(tile_is_border != BORDER_BETWEEN)
|
||||
switch(tile_is_border)
|
||||
if(BORDER_NONE)
|
||||
pending+=NT
|
||||
if(BORDER_2NDTILE)
|
||||
found+=NT //tile included to new area, but we dont seek more
|
||||
if(BORDER_SPACE)
|
||||
return ROOM_ERR_SPACE
|
||||
found+=T
|
||||
return found
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
new /obj/item/crowbar/rescue_axe/red(src)
|
||||
new /obj/item/device/radio/eng/off(src)
|
||||
new /obj/item/grenade/chem_grenade/antifuel(src)
|
||||
new /obj/item/storage/lockbox/shuttle_blueprints(src)
|
||||
new /obj/item/blueprints/outpost(src)
|
||||
|
||||
// Chief Engineer - Clothing Satchel
|
||||
// This satchel is used nowhere except in conjunction with the locker above,
|
||||
|
||||
Reference in New Issue
Block a user