Adds shuttle controller

Moves all ferry shuttle processing into one place: the new shuttle
controller.

Also cleans up the emergency shuttle controller a bit more and fixes
multi-shuttle cooldown.
This commit is contained in:
mwerezak
2014-06-23 11:57:32 -04:00
parent 81f0f868b4
commit 9e0562b16c
12 changed files with 542 additions and 543 deletions

View File

@@ -1,287 +1,220 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
// Controls the emergency shuttle
var/global/datum/shuttle_controller/shuttle_controller
// these define the time taken for the shuttle to get to SS13
// and the time before it leaves again
#define SHUTTLE_PREPTIME 300 // 5 minutes = 300 seconds - after this time, the shuttle cannot be recalled
#define SHUTTLE_LEAVETIME 180 // 3 minutes = 180 seconds - the duration for which the shuttle will wait at the station
#define SHUTTLE_TRANSIT_DURATION 300 // 5 minutes = 300 seconds - how long it takes for the shuttle to get to the station
#define SHUTTLE_TRANSIT_DURATION_RETURN 120 // 2 minutes = 120 seconds - for some reason it takes less time to come back, go figure.
/datum/shuttle_controller
var/list/shuttles //maps shuttle tags to shuttle datums, so that they can be looked up.
var/list/process_shuttles //simple list of shuttles, for processing
var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
/datum/shuttle_controller/proc/process()
//process ferry shuttles
for (var/datum/shuttle/ferry/shuttle in process_shuttles)
if (shuttle.in_use)
shuttle.process()
/datum/shuttle_controller/emergency_shuttle
var/datum/shuttle/ferry/emergency/shuttle
var/list/escape_pods
/datum/shuttle_controller/New()
shuttles = list()
process_shuttles = list()
var/datum/shuttle/ferry/shuttle
var/launch_time //the time at which the shuttle will be launched
var/auto_recall = 0 //if set, the shuttle will be auto-recalled
var/auto_recall_time //the time at which the shuttle will be auto-recalled
var/evac = 0 //1 = emergency evacuation, 0 = crew transfer
var/wait_for_launch = 0 //if the shuttle is waiting to launch
// Escape shuttle and pods
shuttle = new/datum/shuttle/ferry/emergency()
shuttle.location = 1
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/shuttle/escape/centcom)
shuttle.area_station = locate(/area/shuttle/escape/station)
shuttle.area_transition = locate(/area/shuttle/escape/transit)
shuttle.travel_time = 300
//shuttle.docking_controller_tag = "supply_shuttle"
//shuttle.dock_target_station = "cargo_bay"
shuttles["Escape"] = shuttle
process_shuttles += shuttle
var/deny_shuttle = 0 //allows admins to prevent the shuttle from being called
var/departed = 0 //if the shuttle has left the station at least once
/datum/shuttle_controller/emergency_shuttle/proc/setup_pods()
escape_pods = list()
//give the emergency shuttle controller it's shuttle
emergency_shuttle.shuttle = shuttle
emergency_shuttle.setup_pods()
process_shuttles += emergency_shuttle.escape_pods
var/datum/shuttle/ferry/escape_pod/pod
// Supply shuttle
shuttle = new/datum/shuttle/ferry/supply()
shuttle.location = 1
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/supply/dock)
shuttle.area_station = locate(/area/supply/station)
shuttle.docking_controller_tag = "supply_shuttle"
shuttle.dock_target_station = "cargo_bay"
shuttles["Supply"] = shuttle
process_shuttles += shuttle
pod = new()
pod.location = 0
pod.warmup_time = 0
pod.area_station = locate(/area/shuttle/escape_pod1/station)
pod.area_offsite = locate(/area/shuttle/escape_pod1/centcom)
pod.area_transition = locate(/area/shuttle/escape_pod1/transit)
pod.travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
escape_pods += pod
supply_controller.shuttle = shuttle
pod = new()
pod.location = 0
pod.warmup_time = 0
pod.area_station = locate(/area/shuttle/escape_pod2/station)
pod.area_offsite = locate(/area/shuttle/escape_pod2/centcom)
pod.area_transition = locate(/area/shuttle/escape_pod2/transit)
pod.travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
escape_pods += pod
// Admin shuttles.
shuttle = new()
shuttle.location = 1
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/shuttle/transport1/centcom)
shuttle.area_station = locate(/area/shuttle/transport1/station)
shuttle.docking_controller_tag = "centcom_shuttle"
shuttle.dock_target_station = "centcom_shuttle_dock_airlock"
shuttle.dock_target_offsite = "centcom_shuttle_bay"
shuttles["Centcom"] = shuttle
process_shuttles += shuttle
shuttle = new()
shuttle.location = 1
shuttle.warmup_time = 10 //want some warmup time so people can cancel.
shuttle.area_offsite = locate(/area/shuttle/administration/centcom)
shuttle.area_station = locate(/area/shuttle/administration/station)
shuttle.docking_controller_tag = "admin_shuttle"
shuttle.dock_target_station = "admin_shuttle_dock_airlock"
shuttle.dock_target_offsite = "admin_shuttle_bay"
shuttles["Administration"] = shuttle
process_shuttles += shuttle
shuttle = new()
shuttle.area_offsite = locate(/area/shuttle/alien/base)
shuttle.area_station = locate(/area/shuttle/alien/mine)
shuttles["Alien"] = shuttle
//process_shuttles += shuttle //don't need to process this. It can only be moved using admin magic anyways.
// Public shuttles
shuttle = new()
shuttle.location = 1
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/shuttle/constructionsite/site)
shuttle.area_station = locate(/area/shuttle/constructionsite/station)
shuttle.docking_controller_tag = "engineering_shuttle"
shuttle.dock_target_station = "engineering_dock_airlock"
shuttle.dock_target_offsite = "engineering_station_airlock"
shuttles["Engineering"] = shuttle
process_shuttles += shuttle
shuttle = new()
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/shuttle/mining/outpost)
shuttle.area_station = locate(/area/shuttle/mining/station)
shuttle.docking_controller_tag = "mining_shuttle"
shuttle.dock_target_station = "mining_dock_airlock"
shuttle.dock_target_offsite = "mining_outpost_airlock"
shuttles["Mining"] = shuttle
process_shuttles += shuttle
shuttle = new()
shuttle.warmup_time = 10
shuttle.area_offsite = locate(/area/shuttle/research/outpost)
shuttle.area_station = locate(/area/shuttle/research/station)
shuttle.docking_controller_tag = "research_shuttle"
shuttle.dock_target_station = "research_dock_airlock"
shuttle.dock_target_offsite = "research_outpost_dock"
shuttles["Research"] = shuttle
process_shuttles += shuttle
// ERT Shuttle
var/datum/shuttle/ferry/multidock/specops/ERT = new()
ERT.location = 0
ERT.warmup_time = 10
ERT.area_offsite = locate(/area/shuttle/specops/station) //centcom is the home station, the Exodus is offsite
ERT.area_station = locate(/area/shuttle/specops/centcom)
ERT.docking_controller_tag = "specops_shuttle_port"
ERT.docking_controller_tag_station = "specops_shuttle_port"
ERT.docking_controller_tag_offsite = "specops_shuttle_fore"
ERT.dock_target_station = "specops_centcom_dock"
ERT.dock_target_offsite = "specops_dock_airlock"
shuttles["Special Operations"] = ERT
process_shuttles += ERT
//Vox Shuttle.
var/datum/shuttle/multi_shuttle/VS = new/datum/shuttle/multi_shuttle()
VS.origin = /area/shuttle/vox/station
VS.destinations = list(
"Fore Starboard Solars" = /area/vox_station/northeast_solars,
"Fore Port Solars" = /area/vox_station/northwest_solars,
"Aft Starboard Solars" = /area/vox_station/southeast_solars,
"Aft Port Solars" = /area/vox_station/southwest_solars,
"Mining asteroid" = /area/vox_station/mining
)
VS.announcer = "NSV Icarus"
VS.arrival_message = "Attention, Exodus, we just tracked a small target bypassing our defensive perimeter. Can't fire on it without hitting the station - you've got incoming visitors, like it or not."
VS.departure_message = "Your guests are pulling away, Exodus - moving too fast for us to draw a bead on them. Looks like they're heading out of the system at a rapid clip."
VS.interim = /area/vox_station/transit
VS.warmup_time = 10
shuttles["Vox Skipjack"] = VS
//Nuke Ops shuttle.
var/datum/shuttle/multi_shuttle/MS = new/datum/shuttle/multi_shuttle()
MS.origin = /area/syndicate_station/start
MS.destinations = list(
"Northwest of the station" = /area/syndicate_station/northwest,
"North of the station" = /area/syndicate_station/north,
"Northeast of the station" = /area/syndicate_station/northeast,
"Southwest of the station" = /area/syndicate_station/southwest,
"South of the station" = /area/syndicate_station/south,
"Southeast of the station" = /area/syndicate_station/southeast,
"Telecomms Satellite" = /area/syndicate_station/commssat,
"Mining Asteroid" = /area/syndicate_station/mining
)
MS.announcer = "NSV Icarus"
MS.arrival_message = "Attention, Exodus, you have a large signature approaching the station - looks unarmed to surface scans. We're too far out to intercept - brace for visitors."
MS.departure_message = "Your visitors are on their way out of the system, Exodus, burning delta-v like it's nothing. Good riddance."
MS.interim = /area/syndicate_station/transit
MS.warmup_time = 10
shuttles["Syndicate"] = MS
//This is called by gameticker after all the machines and radio frequencies have been properly initialized
/datum/shuttle_controller/proc/setup_shuttle_docks()
var/datum/shuttle/shuttle
var/datum/shuttle/ferry/multidock/multidock
var/list/dock_controller_map = list() //so we only have to iterate once through each list
pod = new()
pod.location = 0
pod.warmup_time = 0
pod.area_station = locate(/area/shuttle/escape_pod3/station)
pod.area_offsite = locate(/area/shuttle/escape_pod3/centcom)
pod.area_transition = locate(/area/shuttle/escape_pod3/transit)
pod.travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
escape_pods += pod
//multidock shuttles
var/list/dock_controller_map_station = list()
var/list/dock_controller_map_offsite = list()
for (var/shuttle_tag in shuttles)
shuttle = shuttles[shuttle_tag]
if (shuttle.docking_controller_tag)
dock_controller_map[shuttle.docking_controller_tag] = shuttle
if (istype(shuttle, /datum/shuttle/ferry/multidock))
multidock = shuttle
dock_controller_map_station[multidock.docking_controller_tag_station] = multidock
dock_controller_map_offsite[multidock.docking_controller_tag_offsite] = multidock
//search for the controllers, if we have one.
if (dock_controller_map.len)
for (var/obj/machinery/embedded_controller/radio/C in machines) //only radio controllers are supported at the moment
if (istype(C.program, /datum/computer/file/embedded_program/docking))
if (C.id_tag in dock_controller_map)
shuttle = dock_controller_map[C.id_tag]
shuttle.docking_controller = C.program
dock_controller_map -= C.id_tag
if (C.id_tag in dock_controller_map_station)
multidock = dock_controller_map_station[C.id_tag]
if (istype(multidock))
multidock.docking_controller_station = C.program
dock_controller_map_station -= C.id_tag
if (C.id_tag in dock_controller_map_offsite)
multidock = dock_controller_map_offsite[C.id_tag]
if (istype(multidock))
multidock.docking_controller_offsite = C.program
dock_controller_map_offsite -= C.id_tag
//There is no pod 4, apparently.
//sanity check
if (dock_controller_map.len || dock_controller_map_station.len || dock_controller_map_offsite.len)
var/dat = ""
for (var/dock_tag in dock_controller_map + dock_controller_map_station + dock_controller_map_offsite)
dat += "\"[dock_tag]\", "
world << "/red /b warning: shuttles with docking tags [dat] could not find their controllers!"
pod = new()
pod.location = 0
pod.warmup_time = 0
pod.area_station = locate(/area/shuttle/escape_pod5/station)
pod.area_offsite = locate(/area/shuttle/escape_pod5/centcom)
pod.area_transition = locate(/area/shuttle/escape_pod5/transit)
pod.travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
escape_pods += pod
/datum/shuttle_controller/emergency_shuttle/proc/process()
if (wait_for_launch)
if (auto_recall && world.time >= auto_recall_time)
recall()
if (world.time >= launch_time) //time to launch the shuttle
wait_for_launch = 0
//set the travel time
if (!shuttle.location) //leaving from the station
//launch the pods!
for (var/datum/shuttle/ferry/escape_pod/pod in escape_pods)
pod.launch(src)
shuttle.travel_time = SHUTTLE_TRANSIT_DURATION_RETURN
else
shuttle.travel_time = SHUTTLE_TRANSIT_DURATION
shuttle.launch(src)
//process the shuttles
if (shuttle.in_use)
shuttle.process_shuttle()
for (var/datum/shuttle/ferry/escape_pod/pod in escape_pods)
if (pod.in_use)
pod.process_shuttle()
//called when the shuttle has arrived.
/datum/shuttle_controller/emergency_shuttle/proc/shuttle_arrived()
if (!shuttle.location) //at station
launch_time = world.time + SHUTTLE_LEAVETIME*10
wait_for_launch = 1 //get ready to return
//so we don't have emergency_shuttle.shuttle.location everywhere
/datum/shuttle_controller/emergency_shuttle/proc/location()
if (!shuttle)
return 1 //if we dont have a shuttle datum, just act like it's at centcom
return shuttle.location
//calls the shuttle for an emergency evacuation
/datum/shuttle_controller/emergency_shuttle/proc/call_evac()
if(!can_call()) return
//set the launch timer
launch_time = world.time + get_shuttle_prep_time()*10
auto_recall_time = rand(world.time + 300, launch_time - 300)
wait_for_launch = 1
evac = 1
captain_announce("An emergency evacuation shuttle has been called. It will arrive in approximately [round(estimate_arrival_time()/60)] minutes.")
world << sound('sound/AI/shuttlecalled.ogg')
for(var/area/A in world)
if(istype(A, /area/hallway))
A.readyalert()
//calls the shuttle for a routine crew transfer
/datum/shuttle_controller/emergency_shuttle/proc/call_transfer()
if(!can_call()) return
//set the launch timer
launch_time = world.time + get_shuttle_prep_time()
auto_recall_time = rand(world.time + 300, launch_time - 300)
wait_for_launch = 1
captain_announce("A crew transfer has been initiated. The shuttle has been called. It will arrive in [round(estimate_arrival_time()/60)] minutes.")
//recalls the shuttle
/datum/shuttle_controller/emergency_shuttle/proc/recall()
if (!can_recall()) return
wait_for_launch = 0
shuttle.cancel_launch(src)
if (evac)
captain_announce("The emergency shuttle has been recalled.")
world << sound('sound/AI/shuttlerecalled.ogg')
for(var/area/A in world)
if(istype(A, /area/hallway))
A.readyreset()
evac = 0
else
captain_announce("The scheduled crew transfer has been cancelled.")
/datum/shuttle_controller/emergency_shuttle/proc/can_call()
if (deny_shuttle)
return 0
if (shuttle.moving_status != SHUTTLE_IDLE || !shuttle.location) //must be idle at centcom
return 0
if (wait_for_launch) //already launching
return 0
return 1
//this only returns 0 if it would absolutely make no sense to recall
//e.g. the shuttle is already at the station or wasn't called to begin with
//other reasons for the shuttle not being recallable should be handled elsewhere
/datum/shuttle_controller/emergency_shuttle/proc/can_recall()
if (shuttle.moving_status == SHUTTLE_INTRANSIT) //if the shuttle is already in transit then it's too late
return 0
if (!shuttle.location) //already at the station.
return 0
if (!wait_for_launch) //we weren't going anywhere, anyways...
return 0
return 1
/datum/shuttle_controller/emergency_shuttle/proc/get_shuttle_prep_time()
// During mutiny rounds, the shuttle takes twice as long.
if(ticker && istype(ticker.mode,/datum/game_mode/mutiny))
return SHUTTLE_PREPTIME * 3 //15 minutes
return SHUTTLE_PREPTIME
/*
These procs are not really used by the controller itself, but are for other parts of the
game whose logic depends on the emergency shuttle.
*/
//returns the time left until the shuttle arrives at it's destination, in seconds
/datum/shuttle_controller/emergency_shuttle/proc/estimate_arrival_time()
var/eta
if (isnull(shuttle.jump_time))
eta = launch_time + shuttle.travel_time
else
eta = shuttle.jump_time + shuttle.travel_time
return (eta - world.time)/10
//returns the time left until the shuttle launches, in seconds
/datum/shuttle_controller/emergency_shuttle/proc/estimate_launch_time()
return (launch_time - world.time)/10
/datum/shuttle_controller/emergency_shuttle/proc/has_eta()
return (wait_for_launch || shuttle.moving_status != SHUTTLE_IDLE)
//returns 1 if the shuttle has gone to the station and come back at least once,
//used for game completion checking purposes
/datum/shuttle_controller/emergency_shuttle/proc/returned()
return (departed && shuttle.moving_status != SHUTTLE_IDLE && shuttle.location) //we've gone to the station at least once, no longer in transit and are idle back at centcom
//returns 1 if the shuttle is not idle at centcom
/datum/shuttle_controller/emergency_shuttle/proc/online()
if (!shuttle.location) //not at centcom
return 1
if (wait_for_launch || shuttle.moving_status != SHUTTLE_IDLE)
return 1
return 0
//returns 1 if the shuttle is currently in transit (or just leaving) to the station
/datum/shuttle_controller/emergency_shuttle/proc/going_to_station()
return (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
//returns 1 if the shuttle is currently in transit (or just leaving) to centcom
/datum/shuttle_controller/emergency_shuttle/proc/going_to_centcom()
return (shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
//returns 1 if the shuttle is docked at the station and waiting to leave
/datum/shuttle_controller/emergency_shuttle/proc/waiting_to_leave()
if (shuttle.location)
return 0 //not at station
if (!wait_for_launch)
return 0 //not going anywhere
if (shuttle.moving_status != SHUTTLE_IDLE)
return 0 //shuttle is doing stuff
return 1
/*
Some slapped-together star effects for maximum spess immershuns. Basically consists of a
spawner, an ender, and bgstar. Spawners create bgstars, bgstars shoot off into a direction
until they reach a starender.
*/
/obj/effect/bgstar
name = "star"
var/speed = 10
var/direction = SOUTH
layer = 2 // TURF_LAYER
/obj/effect/bgstar/New()
..()
pixel_x += rand(-2,30)
pixel_y += rand(-2,30)
var/starnum = pick("1", "1", "1", "2", "3", "4")
icon_state = "star"+starnum
speed = rand(2, 5)
/obj/effect/bgstar/proc/startmove()
while(src)
sleep(speed)
step(src, direction)
for(var/obj/effect/starender/E in loc)
del(src)
/obj/effect/starender
invisibility = 101
/obj/effect/starspawner
invisibility = 101
var/spawndir = SOUTH
var/spawning = 0
/obj/effect/starspawner/West
spawndir = WEST
/obj/effect/starspawner/proc/startspawn()
spawning = 1
while(spawning)
sleep(rand(2, 30))
var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z))
S.direction = spawndir
spawn()
S.startmove()
//makes all shuttles docked to something at round start go into the docked state
for (var/shuttle_tag in shuttles)
shuttle = shuttles[shuttle_tag]
shuttle.dock()