mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2026-08-21 22:16:35 +01:00
<!-- Write **BELOW** The Headers and **ABOVE** The comments else it may not be viewable. --> <!-- You can view Contributing.MD for a detailed description of the pull request process. --> ## About The Pull Request <!-- Describe The Pull Request. Please be sure every change is documented or this can delay review and even discourage maintainers from merging your PR! --> ## Why It's Good For The Game <!-- Argue for the merits of your changes and how they benefit the game, especially if they are controversial and/or far reaching. If you can't actually explain WHY what you are doing will improve the game, then it probably isn't good for the game in the first place. --> ## Changelog <!-- If your PR modifies aspects of the game that can be concretely observed by players or admins you should add a changelog. If your change does NOT meet this description, remove this section. Be sure to properly mark your PRs to prevent unnecessary GBP loss. You can read up on GBP and it's effects on PRs in the tgstation guides for contributors. Please note that maintainers freely reserve the right to remove and add tags should they deem it appropriate. You can attempt to finagle the system all you want, but it's best to shoot for clear communication right off the bat. --> 🆑 fix: Fixed the subsystem not registering overflow spawnpoints /🆑 <!-- Both 🆑's are required for the changelog to work! You can put your name to the right of the first 🆑 if you want to overwrite your GitHub username as author ingame. --> <!-- You can use multiple of the same prefix (they're only used for the icon ingame) and delete the unneeded ones. Despite some of the tags, changelogs should generally represent how a player might be affected by the changes rather than a summary of the PR's contents. -->
214 lines
7.3 KiB
Plaintext
214 lines
7.3 KiB
Plaintext
//* This file is explicitly licensed under the MIT license. *//
|
|
//* Copyright (c) 2023 Citadel Station developers. *//
|
|
|
|
/datum/controller/subsystem/job
|
|
/// All spawnpoints
|
|
var/static/list/spawnpoints = list()
|
|
/// Job spawnpoints keyed to job id/typepath
|
|
var/static/list/job_spawnpoints = list()
|
|
/// Generic latejoin spawnpoints, nested list faction = list()
|
|
var/static/list/latejoin_spawnpoints = list()
|
|
/// Generic overflow spawnpoints, nested list faction = list()
|
|
var/static/list/overflow_spawnpoints = list()
|
|
/// Custom spawnpoints, nested list key = list()
|
|
var/static/list/custom_spawnpoints = list()
|
|
|
|
/**
|
|
* Fully resets spawnpoints list and ensures validity
|
|
*/
|
|
/datum/controller/subsystem/job/proc/reconstruct_spawnpoints()
|
|
spawnpoints = list()
|
|
job_spawnpoints = list()
|
|
latejoin_spawnpoints = list()
|
|
overflow_spawnpoints = list()
|
|
custom_spawnpoints = list()
|
|
// O(2n) but sue me
|
|
for(var/obj/landmark/spawnpoint/S in GLOB.landmarks_list)
|
|
spawnpoints += S
|
|
for(var/obj/landmark/spawnpoint/job/S in GLOB.landmarks_list)
|
|
if(!S.job_path)
|
|
continue
|
|
LAZYDISTINCTADD(job_spawnpoints[S.job_path], S)
|
|
for(var/obj/landmark/spawnpoint/latejoin/S in GLOB.landmarks_list)
|
|
if(!S.faction)
|
|
continue
|
|
LAZYDISTINCTADD(latejoin_spawnpoints[S.faction], S)
|
|
for(var/obj/landmark/spawnpoint/overflow/S in GLOB.landmarks_list)
|
|
if(!S.faction)
|
|
continue
|
|
LAZYDISTINCTADD(overflow_spawnpoints[S.faction], S)
|
|
for(var/obj/landmark/spawnpoint/custom/S in GLOB.landmarks_list)
|
|
if(!S.key)
|
|
continue
|
|
LAZYDISTINCTADD(custom_spawnpoints[S.key], S)
|
|
|
|
/**
|
|
* Gets a valid spawnpoint to use for a roundstart spawn
|
|
*
|
|
* @params
|
|
* - M - the mob being spawned
|
|
* - C - (optional) the client of the player
|
|
* - job_path - (optional) path to job
|
|
* - faction - what faction the player is in terms of job factions
|
|
* - random - deterministic first pick or random?
|
|
* - harder - used when the first iteration failed, tells spawnpoints to skip certain checks
|
|
*
|
|
*/
|
|
/datum/controller/subsystem/job/proc/get_roundstart_spawnpoint(mob/M, client/C, job_path, faction, random = TRUE, harder = FALSE)
|
|
RETURN_TYPE(/obj/landmark/spawnpoint)
|
|
if(random)
|
|
. = list()
|
|
// Priority 1: Job specific spawnpoints
|
|
if(job_path && length(job_spawnpoints[job_path]))
|
|
for(var/obj/landmark/spawnpoint/job/J as anything in job_spawnpoints[job_path])
|
|
if(!J.roundstart)
|
|
continue
|
|
if(!J.Available(M, C, harder))
|
|
continue
|
|
if(random)
|
|
. += J
|
|
else
|
|
return J
|
|
if(random && length(.))
|
|
return pick(.)
|
|
// Priority 2: Overflow spawnpoints as a last resort
|
|
if(length(overflow_spawnpoints[faction]))
|
|
for(var/obj/landmark/spawnpoint/overflow/S as anything in overflow_spawnpoints[faction])
|
|
if(!S.Available(M, C, harder))
|
|
continue
|
|
if(random)
|
|
. += S
|
|
else
|
|
return S
|
|
if(random && length(.))
|
|
return pick(.)
|
|
if(!harder)
|
|
subsystem_log("get_roundstart_spawnpoint() failed to get a spawnpoint, trying against with harder = TRUE")
|
|
return get_roundstart_spawnpoint(M, C, job_path, faction, random, TRUE)
|
|
else
|
|
CRASH("get_roundstart_spawnpoint() failed to get a spawnpoint.")
|
|
|
|
/**
|
|
* Gets a spawnpoint to use for a latejoin spawn
|
|
* Note that there's no mob argument, since latejoin won't make the mob until there's a free spawnpoint
|
|
*
|
|
* This is not a random pick, this is first priority-availability first server and fully deterministic.
|
|
*
|
|
* @params
|
|
* - C - (optional) the client of the player
|
|
* - job_path - (optional) path to job
|
|
* - faction - what faction the player is in terms of job factions
|
|
* - method - (optional) required method for the spawnpoint - this will make the proc return null instead of an overflow, if it can't find something for the method.
|
|
* - random - deterministic first pick or random?
|
|
* - harder - used when the first iteration failed, tells spawnpoints to skip certain checks
|
|
*/
|
|
/datum/controller/subsystem/job/proc/get_latejoin_spawnpoint(client/C, job_path, faction = JOB_FACTION_STATION, method, random = TRUE, harder = FALSE)
|
|
RETURN_TYPE(/obj/landmark/spawnpoint)
|
|
if(random)
|
|
. = list() // Priority 1: Job specific spawnpoints
|
|
if(job_path && length(job_spawnpoints[job_path]))
|
|
for(var/obj/landmark/spawnpoint/job/J as anything in job_spawnpoints[job_path])
|
|
if(!J.latejoin)
|
|
continue
|
|
if(!J.latejoin_override && method && (method != J.method))
|
|
continue
|
|
if(!J.Available(null, C, harder))
|
|
continue
|
|
if(random)
|
|
. += J
|
|
else
|
|
return J
|
|
if(random && length(.))
|
|
return pick(.)
|
|
// Priority 2: Latejoin spawnpoints, if latejoin
|
|
if(length(latejoin_spawnpoints[faction]))
|
|
for(var/obj/landmark/spawnpoint/latejoin/S as anything in latejoin_spawnpoints[faction])
|
|
if(!S.Available(null, C, harder))
|
|
continue
|
|
if(method && (S.method != method))
|
|
continue
|
|
if(random)
|
|
. += S
|
|
else
|
|
return S
|
|
if(random && length(.))
|
|
return pick(.)
|
|
// Priority 3: Overflow spawnpoints as a last resort
|
|
if(length(overflow_spawnpoints[faction]))
|
|
for(var/obj/landmark/spawnpoint/overflow/S as anything in overflow_spawnpoints[faction])
|
|
if(!S.Available(null, C, harder))
|
|
continue
|
|
if(random)
|
|
. += S
|
|
else
|
|
return S
|
|
if(random)
|
|
if(length(.))
|
|
return pick(.)
|
|
else
|
|
. = null
|
|
if(!harder)
|
|
subsystem_log("get_latejoin_spawnpoint() failed to get a spawnpoint, trying against with harder = TRUE")
|
|
return get_roundstart_spawnpoint(C, job_path, faction, method, random, TRUE)
|
|
else
|
|
. = null
|
|
CRASH("get_latejoin_spawnpoint() failed to get a spawnpoint.")
|
|
|
|
/**
|
|
* Gets a list of possible join methods
|
|
*
|
|
* If latejoining and a job-specific spawnpoint has latejoin override, only that method will be returned
|
|
*
|
|
* The "harder" argument is automatically set to TRUE here, as we're checking for all possibilities.
|
|
*
|
|
* @params
|
|
* - C - (optional) the client of the player
|
|
* - job_path - (optional) path to job
|
|
* - faction - what faction the player is in terms of job factions
|
|
*/
|
|
/datum/controller/subsystem/job/proc/possible_latejoin_spawnpoints(client/C, job_path, faction)
|
|
. = list()
|
|
// Get all job specific methods, and allow for override if needed
|
|
if(job_path && length(job_spawnpoints[job_path]))
|
|
for(var/obj/landmark/spawnpoint/job/J as anything in job_spawnpoints[job_path])
|
|
if(!J.latejoin)
|
|
continue
|
|
if(J.latejoin_override)
|
|
return list(J.method)
|
|
if(J.Available(null, C, TRUE))
|
|
continue
|
|
. |= J.method
|
|
// Get all standard latejoin methods
|
|
if(length(latejoin_spawnpoints[faction]))
|
|
for(var/obj/landmark/spawnpoint/latejoin/S as anything in latejoin_spawnpoints[faction])
|
|
if(!S.Available(null, C, TRUE))
|
|
continue
|
|
. |= S.method
|
|
// If there's none, add overflow method if overflow spawnpoints exist
|
|
if(!length(.) && length(overflow_spawnpoints[faction]))
|
|
for(var/obj/landmark/spawnpoint/overflow/S as anything in overflow_spawnpoints[faction])
|
|
if(S.Available(null, C, TRUE))
|
|
return list("Overflow")
|
|
|
|
/**
|
|
* Gets a valid custom spawnpoint to use by key
|
|
*
|
|
* @params
|
|
* - M - (optional) mob being spawned
|
|
* - C - (optional) client of player
|
|
* - key - spawnpoint key to look for
|
|
*/
|
|
/datum/controller/subsystem/job/proc/get_custom_spawnpoint(mob/M, client/C, key)
|
|
if(!length(custom_spawnpoints[key]))
|
|
return
|
|
for(var/obj/landmark/spawnpoint/S as anything in custom_spawnpoints[key])
|
|
if(!S.Available(M, C))
|
|
continue
|
|
return S
|
|
|
|
/**
|
|
* Get all spawnpoint landmarks
|
|
*/
|
|
/datum/controller/subsystem/job/proc/get_all_spawnpoints()
|
|
return spawnpoints
|