mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 00:21:11 +01:00
Landmark Shuttles (#8512)
The lifeless live again. Or in this case, what never actually lived here. Ports Baystation12/Baystation12#17460 probably for real this time. What this allows us to do is create shuttles on runtime and make shuttles easier by just making landmarks and a shuttle instead of areas and shuttles. Also allows runtime landmark creation via flares or whatever AND allows shuttles to use different landmarks at will. I removed most of the overmap stuff, I think. It shouldn't be hard to slam it in whenever we need to. Changes: "Shuttle code has been completely reworked." "Shuttles can now be modified to have more than one destination." "Shuttles now have a takeoff sound." "You can now throw mobs against walls to damage them. A lot." "You now need a neckgrab to throw mobs." "BEING UNBUCKLED DURING SHUTTLE LAUNCH IS DANGEROUS! Don't do it." "Adminghosts can now interact with all shuttles."
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
shuttle_tag = "Skipjack"
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/syndicate
|
||||
/obj/machinery/computer/shuttle_control/multi/antag/syndicate
|
||||
name = "mercenary shuttle control console"
|
||||
req_access = list(access_syndicate)
|
||||
shuttle_tag = "Mercenary"
|
||||
shuttle_tag = "Mercenary Shuttle"
|
||||
light_color = LIGHT_COLOR_RED
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/obj/machinery/computer/shuttle_control/mining
|
||||
name = "mining shuttle control console"
|
||||
shuttle_tag = "Mining"
|
||||
//req_access = list(access_mining)
|
||||
circuit = /obj/item/circuitboard/mining_shuttle
|
||||
|
||||
/obj/machinery/computer/shuttle_control/engineering
|
||||
name = "engineering shuttle control console"
|
||||
shuttle_tag = "Engineering"
|
||||
//req_one_access = list(access_engine_equip,access_atmospherics)
|
||||
circuit = /obj/item/circuitboard/engineering_shuttle
|
||||
|
||||
/obj/machinery/computer/shuttle_control/research
|
||||
@@ -16,10 +14,10 @@
|
||||
req_access = list(access_research)
|
||||
circuit = /obj/item/circuitboard/research_shuttle
|
||||
|
||||
/datum/shuttle/ferry/research
|
||||
/datum/shuttle/autodock/ferry/research
|
||||
var/triggered_away_sites = FALSE
|
||||
|
||||
/datum/shuttle/ferry/research/launch()
|
||||
/datum/shuttle/autodock/ferry/research/shuttle_moved()
|
||||
. = ..()
|
||||
if(!triggered_away_sites)
|
||||
for(var/s in SSghostroles.spawners)
|
||||
@@ -31,4 +29,4 @@
|
||||
/obj/machinery/computer/shuttle_control/merchant
|
||||
name = "merchant shuttle control console"
|
||||
req_access = list(access_merchant)
|
||||
shuttle_tag = "Merchant"
|
||||
shuttle_tag = "Merchant Shuttle"
|
||||
@@ -1,39 +1,44 @@
|
||||
/datum/shuttle/ferry/escape_pod
|
||||
var/list/escape_pods = list()
|
||||
|
||||
/datum/shuttle/autodock/ferry/escape_pod
|
||||
var/datum/computer/file/embedded_program/docking/simple/escape_pod/arming_controller
|
||||
category = /datum/shuttle/autodock/ferry/escape_pod
|
||||
move_time = 100
|
||||
|
||||
/datum/shuttle/ferry/escape_pod/init_docking_controllers()
|
||||
/datum/shuttle/autodock/ferry/escape_pod/New()
|
||||
..()
|
||||
arming_controller = locate(dock_target_station)
|
||||
var/arming_controller_tag = arming_controller
|
||||
arming_controller = SSshuttle.docking_registry[arming_controller_tag]
|
||||
if(!istype(arming_controller))
|
||||
to_world("<span class='danger'>warning: escape pod with station dock tag [dock_target_station] could not find it's dock target!</span>")
|
||||
CRASH("Could not find arming controller for escape pod \"[name]\", tag was '[arming_controller_tag]'.")
|
||||
|
||||
if(docking_controller)
|
||||
var/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/controller_master = docking_controller.master
|
||||
if(!istype(controller_master))
|
||||
to_world("<span class='danger'>warning: escape pod with docking tag [docking_controller_tag] could not find it's controller master!</span>")
|
||||
else
|
||||
controller_master.pod = src
|
||||
escape_pods += src
|
||||
if(dock_target)
|
||||
var/datum/computer/file/embedded_program/docking/simple/own_target = SSshuttle.docking_registry[dock_target]
|
||||
if(own_target)
|
||||
var/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/own_target_master = own_target.master
|
||||
if(own_target_master)
|
||||
own_target_master.pod = src
|
||||
|
||||
/datum/shuttle/ferry/escape_pod/can_launch()
|
||||
/datum/shuttle/autodock/ferry/escape_pod/can_launch()
|
||||
if(arming_controller && !arming_controller.armed) //must be armed
|
||||
return 0
|
||||
if(location)
|
||||
return 0 //it's a one-way trip.
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/escape_pod/can_force()
|
||||
/datum/shuttle/autodock/ferry/escape_pod/can_force()
|
||||
if (arming_controller.eject_time && world.time < arming_controller.eject_time + 50)
|
||||
return 0 //dont allow force launching until 5 seconds after the arming controller has reached it's countdown
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/escape_pod/can_cancel()
|
||||
/datum/shuttle/autodock/ferry/escape_pod/can_cancel()
|
||||
return 0
|
||||
|
||||
|
||||
//This controller goes on the escape pod itself
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod
|
||||
name = "escape pod controller"
|
||||
var/datum/shuttle/ferry/escape_pod/pod
|
||||
var/datum/shuttle/autodock/ferry/escape_pod/pod
|
||||
|
||||
/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
//making this separate from /obj/effect/landmark until that mess can be dealt with
|
||||
/obj/effect/shuttle_landmark
|
||||
name = "Nav Point"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "energynet"
|
||||
anchored = TRUE
|
||||
unacidable = TRUE
|
||||
simulated = 0
|
||||
invisibility = 101
|
||||
|
||||
var/landmark_tag
|
||||
//ID of the controller on the dock side
|
||||
var/datum/computer/file/embedded_program/docking/docking_controller
|
||||
//ID of controller used for this landmark for shuttles with multiple ones.
|
||||
var/list/special_dock_targets
|
||||
|
||||
//when the shuttle leaves this landmark, it will leave behind the base area
|
||||
//also used to determine if the shuttle can arrive here without obstruction
|
||||
var/area/base_area
|
||||
//Will also leave this type of turf behind if set.
|
||||
var/turf/base_turf
|
||||
//Name of the shuttle, null for generic waypoint
|
||||
var/shuttle_restricted
|
||||
var/landmark_flags = 0
|
||||
|
||||
/obj/effect/shuttle_landmark/Initialize()
|
||||
. = ..()
|
||||
if(docking_controller)
|
||||
. = INITIALIZE_HINT_LATELOAD
|
||||
|
||||
if(landmark_flags & SLANDMARK_FLAG_AUTOSET)
|
||||
base_area = get_area(src)
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
base_turf = T.type
|
||||
else
|
||||
base_area = locate(base_area || world.area)
|
||||
|
||||
name = name + " ([x],[y])"
|
||||
SSshuttle.register_landmark(landmark_tag, src)
|
||||
|
||||
/obj/effect/shuttle_landmark/LateInitialize()
|
||||
if(!docking_controller)
|
||||
return
|
||||
var/docking_tag = docking_controller
|
||||
docking_controller = SSshuttle.docking_registry[docking_tag]
|
||||
if(!istype(docking_controller))
|
||||
log_debug("Could not find docking controller for shuttle waypoint '[name]', docking tag was '[docking_tag]'.")
|
||||
|
||||
/obj/effect/shuttle_landmark/proc/is_valid(var/datum/shuttle/shuttle)
|
||||
if(shuttle.current_location == src)
|
||||
return FALSE
|
||||
for(var/area/A in shuttle.shuttle_area)
|
||||
var/list/translation = get_turf_translation(get_turf(shuttle.current_location), get_turf(src), A.contents)
|
||||
if(check_collision(base_area, list_values(translation)))
|
||||
return FALSE
|
||||
var/conn = GetConnectedZlevels(z)
|
||||
for(var/w in (z - shuttle.multiz) to z)
|
||||
if(!(w in conn))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/effect/shuttle_landmark/proc/cannot_depart(datum/shuttle/shuttle)
|
||||
return FALSE
|
||||
|
||||
/obj/effect/shuttle_landmark/proc/shuttle_arrived(datum/shuttle/shuttle)
|
||||
return
|
||||
|
||||
/proc/check_collision(area/target_area, list/target_turfs)
|
||||
for(var/target_turf in target_turfs)
|
||||
var/turf/target = target_turf
|
||||
if(!target)
|
||||
return TRUE //collides with edge of map
|
||||
if(target.loc != target_area)
|
||||
return TRUE //collides with another area
|
||||
if(target.density)
|
||||
return TRUE //dense turf
|
||||
return FALSE
|
||||
|
||||
//Self-naming/numbering ones.
|
||||
/obj/effect/shuttle_landmark/automatic
|
||||
name = "Navpoint"
|
||||
landmark_tag = "navpoint"
|
||||
flags = SLANDMARK_FLAG_AUTOSET
|
||||
|
||||
/obj/effect/shuttle_landmark/automatic/Initialize()
|
||||
landmark_tag += "-[x]-[y]-[z]"
|
||||
return ..()
|
||||
|
||||
//Subtype that calls explosion on init to clear space for shuttles
|
||||
/obj/effect/shuttle_landmark/automatic/clearing
|
||||
var/radius = 10
|
||||
|
||||
/obj/effect/shuttle_landmark/automatic/clearing/Initialize()
|
||||
..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/shuttle_landmark/automatic/clearing/LateInitialize()
|
||||
..()
|
||||
for(var/turf/T in range(radius, src))
|
||||
if(T.density)
|
||||
T.ChangeTurf(get_base_turf_by_area(T))
|
||||
|
||||
/obj/item/device/spaceflare
|
||||
name = "bluespace flare"
|
||||
desc = "Burst transmitter used to broadcast all needed information for shuttle navigation systems. Has a flare attached for marking the spot where you probably shouldn't be standing."
|
||||
icon_state = "bluflare"
|
||||
light_color = "#3728ff"
|
||||
var/active
|
||||
|
||||
/obj/item/device/spaceflare/attack_self(var/mob/user)
|
||||
if(!active)
|
||||
visible_message("<span class='notice'>[user] pulls the cord, activating \the [src].</span>")
|
||||
activate()
|
||||
|
||||
/obj/item/device/spaceflare/proc/activate()
|
||||
if(active)
|
||||
return
|
||||
var/turf/T = get_turf(src)
|
||||
var/mob/M = loc
|
||||
if(istype(M) && !M.unEquip(src, T))
|
||||
return
|
||||
|
||||
active = 1
|
||||
anchored = 1
|
||||
|
||||
var/obj/effect/shuttle_landmark/automatic/mark = new(T)
|
||||
mark.name = "beacon signal ([T.x],[T.y])"
|
||||
T.hotspot_expose(1500, 5)
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/spaceflare/update_icon()
|
||||
if(active)
|
||||
icon_state = "bluflare_on"
|
||||
set_light(0.3, 0.1, 6, 2, "85d1ff")
|
||||
+191
-115
@@ -1,161 +1,237 @@
|
||||
#define DO_BOOT 1
|
||||
#define DO_BUCKLE 2
|
||||
|
||||
//These lists are populated in /datum/shuttle_controller/New()
|
||||
//Shuttle controller is instantiated in master_controller.dm.
|
||||
|
||||
//shuttle moving state defines are in setup.dm
|
||||
|
||||
/datum/shuttle
|
||||
var/name = ""
|
||||
var/warmup_time = 0
|
||||
var/moving_status = SHUTTLE_IDLE
|
||||
var/lift = 0 //To make zlevel stuff work right
|
||||
var/lift_lowest_zlevel = 1 //At least 1 unless you always want open floor
|
||||
|
||||
var/docking_controller_tag //tag of the controller used to coordinate docking
|
||||
var/datum/computer/file/embedded_program/docking/docking_controller //the controller itself. (micro-controller, not game controller)
|
||||
var/list/shuttle_area //can be both single area type or a list of areas
|
||||
var/obj/effect/shuttle_landmark/current_location //This variable is type-abused initially: specify the landmark_tag, not the actual landmark.
|
||||
|
||||
var/arrive_time = 0 //the time at which the shuttle arrives when long jumping
|
||||
var/flags = 0
|
||||
var/process_state = IDLE_STATE //Used with SHUTTLE_FLAGS_PROCESS, as well as to store current state.
|
||||
var/category = /datum/shuttle
|
||||
var/multiz = 0 //how many multiz levels, starts at 0
|
||||
|
||||
/datum/shuttle/proc/init_docking_controllers()
|
||||
if(docking_controller_tag)
|
||||
docking_controller = locate(docking_controller_tag)
|
||||
if(!istype(docking_controller))
|
||||
to_world("<span class='danger'>warning: shuttle with docking tag [docking_controller_tag] could not find it's controller!</span>")
|
||||
var/ceiling_type = /turf/simulated/shuttle_roof
|
||||
|
||||
/datum/shuttle/proc/short_jump(var/area/origin,var/area/destination)
|
||||
var/sound_takeoff = 'sound/effects/shuttle_takeoff.ogg'
|
||||
var/sound_landing = 'sound/effects/shuttle_landing.ogg'
|
||||
|
||||
var/knockdown = TRUE //whether shuttle downs non-buckled people when it moves
|
||||
|
||||
var/defer_initialisation = FALSE //this shuttle will/won't be initialised automatically. If set to true, you are responsible for initialzing the shuttle manually.
|
||||
//Useful for shuttles that are initialed by map_template loading, or shuttles that are created in-game or not used.
|
||||
var/logging_home_tag //Whether in-game logs will be generated whenever the shuttle leaves/returns to the landmark with this landmark_tag.
|
||||
var/logging_access //Controls who has write access to log-related stuff; should correlate with pilot access.
|
||||
|
||||
/datum/shuttle/New(_name, var/obj/effect/shuttle_landmark/initial_location)
|
||||
..()
|
||||
if(_name)
|
||||
src.name = _name
|
||||
|
||||
var/list/areas = list()
|
||||
if(!islist(shuttle_area))
|
||||
shuttle_area = list(shuttle_area)
|
||||
for(var/T in shuttle_area)
|
||||
var/area/A = locate(T)
|
||||
if(!istype(A))
|
||||
CRASH("Shuttle \"[name]\" couldn't locate area [T].")
|
||||
areas += A
|
||||
shuttle_area = areas
|
||||
|
||||
if(initial_location)
|
||||
current_location = initial_location
|
||||
else
|
||||
current_location = SSshuttle.get_landmark(current_location)
|
||||
if(!istype(current_location))
|
||||
CRASH("Shuttle \"[name]\" could not find its starting location.")
|
||||
|
||||
if(src.name in SSshuttle.shuttles)
|
||||
CRASH("A shuttle with the name '[name]' is already defined.")
|
||||
SSshuttle.shuttles[src.name] = src
|
||||
if(flags & SHUTTLE_FLAGS_PROCESS)
|
||||
SSshuttle.process_shuttles += src
|
||||
if(flags & SHUTTLE_FLAGS_SUPPLY)
|
||||
if(SScargo.shuttle)
|
||||
CRASH("A supply shuttle is already defined.")
|
||||
SScargo.shuttle = src
|
||||
|
||||
/datum/shuttle/Destroy()
|
||||
current_location = null
|
||||
|
||||
SSshuttle.shuttles -= src.name
|
||||
SSshuttle.process_shuttles -= src
|
||||
if(SScargo.shuttle == src)
|
||||
SScargo.shuttle = null
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/shuttle/proc/short_jump(var/obj/effect/shuttle_landmark/destination)
|
||||
if(moving_status != SHUTTLE_IDLE) return
|
||||
|
||||
//it would be cool to play a sound here
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
if(sound_takeoff)
|
||||
playsound(current_location, sound_takeoff, 50, 20, is_global = TRUE)
|
||||
spawn(warmup_time*10)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
return //someone cancelled the launch
|
||||
if(moving_status == SHUTTLE_IDLE)
|
||||
return FALSE //someone cancelled the launch
|
||||
|
||||
callHook("shuttle_moved", list(origin,destination))
|
||||
if(!fuel_check()) //fuel error (probably out of fuel) occured, so cancel the launch
|
||||
var/datum/shuttle/autodock/S = src
|
||||
if(istype(S))
|
||||
S.cancel_launch(null)
|
||||
return
|
||||
|
||||
moving_status = SHUTTLE_INTRANSIT //shouldn't matter but just to be safe
|
||||
move(origin, destination)
|
||||
attempt_move(destination)
|
||||
moving_status = SHUTTLE_IDLE
|
||||
|
||||
/datum/shuttle/proc/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
|
||||
if(moving_status != SHUTTLE_IDLE) return
|
||||
/datum/shuttle/proc/long_jump(var/obj/effect/shuttle_landmark/destination, var/obj/effect/shuttle_landmark/interim, var/travel_time)
|
||||
if(moving_status != SHUTTLE_IDLE)
|
||||
return
|
||||
|
||||
var/obj/effect/shuttle_landmark/start_location = current_location
|
||||
|
||||
//it would be cool to play a sound here
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
if(sound_takeoff)
|
||||
playsound(current_location, sound_takeoff, 100, 20, is_global = TRUE)
|
||||
spawn(warmup_time*10)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
if(moving_status == SHUTTLE_IDLE)
|
||||
return //someone cancelled the launch
|
||||
|
||||
callHook("shuttle_moved", list(departing,destination))
|
||||
if(!fuel_check()) //fuel error (probably out of fuel) occured, so cancel the launch
|
||||
var/datum/shuttle/autodock/S = src
|
||||
if(istype(S))
|
||||
S.cancel_launch(null)
|
||||
return
|
||||
|
||||
arrive_time = world.time + travel_time*10
|
||||
moving_status = SHUTTLE_INTRANSIT
|
||||
move(departing, interim, direction)
|
||||
if(attempt_move(interim))
|
||||
var/fwooshed = 0
|
||||
while (world.time < arrive_time)
|
||||
if(!fwooshed && (arrive_time - world.time) < 100)
|
||||
fwooshed = 1
|
||||
playsound(destination, sound_landing, 100, 20, is_global = TRUE)
|
||||
sleep(5)
|
||||
if(!attempt_move(destination))
|
||||
attempt_move(start_location) //try to go back to where we started. If that fails, I guess we're stuck in the interim location
|
||||
|
||||
|
||||
while (world.time < arrive_time)
|
||||
sleep(5)
|
||||
|
||||
move(interim, destination, direction)
|
||||
moving_status = SHUTTLE_IDLE
|
||||
|
||||
/datum/shuttle/proc/dock()
|
||||
if (!docking_controller)
|
||||
return
|
||||
/datum/shuttle/proc/fuel_check()
|
||||
return 1 //fuel check should always pass in non-overmap shuttles (they have magic engines)
|
||||
|
||||
var/dock_target = current_dock_target()
|
||||
if (!dock_target)
|
||||
return
|
||||
/*****************
|
||||
* Shuttle Moved Handling * (Observer Pattern Implementation: Shuttle Moved)
|
||||
* Shuttle Pre Move Handling * (Observer Pattern Implementation: Shuttle Pre Move)
|
||||
*****************/
|
||||
|
||||
docking_controller.initiate_docking(dock_target)
|
||||
/datum/shuttle/proc/attempt_move(var/obj/effect/shuttle_landmark/destination)
|
||||
if(current_location == destination)
|
||||
return FALSE
|
||||
|
||||
/datum/shuttle/proc/undock()
|
||||
if (!docking_controller)
|
||||
return
|
||||
docking_controller.initiate_undocking()
|
||||
|
||||
/datum/shuttle/proc/current_dock_target()
|
||||
return null
|
||||
|
||||
/datum/shuttle/proc/skip_docking_checks()
|
||||
if (!docking_controller || !current_dock_target())
|
||||
return 1 //shuttles without docking controllers or at locations without docking ports act like old-style shuttles
|
||||
return 0
|
||||
if(!destination.is_valid(src))
|
||||
return FALSE
|
||||
if(current_location.cannot_depart(src))
|
||||
return FALSE
|
||||
testing("[src] moving to [destination]. Areas are [english_list(shuttle_area)]")
|
||||
var/list/translation = list()
|
||||
for(var/area/A in shuttle_area)
|
||||
testing("Moving [A]")
|
||||
translation += get_turf_translation(get_turf(current_location), get_turf(destination), A.contents)
|
||||
shuttle_moved(destination, translation)
|
||||
destination.shuttle_arrived(src)
|
||||
return TRUE
|
||||
|
||||
//just moves the shuttle from A to B, if it can be moved
|
||||
//A note to anyone overriding move in a subtype. move() must absolutely not, under any circumstances, fail to move the shuttle.
|
||||
//If you want to conditionally cancel shuttle launches, that logic must go in short_jump() or long_jump()
|
||||
/datum/shuttle/proc/move(var/area/origin, var/area/destination)
|
||||
if(origin == destination)
|
||||
return
|
||||
//A note to anyone overriding move in a subtype. shuttle_moved() must absolutely not, under any circumstances, fail to move the shuttle.
|
||||
//If you want to conditionally cancel shuttle launches, that logic must go in short_jump(), long_jump() or attempt_move()
|
||||
/datum/shuttle/proc/shuttle_moved(var/obj/effect/shuttle_landmark/destination, var/list/turf_translation)
|
||||
|
||||
if(!origin.contents.len || !destination.contents.len)
|
||||
return
|
||||
// log_debug("move_shuttle() called for [shuttle_tag] leaving [origin] en route to [destination].")
|
||||
// log_debug("area_coming_from: [origin]")
|
||||
// log_debug("destination: [destination]")
|
||||
if((flags & SHUTTLE_FLAGS_ZERO_G))
|
||||
var/new_grav = 1
|
||||
if(destination.landmark_flags & SLANDMARK_FLAG_ZERO_G)
|
||||
var/area/new_area = get_area(destination)
|
||||
new_grav = new_area.has_gravity
|
||||
for(var/area/our_area in shuttle_area)
|
||||
if(our_area.has_gravity != new_grav)
|
||||
our_area.gravitychange(new_grav)
|
||||
|
||||
if (docking_controller && !docking_controller.undocked())
|
||||
docking_controller.force_undock()
|
||||
for(var/turf/src_turf in turf_translation)
|
||||
var/turf/dst_turf = turf_translation[src_turf]
|
||||
if(src_turf.is_solid_structure()) //in case someone put a hole in the shuttle and you were lucky enough to be under it
|
||||
for(var/atom/movable/AM in dst_turf)
|
||||
if(!AM.simulated)
|
||||
continue
|
||||
if(isliving(AM))
|
||||
var/mob/living/bug = AM
|
||||
bug.gib()
|
||||
else
|
||||
qdel(AM) //it just gets atomized I guess? TODO throw it into space somewhere, prevents people from using shuttles as an atom-smasher
|
||||
var/list/powernets = list()
|
||||
for(var/area/A in shuttle_area)
|
||||
// if there was a zlevel above our origin, erase our ceiling now we're leaving
|
||||
if(HasAbove(current_location.z))
|
||||
for(var/turf/TO in A.contents)
|
||||
var/turf/TA = GetAbove(TO)
|
||||
if(istype(TA, ceiling_type))
|
||||
TA.ChangeTurf(get_base_turf_by_area(TA), 1, 1)
|
||||
if(knockdown)
|
||||
for(var/mob/M in A)
|
||||
spawn(0)
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if(M.buckled)
|
||||
to_chat(M, "<span class='warning'>Sudden acceleration presses you into your chair!</span>")
|
||||
shake_camera(M, 3, 1)
|
||||
else
|
||||
to_chat(M, "<span class='warning'>The floor lurches beneath you!</span>")
|
||||
shake_camera(M, 10, 1)
|
||||
M.visible_message("<span class='warning'>[M.name] is tossed around by the sudden acceleration!</span>")
|
||||
M.throw_at_random(FALSE, 4, 1)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
for(var/obj/structure/cable/C in A)
|
||||
powernets |= C.powernet
|
||||
|
||||
for(var/turf/T in destination)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
translate_turfs(turf_translation, current_location.base_area, current_location.base_turf)
|
||||
current_location = destination
|
||||
|
||||
for(var/turf/T in dstturfs)
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
T.ChangeTurf(/turf/space)
|
||||
// if there's a zlevel above our destination, paint in a ceiling on it so we retain our air
|
||||
if(HasAbove(current_location.z))
|
||||
for(var/area/A in shuttle_area)
|
||||
for(var/turf/TD in A.contents)
|
||||
var/turf/TA = GetAbove(TD)
|
||||
if(istype(TA, get_base_turf_by_area(TA)) || istype(TA, /turf/simulated/open))
|
||||
if(get_area(TA) in shuttle_area)
|
||||
continue
|
||||
TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE)
|
||||
|
||||
for(var/mob/living/carbon/bug in destination)
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in destination)
|
||||
pest.gib()
|
||||
|
||||
origin.move_contents_to(destination)
|
||||
|
||||
for(var/mob/M in destination)
|
||||
var/effect = FALSE
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H.shoes, /obj/item/clothing/shoes/magboots))
|
||||
var/obj/item/clothing/shoes/magboots/boots = H.shoes
|
||||
if(boots.magpulse)
|
||||
effect = DO_BOOT
|
||||
if(!effect)
|
||||
if(M.buckled)
|
||||
effect = DO_BUCKLE
|
||||
|
||||
if(effect == DO_BOOT)
|
||||
magboot_effect(M)
|
||||
else if(effect == DO_BUCKLE)
|
||||
buckled_effect(M)
|
||||
else // If they have neither of the former, then it'll always be loose (at the time of writing this, oh god)
|
||||
loose_effect(M)
|
||||
|
||||
|
||||
/datum/shuttle/proc/magboot_effect(mob/M)
|
||||
to_chat(M, span("warning","You manage to maintain your footing with the magboots!"))
|
||||
shake_camera(M, 5, 1)
|
||||
|
||||
/datum/shuttle/proc/buckled_effect(mob/M)
|
||||
to_chat(M, span("warning","Sudden acceleration presses you into your chair!"))
|
||||
shake_camera(M, 3, 1)
|
||||
|
||||
/datum/shuttle/proc/loose_effect(mob/M)
|
||||
to_chat(M, span("warning","You lose your footing as the floor lurches beneath you!"))
|
||||
shake_camera(M, 10, 1)
|
||||
M.Weaken(3)
|
||||
// Remove all powernets that were affected, and rebuild them.
|
||||
var/list/cables = list()
|
||||
for(var/datum/powernet/P in powernets)
|
||||
cables |= P.cables
|
||||
qdel(P)
|
||||
for(var/obj/structure/cable/C in cables)
|
||||
if(!C.powernet)
|
||||
var/datum/powernet/NewPN = new()
|
||||
NewPN.add_cable(C)
|
||||
propagate_network(C,C.powernet)
|
||||
|
||||
//returns 1 if the shuttle has a valid arrive time
|
||||
/datum/shuttle/proc/has_arrive_time()
|
||||
return (moving_status == SHUTTLE_INTRANSIT)
|
||||
|
||||
#undef DO_BOOT
|
||||
#undef DO_BUCKLE
|
||||
/datum/shuttle/autodock/proc/get_location_name()
|
||||
if(moving_status == SHUTTLE_INTRANSIT)
|
||||
return "In transit"
|
||||
return current_location.name
|
||||
|
||||
/datum/shuttle/autodock/proc/get_destination_name()
|
||||
if(!next_location)
|
||||
return "None"
|
||||
return next_location.name
|
||||
|
||||
@@ -1,34 +1,26 @@
|
||||
/datum/shuttle/ferry/arrival
|
||||
/datum/shuttle/autodock/ferry/arrival
|
||||
category = /datum/shuttle/autodock/ferry/arrival
|
||||
|
||||
/datum/shuttle/ferry/arrival/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
|
||||
if(isnull(location))
|
||||
return
|
||||
/datum/shuttle/autodock/ferry/arrival/New(var/_name, var/obj/effect/shuttle_landmark/start_waypoint)
|
||||
..(_name, start_waypoint)
|
||||
SSarrivals.shuttle = src
|
||||
|
||||
if(!destination)
|
||||
destination = get_location_area(!location)
|
||||
if(!departing)
|
||||
departing = get_location_area(location)
|
||||
/datum/shuttle/autodock/ferry/arrival/proc/try_jump()
|
||||
spawn(warmup_time * 10)
|
||||
if(moving_status != SHUTTLE_IDLE) //The shuttle's already been launched.
|
||||
return FALSE
|
||||
|
||||
direction = !location
|
||||
|
||||
if(moving_status != SHUTTLE_IDLE) return
|
||||
|
||||
//it would be cool to play a sound here
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
spawn(warmup_time*10)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
return //someone cancelled the launch
|
||||
|
||||
if (at_station() && forbidden_atoms_check())
|
||||
if(at_station() && forbidden_atoms_check())
|
||||
//cancel the launch because of forbidden atoms
|
||||
moving_status = SHUTTLE_IDLE
|
||||
global_announcer.autosay("Unacceptable items detected aboard the arrivals shuttle. Launch attempt failed. Restarting launch in one minute.", "Arrivals Shuttle Oversight")
|
||||
global_announcer.autosay("Unacceptable items or lifeforms detected aboard the arrivals shuttle. Launch attempt aborted. Reattempting launch in one minute.", "Arrivals Shuttle Oversight")
|
||||
SSarrivals.set_launch_countdown(60)
|
||||
SSarrivals.failreturnnumber++
|
||||
if(SSarrivals.failreturnnumber >= 2) // get off my shuttle fool
|
||||
var/list/mobstoyellat = mobs_in_area(get_location_area(location))
|
||||
var/list/mobstoyellat = list()
|
||||
for(var/area/subarea in shuttle_area)
|
||||
mobs_in_area(subarea)
|
||||
if (!mobstoyellat || !mobstoyellat.len)
|
||||
return
|
||||
return FALSE
|
||||
for(var/mob/living/A in mobstoyellat)
|
||||
to_chat(A, "<span class='danger'>You feel as if you shouldn't be on the shuttle.</span>") // give them an angry text
|
||||
if(!A.client && ishuman(A) && SSarrivals.failreturnnumber >= 3) // well they are SSD and holding up the shuttle so might as well.
|
||||
@@ -38,38 +30,30 @@
|
||||
else if(A.client && ishuman(A) && SSarrivals.failreturnnumber >= 3) // they aren't SSD and are holding up the shuttle so we are booting them.
|
||||
A.forceMove(pick(kickoffsloc))
|
||||
mobstoyellat -= A
|
||||
else if(!ishuman(A) && SSarrivals.failreturnnumber >=4 && !A.client) // remove non-player mobs to keep things rolling
|
||||
else if(!ishuman(A) && SSarrivals.failreturnnumber >= 4 && !A.client) // remove non-player mobs to keep things rolling
|
||||
qdel(A)
|
||||
else if(issilicon(A.loc) && isMMI(A))
|
||||
mobstoyellat -= A
|
||||
if (mobstoyellat)
|
||||
global_announcer.autosay("Current life-forms on shuttle: [english_list(mobstoyellat)].", "Arrivals Shuttle Oversight") // tell on them
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if (!forbidden_atoms_check() && !at_station())
|
||||
//cancel the launch because of there's no one on the shuttle.
|
||||
moving_status = SHUTTLE_IDLE
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(!at_station())
|
||||
global_announcer.autosay("Central Command Arrivals shuttle inbound to [station_name()]. ETA: one minute.", "Arrivals Shuttle Oversight")
|
||||
SSarrivals.failreturnnumber = 0
|
||||
arrive_time = world.time + travel_time*10
|
||||
moving_status = SHUTTLE_INTRANSIT
|
||||
move(departing, interim, direction)
|
||||
launch(SSarrivals)
|
||||
|
||||
|
||||
while (world.time < arrive_time)
|
||||
sleep(5)
|
||||
|
||||
move(interim, destination, direction)
|
||||
moving_status = SHUTTLE_IDLE
|
||||
|
||||
/datum/shuttle/ferry/arrival/arrived()
|
||||
/datum/shuttle/autodock/ferry/arrival/arrived()
|
||||
SSarrivals.shuttle_arrived()
|
||||
|
||||
/datum/shuttle/ferry/arrival/proc/forbidden_atoms_check()
|
||||
return SSarrivals.forbidden_atoms_check(get_location_area())
|
||||
/datum/shuttle/autodock/ferry/arrival/proc/forbidden_atoms_check()
|
||||
for(var/area/subarea in shuttle_area)
|
||||
if(SSarrivals.forbidden_atoms_check(subarea))
|
||||
return TRUE
|
||||
|
||||
/datum/shuttle/ferry/arrival/proc/at_station()
|
||||
/datum/shuttle/autodock/ferry/arrival/proc/at_station()
|
||||
return (!location)
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
#define DOCK_ATTEMPT_TIMEOUT 200 //how long in ticks we wait before assuming the docking controller is broken or blown up.
|
||||
|
||||
/datum/shuttle/autodock
|
||||
var/in_use = null //tells the controller whether this shuttle needs processing, also attempts to prevent double-use
|
||||
var/last_dock_attempt_time = 0
|
||||
var/current_dock_target
|
||||
//ID of the controller on the shuttle
|
||||
var/dock_target = null
|
||||
|
||||
var/obj/effect/shuttle_landmark/next_location
|
||||
var/datum/computer/file/embedded_program/docking/active_docking_controller
|
||||
|
||||
var/obj/effect/shuttle_landmark/landmark_transition
|
||||
var/move_time = 240 //the time spent in the transition area
|
||||
|
||||
category = /datum/shuttle/autodock
|
||||
flags = SHUTTLE_FLAGS_PROCESS | SHUTTLE_FLAGS_ZERO_G
|
||||
|
||||
/datum/shuttle/autodock/New(var/_name, var/obj/effect/shuttle_landmark/start_waypoint)
|
||||
..(_name, start_waypoint)
|
||||
|
||||
//Initial dock
|
||||
update_docking_target(current_location)
|
||||
active_docking_controller = current_location.docking_controller
|
||||
current_dock_target = get_docking_target(current_location)
|
||||
dock()
|
||||
|
||||
//Optional transition area
|
||||
if(landmark_transition)
|
||||
landmark_transition = SSshuttle.get_landmark(landmark_transition)
|
||||
|
||||
/datum/shuttle/autodock/Destroy()
|
||||
next_location = null
|
||||
active_docking_controller = null
|
||||
landmark_transition = null
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/autodock/shuttle_moved()
|
||||
force_undock() //bye!
|
||||
..()
|
||||
|
||||
/datum/shuttle/autodock/proc/update_docking_target(var/obj/effect/shuttle_landmark/location)
|
||||
if(location && location.special_dock_targets && location.special_dock_targets[name])
|
||||
current_dock_target = location.special_dock_targets[name]
|
||||
else
|
||||
current_dock_target = dock_target
|
||||
active_docking_controller = SSshuttle.docking_registry[current_dock_target]
|
||||
|
||||
/datum/shuttle/autodock/proc/get_docking_target(var/obj/effect/shuttle_landmark/location)
|
||||
if(location && location.special_dock_targets)
|
||||
if(location.special_dock_targets[name])
|
||||
return location.special_dock_targets[name]
|
||||
return dock_target
|
||||
/*
|
||||
Docking stuff
|
||||
*/
|
||||
/datum/shuttle/autodock/proc/dock()
|
||||
if(active_docking_controller)
|
||||
active_docking_controller.initiate_docking(current_dock_target)
|
||||
last_dock_attempt_time = world.time
|
||||
|
||||
/datum/shuttle/autodock/proc/undock()
|
||||
if(active_docking_controller)
|
||||
active_docking_controller.initiate_undocking()
|
||||
|
||||
/datum/shuttle/autodock/proc/force_undock()
|
||||
if(active_docking_controller)
|
||||
active_docking_controller.force_undock()
|
||||
|
||||
/datum/shuttle/autodock/proc/check_docked()
|
||||
if(active_docking_controller)
|
||||
return active_docking_controller.docked()
|
||||
return TRUE
|
||||
|
||||
/datum/shuttle/autodock/proc/check_undocked()
|
||||
if(active_docking_controller)
|
||||
return active_docking_controller.can_launch()
|
||||
return TRUE
|
||||
|
||||
/*
|
||||
Please ensure that long_jump() and short_jump() are only called from here. This applies to subtypes as well.
|
||||
Doing so will ensure that multiple jumps cannot be initiated in parallel.
|
||||
*/
|
||||
/datum/shuttle/autodock/process()
|
||||
switch(process_state)
|
||||
if (WAIT_LAUNCH)
|
||||
if(check_undocked())
|
||||
//*** ready to go
|
||||
if(next_location.is_valid(src))
|
||||
process_launch()
|
||||
process_state = WAIT_ARRIVE
|
||||
else
|
||||
process_state = IDLE_STATE
|
||||
in_use = null
|
||||
|
||||
if (FORCE_LAUNCH)
|
||||
process_launch()
|
||||
|
||||
if (WAIT_ARRIVE)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
//*** we made it to the destination, update stuff
|
||||
process_arrived()
|
||||
process_state = WAIT_FINISH
|
||||
|
||||
if (WAIT_FINISH)
|
||||
if (world.time > last_dock_attempt_time + DOCK_ATTEMPT_TIMEOUT || check_docked())
|
||||
//*** all done here
|
||||
process_state = IDLE_STATE
|
||||
arrived()
|
||||
|
||||
//not to be confused with the arrived() proc
|
||||
/datum/shuttle/autodock/proc/process_arrived()
|
||||
update_docking_target(next_location)
|
||||
active_docking_controller = next_location.docking_controller
|
||||
current_dock_target = get_docking_target(next_location)
|
||||
dock()
|
||||
|
||||
next_location = null
|
||||
in_use = null //release lock
|
||||
|
||||
/datum/shuttle/autodock/proc/process_launch()
|
||||
if (move_time && landmark_transition)
|
||||
. = long_jump(next_location, landmark_transition, move_time)
|
||||
else
|
||||
. = short_jump(next_location)
|
||||
process_state = WAIT_ARRIVE
|
||||
|
||||
/*
|
||||
Guards
|
||||
*/
|
||||
/datum/shuttle/autodock/proc/can_launch()
|
||||
return (next_location && moving_status == SHUTTLE_IDLE && !in_use)
|
||||
|
||||
/datum/shuttle/autodock/proc/can_force()
|
||||
return (next_location && moving_status == SHUTTLE_IDLE && process_state == WAIT_LAUNCH)
|
||||
|
||||
/datum/shuttle/autodock/proc/can_cancel()
|
||||
return (moving_status == SHUTTLE_WARMUP || process_state == WAIT_LAUNCH || process_state == FORCE_LAUNCH)
|
||||
|
||||
/*
|
||||
"Public" procs
|
||||
*/
|
||||
/datum/shuttle/autodock/proc/launch(var/user)
|
||||
if(!can_launch())
|
||||
return
|
||||
|
||||
in_use = user //obtain an exclusive lock on the shuttle
|
||||
|
||||
process_state = WAIT_LAUNCH
|
||||
undock()
|
||||
|
||||
/datum/shuttle/autodock/proc/force_launch(var/user)
|
||||
if(!can_force())
|
||||
return
|
||||
|
||||
in_use = user //obtain an exclusive lock on the shuttle
|
||||
|
||||
process_state = FORCE_LAUNCH
|
||||
|
||||
/datum/shuttle/autodock/proc/cancel_launch(var/user)
|
||||
if (!can_cancel()) return
|
||||
|
||||
moving_status = SHUTTLE_IDLE
|
||||
process_state = WAIT_FINISH
|
||||
in_use = null
|
||||
|
||||
//whatever we were doing with docking: stop it, then redock
|
||||
force_undock()
|
||||
spawn(1 SECOND)
|
||||
dock()
|
||||
|
||||
//returns 1 if the shuttle is getting ready to move, but is not in transit yet
|
||||
/datum/shuttle/autodock/proc/is_launching()
|
||||
return (moving_status == SHUTTLE_WARMUP || process_state == WAIT_LAUNCH || process_state == FORCE_LAUNCH)
|
||||
|
||||
//This gets called when the shuttle finishes arriving at it's destination
|
||||
//This can be used by subtypes to do things when the shuttle arrives.
|
||||
//Note that this is called when the shuttle leaves the WAIT_FINISHED state, the proc name is a little misleading
|
||||
/datum/shuttle/autodock/proc/arrived()
|
||||
return //do nothing for now
|
||||
@@ -1,17 +1,18 @@
|
||||
/datum/shuttle/ferry/autoreturn
|
||||
/datum/shuttle/autodock/ferry/autoreturn
|
||||
var/auto_return_time = 60 //Time after which the shuttle should return in seconds
|
||||
category = /datum/shuttle/autodock/ferry/autoreturn
|
||||
|
||||
/datum/shuttle/ferry/autoreturn/arrived()
|
||||
addtimer(CALLBACK(src, .proc/announce_return), 20)
|
||||
addtimer(CALLBACK(src, .proc/do_return), auto_return_time*10)
|
||||
/datum/shuttle/autodock/ferry/autoreturn/arrived()
|
||||
if(waypoint_station == current_location)
|
||||
addtimer(CALLBACK(src, .proc/announce_return), 20)
|
||||
addtimer(CALLBACK(src, .proc/do_return), auto_return_time*10)
|
||||
|
||||
/datum/shuttle/ferry/autoreturn/proc/announce_return()
|
||||
/datum/shuttle/autodock/ferry/autoreturn/proc/announce_return()
|
||||
if(!location)
|
||||
for(var/turf/T in get_area_turfs(area_station))
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, span("notice","You have arrived at [current_map.station_name]. The shuttle will return in [auto_return_time] seconds."))
|
||||
for(var/area/A in shuttle_area)
|
||||
for(var/mob/M in A)
|
||||
if(ishuman(M))
|
||||
to_chat(M, SPAN_NOTICE("You have arrived at the [current_map.station_name]! The shuttle will return in [auto_return_time] seconds. Enjoy your stay!"))
|
||||
|
||||
/datum/shuttle/ferry/autoreturn/proc/do_return()
|
||||
if(!location)
|
||||
launch(null)
|
||||
force_launch(null)
|
||||
/datum/shuttle/autodock/ferry/autoreturn/proc/do_return()
|
||||
launch(src)
|
||||
|
||||
@@ -1,102 +1,122 @@
|
||||
/obj/machinery/computer/shuttle_control
|
||||
name = "shuttle control console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_screen = "explosive"
|
||||
light_color = LIGHT_COLOR_ORANGE
|
||||
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
icon_screen = "shuttle"
|
||||
circuit = null
|
||||
var/shuttle_tag // Used to coordinate data in shuttle controller.
|
||||
var/hacked = FALSE // Has been emagged, no access restrictions.
|
||||
|
||||
var/shuttle_tag // Used to coordinate data in shuttle controller.
|
||||
var/hacked = 0 // Has been emagged, no access restrictions.
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle_control/attack_hand(user as mob)
|
||||
if(..(user))
|
||||
return
|
||||
//src.add_fingerprint(user) //shouldn't need fingerprints just for looking at it.
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
var/ui_template = "shuttle_control_console.tmpl"
|
||||
|
||||
/obj/machinery/computer/shuttle_control/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
|
||||
if (!istype(shuttle))
|
||||
return
|
||||
/obj/machinery/computer/shuttle_control/attack_ai(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/attack_ghost(var/mob/abstract/observer/user)
|
||||
if(check_rights(R_ADMIN, 0, user))
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/proc/get_ui_data(var/datum/shuttle/autodock/shuttle)
|
||||
var/shuttle_state
|
||||
switch(shuttle.moving_status)
|
||||
if(SHUTTLE_IDLE) shuttle_state = "idle"
|
||||
if(SHUTTLE_WARMUP) shuttle_state = "warmup"
|
||||
if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit"
|
||||
if(SHUTTLE_HALT) shuttle_state = "halt"
|
||||
|
||||
var/shuttle_status
|
||||
switch (shuttle.process_state)
|
||||
if(IDLE_STATE)
|
||||
var/cannot_depart = shuttle.current_location.cannot_depart(shuttle)
|
||||
if (shuttle.in_use)
|
||||
shuttle_status = "Busy."
|
||||
else if (!shuttle.location)
|
||||
shuttle_status = "Standing-by at station."
|
||||
else if(cannot_depart)
|
||||
shuttle_status = cannot_depart
|
||||
else
|
||||
shuttle_status = "Standing-by at offsite location."
|
||||
shuttle_status = "Standing-by at \the [shuttle.get_location_name()]."
|
||||
|
||||
if(WAIT_LAUNCH, FORCE_LAUNCH)
|
||||
shuttle_status = "Shuttle has received command and will depart shortly."
|
||||
shuttle_status = "Shuttle has recieved command and will depart shortly."
|
||||
if(WAIT_ARRIVE)
|
||||
shuttle_status = "Proceeding to destination."
|
||||
shuttle_status = "Proceeding to \the [shuttle.get_destination_name()]."
|
||||
if(WAIT_FINISH)
|
||||
shuttle_status = "Arriving at destination now."
|
||||
|
||||
data = list(
|
||||
return list(
|
||||
"shuttle_status" = shuttle_status,
|
||||
"shuttle_state" = shuttle_state,
|
||||
"has_docking" = shuttle.docking_controller? 1 : 0,
|
||||
"docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null,
|
||||
"docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null,
|
||||
"has_docking" = shuttle.active_docking_controller? 1 : 0,
|
||||
"docking_status" = shuttle.active_docking_controller? shuttle.active_docking_controller.get_docking_status() : null,
|
||||
"docking_override" = shuttle.active_docking_controller? shuttle.active_docking_controller.override_enabled : null,
|
||||
"can_launch" = shuttle.can_launch(),
|
||||
"can_cancel" = shuttle.can_cancel(),
|
||||
"can_force" = shuttle.can_force()
|
||||
"can_force" = shuttle.can_force(),
|
||||
)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
// This is a subset of the actual checks; contains those that give messages to the user.
|
||||
/obj/machinery/computer/shuttle_control/proc/can_move(var/datum/shuttle/autodock/shuttle, var/user)
|
||||
var/cannot_depart = shuttle.current_location.cannot_depart(shuttle)
|
||||
if(cannot_depart)
|
||||
to_chat(user, SPAN_WARNING(cannot_depart))
|
||||
return FALSE
|
||||
if(!shuttle.next_location.is_valid(shuttle))
|
||||
to_chat(user, SPAN_WARNING("Destination zone is invalid or obstructed."))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "shuttle_control_console.tmpl", "[shuttle_tag] Shuttle Control", 470, 310)
|
||||
/obj/machinery/computer/shuttle_control/proc/handle_topic_href(var/datum/shuttle/autodock/shuttle, var/list/href_list, var/user)
|
||||
if(!istype(shuttle))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if(href_list["move"])
|
||||
if(can_move(shuttle, user))
|
||||
shuttle.launch(src)
|
||||
return TOPIC_REFRESH
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if(href_list["force"])
|
||||
if(can_move(shuttle, user))
|
||||
shuttle.force_launch(src)
|
||||
return TOPIC_REFRESH
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if(href_list["cancel"])
|
||||
shuttle.cancel_launch(src)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
/obj/machinery/computer/shuttle_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/datum/shuttle/autodock/shuttle = SSshuttle.shuttles[shuttle_tag]
|
||||
if (!istype(shuttle))
|
||||
to_chat(user,"<span class='warning'>Unable to establish link with the shuttle.</span>")
|
||||
return
|
||||
|
||||
var/list/data = get_ui_data(shuttle)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, ui_template, "[shuttle_tag] Shuttle Control", 470, 450)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
/obj/machinery/computer/shuttle_control/Topic(user, href_list)
|
||||
..()
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
|
||||
if (!istype(shuttle))
|
||||
return
|
||||
|
||||
if(href_list["move"])
|
||||
shuttle.launch(src)
|
||||
if(href_list["force"])
|
||||
shuttle.force_launch(src)
|
||||
else if(href_list["cancel"])
|
||||
shuttle.cancel_launch(src)
|
||||
handle_topic_href(SSshuttle.shuttles[shuttle_tag], href_list, user)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/emag_act(var/remaining_charges, var/mob/user)
|
||||
if (!hacked)
|
||||
if(!hacked)
|
||||
req_access = list()
|
||||
req_one_access = list()
|
||||
hacked = 1
|
||||
hacked = TRUE
|
||||
to_chat(user, "You short out the console's ID checking system. It's now available to everyone!")
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/shuttle_control/bullet_act(var/obj/item/projectile/Proj)
|
||||
visible_message("\The [Proj] ricochets off \the [src]!")
|
||||
|
||||
/obj/machinery/computer/shuttle_control/ex_act(var/severity = 2.0)
|
||||
/obj/machinery/computer/shuttle_control/ex_act()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/shuttle_control/emp_act()
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/obj/machinery/computer/shuttle_control/multi
|
||||
ui_template = "shuttle_control_console_multi.tmpl"
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/get_ui_data(var/datum/shuttle/autodock/multi/shuttle)
|
||||
. = ..()
|
||||
if(istype(shuttle))
|
||||
. += list(
|
||||
"destination_name" = shuttle.next_location? shuttle.next_location.name : "No destination set.",
|
||||
"can_pick" = shuttle.moving_status == SHUTTLE_IDLE,
|
||||
)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/handle_topic_href(var/datum/shuttle/autodock/multi/shuttle, var/list/href_list)
|
||||
..()
|
||||
|
||||
if(href_list["pick"])
|
||||
var/dest_key = input("Choose shuttle destination", "Shuttle Destination") as null|anything in shuttle.get_destinations()
|
||||
if(dest_key && (!use_check(usr) || (isobserver(usr) && check_rights(R_ADMIN, FALSE))))
|
||||
shuttle.set_destination(dest_key, usr)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/antag
|
||||
ui_template = "shuttle_control_console_antag.tmpl"
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/antag/get_ui_data(var/datum/shuttle/autodock/multi/antag/shuttle)
|
||||
. = ..()
|
||||
if(istype(shuttle))
|
||||
. += list(
|
||||
"cloaked" = shuttle.cloaked,
|
||||
)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/antag/handle_topic_href(var/datum/shuttle/autodock/multi/antag/shuttle, var/list/href_list)
|
||||
..()
|
||||
|
||||
if(href_list["toggle_cloaked"])
|
||||
shuttle.cloaked = !shuttle.cloaked
|
||||
return TOPIC_REFRESH
|
||||
@@ -1,30 +1,32 @@
|
||||
/datum/shuttle/ferry/emergency
|
||||
/datum/shuttle/autodock/ferry/emergency
|
||||
//pass
|
||||
|
||||
/datum/shuttle/ferry/emergency/arrived()
|
||||
/datum/shuttle/autodock/ferry/emergency/New()
|
||||
..()
|
||||
if(emergency_shuttle.shuttle)
|
||||
CRASH("An emergency shuttle has already been created.")
|
||||
return
|
||||
emergency_shuttle.shuttle = src
|
||||
|
||||
/datum/shuttle/autodock/ferry/emergency/arrived()
|
||||
. = ..()
|
||||
if (istype(in_use, /obj/machinery/computer/shuttle_control/emergency))
|
||||
var/obj/machinery/computer/shuttle_control/emergency/C = in_use
|
||||
C.reset_authorization()
|
||||
|
||||
emergency_shuttle.shuttle_arrived()
|
||||
|
||||
/datum/shuttle/ferry/emergency/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
|
||||
if (!location)
|
||||
travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
|
||||
else
|
||||
travel_time = SHUTTLE_TRANSIT_DURATION
|
||||
/datum/shuttle/autodock/ferry/emergency/long_jump(var/obj/effect/shuttle_landmark/destination, var/obj/effect/shuttle_landmark/interim, var/travel_time)
|
||||
var/time_to_go = SHUTTLE_TRANSIT_DURATION
|
||||
if(destination == waypoint_offsite)
|
||||
time_to_go = SHUTTLE_TRANSIT_DURATION_RETURN
|
||||
|
||||
//update move_time and launch_time so we get correct ETAs
|
||||
move_time = travel_time
|
||||
..(destination, interim, time_to_go)
|
||||
emergency_shuttle.launch_time = world.time
|
||||
|
||||
..()
|
||||
|
||||
/datum/shuttle/ferry/emergency/move(var/area/origin,var/area/destination)
|
||||
..(origin, destination)
|
||||
|
||||
if (origin == area_station) //leaving the station
|
||||
emergency_shuttle.departed = 1
|
||||
/datum/shuttle/autodock/ferry/emergency/shuttle_moved()
|
||||
if (next_location != waypoint_station) //leaving the station
|
||||
emergency_shuttle.departed = TRUE
|
||||
|
||||
var/list/replacements = list(
|
||||
"%ETA%" = round(emergency_shuttle.estimate_arrival_time()/60,1),
|
||||
@@ -34,15 +36,16 @@
|
||||
priority_announcement.Announce(replacemany(current_map.emergency_shuttle_leaving_dock, replacements))
|
||||
else
|
||||
priority_announcement.Announce(replacemany(current_map.shuttle_leaving_dock, replacements))
|
||||
..()
|
||||
|
||||
/datum/shuttle/ferry/emergency/can_launch(var/user)
|
||||
/datum/shuttle/autodock/ferry/emergency/can_launch(var/user)
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency))
|
||||
var/obj/machinery/computer/shuttle_control/emergency/C = user
|
||||
if (!C.has_authorization())
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/emergency/can_force(var/user)
|
||||
/datum/shuttle/autodock/ferry/emergency/can_force(var/user)
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency))
|
||||
var/obj/machinery/computer/shuttle_control/emergency/C = user
|
||||
|
||||
@@ -52,7 +55,7 @@
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/emergency/can_cancel(var/user)
|
||||
/datum/shuttle/autodock/ferry/emergency/can_cancel(var/user)
|
||||
//If we try to cancel it via the shuttle computer
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency))
|
||||
var/obj/machinery/computer/shuttle_control/emergency/C = user
|
||||
@@ -61,13 +64,14 @@
|
||||
return 0
|
||||
|
||||
// If the emergency shuttle is waiting to leave the station and the world time exceeded the force time
|
||||
if (emergency_shuttle.waiting_to_leave() && (world.time > emergency_shuttle.force_time))
|
||||
if(emergency_shuttle.waiting_to_leave() && (world.time > emergency_shuttle.force_time))
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/emergency/launch(var/user)
|
||||
if (!can_launch(user)) return
|
||||
/datum/shuttle/autodock/ferry/emergency/launch(var/user)
|
||||
if (!can_launch(user))
|
||||
return
|
||||
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
|
||||
if (emergency_shuttle.autopilot)
|
||||
@@ -80,8 +84,9 @@
|
||||
|
||||
..(user)
|
||||
|
||||
/datum/shuttle/ferry/emergency/force_launch(var/user)
|
||||
if (!can_force(user)) return
|
||||
/datum/shuttle/autodock/ferry/emergency/force_launch(var/user)
|
||||
if (!can_force(user))
|
||||
return
|
||||
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
|
||||
if (emergency_shuttle.autopilot)
|
||||
@@ -94,8 +99,9 @@
|
||||
|
||||
..(user)
|
||||
|
||||
/datum/shuttle/ferry/emergency/cancel_launch(var/user)
|
||||
if (!can_cancel(user)) return
|
||||
/datum/shuttle/autodock/ferry/emergency/cancel_launch(var/user)
|
||||
if (!can_cancel(user))
|
||||
return
|
||||
|
||||
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
|
||||
if (emergency_shuttle.autopilot)
|
||||
@@ -108,10 +114,8 @@
|
||||
|
||||
..(user)
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle_control/emergency
|
||||
shuttle_tag = "Escape"
|
||||
shuttle_tag = "Escape Shuttle"
|
||||
var/debug = 0
|
||||
var/req_authorizations = 2
|
||||
var/list/authorized = list()
|
||||
@@ -177,7 +181,7 @@
|
||||
|
||||
/obj/machinery/computer/shuttle_control/emergency/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
var/datum/shuttle/ferry/emergency/shuttle = shuttle_controller.shuttles[shuttle_tag]
|
||||
var/datum/shuttle/autodock/ferry/emergency/shuttle = SSshuttle.shuttles[shuttle_tag]
|
||||
if (!istype(shuttle))
|
||||
return
|
||||
|
||||
@@ -223,9 +227,9 @@
|
||||
data = list(
|
||||
"shuttle_status" = shuttle_status,
|
||||
"shuttle_state" = shuttle_state,
|
||||
"has_docking" = shuttle.docking_controller? 1 : 0,
|
||||
"docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null,
|
||||
"docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null,
|
||||
"has_docking" = shuttle.active_docking_controller? 1 : 0,
|
||||
"docking_status" = shuttle.active_docking_controller? shuttle.active_docking_controller.get_docking_status() : null,
|
||||
"docking_override" = shuttle.active_docking_controller? shuttle.active_docking_controller.override_enabled : null,
|
||||
"can_launch" = shuttle.can_launch(src),
|
||||
"can_cancel" = shuttle.can_cancel(src),
|
||||
"can_force" = shuttle.can_force(src),
|
||||
|
||||
@@ -1,175 +1,47 @@
|
||||
#define DOCK_ATTEMPT_TIMEOUT 200 //how long in ticks we wait before assuming the docking controller is broken or blown up.
|
||||
|
||||
/datum/shuttle/ferry
|
||||
|
||||
/datum/shuttle/autodock/ferry
|
||||
var/location = 0 //0 = at area_station, 1 = at area_offsite
|
||||
var/direction = 0 //0 = going to station, 1 = going to offsite.
|
||||
var/process_state = IDLE_STATE
|
||||
|
||||
var/in_use = null //tells the controller whether this shuttle needs processing
|
||||
var/obj/effect/shuttle_landmark/waypoint_station //This variable is type-abused initially: specify the landmark_tag, not the actual landmark.
|
||||
var/obj/effect/shuttle_landmark/waypoint_offsite //This variable is type-abused initially: specify the landmark_tag, not the actual landmark.
|
||||
|
||||
var/area_transition
|
||||
var/move_time = 0 //the time spent in the transition area
|
||||
var/transit_direction = null //needed for area/move_contents_to() to properly handle shuttle corners - not exactly sure how it works.
|
||||
category = /datum/shuttle/autodock/ferry
|
||||
|
||||
var/area/area_station
|
||||
var/area/area_offsite
|
||||
//TODO: change location to a string and use a mapping for area and dock targets.
|
||||
var/dock_target_station
|
||||
var/dock_target_offsite
|
||||
/datum/shuttle/autodock/ferry/New(_name)
|
||||
if(waypoint_station)
|
||||
waypoint_station = SSshuttle.get_landmark(waypoint_station)
|
||||
if(waypoint_offsite)
|
||||
waypoint_offsite = SSshuttle.get_landmark(waypoint_offsite)
|
||||
|
||||
var/last_dock_attempt_time = 0
|
||||
..(_name, get_location_waypoint(location))
|
||||
|
||||
/datum/shuttle/ferry/short_jump(var/area/origin, var/area/destination)
|
||||
if(isnull(location))
|
||||
return
|
||||
next_location = get_location_waypoint(!location)
|
||||
|
||||
if(!destination)
|
||||
destination = get_location_area(!location)
|
||||
if(!origin)
|
||||
origin = get_location_area(location)
|
||||
|
||||
direction = !location
|
||||
..(origin, destination)
|
||||
|
||||
/datum/shuttle/ferry/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
|
||||
if(isnull(location))
|
||||
return
|
||||
|
||||
if(!destination)
|
||||
destination = get_location_area(!location)
|
||||
if(!departing)
|
||||
departing = get_location_area(location)
|
||||
|
||||
direction = !location
|
||||
..(departing, destination, interim, travel_time, direction)
|
||||
|
||||
/datum/shuttle/ferry/move(var/area/origin,var/area/destination)
|
||||
..(origin, destination)
|
||||
|
||||
if (destination == area_station) location = 0
|
||||
if (destination == area_offsite) location = 1
|
||||
//if this is a long_jump retain the location we were last at until we get to the new one
|
||||
|
||||
/datum/shuttle/ferry/dock()
|
||||
..()
|
||||
last_dock_attempt_time = world.time
|
||||
|
||||
/datum/shuttle/ferry/proc/get_location_area(location_id = null)
|
||||
//Gets the shuttle landmark associated with the given location (defaults to current location)
|
||||
/datum/shuttle/autodock/ferry/proc/get_location_waypoint(location_id = null)
|
||||
if (isnull(location_id))
|
||||
location_id = location
|
||||
|
||||
if (!location_id)
|
||||
return area_station
|
||||
return area_offsite
|
||||
return waypoint_station
|
||||
return waypoint_offsite
|
||||
|
||||
/*
|
||||
Please ensure that long_jump() and short_jump() are only called from here. This applies to subtypes as well.
|
||||
Doing so will ensure that multiple jumps cannot be initiated in parallel.
|
||||
*/
|
||||
/datum/shuttle/ferry/process()
|
||||
if(moving_status != SHUTTLE_HALT)
|
||||
if(!area_station || !area_offsite)
|
||||
moving_status = SHUTTLE_HALT
|
||||
return
|
||||
if(!area_station.contents.len || !area_offsite.contents.len)
|
||||
moving_status = SHUTTLE_HALT
|
||||
return
|
||||
switch(process_state)
|
||||
if (WAIT_LAUNCH)
|
||||
if (skip_docking_checks() || docking_controller.can_launch())
|
||||
/datum/shuttle/autodock/ferry/short_jump(var/destination)
|
||||
direction = !location
|
||||
..()
|
||||
|
||||
if (move_time && area_transition)
|
||||
long_jump(interim=area_transition, travel_time=move_time, direction=transit_direction)
|
||||
else
|
||||
short_jump()
|
||||
/datum/shuttle/autodock/ferry/long_jump(var/obj/effect/shuttle_landmark/destination, var/obj/effect/shuttle_landmark/interim, var/travel_time)
|
||||
direction = !location
|
||||
..()
|
||||
|
||||
process_state = WAIT_ARRIVE
|
||||
/datum/shuttle/autodock/ferry/shuttle_moved()
|
||||
..()
|
||||
|
||||
if (FORCE_LAUNCH)
|
||||
if (move_time && area_transition)
|
||||
long_jump(interim=area_transition, travel_time=move_time, direction=transit_direction)
|
||||
else
|
||||
short_jump()
|
||||
|
||||
process_state = WAIT_ARRIVE
|
||||
|
||||
if (WAIT_ARRIVE)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
dock()
|
||||
in_use = null //release lock
|
||||
process_state = WAIT_FINISH
|
||||
|
||||
if (WAIT_FINISH)
|
||||
if (skip_docking_checks() || docking_controller.docked() || world.time > last_dock_attempt_time + DOCK_ATTEMPT_TIMEOUT)
|
||||
process_state = IDLE_STATE
|
||||
arrived()
|
||||
|
||||
/datum/shuttle/ferry/current_dock_target()
|
||||
var/dock_target
|
||||
if (!location) //station
|
||||
dock_target = dock_target_station
|
||||
else
|
||||
dock_target = dock_target_offsite
|
||||
return dock_target
|
||||
|
||||
|
||||
/datum/shuttle/ferry/proc/launch(var/user)
|
||||
if (!can_launch()) return
|
||||
|
||||
in_use = user //obtain an exclusive lock on the shuttle
|
||||
|
||||
process_state = WAIT_LAUNCH
|
||||
undock()
|
||||
|
||||
/datum/shuttle/ferry/proc/force_launch(var/user)
|
||||
if (!can_force()) return
|
||||
|
||||
in_use = user //obtain an exclusive lock on the shuttle
|
||||
|
||||
process_state = FORCE_LAUNCH
|
||||
|
||||
/datum/shuttle/ferry/proc/cancel_launch(var/user)
|
||||
if (!can_cancel()) return
|
||||
|
||||
moving_status = SHUTTLE_IDLE
|
||||
process_state = WAIT_FINISH
|
||||
in_use = null
|
||||
|
||||
if (docking_controller && !docking_controller.undocked())
|
||||
docking_controller.force_undock()
|
||||
|
||||
spawn(10)
|
||||
dock()
|
||||
|
||||
return
|
||||
|
||||
/datum/shuttle/ferry/proc/can_launch()
|
||||
if (moving_status != SHUTTLE_IDLE)
|
||||
return 0
|
||||
|
||||
if (in_use)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/datum/shuttle/ferry/proc/can_force()
|
||||
if (moving_status == SHUTTLE_IDLE && process_state == WAIT_LAUNCH)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/shuttle/ferry/proc/can_cancel()
|
||||
if(moving_status == SHUTTLE_HALT)
|
||||
return 0
|
||||
if (moving_status == SHUTTLE_WARMUP || process_state == WAIT_LAUNCH || process_state == FORCE_LAUNCH)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//returns 1 if the shuttle is getting ready to move, but is not in transit yet
|
||||
/datum/shuttle/ferry/proc/is_launching()
|
||||
return (moving_status == SHUTTLE_WARMUP || process_state == WAIT_LAUNCH || process_state == FORCE_LAUNCH)
|
||||
|
||||
//This gets called when the shuttle finishes arriving at it's destination
|
||||
//This can be used by subtypes to do things when the shuttle arrives.
|
||||
/datum/shuttle/ferry/proc/arrived()
|
||||
return //do nothing for now
|
||||
if (next_location == waypoint_station) location = 0
|
||||
if (next_location == waypoint_offsite) location = 1
|
||||
|
||||
/datum/shuttle/autodock/ferry/process_arrived()
|
||||
..()
|
||||
next_location = get_location_waypoint(!location)
|
||||
|
||||
@@ -1,60 +1,32 @@
|
||||
/obj/machinery/computer/shuttle_control/specops
|
||||
name = "special operations shuttle console"
|
||||
shuttle_tag = "Special Operations"
|
||||
shuttle_tag = "Phoenix Shuttle"
|
||||
req_access = list(access_cent_specops)
|
||||
|
||||
/obj/machinery/computer/shuttle_control/specops/attack_ai(user as mob)
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
|
||||
//for shuttles that may use a different docking port at each location
|
||||
/datum/shuttle/ferry/multidock
|
||||
var/docking_controller_tag_station
|
||||
var/docking_controller_tag_offsite
|
||||
var/datum/computer/file/embedded_program/docking/docking_controller_station
|
||||
var/datum/computer/file/embedded_program/docking/docking_controller_offsite
|
||||
|
||||
/datum/shuttle/ferry/multidock/init_docking_controllers()
|
||||
if(docking_controller_tag_station)
|
||||
docking_controller_station = locate(docking_controller_tag_station)
|
||||
if(!istype(docking_controller_station))
|
||||
to_world("<span class='danger'>warning: shuttle with docking tag [docking_controller_station] could not find it's controller!</span>")
|
||||
if(docking_controller_tag_offsite)
|
||||
docking_controller_offsite = locate(docking_controller_tag_offsite)
|
||||
if(!istype(docking_controller_offsite))
|
||||
to_world("<span class='danger'>warning: shuttle with docking tag [docking_controller_offsite] could not find it's controller!</span>")
|
||||
if (!location)
|
||||
docking_controller = docking_controller_station
|
||||
else
|
||||
docking_controller = docking_controller_offsite
|
||||
|
||||
/datum/shuttle/ferry/multidock/move(var/area/origin,var/area/destination)
|
||||
..(origin, destination)
|
||||
if (!location)
|
||||
docking_controller = docking_controller_station
|
||||
else
|
||||
docking_controller = docking_controller_offsite
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops
|
||||
/datum/shuttle/autodock/ferry/specops
|
||||
var/specops_return_delay = 6000 //After moving, the amount of time that must pass before the shuttle may move again
|
||||
var/specops_countdown_time = 600 //Length of the countdown when moving the shuttle
|
||||
|
||||
var/obj/item/device/radio/intercom/announcer = null
|
||||
var/obj/item/device/radio/intercom/announcer
|
||||
var/reset_time = 0 //the world.time at which the shuttle will be ready to move again.
|
||||
var/launch_prep = 0
|
||||
var/cancel_countdown = 0
|
||||
category = /datum/shuttle/autodock/ferry/specops
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/New()
|
||||
/datum/shuttle/autodock/ferry/specops/New()
|
||||
..()
|
||||
announcer = new /obj/item/device/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
announcer.config(list("Response Team" = 0))
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/proc/radio_announce(var/message)
|
||||
/datum/shuttle/autodock/ferry/specops/proc/radio_announce(var/message)
|
||||
if(announcer)
|
||||
announcer.autosay(message, "Bubble", "Response Team")
|
||||
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/launch(var/user)
|
||||
/datum/shuttle/autodock/ferry/specops/launch(var/user)
|
||||
if (!can_launch())
|
||||
return
|
||||
|
||||
@@ -79,31 +51,31 @@
|
||||
sleep_until_launch()
|
||||
|
||||
if (location)
|
||||
var/obj/machinery/light/small/readylight/light = locate() in get_location_area()
|
||||
var/obj/machinery/light/small/readylight/light = locate() in shuttle_area
|
||||
if(light) light.set_state(0)
|
||||
|
||||
//launch
|
||||
radio_announce("ALERT: INITIATING LAUNCH SEQUENCE")
|
||||
..(user)
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/move(var/area/origin,var/area/destination)
|
||||
..(origin, destination)
|
||||
/datum/shuttle/autodock/ferry/specops/shuttle_moved()
|
||||
. = ..()
|
||||
|
||||
spawn(20)
|
||||
if (!location) //just arrived home
|
||||
for(var/turf/T in get_area_turfs(destination))
|
||||
for(var/turf/T in get_area_turfs(shuttle_area))
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='danger'>You have arrived at [current_map.boss_name]. Operation has ended!</span>")
|
||||
else //just left for the station
|
||||
launch_mauraders()
|
||||
for(var/turf/T in get_area_turfs(destination))
|
||||
for(var/turf/T in get_area_turfs(shuttle_area))
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='danger'>You have arrived at [current_map.station_name]. Commence operation!</span>")
|
||||
|
||||
var/obj/machinery/light/small/readylight/light = locate() in T
|
||||
if(light) light.set_state(1)
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/cancel_launch()
|
||||
/datum/shuttle/autodock/ferry/specops/cancel_launch()
|
||||
if (!can_cancel())
|
||||
return
|
||||
|
||||
@@ -115,23 +87,21 @@
|
||||
|
||||
..()
|
||||
|
||||
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/can_launch()
|
||||
/datum/shuttle/autodock/ferry/specops/can_launch()
|
||||
if(launch_prep)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
//should be fine to allow forcing. process_state only becomes WAIT_LAUNCH after the countdown is over.
|
||||
///datum/shuttle/ferry/multidock/specops/can_force()
|
||||
///datum/shuttle/autodock/ferry/specops/can_force()
|
||||
// return 0
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/can_cancel()
|
||||
/datum/shuttle/autodock/ferry/specops/can_cancel()
|
||||
if(launch_prep)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/ferry/multidock/specops/proc/sleep_until_launch()
|
||||
/datum/shuttle/autodock/ferry/specops/proc/sleep_until_launch()
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
|
||||
var/launch_time = world.time + specops_countdown_time
|
||||
@@ -246,17 +216,17 @@
|
||||
/obj/machinery/computer/shuttle_control/legion
|
||||
name = "dropship control console"
|
||||
req_access = list(access_legion)
|
||||
shuttle_tag = "Tau Ceti Foreign Legion"
|
||||
shuttle_tag = "Legion Shuttle"
|
||||
|
||||
/datum/shuttle/ferry/legion
|
||||
/datum/shuttle/autodock/ferry/legion
|
||||
var/dropship_return_delay = 6600
|
||||
var/earliest_departure_time = 0
|
||||
|
||||
/datum/shuttle/ferry/legion/arrived()
|
||||
/datum/shuttle/autodock/ferry/legion/arrived()
|
||||
if(!location)
|
||||
earliest_departure_time = world.time + dropship_return_delay
|
||||
|
||||
/datum/shuttle/ferry/legion/launch(var/user)
|
||||
/datum/shuttle/autodock/ferry/legion/launch(var/user)
|
||||
if(!location && earliest_departure_time > world.time)
|
||||
var/obj/machinery/computer/shuttle_control/legion/L = user
|
||||
L.visible_message(span("notice","The dropship's skipthrusters will be done recharging in approximately [round((earliest_departure_time - world.time)/600)] minute\s."),null,3)
|
||||
@@ -267,4 +237,4 @@
|
||||
/obj/machinery/computer/shuttle_control/distress
|
||||
name = "shuttle control computer"
|
||||
req_access = list(access_distress)
|
||||
shuttle_tag = "Distress"
|
||||
shuttle_tag = "Distress Shuttle"
|
||||
|
||||
@@ -1,75 +1,77 @@
|
||||
/datum/shuttle/ferry/supply
|
||||
/datum/shuttle/autodock/ferry/supply
|
||||
category = /datum/shuttle/autodock/ferry/supply
|
||||
var/away_location = 1 //the location to hide at while pretending to be in-transit
|
||||
var/late_chance = 80
|
||||
var/max_late_time = 300
|
||||
|
||||
/datum/shuttle/ferry/supply/short_jump(var/area/origin,var/area/destination)
|
||||
/datum/shuttle/autodock/ferry/supply/New(var/_name, var/obj/effect/shuttle_landmark/start_waypoint)
|
||||
..(_name, start_waypoint)
|
||||
SScargo.shuttle = src
|
||||
|
||||
/datum/shuttle/autodock/ferry/supply/short_jump(var/area/destination)
|
||||
if(moving_status != SHUTTLE_IDLE)
|
||||
return
|
||||
|
||||
|
||||
if(isnull(location))
|
||||
return
|
||||
|
||||
if(!destination)
|
||||
destination = get_location_area(!location)
|
||||
if(!origin)
|
||||
origin = get_location_area(location)
|
||||
|
||||
//it would be cool to play a sound here
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
spawn(warmup_time*10)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
if (moving_status == SHUTTLE_IDLE)
|
||||
return //someone cancelled the launch
|
||||
|
||||
|
||||
if (at_station() && forbidden_atoms_check())
|
||||
//cancel the launch because of forbidden atoms. announce over supply channel?
|
||||
moving_status = SHUTTLE_IDLE
|
||||
return
|
||||
|
||||
|
||||
if (!at_station()) //at centcom
|
||||
if(!SScargo.buy()) //Check if the shuttle can be sent
|
||||
moving_status = SHUTTLE_IDLE //Dont move the shuttle
|
||||
|
||||
|
||||
//We pretend it's a long_jump by making the shuttle stay at centcom for the "in-transit" period.
|
||||
var/area/away_area = get_location_area(away_location)
|
||||
var/obj/effect/shuttle_landmark/away_waypoint = get_location_waypoint(away_location)
|
||||
moving_status = SHUTTLE_INTRANSIT
|
||||
|
||||
//If we are at the away_area then we are just pretending to move, otherwise actually do the move
|
||||
if (origin != away_area)
|
||||
move(origin, away_area)
|
||||
|
||||
//If we are at the away_landmark then we are just pretending to move, otherwise actually do the move
|
||||
if (next_location == away_waypoint)
|
||||
attempt_move(away_waypoint)
|
||||
|
||||
//wait ETA here.
|
||||
arrive_time = world.time + SScargo.movetime
|
||||
while (world.time <= arrive_time)
|
||||
sleep(5)
|
||||
|
||||
if (destination != away_area)
|
||||
if (next_location != away_waypoint)
|
||||
//late
|
||||
if (prob(late_chance))
|
||||
sleep(rand(0,max_late_time))
|
||||
|
||||
move(away_area, destination)
|
||||
|
||||
|
||||
attempt_move(destination)
|
||||
|
||||
moving_status = SHUTTLE_IDLE
|
||||
|
||||
|
||||
if (!at_station()) //at centcom
|
||||
SScargo.sell()
|
||||
|
||||
// returns 1 if the supply shuttle should be prevented from moving because it contains forbidden atoms
|
||||
/datum/shuttle/ferry/supply/proc/forbidden_atoms_check()
|
||||
/datum/shuttle/autodock/ferry/supply/proc/forbidden_atoms_check()
|
||||
if (!at_station())
|
||||
return 0 //if badmins want to send mobs or a nuke on the supply shuttle from centcom we don't care
|
||||
|
||||
return SScargo.forbidden_atoms_check(get_location_area())
|
||||
|
||||
/datum/shuttle/ferry/supply/proc/at_station()
|
||||
for(var/area/A in shuttle_area)
|
||||
if(SScargo.forbidden_atoms_check(A))
|
||||
return 1
|
||||
|
||||
/datum/shuttle/autodock/ferry/supply/proc/at_station()
|
||||
return (!location)
|
||||
|
||||
//returns 1 if the shuttle is idle and we can still mess with the cargo shopping list
|
||||
/datum/shuttle/ferry/supply/proc/idle()
|
||||
/datum/shuttle/autodock/ferry/supply/proc/idle()
|
||||
return (moving_status == SHUTTLE_IDLE)
|
||||
|
||||
//returns the ETA in minutes
|
||||
/datum/shuttle/ferry/supply/proc/eta_minutes()
|
||||
/datum/shuttle/autodock/ferry/supply/proc/eta_minutes()
|
||||
var/ticksleft = arrive_time - world.time
|
||||
return round(ticksleft/600,1)
|
||||
|
||||
@@ -1,256 +1,72 @@
|
||||
//This is a holder for things like the Skipjack and Nuke shuttle.
|
||||
/datum/shuttle/multi_shuttle
|
||||
/datum/shuttle/autodock/multi
|
||||
var/list/destination_tags
|
||||
var/list/destinations_cache = list()
|
||||
var/last_cache_rebuild_time = 0
|
||||
category = /datum/shuttle/autodock/multi
|
||||
|
||||
var/cloaked = 1
|
||||
var/at_origin = 1
|
||||
var/returned_home = 0
|
||||
var/move_time = 240
|
||||
var/cooldown = 20
|
||||
var/last_move = 0 //the time at which we last moved
|
||||
/datum/shuttle/autodock/multi/proc/set_destination(var/destination_key, mob/user)
|
||||
if(moving_status != SHUTTLE_IDLE)
|
||||
return
|
||||
next_location = destinations_cache[destination_key]
|
||||
|
||||
/datum/shuttle/autodock/multi/proc/get_destinations()
|
||||
if (last_cache_rebuild_time < SSshuttle.last_landmark_registration_time)
|
||||
build_destinations_cache()
|
||||
return destinations_cache
|
||||
|
||||
/datum/shuttle/autodock/multi/proc/build_destinations_cache()
|
||||
last_cache_rebuild_time = world.time
|
||||
destinations_cache.Cut()
|
||||
for(var/destination_tag in destination_tags)
|
||||
var/obj/effect/shuttle_landmark/landmark = SSshuttle.get_landmark(destination_tag)
|
||||
if(istype(landmark))
|
||||
destinations_cache["[landmark.name]"] = landmark
|
||||
|
||||
//Antag play announcements when they leave/return to their home area
|
||||
/datum/shuttle/autodock/multi/antag
|
||||
warmup_time = 10 SECONDS //replaced the old move cooldown
|
||||
//This variable is type-abused initially: specify the landmark_tag, not the actual landmark.
|
||||
var/obj/effect/shuttle_landmark/home_waypoint
|
||||
|
||||
var/cloaked = TRUE
|
||||
var/returned = FALSE
|
||||
var/announcer
|
||||
var/arrival_message
|
||||
var/departure_message
|
||||
|
||||
var/area/interim
|
||||
var/area/last_departed
|
||||
var/start_location
|
||||
var/last_location
|
||||
var/list/destinations
|
||||
var/list/destination_dock_controller_tags = list() //optional, in case the shuttle has multiple docking ports like the ERT shuttle (even though that isn't a multi_shuttle)
|
||||
var/list/destination_dock_controllers = list()
|
||||
var/list/destination_dock_targets = list()
|
||||
var/area/origin
|
||||
var/return_warning = 0
|
||||
var/start_warning = 0
|
||||
category = /datum/shuttle/autodock/multi/antag
|
||||
|
||||
/datum/shuttle/multi_shuttle/New()
|
||||
/datum/shuttle/autodock/multi/antag/New()
|
||||
..()
|
||||
if(home_waypoint)
|
||||
home_waypoint = SSshuttle.get_landmark(home_waypoint)
|
||||
else
|
||||
home_waypoint = current_location
|
||||
|
||||
/datum/shuttle/autodock/multi/antag/shuttle_moved()
|
||||
if(current_location == home_waypoint)
|
||||
announce_arrival()
|
||||
else if(next_location == home_waypoint)
|
||||
announce_departure()
|
||||
..()
|
||||
|
||||
/datum/shuttle/multi_shuttle/init_docking_controllers()
|
||||
..()
|
||||
for(var/destination in destinations)
|
||||
var/controller_tag = destination_dock_controller_tags[destination]
|
||||
if(!controller_tag)
|
||||
destination_dock_controllers[destination] = docking_controller
|
||||
else
|
||||
var/datum/computer/file/embedded_program/docking/C = locate(controller_tag)
|
||||
/datum/shuttle/autodock/multi/antag/arrived()
|
||||
if(current_location == home_waypoint)
|
||||
returned = TRUE
|
||||
|
||||
if(!istype(C))
|
||||
to_world("<span class='danger'>warning: shuttle with docking tag [controller_tag] could not find it's controller!</span>")
|
||||
else
|
||||
destination_dock_controllers[destination] = C
|
||||
|
||||
//might as well set this up here.
|
||||
if(origin) last_departed = origin
|
||||
last_location = start_location
|
||||
|
||||
/datum/shuttle/multi_shuttle/current_dock_target()
|
||||
return destination_dock_targets[last_location]
|
||||
|
||||
//If they returned home, they wont be able to depart again
|
||||
/datum/shuttle/multi_shuttle/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
|
||||
if(returned_home)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/shuttle/multi_shuttle/move(var/area/origin, var/area/destination)
|
||||
..()
|
||||
last_move = world.time
|
||||
if (destination == src.origin)
|
||||
returned_home = 1
|
||||
docking_controller = destination_dock_controllers[last_location]
|
||||
|
||||
/datum/shuttle/multi_shuttle/proc/announce_departure()
|
||||
/datum/shuttle/autodock/multi/antag/launch(var/user)
|
||||
if(returned)
|
||||
if(user)
|
||||
to_chat(user, SPAN_WARNING("You don't have enough fuel for another launch!"))
|
||||
return //Nada, can't go back.
|
||||
..(user)
|
||||
|
||||
/datum/shuttle/autodock/multi/antag/proc/announce_departure()
|
||||
if(cloaked || isnull(departure_message))
|
||||
return
|
||||
command_announcement.Announce(departure_message, announcer || "[current_map.boss_name]")
|
||||
|
||||
command_announcement.Announce(departure_message,(announcer ? announcer : "[current_map.boss_name]"))
|
||||
|
||||
/datum/shuttle/multi_shuttle/proc/announce_arrival()
|
||||
|
||||
/datum/shuttle/autodock/multi/antag/proc/announce_arrival()
|
||||
if(cloaked || isnull(arrival_message))
|
||||
return
|
||||
|
||||
command_announcement.Announce(arrival_message,(announcer ? announcer : "[current_map.boss_name]"))
|
||||
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi
|
||||
|
||||
icon_screen = "syndishuttle"
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/attack_hand(user as mob)
|
||||
|
||||
if(..(user))
|
||||
return
|
||||
src.add_fingerprint(user)
|
||||
|
||||
var/datum/shuttle/multi_shuttle/MS = shuttle_controller.shuttles[shuttle_tag]
|
||||
if(!istype(MS)) return
|
||||
|
||||
var/dat
|
||||
dat = "<center>[shuttle_tag] Ship Control<hr>"
|
||||
|
||||
|
||||
if(MS.moving_status != SHUTTLE_IDLE)
|
||||
dat += "Location: <font color='red'>Moving</font> <br>"
|
||||
else
|
||||
var/area/areacheck = get_area(src)
|
||||
dat += "Location: [areacheck.name]<br>"
|
||||
|
||||
if((MS.last_move + MS.cooldown*10) > world.time)
|
||||
dat += "<font color='red'>Engines charging.</font><br>"
|
||||
else if (MS.returned_home)
|
||||
dat += "<font color='red'>Engines offline.</font><br>"
|
||||
else
|
||||
dat += "<font color='green'>Engines ready.</font><br>"
|
||||
dat += "<br><b><A href='?src=\ref[src];toggle_cloak=[1]'>Toggle cloaking field</A></b><br>"
|
||||
dat += "<b><A href='?src=\ref[src];move_multi=[1]'>Move ship</A></b><br>"
|
||||
dat += "<b><A href='?src=\ref[src];start=[1]'>Return to base</A></b></center>"
|
||||
|
||||
//Docking
|
||||
dat += "<center><br><br>"
|
||||
if(MS.skip_docking_checks())
|
||||
dat += "Docking Status: <font color='grey'>Not in use.</font>"
|
||||
else
|
||||
var/override_en = MS.docking_controller.override_enabled
|
||||
var/docking_status = MS.docking_controller.get_docking_status()
|
||||
|
||||
dat += "Docking Status: "
|
||||
switch(docking_status)
|
||||
if("undocked")
|
||||
dat += "<font color='[override_en? "red" : "grey"]'>Undocked</font>"
|
||||
if("docking")
|
||||
dat += "<font color='[override_en? "red" : "yellow"]'>Docking</font>"
|
||||
if("undocking")
|
||||
dat += "<font color='[override_en? "red" : "yellow"]'>Undocking</font>"
|
||||
if("docked")
|
||||
dat += "<font color='[override_en? "red" : "green"]'>Docked</font>"
|
||||
|
||||
if(override_en) dat += " <font color='red'>(Override Enabled)</font>"
|
||||
|
||||
dat += ". <A href='?src=\ref[src];refresh=[1]'>\[Refresh\]</A><br><br>"
|
||||
|
||||
switch(docking_status)
|
||||
if("undocked")
|
||||
dat += "<b><A href='?src=\ref[src];dock_command=[1]'>Dock</A></b>"
|
||||
if("docked")
|
||||
dat += "<b><A href='?src=\ref[src];undock_command=[1]'>Undock</A></b>"
|
||||
dat += "</center>"
|
||||
|
||||
user << browse("[dat]", "window=[shuttle_tag]shuttlecontrol;size=300x600")
|
||||
|
||||
//check if we're undocked, give option to force launch
|
||||
/obj/machinery/computer/shuttle_control/proc/check_docking(datum/shuttle/multi_shuttle/MS)
|
||||
if(MS.skip_docking_checks() || MS.docking_controller.can_launch())
|
||||
return 1
|
||||
|
||||
var/choice = alert("The shuttle is currently docked! Please undock before continuing.","Error","Cancel","Force Launch")
|
||||
if(choice == "Cancel")
|
||||
return 0
|
||||
|
||||
choice = alert("Forcing a shuttle launch while docked may result in severe injury, death and/or damage to property. Are you sure you wish to continue?", "Force Launch", "Force Launch", "Cancel")
|
||||
if(choice == "Cancel")
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/shuttle_control/multi/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
usr.set_machine(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
var/datum/shuttle/multi_shuttle/MS = shuttle_controller.shuttles[shuttle_tag]
|
||||
if(!istype(MS))
|
||||
return
|
||||
|
||||
if(href_list["refresh"])
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if (MS.moving_status != SHUTTLE_IDLE)
|
||||
to_chat(usr, "<span class='notice'>[shuttle_tag] vessel is moving.</span>")
|
||||
return
|
||||
|
||||
if(href_list["dock_command"])
|
||||
MS.dock()
|
||||
return
|
||||
|
||||
if(href_list["undock_command"])
|
||||
MS.undock()
|
||||
return
|
||||
|
||||
if(href_list["start"])
|
||||
if(MS.at_origin)
|
||||
to_chat(usr, "<span class='warning'>You are already at your home base.</span>")
|
||||
return
|
||||
|
||||
if((MS.last_move + MS.cooldown*10) > world.time)
|
||||
to_chat(usr, "<span class='warning'>The ship's drive is inoperable while the engines are charging.</span>")
|
||||
return
|
||||
|
||||
if(!check_docking(MS))
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(!MS.return_warning)
|
||||
to_chat(usr, "<span class='warning'>Returning to your home base will end your mission. If you are sure, press the button again.</span>")
|
||||
MS.return_warning = 1
|
||||
return
|
||||
|
||||
MS.long_jump(MS.last_departed,MS.origin,MS.interim,MS.move_time)
|
||||
MS.last_departed = MS.origin
|
||||
MS.last_location = MS.start_location
|
||||
MS.at_origin = 1
|
||||
|
||||
if(href_list["toggle_cloak"])
|
||||
|
||||
MS.cloaked = !MS.cloaked
|
||||
to_chat(usr, "<span class='warning'>Ship stealth systems have been [(MS.cloaked ? "activated. The station will not" : "deactivated. The station will")] be warned of our arrival.</span>")
|
||||
|
||||
if(href_list["move_multi"])
|
||||
if(MS.returned_home)
|
||||
to_chat(usr, "<span class='warning'>The ship's drive is offline.</span>")
|
||||
return
|
||||
|
||||
if(MS.at_origin && !MS.start_warning)
|
||||
MS.start_warning = 1
|
||||
to_chat(usr, "<span class='warning'>You can only make one roundtrip between the target and the base. If you are sure you want to depart, press the button again.</span>")
|
||||
return
|
||||
|
||||
if((MS.last_move + MS.cooldown*10) > world.time)
|
||||
to_chat(usr, "<span class='warning'>The ship's drive is inoperable while the engines are charging.</span>")
|
||||
return
|
||||
|
||||
if(!check_docking(MS))
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
var/choice = input("Select a destination.") as null|anything in MS.destinations
|
||||
if(!choice) return
|
||||
|
||||
to_chat(usr, "<span class='notice'>[shuttle_tag] main computer received message.</span>")
|
||||
|
||||
if(MS.at_origin)
|
||||
MS.announce_arrival()
|
||||
MS.last_departed = MS.origin
|
||||
MS.at_origin = 0
|
||||
|
||||
|
||||
MS.long_jump(MS.last_departed, MS.destinations[choice], MS.interim, MS.move_time)
|
||||
MS.last_departed = MS.destinations[choice]
|
||||
MS.last_location = choice
|
||||
return
|
||||
|
||||
else if(choice == MS.origin)
|
||||
|
||||
MS.announce_departure()
|
||||
|
||||
MS.short_jump(MS.last_departed, MS.destinations[choice])
|
||||
MS.last_departed = MS.destinations[choice]
|
||||
MS.last_location = choice
|
||||
|
||||
updateUsrDialog()
|
||||
command_announcement.Announce(arrival_message, announcer || "[current_map.boss_name]")
|
||||
|
||||
Reference in New Issue
Block a user