mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Merge branch 'master' into upstream-merge-6762
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
//Config stuff
|
||||
#define SUPPLY_DOCKZ 2 //Z-level of the Dock.
|
||||
#define SUPPLY_STATIONZ 1 //Z-level of the Station.
|
||||
#define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station
|
||||
#define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock
|
||||
|
||||
// TODO - Refactor to use the Supply Subsystem (SSsupply)
|
||||
|
||||
//Supply packs are in /code/datums/supplypacks
|
||||
//Computers are in /code/game/machinery/computer/supply.dm
|
||||
@@ -43,7 +40,7 @@ var/datum/controller/supply/supply_controller = new()
|
||||
var/list/adm_export_history = list() // Complete history of all crates sent back on the shuttle, for admin use
|
||||
//shuttle movement
|
||||
var/movetime = 1200
|
||||
var/datum/shuttle/ferry/supply/shuttle
|
||||
var/datum/shuttle/autodock/ferry/supply/shuttle
|
||||
var/list/material_points_conversion = list( // Any materials not named in this list are worth 0 points
|
||||
"phoron" = 5,
|
||||
"platinum" = 5
|
||||
@@ -90,83 +87,98 @@ var/datum/controller/supply/supply_controller = new()
|
||||
|
||||
//Selling
|
||||
/datum/controller/supply/proc/sell()
|
||||
var/area/area_shuttle = shuttle.get_location_area()
|
||||
if(!area_shuttle)
|
||||
return
|
||||
// Loop over each area in the supply shuttle
|
||||
for(var/area/subarea in shuttle.shuttle_area)
|
||||
callHook("sell_shuttle", list(subarea));
|
||||
for(var/atom/movable/MA in subarea)
|
||||
if(MA.anchored)
|
||||
continue
|
||||
|
||||
callHook("sell_shuttle", list(area_shuttle));
|
||||
var/datum/exported_crate/EC = new /datum/exported_crate()
|
||||
EC.name = "\proper[MA.name]"
|
||||
EC.value = 0
|
||||
EC.contents = list()
|
||||
var/base_value = 0
|
||||
|
||||
for(var/atom/movable/MA in area_shuttle)
|
||||
if(MA.anchored)
|
||||
continue
|
||||
// Must be in a crate!
|
||||
if(istype(MA,/obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/CR = MA
|
||||
callHook("sell_crate", list(CR, subarea))
|
||||
|
||||
var/datum/exported_crate/EC = new /datum/exported_crate()
|
||||
EC.name = "\proper[MA.name]"
|
||||
EC.value = 0
|
||||
EC.contents = list()
|
||||
var/base_value = 0
|
||||
points += CR.points_per_crate
|
||||
if(CR.points_per_crate)
|
||||
base_value = CR.points_per_crate
|
||||
var/find_slip = 1
|
||||
|
||||
// Must be in a crate!
|
||||
if(istype(MA,/obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/CR = MA
|
||||
callHook("sell_crate", list(CR, area_shuttle))
|
||||
for(var/atom/A in CR)
|
||||
EC.contents[++EC.contents.len] = list(
|
||||
"object" = "\proper[A.name]",
|
||||
"value" = 0,
|
||||
"quantity" = 1
|
||||
)
|
||||
|
||||
points += CR.points_per_crate
|
||||
if(CR.points_per_crate)
|
||||
base_value = CR.points_per_crate
|
||||
var/find_slip = 1
|
||||
// Sell manifests
|
||||
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
|
||||
var/obj/item/weapon/paper/manifest/slip = A
|
||||
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
|
||||
points += points_per_slip
|
||||
EC.contents[EC.contents.len]["value"] = points_per_slip
|
||||
find_slip = 0
|
||||
continue
|
||||
|
||||
for(var/atom/A in CR)
|
||||
EC.contents[++EC.contents.len] = list(
|
||||
"object" = "\proper[A.name]",
|
||||
"value" = 0,
|
||||
"quantity" = 1
|
||||
// Sell phoron and platinum
|
||||
if(istype(A, /obj/item/stack))
|
||||
var/obj/item/stack/P = A
|
||||
if(material_points_conversion[P.get_material_name()])
|
||||
EC.contents[EC.contents.len]["value"] = P.get_amount() * material_points_conversion[P.get_material_name()]
|
||||
EC.contents[EC.contents.len]["quantity"] = P.get_amount()
|
||||
EC.value += EC.contents[EC.contents.len]["value"]
|
||||
|
||||
//Sell spacebucks
|
||||
if(istype(A, /obj/item/weapon/spacecash))
|
||||
var/obj/item/weapon/spacecash/cashmoney = A
|
||||
EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money
|
||||
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
|
||||
EC.value += EC.contents[EC.contents.len]["value"]
|
||||
|
||||
|
||||
|
||||
// Make a log of it, but it wasn't shipped properly, and so isn't worth anything
|
||||
else
|
||||
EC.contents = list(
|
||||
"error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement."
|
||||
)
|
||||
|
||||
// Sell manifests
|
||||
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
|
||||
var/obj/item/weapon/paper/manifest/slip = A
|
||||
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
|
||||
points += points_per_slip
|
||||
EC.contents[EC.contents.len]["value"] = points_per_slip
|
||||
find_slip = 0
|
||||
exported_crates += EC
|
||||
points += EC.value
|
||||
EC.value += base_value
|
||||
|
||||
// Duplicate the receipt for the admin-side log
|
||||
var/datum/exported_crate/adm = new()
|
||||
adm.name = EC.name
|
||||
adm.value = EC.value
|
||||
adm.contents = deepCopyList(EC.contents)
|
||||
adm_export_history += adm
|
||||
|
||||
qdel(MA)
|
||||
|
||||
/datum/controller/supply/proc/get_clear_turfs()
|
||||
var/list/clear_turfs = list()
|
||||
|
||||
for(var/area/subarea in shuttle.shuttle_area)
|
||||
for(var/turf/T in subarea)
|
||||
if(T.density)
|
||||
continue
|
||||
var/occupied = 0
|
||||
for(var/atom/A in T.contents)
|
||||
if(!A.simulated)
|
||||
continue
|
||||
occupied = 1
|
||||
break
|
||||
if(!occupied)
|
||||
clear_turfs += T
|
||||
|
||||
// Sell phoron and platinum
|
||||
if(istype(A, /obj/item/stack))
|
||||
var/obj/item/stack/P = A
|
||||
if(material_points_conversion[P.get_material_name()])
|
||||
EC.contents[EC.contents.len]["value"] = P.get_amount() * material_points_conversion[P.get_material_name()]
|
||||
EC.contents[EC.contents.len]["quantity"] = P.get_amount()
|
||||
EC.value += EC.contents[EC.contents.len]["value"]
|
||||
|
||||
//Sell spacebucks
|
||||
if(istype(A, /obj/item/weapon/spacecash))
|
||||
var/obj/item/weapon/spacecash/cashmoney = A
|
||||
EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money
|
||||
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
|
||||
EC.value += EC.contents[EC.contents.len]["value"]
|
||||
|
||||
|
||||
|
||||
// Make a log of it, but it wasn't shipped properly, and so isn't worth anything
|
||||
else
|
||||
EC.contents = list(
|
||||
"error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement."
|
||||
)
|
||||
|
||||
exported_crates += EC
|
||||
points += EC.value
|
||||
EC.value += base_value
|
||||
|
||||
// Duplicate the receipt for the admin-side log
|
||||
var/datum/exported_crate/adm = new()
|
||||
adm.name = EC.name
|
||||
adm.value = EC.value
|
||||
adm.contents = deepCopyList(EC.contents)
|
||||
adm_export_history += adm
|
||||
|
||||
qdel(MA)
|
||||
return clear_turfs
|
||||
|
||||
//Buying
|
||||
/datum/controller/supply/proc/buy()
|
||||
@@ -177,26 +189,9 @@ var/datum/controller/supply/supply_controller = new()
|
||||
|
||||
if(!shoppinglist.len)
|
||||
return
|
||||
|
||||
var/orderedamount = shoppinglist.len
|
||||
|
||||
var/area/area_shuttle = shuttle.get_location_area()
|
||||
if(!area_shuttle)
|
||||
return
|
||||
|
||||
var/list/clear_turfs = list()
|
||||
|
||||
for(var/turf/T in area_shuttle)
|
||||
if(T.density)
|
||||
continue
|
||||
var/contcount
|
||||
for(var/atom/A in T.contents)
|
||||
if(!A.simulated)
|
||||
continue
|
||||
contcount++
|
||||
if(contcount)
|
||||
continue
|
||||
clear_turfs += T
|
||||
var/list/clear_turfs = get_clear_turfs()
|
||||
|
||||
for(var/datum/supply_order/SO in shoppinglist)
|
||||
if(!clear_turfs.len)
|
||||
|
||||
@@ -31,6 +31,7 @@ var/list/gamemode_cache = list()
|
||||
var/allow_admin_jump = 1 // allows admin jumping
|
||||
var/allow_admin_spawning = 1 // allows admin item spawning
|
||||
var/allow_admin_rev = 1 // allows admin revives
|
||||
var/pregame_time = 180 // pregame time in seconds
|
||||
var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
|
||||
var/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
|
||||
var/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called
|
||||
@@ -420,6 +421,9 @@ var/list/gamemode_cache = list()
|
||||
if ("default_no_vote")
|
||||
config.vote_no_default = 1
|
||||
|
||||
if ("pregame_time")
|
||||
config.pregame_time = text2num(value)
|
||||
|
||||
if ("vote_delay")
|
||||
config.vote_delay = text2num(value)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
|
||||
/datum/emergency_shuttle_controller
|
||||
var/datum/shuttle/ferry/emergency/shuttle
|
||||
var/datum/shuttle/autodock/ferry/emergency/shuttle // Set in shuttle_emergency.dm TODO - is it really?
|
||||
var/list/escape_pods
|
||||
|
||||
var/launch_time //the time at which the shuttle will be launched
|
||||
@@ -36,8 +36,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
if (!shuttle.location) //leaving from the station
|
||||
//launch the pods!
|
||||
for (var/EP in escape_pods)
|
||||
var/datum/shuttle/ferry/escape_pod/pod
|
||||
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
|
||||
var/datum/shuttle/autodock/ferry/escape_pod/pod
|
||||
if(istype(escape_pods[EP], /datum/shuttle/autodock/ferry/escape_pod))
|
||||
pod = escape_pods[EP]
|
||||
else
|
||||
continue
|
||||
@@ -63,8 +63,8 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
//arm the escape pods
|
||||
if (evac)
|
||||
for (var/EP in escape_pods)
|
||||
var/datum/shuttle/ferry/escape_pod/pod
|
||||
if(istype(escape_pods[EP], /datum/shuttle/ferry/escape_pod))
|
||||
var/datum/shuttle/autodock/ferry/escape_pod/pod
|
||||
if(istype(escape_pods[EP], /datum/shuttle/autodock/ferry/escape_pod))
|
||||
pod = escape_pods[EP]
|
||||
else
|
||||
continue
|
||||
@@ -215,11 +215,11 @@ var/global/datum/emergency_shuttle_controller/emergency_shuttle
|
||||
|
||||
//returns 1 if the shuttle is currently in transit (or just leaving) to the station
|
||||
/datum/emergency_shuttle_controller/proc/going_to_station()
|
||||
return (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
return shuttle && (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
|
||||
//returns 1 if the shuttle is currently in transit (or just leaving) to centcom
|
||||
/datum/emergency_shuttle_controller/proc/going_to_centcom()
|
||||
return (shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
return shuttle && (shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
|
||||
|
||||
/datum/emergency_shuttle_controller/proc/get_status_panel_eta()
|
||||
|
||||
@@ -25,7 +25,7 @@ SUBSYSTEM_DEF(ai)
|
||||
// var/mob/living/L = currentrun[currentrun.len]
|
||||
var/datum/ai_holder/A = currentrun[currentrun.len]
|
||||
--currentrun.len
|
||||
if(!A || QDELETED(A)) // Doesn't exist or won't exist soon.
|
||||
if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
|
||||
continue
|
||||
if(times_fired % 4 == 0 && A.holder.stat != DEAD)
|
||||
A.handle_strategicals()
|
||||
|
||||
@@ -1,42 +1,58 @@
|
||||
SUBSYSTEM_DEF(inactivity)
|
||||
name = "AFK Kick"
|
||||
wait = 600
|
||||
flags = SS_BACKGROUND | SS_NO_TICK_CHECK
|
||||
name = "Inactivity"
|
||||
wait = 1 MINUTE
|
||||
flags = SS_NO_INIT | SS_BACKGROUND
|
||||
var/tmp/list/client_list
|
||||
var/number_kicked = 0
|
||||
|
||||
/datum/controller/subsystem/inactivity/fire()
|
||||
if(config.kick_inactive)
|
||||
for(var/i in GLOB.clients)
|
||||
var/client/C = i
|
||||
if(C.is_afk(config.kick_inactive MINUTES) && !C.holder) // VOREStation Edit - Allow admins to idle
|
||||
to_chat(C,"<span class='warning'>You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.</span>")
|
||||
var/information
|
||||
/datum/controller/subsystem/inactivity/fire(resumed = FALSE)
|
||||
if (!config.kick_inactive)
|
||||
can_fire = FALSE
|
||||
return
|
||||
if (!resumed)
|
||||
client_list = GLOB.clients.Copy()
|
||||
|
||||
if(C.mob)
|
||||
if(ishuman(C.mob))
|
||||
var/job
|
||||
var/mob/living/carbon/human/H = C.mob
|
||||
var/datum/data/record/R = find_general_record("name", H.real_name)
|
||||
if(R)
|
||||
job = R.fields["real_rank"]
|
||||
if(!job && H.mind)
|
||||
job = H.mind.assigned_role
|
||||
if(!job && H.job)
|
||||
job = H.job
|
||||
if(job)
|
||||
information = " while [job]."
|
||||
while(client_list.len)
|
||||
var/client/C = client_list[client_list.len]
|
||||
client_list.len--
|
||||
if(!C.holder && C.is_afk(config.kick_inactive MINUTES) && !isobserver(C.mob))
|
||||
|
||||
to_chat(C, "<span class='warning'>You have been inactive for more than [config.kick_inactive] minute\s and have been disconnected.</span>")
|
||||
|
||||
else if(issilicon(C.mob))
|
||||
information = " while a silicon."
|
||||
if(isAI(C.mob))
|
||||
var/mob/living/silicon/ai/A = C.mob
|
||||
empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(A.loc)
|
||||
global_announcer.autosay("[A] has been moved to intelligence storage.", "Artificial Intelligence Oversight")
|
||||
A.clear_client()
|
||||
information = " while an AI."
|
||||
var/information
|
||||
if(C.mob)
|
||||
if(ishuman(C.mob))
|
||||
var/job
|
||||
var/mob/living/carbon/human/H = C.mob
|
||||
var/datum/data/record/R = find_general_record("name", H.real_name)
|
||||
if(R)
|
||||
job = R.fields["real_rank"]
|
||||
if(!job && H.mind)
|
||||
job = H.mind.assigned_role
|
||||
if(!job && H.job)
|
||||
job = H.job
|
||||
if(job)
|
||||
information = " while [job]."
|
||||
|
||||
var/adminlinks
|
||||
adminlinks = " (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[C.mob.x];Y=[C.mob.y];Z=[C.mob.z]'>JMP</a>|<A HREF='?_src_=holder;cryoplayer=\ref[C.mob]'>CRYO</a>)"
|
||||
else if(issilicon(C.mob))
|
||||
information = " while a silicon."
|
||||
if(isAI(C.mob))
|
||||
var/mob/living/silicon/ai/A = C.mob
|
||||
empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(A.loc)
|
||||
global_announcer.autosay("[A] has been moved to intelligence storage.", "Artificial Intelligence Oversight")
|
||||
A.clear_client()
|
||||
information = " while an AI."
|
||||
|
||||
log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob)
|
||||
var/adminlinks
|
||||
adminlinks = " (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[C.mob.x];Y=[C.mob.y];Z=[C.mob.z]'>JMP</a>|<A HREF='?_src_=holder;cryoplayer=\ref[C.mob]'>CRYO</a>)"
|
||||
|
||||
qdel(C)
|
||||
log_and_message_admins("being kicked for AFK[information][adminlinks]", C.mob)
|
||||
|
||||
qdel(C)
|
||||
number_kicked++
|
||||
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/inactivity/stat_entry()
|
||||
..("Kicked: [number_kicked]")
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//
|
||||
// SSshuttles subsystem - Handles initialization and processing of shuttles.
|
||||
//
|
||||
// Also handles initialization and processing of overmap sectors.
|
||||
//
|
||||
|
||||
// This global variable exists for legacy support so we don't have to rename every shuttle_controller to SSshuttles yet.
|
||||
var/global/datum/controller/subsystem/shuttles/shuttle_controller
|
||||
@@ -13,71 +15,168 @@ SUBSYSTEM_DEF(shuttles)
|
||||
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
|
||||
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
|
||||
|
||||
var/list/shuttles = list() // Maps shuttle tags to shuttle datums, so that they can be looked up.
|
||||
var/list/process_shuttles = list() // Simple list of shuttles, for processing
|
||||
var/list/current_run = list() // Shuttles remaining to process this fire() tick
|
||||
var/list/docks_init_callbacks // List of callbacks to run when we finish setting up shuttle docks.
|
||||
var/docks_initialized = FALSE
|
||||
// TODO OVERMAP - These two are unused for now
|
||||
var/overmap_halted = FALSE // Whether ships can move on the overmap; used for adminbus.
|
||||
var/list/ships = list() // List of all ships.
|
||||
|
||||
var/list/shuttles = list() // Maps shuttle tags to shuttle datums, so that they can be looked up.
|
||||
var/list/process_shuttles = list() // Simple list of shuttles, for processing
|
||||
|
||||
var/list/registered_shuttle_landmarks = list() // Maps shuttle landmark tags to instances
|
||||
var/last_landmark_registration_time // world.time of most recent addition to registered_shuttle_landmarks
|
||||
var/list/shuttle_logs = list() // (Not Implemented) Keeps records of shuttle movement, format is list(datum/shuttle = datum/shuttle_log)
|
||||
var/list/shuttle_areas = list() // All the areas of all shuttles.
|
||||
var/list/docking_registry = list() // Docking controller tag -> docking controller program, mostly for init purposes.
|
||||
|
||||
var/list/landmarks_awaiting_sector = list() // Stores automatic landmarks that are waiting for a sector to finish loading.
|
||||
var/list/landmarks_still_needed = list() // Stores landmark_tags that need to be assigned to the sector (landmark_tag = sector) when registered.
|
||||
var/list/shuttles_to_initialize // A queue for shuttles to initialize at the appropriate time.
|
||||
var/list/sectors_to_initialize // Used to find all sector objects at the appropriate time.
|
||||
var/block_init_queue = TRUE // Block initialization of new shuttles/sectors
|
||||
|
||||
var/tmp/list/current_run // Shuttles remaining to process this fire() tick
|
||||
|
||||
/datum/controller/subsystem/shuttles/PreInit()
|
||||
global.shuttle_controller = src // TODO - Remove this! Change everything to point at SSshuttles intead
|
||||
|
||||
/datum/controller/subsystem/shuttles/Initialize(timeofday)
|
||||
global.shuttle_controller = src
|
||||
setup_shuttle_docks()
|
||||
for(var/I in docks_init_callbacks)
|
||||
var/datum/callback/cb = I
|
||||
cb.InvokeAsync()
|
||||
LAZYCLEARLIST(docks_init_callbacks)
|
||||
docks_init_callbacks = null
|
||||
last_landmark_registration_time = world.time
|
||||
// Find all declared shuttle datums and initailize them. (Okay, queue them for initialization a few lines further down)
|
||||
for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more.
|
||||
var/datum/shuttle/shuttle = shuttle_type
|
||||
if(initial(shuttle.category) == shuttle_type)
|
||||
continue // Its an "abstract class" datum, not for a real shuttle.
|
||||
if(!initial(shuttle.defer_initialisation)) // Skip if it asks not to be initialized at startup.
|
||||
LAZYDISTINCTADD(shuttles_to_initialize, shuttle_type)
|
||||
block_init_queue = FALSE
|
||||
process_init_queues()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/shuttles/fire(resumed = 0)
|
||||
do_process_shuttles(resumed)
|
||||
|
||||
/datum/controller/subsystem/shuttles/stat_entry()
|
||||
var/msg = list()
|
||||
msg += "AS:[shuttles.len]|"
|
||||
msg += "PS:[process_shuttles.len]|"
|
||||
..(jointext(msg, null))
|
||||
|
||||
/datum/controller/subsystem/shuttles/proc/do_process_shuttles(resumed = 0)
|
||||
if (!resumed)
|
||||
src.current_run = process_shuttles.Copy()
|
||||
|
||||
var/list/current_run = src.current_run // Cache for sanic speed
|
||||
while(current_run.len)
|
||||
var/datum/shuttle/S = current_run[current_run.len]
|
||||
current_run.len--
|
||||
if(istype(S) && !QDELETED(S))
|
||||
if(istype(S, /datum/shuttle/ferry)) // Ferry shuttles get special treatment
|
||||
var/datum/shuttle/ferry/F = S
|
||||
if(F.process_state || F.always_process)
|
||||
F.process()
|
||||
else
|
||||
S.process()
|
||||
else
|
||||
var/list/working_shuttles = src.current_run // Cache for sanic speed
|
||||
while(working_shuttles.len)
|
||||
var/datum/shuttle/S = working_shuttles[working_shuttles.len]
|
||||
working_shuttles.len--
|
||||
if(!istype(S) || QDELETED(S))
|
||||
error("Bad entry in SSshuttles.process_shuttles - [log_info_line(S)] ")
|
||||
process_shuttles -= S
|
||||
continue
|
||||
// NOTE - In old system, /datum/shuttle/ferry was processed only if (F.process_state || F.always_process)
|
||||
if(S.process_state && (S.process(wait, times_fired, src) == PROCESS_KILL))
|
||||
process_shuttles -= S
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
// This should be called after all the machines and radio frequencies have been properly initialized
|
||||
/datum/controller/subsystem/shuttles/proc/setup_shuttle_docks()
|
||||
// Find all declared shuttle datums and initailize them.
|
||||
for(var/shuttle_type in subtypesof(/datum/shuttle))
|
||||
var/datum/shuttle/shuttle = shuttle_type
|
||||
if(initial(shuttle.category) == shuttle_type)
|
||||
continue
|
||||
/datum/controller/subsystem/shuttles/proc/process_init_queues()
|
||||
if(block_init_queue)
|
||||
return
|
||||
initialize_shuttles()
|
||||
initialize_sectors()
|
||||
|
||||
// Initializes all shuttles in shuttles_to_initialize
|
||||
/datum/controller/subsystem/shuttles/proc/initialize_shuttles()
|
||||
var/list/shuttles_made = list()
|
||||
for(var/shuttle_type in shuttles_to_initialize)
|
||||
var/shuttle = initialize_shuttle(shuttle_type)
|
||||
if(shuttle)
|
||||
shuttles_made += shuttle
|
||||
hook_up_motherships(shuttles_made)
|
||||
shuttles_to_initialize = null
|
||||
|
||||
/datum/controller/subsystem/shuttles/proc/initialize_sectors()
|
||||
for(var/sector in sectors_to_initialize)
|
||||
initialize_sector(sector)
|
||||
sectors_to_initialize = null
|
||||
|
||||
/datum/controller/subsystem/shuttles/proc/register_landmark(shuttle_landmark_tag, obj/effect/shuttle_landmark/shuttle_landmark)
|
||||
if (registered_shuttle_landmarks[shuttle_landmark_tag])
|
||||
CRASH("Attempted to register shuttle landmark with tag [shuttle_landmark_tag], but it is already registered!")
|
||||
if (istype(shuttle_landmark))
|
||||
registered_shuttle_landmarks[shuttle_landmark_tag] = shuttle_landmark
|
||||
last_landmark_registration_time = world.time
|
||||
|
||||
// TODO - Uncomment once overmap sectors are ported
|
||||
//var/obj/effect/overmap/visitable/O = landmarks_still_needed[shuttle_landmark_tag]
|
||||
//if(O) //These need to be added to sectors, which we handle.
|
||||
// try_add_landmark_tag(shuttle_landmark_tag, O)
|
||||
// landmarks_still_needed -= shuttle_landmark_tag
|
||||
//else if(istype(shuttle_landmark, /obj/effect/shuttle_landmark/automatic)) //These find their sector automatically
|
||||
// O = map_sectors["[shuttle_landmark.z]"]
|
||||
// O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
|
||||
|
||||
/datum/controller/subsystem/shuttles/proc/get_landmark(var/shuttle_landmark_tag)
|
||||
return registered_shuttle_landmarks[shuttle_landmark_tag]
|
||||
|
||||
//Checks if the given sector's landmarks have initialized; if so, registers them with the sector, if not, marks them for assignment after they come in.
|
||||
//Also adds automatic landmarks that were waiting on their sector to spawn.
|
||||
/datum/controller/subsystem/shuttles/proc/initialize_sector(obj/effect/overmap/visitable/given_sector)
|
||||
return // TODO - Uncomment once overmap sectors are ported
|
||||
// given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
|
||||
|
||||
// for(var/landmark_tag in given_sector.initial_generic_waypoints)
|
||||
// if(!try_add_landmark_tag(landmark_tag, given_sector))
|
||||
// landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
|
||||
|
||||
// for(var/shuttle_name in given_sector.initial_restricted_waypoints)
|
||||
// for(var/landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
|
||||
// if(!try_add_landmark_tag(landmark_tag, given_sector))
|
||||
// landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
|
||||
|
||||
// var/landmarks_to_check = landmarks_awaiting_sector.Copy()
|
||||
// for(var/thing in landmarks_to_check)
|
||||
// var/obj/effect/shuttle_landmark/automatic/landmark = thing
|
||||
// if(landmark.z in given_sector.map_z)
|
||||
// given_sector.add_landmark(landmark, landmark.shuttle_restricted)
|
||||
// landmarks_awaiting_sector -= landmark
|
||||
|
||||
// TODO - Uncomment once overmap sectors are ported
|
||||
//// Attempts to add a landmark instance with a sector (returns false if landmark isn't registered yet)
|
||||
///datum/controller/subsystem/shuttles/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
|
||||
// var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
|
||||
// if(!landmark)
|
||||
// return
|
||||
|
||||
// if(landmark.landmark_tag in given_sector.initial_generic_waypoints)
|
||||
// given_sector.add_landmark(landmark)
|
||||
// . = 1
|
||||
// for(var/shuttle_name in given_sector.initial_restricted_waypoints)
|
||||
// if(landmark.landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
|
||||
// given_sector.add_landmark(landmark, shuttle_name)
|
||||
// . = 1
|
||||
|
||||
/datum/controller/subsystem/shuttles/proc/initialize_shuttle(var/shuttle_type)
|
||||
var/datum/shuttle/shuttle = shuttle_type
|
||||
if(initial(shuttle.category) != shuttle_type) // Skip if its an "abstract class" datum
|
||||
shuttle = new shuttle()
|
||||
shuttle.init_docking_controllers()
|
||||
shuttle.dock() //makes all shuttles docked to something at round start go into the docked state
|
||||
CHECK_TICK
|
||||
shuttle_areas |= shuttle.shuttle_area
|
||||
log_debug("Initialized shuttle [shuttle] ([shuttle.type])")
|
||||
return shuttle
|
||||
// Historical note: No need to call shuttle.init_docking_controllers(), controllers register themselves
|
||||
// and shuttles fetch refs in New(). Shuttles also dock() themselves in new if they want.
|
||||
|
||||
for(var/obj/machinery/embedded_controller/C in machines)
|
||||
if(istype(C.program, /datum/computer/file/embedded_program/docking))
|
||||
C.program.tag = null //clear the tags, 'cause we don't need 'em anymore
|
||||
docks_initialized = TRUE
|
||||
// TODO - Leshana to hook up more of this when overmap is ported.
|
||||
/datum/controller/subsystem/shuttles/proc/hook_up_motherships(shuttles_list)
|
||||
for(var/datum/shuttle/S in shuttles_list)
|
||||
if(S.mothershuttle && !S.motherdock)
|
||||
var/datum/shuttle/mothership = shuttles[S.mothershuttle]
|
||||
if(mothership)
|
||||
S.motherdock = S.current_location.landmark_tag
|
||||
mothership.shuttle_area |= S.shuttle_area
|
||||
else
|
||||
error("Shuttle [S] was unable to find mothership [mothership]!")
|
||||
|
||||
// Register a callback that will be invoked once the shuttles have been initialized
|
||||
/datum/controller/subsystem/shuttles/proc/OnDocksInitialized(datum/callback/cb)
|
||||
if(!docks_initialized)
|
||||
LAZYADD(docks_init_callbacks, cb)
|
||||
else
|
||||
cb.InvokeAsync()
|
||||
// Admin command to halt/resume overmap
|
||||
// /datum/controller/subsystem/shuttles/proc/toggle_overmap(new_setting)
|
||||
// if(overmap_halted == new_setting)
|
||||
// return
|
||||
// overmap_halted = !overmap_halted
|
||||
// for(var/ship in ships)
|
||||
// var/obj/effect/overmap/visitable/ship/ship_effect = ship
|
||||
// overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
|
||||
|
||||
/datum/controller/subsystem/shuttles/stat_entry()
|
||||
..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
|
||||
|
||||
Reference in New Issue
Block a user