mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-13 02:13:06 +00:00
cl ninjanomnom fix: Shuttles have proper baseturfs now. fix: Mineral walls properly use their baseturfs when destroyed/drilled. add: A new engineering goggle mode allows you to see the shuttle area you're standing in. admin: Buildmode works a bit better with baseturfs now and can properly only remove the top layer of turfs when editing. Note that as a result the order you place turfs is important and a wall placed on space means when the wall is removed there will be space underneath. /cl This adds an area hook for turfs getting the PlaceOnTop proc called so shuttle areas are able to intercept it and add a special turf used for determining where the bottom of the shuttle is. I'm not too certain on this being the best way to handle it but the alternatives restrict the kind of turfs that are allowed to be on shuttles which I didn't want to do as it was part of the whole intent of the baseturf change to allow any turf type on shuttles. The alternative to the area hook would require a tool which attaches turfs to a shuttle which is why there's a shuttle area viewing tool in this pr. I considered doing it this way first but decided it was too clunky. In addition to other changes: Tiled/Reinforced floors have proper baseturfs now. A large amount of the remaining ChangeTurf calls were swapped over to various baseturf helpers so, for example, mining doesn't create a lavaland turf if somehow the mineral wall is on plating. Escape pods, the aux base, and syndicate drop pod have been converted over to shuttle templates as well. The error when the timid var is set incorrectly has been changed to a stack_trace. The change turf file has been made all lowercase as per standard.
297 lines
8.7 KiB
Plaintext
297 lines
8.7 KiB
Plaintext
/obj/machinery/shuttle_manipulator
|
|
name = "shuttle manipulator"
|
|
desc = "I shall be telling this with a sigh\n\
|
|
Somewhere ages and ages hence:\n\
|
|
Two roads diverged in a wood, and I,\n\
|
|
I took the one less traveled by,\n\
|
|
And that has made all the difference."
|
|
|
|
icon = 'icons/obj/machines/shuttle_manipulator.dmi'
|
|
icon_state = "holograph_on"
|
|
|
|
anchored = TRUE
|
|
density = TRUE
|
|
|
|
// UI state variables
|
|
var/datum/map_template/shuttle/selected
|
|
|
|
var/obj/docking_port/mobile/existing_shuttle
|
|
|
|
var/obj/docking_port/mobile/preview_shuttle
|
|
var/datum/map_template/shuttle/preview_template
|
|
|
|
/obj/machinery/shuttle_manipulator/Initialize()
|
|
. = ..()
|
|
update_icon()
|
|
SSshuttle.manipulator = src
|
|
|
|
/obj/machinery/shuttle_manipulator/Destroy(force)
|
|
if(!force)
|
|
. = QDEL_HINT_LETMELIVE
|
|
else
|
|
SSshuttle.manipulator = null
|
|
. = ..()
|
|
|
|
/obj/machinery/shuttle_manipulator/update_icon()
|
|
cut_overlays()
|
|
var/mutable_appearance/hologram_projection = mutable_appearance(icon, "hologram_on")
|
|
hologram_projection.pixel_y = 22
|
|
var/mutable_appearance/hologram_ship = mutable_appearance(icon, "hologram_whiteship")
|
|
hologram_ship.pixel_y = 27
|
|
add_overlay(hologram_projection)
|
|
add_overlay(hologram_ship)
|
|
|
|
/obj/machinery/shuttle_manipulator/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state)
|
|
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
|
if(!ui)
|
|
ui = new(user, src, ui_key, "shuttle_manipulator", name, 800, 600, master_ui, state)
|
|
ui.open()
|
|
|
|
/proc/shuttlemode2str(mode)
|
|
switch(mode)
|
|
if(SHUTTLE_IDLE)
|
|
. = "idle"
|
|
if(SHUTTLE_IGNITING)
|
|
. = "engines charging"
|
|
if(SHUTTLE_RECALL)
|
|
. = "recalled"
|
|
if(SHUTTLE_CALL)
|
|
. = "called"
|
|
if(SHUTTLE_DOCKED)
|
|
. = "docked"
|
|
if(SHUTTLE_STRANDED)
|
|
. = "stranded"
|
|
if(SHUTTLE_ESCAPE)
|
|
. = "escape"
|
|
if(SHUTTLE_ENDGAME)
|
|
. = "endgame"
|
|
if(!.)
|
|
CRASH("shuttlemode2str(): invalid mode [mode]")
|
|
|
|
|
|
/obj/machinery/shuttle_manipulator/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["tabs"] = list("Status", "Templates", "Modification")
|
|
|
|
// Templates panel
|
|
data["templates"] = list()
|
|
var/list/templates = data["templates"]
|
|
data["templates_tabs"] = list()
|
|
data["selected"] = list()
|
|
|
|
for(var/shuttle_id in SSmapping.shuttle_templates)
|
|
var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id]
|
|
|
|
if(!templates[S.port_id])
|
|
data["templates_tabs"] += S.port_id
|
|
templates[S.port_id] = list(
|
|
"port_id" = S.port_id,
|
|
"templates" = list())
|
|
|
|
var/list/L = list()
|
|
L["name"] = S.name
|
|
L["shuttle_id"] = S.shuttle_id
|
|
L["port_id"] = S.port_id
|
|
L["description"] = S.description
|
|
L["admin_notes"] = S.admin_notes
|
|
|
|
if(selected == S)
|
|
data["selected"] = L
|
|
|
|
templates[S.port_id]["templates"] += list(L)
|
|
|
|
data["templates_tabs"] = sortList(data["templates_tabs"])
|
|
|
|
data["existing_shuttle"] = null
|
|
|
|
// Status panel
|
|
data["shuttles"] = list()
|
|
for(var/i in SSshuttle.mobile)
|
|
var/obj/docking_port/mobile/M = i
|
|
var/list/L = list()
|
|
L["name"] = M.name
|
|
L["id"] = M.id
|
|
L["timer"] = M.timer
|
|
L["timeleft"] = M.getTimerStr()
|
|
var/can_fast_travel = FALSE
|
|
if(M.timer && M.timeLeft() >= 50)
|
|
can_fast_travel = TRUE
|
|
L["can_fast_travel"] = can_fast_travel
|
|
L["mode"] = capitalize(shuttlemode2str(M.mode))
|
|
L["status"] = M.getStatusText()
|
|
if(M == existing_shuttle)
|
|
data["existing_shuttle"] = L
|
|
|
|
data["shuttles"] += list(L)
|
|
|
|
return data
|
|
|
|
/obj/machinery/shuttle_manipulator/ui_act(action, params)
|
|
if(..())
|
|
return
|
|
|
|
var/mob/user = usr
|
|
|
|
// Preload some common parameters
|
|
var/shuttle_id = params["shuttle_id"]
|
|
var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id]
|
|
|
|
switch(action)
|
|
if("select_template")
|
|
if(S)
|
|
existing_shuttle = SSshuttle.getShuttle(S.port_id)
|
|
selected = S
|
|
. = TRUE
|
|
if("jump_to")
|
|
if(params["type"] == "mobile")
|
|
for(var/i in SSshuttle.mobile)
|
|
var/obj/docking_port/mobile/M = i
|
|
if(M.id == params["id"])
|
|
user.forceMove(get_turf(M))
|
|
. = TRUE
|
|
break
|
|
if("fast_travel")
|
|
for(var/i in SSshuttle.mobile)
|
|
var/obj/docking_port/mobile/M = i
|
|
if(M.id == params["id"] && M.timer && M.timeLeft() >= 50)
|
|
M.setTimer(50)
|
|
. = TRUE
|
|
message_admins("[key_name_admin(usr)] fast travelled \
|
|
[M]")
|
|
log_admin("[key_name(usr)] fast travelled [M]")
|
|
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[M.name]")
|
|
break
|
|
|
|
if("preview")
|
|
if(S)
|
|
. = TRUE
|
|
unload_preview()
|
|
load_template(S)
|
|
if(preview_shuttle)
|
|
preview_template = S
|
|
user.forceMove(get_turf(preview_shuttle))
|
|
if("load")
|
|
if(existing_shuttle == SSshuttle.backup_shuttle)
|
|
// TODO make the load button disabled
|
|
WARNING("The shuttle that the selected shuttle will replace \
|
|
is the backup shuttle. Backup shuttle is required to be \
|
|
intact for round sanity.")
|
|
else if(S)
|
|
. = TRUE
|
|
// If successful, returns the mobile docking port
|
|
var/obj/docking_port/mobile/mdp = action_load(S)
|
|
if(mdp)
|
|
user.forceMove(get_turf(mdp))
|
|
message_admins("[key_name_admin(usr)] loaded [mdp] \
|
|
with the shuttle manipulator.")
|
|
log_admin("[key_name(usr)] loaded [mdp] with the \
|
|
shuttle manipulator.</span>")
|
|
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]")
|
|
|
|
update_icon()
|
|
|
|
/obj/machinery/shuttle_manipulator/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port)
|
|
// Check for an existing preview
|
|
if(preview_shuttle && (loading_template != preview_template))
|
|
preview_shuttle.jumpToNullSpace()
|
|
preview_shuttle = null
|
|
preview_template = null
|
|
|
|
if(!preview_shuttle)
|
|
load_template(loading_template)
|
|
preview_template = loading_template
|
|
|
|
// get the existing shuttle information, if any
|
|
var/timer = 0
|
|
var/mode = SHUTTLE_IDLE
|
|
var/obj/docking_port/stationary/D
|
|
|
|
if(istype(destination_port))
|
|
D = destination_port
|
|
else if(existing_shuttle)
|
|
timer = existing_shuttle.timer
|
|
mode = existing_shuttle.mode
|
|
D = existing_shuttle.get_docked()
|
|
|
|
if(!D)
|
|
var/m = "No dock found for preview shuttle ([preview_template.name]), aborting."
|
|
throw EXCEPTION(m)
|
|
|
|
var/result = preview_shuttle.canDock(D)
|
|
// truthy value means that it cannot dock for some reason
|
|
// but we can ignore the someone else docked error because we'll
|
|
// be moving into their place shortly
|
|
if((result != SHUTTLE_CAN_DOCK) && (result != SHUTTLE_SOMEONE_ELSE_DOCKED))
|
|
WARNING("Template shuttle [preview_shuttle] cannot dock at [D] ([result]).")
|
|
return
|
|
|
|
if(existing_shuttle)
|
|
existing_shuttle.jumpToNullSpace()
|
|
|
|
preview_shuttle.initiate_docking(D)
|
|
. = preview_shuttle
|
|
|
|
// Shuttle state involves a mode and a timer based on world.time, so
|
|
// plugging the existing shuttles old values in works fine.
|
|
preview_shuttle.timer = timer
|
|
preview_shuttle.mode = mode
|
|
|
|
preview_shuttle.register()
|
|
|
|
// TODO indicate to the user that success happened, rather than just
|
|
// blanking the modification tab
|
|
preview_shuttle = null
|
|
preview_template = null
|
|
existing_shuttle = null
|
|
selected = null
|
|
|
|
/obj/machinery/shuttle_manipulator/proc/load_template(
|
|
datum/map_template/shuttle/S)
|
|
// load shuttle template, centred at shuttle import landmark,
|
|
var/turf/landmark_turf = get_turf(locate(/obj/effect/landmark/shuttle_import) in GLOB.landmarks_list)
|
|
S.load(landmark_turf, centered = TRUE)
|
|
|
|
var/affected = S.get_affected_turfs(landmark_turf, centered=TRUE)
|
|
|
|
var/found = 0
|
|
// Search the turfs for docking ports
|
|
// - We need to find the mobile docking port because that is the heart of
|
|
// the shuttle.
|
|
// - We need to check that no additional ports have slipped in from the
|
|
// template, because that causes unintended behaviour.
|
|
for(var/T in affected)
|
|
for(var/obj/docking_port/P in T)
|
|
if(istype(P, /obj/docking_port/mobile))
|
|
var/obj/docking_port/mobile/M = P
|
|
found++
|
|
if(found > 1)
|
|
qdel(P, force=TRUE)
|
|
log_world("Map warning: Shuttle Template [S.mappath] has multiple mobile docking ports.")
|
|
else if(!M.timid)
|
|
// The shuttle template we loaded isn't "timid" which means
|
|
// it's already registered with the shuttles subsystem.
|
|
// This is a bad thing.
|
|
stack_trace("Template [S] is non-timid! Unloading.")
|
|
M.jumpToNullSpace()
|
|
return
|
|
else
|
|
preview_shuttle = P
|
|
if(istype(P, /obj/docking_port/stationary))
|
|
log_world("Map warning: Shuttle Template [S.mappath] has a stationary docking port.")
|
|
if(!found)
|
|
var/msg = "load_template(): Shuttle Template [S.mappath] has no mobile docking port. Aborting import."
|
|
for(var/T in affected)
|
|
var/turf/T0 = T
|
|
T0.empty()
|
|
|
|
message_admins(msg)
|
|
WARNING(msg)
|
|
return
|
|
//Everything fine
|
|
S.on_bought()
|
|
|
|
/obj/machinery/shuttle_manipulator/proc/unload_preview()
|
|
if(preview_shuttle)
|
|
preview_shuttle.jumpToNullSpace()
|
|
preview_shuttle = null
|