mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 12:08:28 +01:00
removes the last of the old job controller (#19344)
* removes the last of the old job controller * . * . * . * . * . * Update admin_verbs.dm * Update admin_verbs.dm --------- Co-authored-by: Cameron Lennox <killer65311@gmail.com>
This commit is contained in:
co-authored by
Cameron Lennox
parent
a3b7c0e836
commit
12c5adeeb3
@@ -16,7 +16,6 @@ GLOBAL_LIST_EMPTY(cable_list) //Index for all cables, so that powernets don
|
||||
GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created
|
||||
GLOBAL_LIST_EMPTY(event_triggers) //Associative list of creator_ckey:list(landmark references) for event triggers
|
||||
GLOBAL_LIST_EMPTY(surgery_steps) //list of all surgery steps |BS12
|
||||
GLOBAL_LIST_EMPTY(joblist) //list of all jobstypes, minus borg and AI
|
||||
|
||||
GLOBAL_LIST_EMPTY(mechas_list) //list of all mechs. Used by hostile mobs target tracking.
|
||||
GLOBAL_LIST_EMPTY_TYPED(PDAs, /obj/item/pda)
|
||||
@@ -173,13 +172,6 @@ GLOBAL_LIST_EMPTY(mannequins)
|
||||
GLOB.surgery_steps += S
|
||||
sort_surgeries()
|
||||
|
||||
//List of job. I can't believe this was calculated multiple times per tick!
|
||||
paths = subtypesof(/datum/job)
|
||||
paths -= GLOB.exclude_jobs
|
||||
for(var/T in paths)
|
||||
var/datum/job/J = new T
|
||||
GLOB.joblist[J.title] = J
|
||||
|
||||
//Languages
|
||||
paths = subtypesof(/datum/language)
|
||||
for(var/T in paths)
|
||||
|
||||
@@ -77,8 +77,6 @@ ADMIN_VERB(debug_controller, R_DEBUG, "Debug Controller", "Debug the various per
|
||||
options[strtype] = S
|
||||
|
||||
//Goon PS stuff, and other yet-to-be-subsystem things.
|
||||
options["LEGACY: master_controller"] = GLOB.master_controller
|
||||
options["LEGACY: job_master"] = GLOB.job_master
|
||||
options["LEGACY: cameranet"] = GLOB.cameranet
|
||||
|
||||
var/pick = tgui_input_list(user, "Choose a controller to debug/view variables of.", "VV controller:", options)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
//simplified MC that is designed to fail when procs 'break'. When it fails it's just replaced with a new one.
|
||||
//It ensures master_controller.process() is never doubled up by killing the MC (hence terminating any of its sleeping procs)
|
||||
//WIP, needs lots of work still
|
||||
|
||||
//
|
||||
// TODO - This will be completely replaced by master.dm in time.
|
||||
//
|
||||
GLOBAL_DATUM(master_controller, /datum/controller/game_controller) //Set in world.New()
|
||||
|
||||
/datum/controller/game_controller
|
||||
var/list/shuttle_list // For debugging and VV
|
||||
|
||||
/datum/controller/game_controller/New()
|
||||
//There can be only one master_controller. Out with the old and in with the new.
|
||||
if(GLOB.master_controller != src)
|
||||
log_world("Rebuilding Master Controller")
|
||||
if(istype(GLOB.master_controller))
|
||||
qdel(GLOB.master_controller)
|
||||
GLOB.master_controller = src
|
||||
|
||||
if(!GLOB.job_master)
|
||||
GLOB.job_master = new /datum/controller/occupations()
|
||||
GLOB.job_master.SetupOccupations()
|
||||
GLOB.job_master.LoadJobs("config/jobs.txt")
|
||||
admin_notice(span_danger("Job setup complete"), R_DEBUG)
|
||||
|
||||
/datum/controller/game_controller/proc/setup()
|
||||
// setupgenetics() Moved to SSatoms
|
||||
// SetupXenoarch() - Moved to SSxenoarch
|
||||
|
||||
admin_notice(span_danger("Initializations complete."), R_DEBUG)
|
||||
|
||||
// #if UNIT_TESTS
|
||||
// # define CHECK_SLEEP_MASTER // For unit tests we don't care about a smooth lobby screen experience. We care about speed.
|
||||
// #else
|
||||
// # define CHECK_SLEEP_MASTER if(++initialized_objects > 500) { initialized_objects=0;sleep(world.tick_lag); }
|
||||
// #endif
|
||||
@@ -2,6 +2,9 @@ SUBSYSTEM_DEF(antag_job)
|
||||
name = "Antag Job"
|
||||
flags = SS_NO_FIRE
|
||||
//List of all jobs
|
||||
dependencies = list(
|
||||
/datum/controller/subsystem/job
|
||||
)
|
||||
var/list/occupations = list()
|
||||
|
||||
var/list/syndicate_code_phrase
|
||||
@@ -73,7 +76,7 @@ SUBSYSTEM_DEF(antag_job)
|
||||
code_phrase += " "
|
||||
code_phrase += pick(GLOB.last_names)
|
||||
if(2)
|
||||
code_phrase += pick(GLOB.joblist)//Returns a job.
|
||||
code_phrase += pick(SSjob.occupations_by_name)//Returns a job.
|
||||
safety -= 1
|
||||
if(2)
|
||||
switch(rand(1,2))//Places or things.
|
||||
|
||||
@@ -5,43 +5,50 @@ SUBSYSTEM_DEF(job)
|
||||
)
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
var/list/occupations = list() //List of all jobs
|
||||
var/list/datum/job/name_occupations = list() //Dict of all jobs, keys are titles
|
||||
//List of all jobs
|
||||
var/list/datum/job/occupations = list()
|
||||
//List of all jobs
|
||||
var/list/datum/job/occupation_with_excludes = list()
|
||||
//Players who need jobs
|
||||
var/list/mob/new_player/unassigned = list()
|
||||
var/list/datum/job/occupations_by_name = list() //Dict of all jobs, keys are titles
|
||||
var/list/type_occupations = list() //Dict of all jobs, keys are types
|
||||
|
||||
var/list/department_datums = list()
|
||||
var/list/job_icon_cache = list()
|
||||
var/debug_messages = FALSE
|
||||
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_all_job_icons() //For all existing HUD icons
|
||||
return occupation_with_excludes + GLOB.alt_titles_with_icons + list("Prisoner")
|
||||
|
||||
/datum/controller/subsystem/job/Initialize()
|
||||
if(!length(department_datums))
|
||||
setup_departments()
|
||||
if(!length(occupations))
|
||||
setup_occupations()
|
||||
setup_departments()
|
||||
setup_occupations()
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/job/proc/setup_occupations(faction = FACTION_STATION)
|
||||
occupations = list()
|
||||
occupations.Cut()
|
||||
var/list/all_jobs = subtypesof(/datum/job)
|
||||
if(!length(all_jobs))
|
||||
to_chat(world, span_warning("Error setting up jobs, no job datums found"))
|
||||
return FALSE
|
||||
|
||||
for(var/J in all_jobs)
|
||||
var/datum/job/job = new J()
|
||||
if(!job)
|
||||
continue
|
||||
for(var/job_path in all_jobs)
|
||||
var/datum/job/job = new job_path()
|
||||
if(job.faction != faction)
|
||||
continue
|
||||
occupations += job
|
||||
name_occupations[job.title] = job
|
||||
type_occupations[J] = job
|
||||
if(!(is_type_in_list(job, GLOB.exclude_jobs)))
|
||||
occupation_with_excludes += job
|
||||
occupations_by_name[job.title] = job
|
||||
type_occupations[job_path] = job
|
||||
if(LAZYLEN(job.departments))
|
||||
add_to_departments(job)
|
||||
|
||||
sortTim(occupations, GLOBAL_PROC_REF(cmp_job_datums))
|
||||
for(var/D in department_datums)
|
||||
var/datum/department/dept = department_datums[D]
|
||||
for(var/department, value in department_datums)
|
||||
var/datum/department/dept = value
|
||||
sortTim(dept.jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
|
||||
sortTim(dept.primary_jobs, GLOBAL_PROC_REF(cmp_job_datums), TRUE)
|
||||
|
||||
@@ -80,7 +87,12 @@ SUBSYSTEM_DEF(job)
|
||||
return dept_datums
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_job(rank)
|
||||
return name_occupations[rank]
|
||||
if(!rank)
|
||||
return null
|
||||
return occupations_by_name[rank]
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_player_alt_title(mob/new_player/player, rank)
|
||||
return player.client.prefs.GetPlayerAltTitle(get_job(rank))
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_job_type(jobtype)
|
||||
return type_occupations[jobtype]
|
||||
@@ -139,3 +151,908 @@ SUBSYSTEM_DEF(job)
|
||||
/datum/controller/subsystem/job/proc/job_debug_message(message)
|
||||
if(debug_messages)
|
||||
log_world("JOB DEBUG: [message]")
|
||||
|
||||
/datum/controller/subsystem/job/proc/assign_role(mob/new_player/player, rank, latejoin = FALSE)
|
||||
job_debug_message("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
|
||||
if(player && player.mind && rank)
|
||||
var/datum/job/job = get_job(rank)
|
||||
if(!job)
|
||||
return FALSE
|
||||
if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
return FALSE
|
||||
if(jobban_isbanned(player, rank))
|
||||
return FALSE
|
||||
if(!job.player_old_enough(player.client))
|
||||
return FALSE
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
return FALSE
|
||||
if(!is_job_whitelisted(player, rank))
|
||||
return FALSE
|
||||
|
||||
var/position_limit = job.total_positions
|
||||
if(!latejoin)
|
||||
position_limit = job.spawn_positions
|
||||
if((job.current_positions < position_limit) || position_limit == -1)
|
||||
job_debug_message("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
|
||||
player.mind.assigned_role = rank
|
||||
player.mind.role_alt_title = get_player_alt_title(player, rank)
|
||||
unassigned -= player
|
||||
job.current_positions++
|
||||
return TRUE
|
||||
job_debug_message("AR has failed, Player: [player], Rank: [rank]")
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/job/proc/free_role(rank) //making additional slot on the fly
|
||||
var/datum/job/job = get_job(rank)
|
||||
if(job && job.total_positions != -1)
|
||||
job.total_positions++
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/job/proc/update_limit(rank, comperator)
|
||||
var/datum/job/job = get_job(rank)
|
||||
if(job && job.total_positions != -1)
|
||||
job.update_limit(comperator)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/job/proc/find_occupation_candidate(datum/job/job, level, flag)
|
||||
job_debug_message("Running FOC, Job: [job], Level: [level], Flag: [flag]")
|
||||
var/list/candidates = list()
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(jobban_isbanned(player, job.title))
|
||||
job_debug_message("FOC isbanned failed, Player: [player]")
|
||||
continue
|
||||
if(!job.player_old_enough(player.client))
|
||||
job_debug_message("FOC player not old enough, Player: [player]")
|
||||
continue
|
||||
if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
job_debug_message("FOC character not old enough, Player: [player]")
|
||||
continue
|
||||
//VOREStation Code Start
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
job_debug_message("FOC character not enough playtime, Player: [player]")
|
||||
continue
|
||||
if(!is_job_whitelisted(player, job.title))
|
||||
job_debug_message("FOC is_job_whitelisted failed, Player: [player]")
|
||||
continue
|
||||
//VOREStation Code End
|
||||
if(flag && !(player.client.prefs.be_special & flag))
|
||||
job_debug_message("FOC flag failed, Player: [player], Flag: [flag], ")
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
job_debug_message("FOC pass, Player: [player], Level:[level]")
|
||||
candidates += player
|
||||
return candidates
|
||||
|
||||
/datum/controller/subsystem/job/proc/give_random_job(mob/new_player/player)
|
||||
job_debug_message("GRJ Giving random job, Player: [player]")
|
||||
for(var/datum/job/job in shuffle(occupations))
|
||||
if(!job)
|
||||
continue
|
||||
|
||||
if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
continue
|
||||
|
||||
if(istype(job, get_job(JOB_ALT_VISITOR))) // We don't want to give him assistant, that's boring! //VOREStation Edit - Visitor not Assistant
|
||||
continue
|
||||
|
||||
if(SSjob.is_job_in_department(job.title, DEPARTMENT_COMMAND)) //If you want a command position, select it!
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
job_debug_message("GRJ isbanned failed, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
job_debug_message("GRJ player not old enough, Player: [player]")
|
||||
continue
|
||||
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
job_debug_message("GRJ player not enough playtime, Player: [player]")
|
||||
continue
|
||||
if(!is_job_whitelisted(player, job.title))
|
||||
job_debug_message("GRJ player not whitelisted for this job, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
job_debug_message("GRJ Random job given, Player: [player], Job: [job]")
|
||||
assign_role(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
/datum/controller/subsystem/job/proc/reset_occupations()
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if((player) && (player.mind))
|
||||
player.mind.assigned_role = null
|
||||
player.mind.special_role = null
|
||||
setup_occupations()
|
||||
unassigned = list()
|
||||
return
|
||||
|
||||
///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check
|
||||
/datum/controller/subsystem/job/proc/fill_head_position()
|
||||
for(var/level = 1 to 3)
|
||||
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
var/datum/job/job = get_job(command_position)
|
||||
if(!job)
|
||||
continue
|
||||
var/list/candidates = find_occupation_candidate(job, level)
|
||||
if(!length(candidates))
|
||||
continue
|
||||
|
||||
// Build a weighted list, weight by age.
|
||||
var/list/weightedCandidates = list()
|
||||
for(var/mob/mob_candidate in candidates)
|
||||
// Log-out during round-start? What a bad boy, no head position for you!
|
||||
if(!mob_candidate.client)
|
||||
continue
|
||||
var/age = mob_candidate.read_preference(/datum/preference/numeric/human/age)
|
||||
|
||||
if(age < job.get_min_age(mob_candidate.client.prefs.read_preference(/datum/preference/choiced/species), mob_candidate.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])) // Nope.
|
||||
continue
|
||||
|
||||
var/idealage = job.get_ideal_age(mob_candidate.client.prefs.read_preference(/datum/preference/choiced/species), mob_candidate.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])
|
||||
var/agediff = abs(idealage - age) // Compute the absolute difference in age from target
|
||||
switch(agediff) /// If the math sucks, it's because I almost failed algebra in high school.
|
||||
if(20 to INFINITY)
|
||||
weightedCandidates[mob_candidate] = 3 // Too far off
|
||||
if(10 to 20)
|
||||
weightedCandidates[mob_candidate] = 6 // Nearer the mark, but not quite
|
||||
if(0 to 10)
|
||||
weightedCandidates[mob_candidate] = 10 // On the mark
|
||||
else
|
||||
// If there's ABSOLUTELY NOBODY ELSE
|
||||
if(length(candidates) == 1)
|
||||
weightedCandidates[mob_candidate] = 1
|
||||
|
||||
|
||||
var/mob/new_player/candidate = pickweight(weightedCandidates)
|
||||
if(assign_role(candidate, command_position))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
|
||||
/datum/controller/subsystem/job/proc/check_head_position(level)
|
||||
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
var/datum/job/job = get_job(command_position)
|
||||
if(!job)
|
||||
continue
|
||||
var/list/candidates = find_occupation_candidate(job, level)
|
||||
if(!length(candidates))
|
||||
continue
|
||||
var/mob/new_player/candidate = pick(candidates)
|
||||
assign_role(candidate, command_position)
|
||||
|
||||
/** Proc DivideOccupations
|
||||
* fills var "assigned_role" for all ready players.
|
||||
* This proc must not have any side effect besides of modifying "assigned_role".
|
||||
**/
|
||||
/datum/controller/subsystem/job/proc/divide_occupations()
|
||||
//Setup new player list and get the jobs list
|
||||
job_debug_message("Running DO")
|
||||
setup_occupations()
|
||||
|
||||
//Holder for Triumvirate is stored in the ticker, this just processes it
|
||||
if(SSticker && GLOB.triai)
|
||||
for(var/datum/job/A in occupations)
|
||||
if(A.title == JOB_AI)
|
||||
A.spawn_positions = 3
|
||||
break
|
||||
|
||||
//Get the players who are ready
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(player.ready && player.mind && !player.mind.assigned_role)
|
||||
unassigned += player
|
||||
|
||||
job_debug_message("DO, Len: [length(unassigned)]")
|
||||
if(!length(unassigned))
|
||||
return FALSE
|
||||
|
||||
//Shuffle players and jobs
|
||||
unassigned = shuffle(unassigned)
|
||||
|
||||
handle_feedback_gathering()
|
||||
|
||||
//People who wants to be assistants, sure, go on.
|
||||
job_debug_message("DO, Running Assistant Check 1")
|
||||
var/datum/job/assist = new DEFAULT_JOB_TYPE ()
|
||||
var/list/assistant_candidates = find_occupation_candidate(assist, 3)
|
||||
job_debug_message("AC1, Candidates: [length(assistant_candidates)]")
|
||||
for(var/mob/new_player/player in assistant_candidates)
|
||||
job_debug_message("AC1 pass, Player: [player]")
|
||||
assign_role(player, JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant
|
||||
assistant_candidates -= player
|
||||
job_debug_message("DO, AC1 end")
|
||||
|
||||
//Select one head
|
||||
job_debug_message("DO, Running Head Check")
|
||||
fill_head_position()
|
||||
job_debug_message("DO, Head Check end")
|
||||
|
||||
//Other jobs are now checked
|
||||
job_debug_message("DO, Running Standard Check")
|
||||
|
||||
|
||||
// New job giving system by Donkie
|
||||
// This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all.
|
||||
// Hopefully this will add more randomness and fairness to job giving.
|
||||
|
||||
// Loop through all levels from high to low
|
||||
var/list/shuffledoccupations = shuffle(occupations)
|
||||
// var/list/disabled_jobs = SSticker.mode.disabled_jobs // So we can use .Find down below without a colon.
|
||||
for(var/level = 1 to 3)
|
||||
//Check the head jobs first each level
|
||||
check_head_position(level)
|
||||
|
||||
// Loop through all unassigned players
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
|
||||
// Loop through all jobs
|
||||
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
|
||||
if(!job || SSticker.mode.disabled_jobs.Find(job.title) )
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
job_debug_message("DO isbanned failed, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
job_debug_message("DO player not old enough, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
//VOREStation Add
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
job_debug_message("DO player not enough playtime, Player: [player]")
|
||||
continue
|
||||
//VOREStation Add End
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
job_debug_message("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
assign_role(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
|
||||
give_random_job(player)
|
||||
|
||||
job_debug_message("DO, Standard Check end")
|
||||
|
||||
job_debug_message("DO, Running AC2")
|
||||
|
||||
// For those who wanted to be assistant if their preferences were filled, here you go.
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == BE_ASSISTANT)
|
||||
job_debug_message("AC2 Assistant located, Player: [player]")
|
||||
assign_role(player, JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant
|
||||
|
||||
//For ones returning to lobby
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
|
||||
player.ready = PLAYER_NOT_READY
|
||||
unassigned -= player
|
||||
return TRUE
|
||||
|
||||
/datum/controller/subsystem/job/proc/equip_rank(mob/living/carbon/human/human_mob, rank, joined_late = 0, announce = TRUE)
|
||||
if(!human_mob)
|
||||
return null
|
||||
|
||||
var/datum/job/job = get_job(rank)
|
||||
var/list/spawn_in_storage = list()
|
||||
|
||||
if(!joined_late)
|
||||
var/obj/spawn_point = null
|
||||
var/list/possible_spawns = list()
|
||||
for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list)
|
||||
if(sloc.name != rank) continue
|
||||
if(locate(/mob/living) in sloc.loc) continue
|
||||
possible_spawns.Add(sloc)
|
||||
if(length(possible_spawns))
|
||||
spawn_point = pick(possible_spawns)
|
||||
if(!spawn_point)
|
||||
spawn_point = locate("start*[rank]") // use old stype
|
||||
if(istype(spawn_point, /obj/effect/landmark/start) && istype(spawn_point.loc, /turf))
|
||||
human_mob.forceMove(spawn_point.loc)
|
||||
else
|
||||
var/list/spawn_props = late_spawn(human_mob.client, rank)
|
||||
var/turf/spawn_turf = spawn_props["turf"]
|
||||
if(!spawn_turf)
|
||||
to_chat(human_mob, span_critical("You were unable to be spawned at your chosen late-join spawnpoint. Please verify your job/spawn point combination makes sense, and try another one."))
|
||||
return
|
||||
else
|
||||
human_mob.forceMove(spawn_turf)
|
||||
|
||||
// Moving wheelchair if they have one
|
||||
if(human_mob.buckled && istype(human_mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
human_mob.buckled.forceMove(human_mob.loc)
|
||||
human_mob.buckled.set_dir(human_mob.dir)
|
||||
|
||||
if(job)
|
||||
|
||||
//Equip custom gear loadout.
|
||||
var/list/custom_equip_slots = list()
|
||||
var/list/custom_equip_leftovers = list()
|
||||
if(human_mob?.client?.prefs && !(job.mob_type & JOB_SILICON))
|
||||
var/list/active_gear_list = LAZYACCESS(human_mob.client.prefs.gear_list, "[human_mob.client.prefs.gear_slot]")
|
||||
for(var/thing in active_gear_list)
|
||||
var/datum/gear/gaar_thing = GLOB.gear_datums[thing]
|
||||
if(!gaar_thing) //Not a real gear datum (maybe removed, as this is loaded from their savefile)
|
||||
continue
|
||||
|
||||
var/permitted
|
||||
// Check if it is restricted to certain roles
|
||||
if(gaar_thing.allowed_roles)
|
||||
for(var/job_name in gaar_thing.allowed_roles)
|
||||
if(job.title == job_name)
|
||||
permitted = TRUE
|
||||
else
|
||||
permitted = TRUE
|
||||
|
||||
// Check if they're whitelisted for this gear (in alien whitelist? seriously?)
|
||||
if(gaar_thing.whitelisted && !is_alien_whitelisted(human_mob.client, GLOB.all_species[gaar_thing.whitelisted]))
|
||||
permitted = FALSE
|
||||
|
||||
// If they aren't, tell them
|
||||
if(!permitted)
|
||||
to_chat(human_mob, span_warning("Your current species, job or whitelist status does not permit you to spawn with [thing]!"))
|
||||
continue
|
||||
|
||||
// Implants get special treatment
|
||||
if(gaar_thing.slot == "implant")
|
||||
var/obj/item/implant/gear_implant = gaar_thing.spawn_item(human_mob, active_gear_list[gaar_thing.display_name])
|
||||
gear_implant.invisibility = INVISIBILITY_MAXIMUM
|
||||
gear_implant.implant_loadout(human_mob)
|
||||
continue
|
||||
|
||||
// Try desperately (and sorta poorly) to equip the item. Now with increased desperation!
|
||||
if(gaar_thing.slot && !(gaar_thing.slot in custom_equip_slots))
|
||||
var/metadata = active_gear_list[gaar_thing.display_name]
|
||||
//if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
|
||||
// custom_equip_leftovers += thing
|
||||
//else
|
||||
if(gaar_thing.slot == slot_wear_suit && human_mob.client?.prefs?.no_jacket)
|
||||
continue
|
||||
if(gaar_thing.slot == slot_shoes && human_mob.client?.prefs?.shoe_hater) //RS ADD
|
||||
continue
|
||||
if(human_mob.equip_to_slot_or_del(gaar_thing.spawn_item(human_mob, metadata), gaar_thing.slot))
|
||||
to_chat(human_mob, span_notice("Equipping you with \the [thing]!"))
|
||||
if(gaar_thing.slot != slot_tie)
|
||||
custom_equip_slots.Add(gaar_thing.slot)
|
||||
else
|
||||
custom_equip_leftovers.Add(thing)
|
||||
else
|
||||
spawn_in_storage += thing
|
||||
|
||||
// Set up their account
|
||||
job.setup_account(human_mob)
|
||||
|
||||
// Equip job items.
|
||||
job.equip(human_mob, human_mob.mind ? human_mob.mind.role_alt_title : "")
|
||||
|
||||
// Stick their fingerprints on literally everything
|
||||
job.apply_fingerprints(human_mob)
|
||||
|
||||
// Only non-silicons get post-job-equip equipment and dormant diseases
|
||||
if(!(job.mob_type & JOB_SILICON))
|
||||
human_mob.equip_post_job()
|
||||
human_mob.give_random_dormant_disease(guaranteed_symptoms = job.symptoms)
|
||||
|
||||
// If some custom items could not be equipped before, try again now.
|
||||
for(var/thing in custom_equip_leftovers)
|
||||
var/datum/gear/gear_thing = GLOB.gear_datums[thing]
|
||||
if(gear_thing.slot == slot_wear_suit && human_mob.client?.prefs?.no_jacket)
|
||||
continue
|
||||
if(gear_thing.slot == slot_shoes && human_mob.client?.prefs?.shoe_hater)
|
||||
continue
|
||||
if(gear_thing.slot in custom_equip_slots)
|
||||
spawn_in_storage += thing
|
||||
else
|
||||
var/list/active_gear_list = LAZYACCESS(human_mob.client.prefs.gear_list, "[human_mob.client.prefs.gear_slot]")
|
||||
var/metadata = active_gear_list[gear_thing.display_name]
|
||||
if(human_mob.equip_to_slot_or_del(gear_thing.spawn_item(human_mob, metadata), gear_thing.slot))
|
||||
to_chat(human_mob, span_notice("Equipping you with \the [thing]!"))
|
||||
custom_equip_slots.Add(gear_thing.slot)
|
||||
else
|
||||
spawn_in_storage += thing
|
||||
|
||||
//Give new players a welcome guide!
|
||||
if(isnum(human_mob.client?.player_age) && human_mob.client.player_age < 10)
|
||||
human_mob.equip_to_slot_or_del(new /obj/item/book/manual/virgo_pamphlet(human_mob), slot_r_hand)
|
||||
else
|
||||
to_chat(human_mob, span_filter_notice("Your job is [rank] and the game just can't handle it! Please report this bug to an administrator."))
|
||||
|
||||
human_mob.job = rank
|
||||
log_game("JOINED [key_name(human_mob)] as \"[rank]\"")
|
||||
log_game("SPECIES [key_name(human_mob)] is a: \"[human_mob.species.name]\"") //VOREStation Add
|
||||
|
||||
// If they're head, give them the account info for their department
|
||||
if(human_mob.mind && job.department_accounts)
|
||||
var/remembered_info = ""
|
||||
for(var/job_department in job.department_accounts)
|
||||
var/datum/money_account/department_account = GLOB.department_accounts[job_department]
|
||||
if(department_account)
|
||||
remembered_info += span_bold("Department account number ([job_department]):") + " #[department_account.account_number]<br>"
|
||||
remembered_info += span_bold("Department account pin ([job_department]):") + " [department_account.remote_access_pin]<br>"
|
||||
remembered_info += span_bold("Department account funds ([job_department]):") + " $[department_account.money]<br>"
|
||||
|
||||
human_mob.mind.store_memory(remembered_info)
|
||||
|
||||
var/alt_title = null
|
||||
if(human_mob.mind)
|
||||
human_mob.mind.assigned_role = rank
|
||||
alt_title = human_mob.mind.role_alt_title
|
||||
|
||||
// If we're a silicon, we may be done at this point
|
||||
if(job.mob_type & JOB_SILICON_ROBOT)
|
||||
return human_mob.Robotize()
|
||||
if(job.mob_type & JOB_SILICON_AI)
|
||||
return human_mob
|
||||
|
||||
// TWEET PEEP
|
||||
if(rank == JOB_SITE_MANAGER && announce)
|
||||
var/sound/announce_sound = (SSticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20)
|
||||
GLOB.captain_announcement.Announce("All hands, [alt_title ? alt_title : JOB_SITE_MANAGER] [human_mob.real_name] on deck!", new_sound = announce_sound, zlevel = human_mob.z)
|
||||
|
||||
//Deferred item spawning.
|
||||
if(spawn_in_storage && length(spawn_in_storage))
|
||||
var/obj/item/storage/storage_bag
|
||||
for(var/obj/item/storage/worn_bag in human_mob.contents)
|
||||
storage_bag = worn_bag
|
||||
break
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(human_mob.client.prefs.gear_list, "[human_mob.client.prefs.gear_slot]")
|
||||
if(!isnull(storage_bag))
|
||||
for(var/thing in spawn_in_storage)
|
||||
to_chat(human_mob, span_notice("Placing \the [thing] in your [storage_bag.name]!"))
|
||||
var/datum/gear/gear_thing = GLOB.gear_datums[thing]
|
||||
var/metadata = active_gear_list[gear_thing.display_name]
|
||||
gear_thing.spawn_item(storage_bag, metadata)
|
||||
else
|
||||
to_chat(human_mob, span_danger("Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug."))
|
||||
|
||||
if(istype(human_mob)) //give humans wheelchairs, if they need them.
|
||||
var/obj/item/organ/external/l_foot = human_mob.get_organ(BP_L_FOOT)
|
||||
var/obj/item/organ/external/r_foot = human_mob.get_organ(BP_R_FOOT)
|
||||
var/obj/item/storage/storage_bag = locate() in human_mob.contents
|
||||
var/obj/item/wheelchair/used_wheelchair
|
||||
if(storage_bag)
|
||||
used_wheelchair = locate() in storage_bag.contents
|
||||
if(!l_foot || !r_foot || used_wheelchair)
|
||||
var/wheelchair_type = used_wheelchair?.unfolded_type || /obj/structure/bed/chair/wheelchair
|
||||
var/obj/structure/bed/chair/wheelchair/active_wheelchair = new wheelchair_type(human_mob.loc)
|
||||
active_wheelchair.buckle_mob(human_mob)
|
||||
human_mob.update_canmove()
|
||||
active_wheelchair.set_dir(human_mob.dir)
|
||||
active_wheelchair.add_fingerprint(human_mob)
|
||||
if(used_wheelchair)
|
||||
active_wheelchair.color = used_wheelchair.color
|
||||
qdel(used_wheelchair)
|
||||
|
||||
to_chat(human_mob, span_filter_notice(span_bold("You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank].")))
|
||||
|
||||
if(job.supervisors)
|
||||
to_chat(human_mob, span_filter_notice(span_bold("As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")))
|
||||
if(job.has_headset)
|
||||
human_mob.equip_to_slot_or_del(new /obj/item/radio/headset(human_mob), slot_l_ear)
|
||||
to_chat(human_mob, span_filter_notice(span_bold("To speak on your department's radio channel use :h. For the use of other channels, examine your headset.")))
|
||||
|
||||
if(job.req_admin_notify)
|
||||
to_chat(human_mob, span_filter_notice(span_bold("You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.")))
|
||||
|
||||
// EMAIL GENERATION
|
||||
// Email addresses will be created under this domain name. Mostly for the looks.
|
||||
var/domain = "freemail.nt"
|
||||
if(using_map && LAZYLEN(using_map.usable_email_tlds))
|
||||
domain = using_map.usable_email_tlds[1]
|
||||
var/sanitized_name = sanitize(replacetext(replacetext(lowertext(human_mob.real_name), " ", "."), "'", ""))
|
||||
var/complete_login = "[sanitized_name]@[domain]"
|
||||
|
||||
// It is VERY unlikely that we'll have two players, in the same round, with the same name and branch, but still, this is here.
|
||||
// If such conflict is encountered, a random number will be appended to the email address. If this fails too, no email account will be created.
|
||||
if(GLOB.ntnet_global.does_email_exist(complete_login))
|
||||
complete_login = "[sanitized_name][random_id(/datum/computer_file/data/email_account/, 100, 999)]@[domain]"
|
||||
|
||||
// If even fallback login generation failed, just don't give them an email. The chance of this happening is astronomically low.
|
||||
if(GLOB.ntnet_global.does_email_exist(complete_login))
|
||||
to_chat(human_mob, span_filter_notice("You were not assigned an email address."))
|
||||
human_mob.mind.store_memory("You were not assigned an email address.")
|
||||
else
|
||||
var/datum/computer_file/data/email_account/user_mail_acc = new/datum/computer_file/data/email_account()
|
||||
user_mail_acc.password = GenerateKey()
|
||||
user_mail_acc.login = complete_login
|
||||
to_chat(human_mob, span_filter_notice("Your email account address is " + span_bold("[user_mail_acc.login]") + " and the password is " + span_bold("[user_mail_acc.password]") + ". This information has also been placed into your notes."))
|
||||
human_mob.mind.store_memory("Your email account address is [user_mail_acc.login] and the password is [user_mail_acc.password].")
|
||||
// END EMAIL GENERATION
|
||||
|
||||
//Gives glasses to the vision impaired
|
||||
if(human_mob.disabilities & NEARSIGHTED)
|
||||
var/equipped = human_mob.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(human_mob), slot_glasses)
|
||||
if(equipped != 1)
|
||||
var/obj/item/clothing/glasses/worn_glasses = human_mob.glasses
|
||||
worn_glasses.prescription = TRUE
|
||||
|
||||
BITSET(human_mob.hud_updateflag, ID_HUD)
|
||||
BITSET(human_mob.hud_updateflag, IMPLOYAL_HUD)
|
||||
BITSET(human_mob.hud_updateflag, SPECIALROLE_HUD)
|
||||
return human_mob
|
||||
|
||||
/datum/controller/subsystem/job/proc/handle_feedback_gathering()
|
||||
for(var/datum/job/job in occupations)
|
||||
var/tmp_str = "|[job.title]|"
|
||||
|
||||
var/level1 = 0 //high
|
||||
var/level2 = 0 //medium
|
||||
var/level3 = 0 //low
|
||||
var/level4 = 0 //never
|
||||
var/level5 = 0 //banned
|
||||
var/level6 = 0 //account too young
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(!(player.ready && player.mind && !player.mind.assigned_role))
|
||||
continue //This player is not ready
|
||||
if(jobban_isbanned(player, job.title))
|
||||
level5++
|
||||
continue
|
||||
if(!job.player_old_enough(player.client))
|
||||
level6++
|
||||
continue
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
level6++
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
level1++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
level2++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
|
||||
level3++
|
||||
else level4++ //not selected
|
||||
|
||||
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
|
||||
feedback_add_details("job_preferences",tmp_str)
|
||||
|
||||
/datum/controller/subsystem/job/proc/late_spawn(client/spawn_client, rank)
|
||||
|
||||
var/datum/spawnpoint/spawnpos
|
||||
var/fail_deadly = FALSE
|
||||
var/obj/belly/vore_spawn_gut
|
||||
var/absorb_choice = FALSE // Ability to start absorbed with vorespawn
|
||||
var/mob/living/prey_to_nomph
|
||||
var/obj/item/item_to_be // Item TF spawning
|
||||
var/mob/living/item_carrier // Capture crystal spawning
|
||||
var/vorgans = FALSE // capture crystal simplemob spawning
|
||||
|
||||
// Remove fail_deadly addition on offmap_spawn
|
||||
|
||||
//Spawn them at their preferred one
|
||||
if(spawn_client?.prefs.read_preference(/datum/preference/choiced/living/spawnpoint))
|
||||
if(spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Vorespawn - Prey")
|
||||
var/list/preds = list()
|
||||
var/list/pred_names = list() //This is cringe
|
||||
for(var/client/current_client in GLOB.clients)
|
||||
if(!isliving(current_client.mob))
|
||||
continue
|
||||
var/mob/living/current_mob = current_client.mob
|
||||
if(current_mob.stat == UNCONSCIOUS || current_mob.stat == DEAD || (current_mob.client.is_afk(10 MINUTES) && !current_mob.no_latejoin_vore_warning))
|
||||
continue
|
||||
if(!current_mob.latejoin_vore)
|
||||
continue
|
||||
if(!(current_mob.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
preds += current_mob
|
||||
pred_names += current_mob.real_name //very cringe
|
||||
|
||||
if(length(preds))
|
||||
var/pred_name = tgui_input_list(spawn_client, "Choose a Predator.", "Pred Spawnpoint", pred_names)
|
||||
if(!pred_name)
|
||||
return
|
||||
var/index = pred_names.Find(pred_name)
|
||||
var/mob/living/pred = preds[index]
|
||||
var/list/available_bellies = list()
|
||||
for(var/obj/belly/current_belly in pred.vore_organs)
|
||||
if(current_belly.vorespawn_blacklist)
|
||||
continue
|
||||
if(LAZYLEN(current_belly.vorespawn_whitelist) && !(spawn_client.ckey in current_belly.vorespawn_whitelist))
|
||||
continue
|
||||
available_bellies += current_belly
|
||||
var/backup = tgui_alert(spawn_client, "Do you want a mind backup?", "Confirm", list("Yes", "No"))
|
||||
if(backup == "Yes")
|
||||
backup = 1
|
||||
vore_spawn_gut = tgui_input_list(spawn_client, "Choose a Belly.", "Belly Spawnpoint", available_bellies)
|
||||
if(!vore_spawn_gut)
|
||||
return
|
||||
if(vore_spawn_gut.vorespawn_absorbed & VS_FLAG_ABSORB_YES)
|
||||
absorb_choice = TRUE
|
||||
if(vore_spawn_gut.vorespawn_absorbed & VS_FLAG_ABSORB_PREY)
|
||||
if(tgui_alert(spawn_client, "Do you want to start absorbed into [pred]'s [vore_spawn_gut]?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
absorb_choice = FALSE
|
||||
else if(tgui_alert(spawn_client, "[pred]'s [vore_spawn_gut] will start with you absorbed. Continue?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
to_chat(spawn_client, span_boldwarning("[pred] has received your spawn request. Please wait."))
|
||||
log_admin("[key_name(spawn_client)] has requested to vore spawn into [key_name(pred)]")
|
||||
message_admins("[key_name(spawn_client)] has requested to vore spawn into [key_name(pred)]")
|
||||
|
||||
var/confirm
|
||||
var/spawner_name = spawn_client.prefs.read_preference(/datum/preference/name/real_name)
|
||||
if(pred.no_latejoin_vore_warning)
|
||||
if(pred.no_latejoin_vore_warning_time > 0)
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn absorbed as your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), pred.no_latejoin_vore_warning_time SECONDS)
|
||||
else
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn into your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), pred.no_latejoin_vore_warning_time SECONDS)
|
||||
if(!confirm)
|
||||
confirm = "Yes"
|
||||
else
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn absorbed as your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
else
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn into your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(spawn_client, span_warning("[pred] has declined your spawn request."))
|
||||
var/message = tgui_input_text(pred,"Do you want to leave them a message?", "Notify Prey", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(spawn_client, span_notice("[pred] message : [message]"))
|
||||
return
|
||||
if(!vore_spawn_gut || QDELETED(vore_spawn_gut))
|
||||
to_chat(spawn_client, span_warning("Somehow, the belly you were trying to enter no longer exists."))
|
||||
return
|
||||
if(pred.stat == UNCONSCIOUS || pred.stat == DEAD)
|
||||
to_chat(spawn_client, span_warning("[pred] is not conscious."))
|
||||
to_chat(pred, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(pred.z in using_map.vorespawn_levels))
|
||||
to_chat(spawn_client, span_warning("[pred] is no longer in station grounds."))
|
||||
to_chat(pred, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), spawn_client), 5 SECONDS)
|
||||
log_admin("[key_name(spawn_client)] has vore spawned into [key_name(pred)]")
|
||||
message_admins("[key_name(spawn_client)] has vore spawned into [key_name(pred)]")
|
||||
to_chat(spawn_client, span_notice("You have been spawned via vore. You are free to roleplay how you got there as you please, such as teleportation or having had already been there."))
|
||||
if(vore_spawn_gut.entrance_logs)
|
||||
to_chat(pred, span_notice("Your prey has spawned via vore. You are free to roleplay this how you please, such as teleportation or having had already been there."))
|
||||
else
|
||||
to_chat(spawn_client, span_warning("No predators were available to accept you."))
|
||||
return
|
||||
spawnpos = GLOB.spawntypes[spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]
|
||||
if(spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Vorespawn - Pred") //Same as above, but in reverse!
|
||||
var/list/preys = list()
|
||||
var/list/prey_names = list() //This is still cringe
|
||||
for(var/client/current_client in GLOB.clients)
|
||||
if(!isliving(current_client.mob))
|
||||
continue
|
||||
var/mob/living/current_mob = current_client.mob
|
||||
if(current_mob.stat == UNCONSCIOUS || current_mob.stat == DEAD || (current_mob.client.is_afk(10 MINUTES) && !current_mob.no_latejoin_prey_warning))
|
||||
continue
|
||||
if(!current_mob.latejoin_prey)
|
||||
continue
|
||||
if(!(current_mob.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
preys += current_mob
|
||||
prey_names += current_mob.real_name
|
||||
if(length(preys))
|
||||
var/prey_name = tgui_input_list(spawn_client, "Choose a Prey to spawn nom.", "Prey Spawnpoint", prey_names)
|
||||
if(!prey_name)
|
||||
return
|
||||
var/index = prey_names.Find(prey_name)
|
||||
var/mob/living/prey = preys[index]
|
||||
var/list/available_bellies = list()
|
||||
|
||||
var/datum/vore_preferences/spawn_preferences = spawn_client.prefs_vr
|
||||
for(var/preference in spawn_preferences.belly_prefs)
|
||||
available_bellies += preference["name"]
|
||||
vore_spawn_gut = tgui_input_list(spawn_client, "Choose your Belly.", "Belly Spawnpoint", available_bellies)
|
||||
if(!vore_spawn_gut)
|
||||
return
|
||||
if(alert(spawn_client, "Do you want to instantly absorb them?", "Confirm", "Yes", "No") == "Yes")
|
||||
absorb_choice = TRUE
|
||||
to_chat(spawn_client, span_boldwarning("[prey] has received your spawn request. Please wait."))
|
||||
log_admin("[key_name(spawn_client)] has requested to pred spawn onto [key_name(prey)]")
|
||||
message_admins("[key_name(spawn_client)] has requested to pred spawn onto [key_name(prey)]")
|
||||
|
||||
var/confirm
|
||||
var/spawner_name = spawn_client.prefs.read_preference(/datum/preference/name/real_name)
|
||||
if(prey.no_latejoin_prey_warning)
|
||||
if(prey.no_latejoin_prey_warning_time > 0)
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore and instantly absorb you with their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), prey.no_latejoin_prey_warning_time SECONDS)
|
||||
else
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore you into their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), prey.no_latejoin_prey_warning_time SECONDS)
|
||||
if(!confirm)
|
||||
confirm = "Yes"
|
||||
else
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore and instantly absorb you with their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
else
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore you into their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(spawn_client, span_warning("[prey] has declined your spawn request."))
|
||||
var/message = tgui_input_text(prey,"Do you want to leave them a message?", "Notify Pred", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(spawn_client, span_notice("[prey] message : [message]"))
|
||||
return
|
||||
if(prey.stat == UNCONSCIOUS || prey.stat == DEAD)
|
||||
to_chat(spawn_client, span_warning("[prey] is not conscious."))
|
||||
to_chat(prey, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(prey.z in using_map.vorespawn_levels))
|
||||
to_chat(spawn_client, span_warning("[prey] is no longer in station grounds."))
|
||||
to_chat(prey, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
log_admin("[key_name(spawn_client)] has pred spawned onto [key_name(prey)]")
|
||||
message_admins("[key_name(spawn_client)] has pred spawned onto [key_name(prey)]")
|
||||
prey_to_nomph = prey
|
||||
else
|
||||
to_chat(spawn_client, span_warning("No prey were available to accept you."))
|
||||
return
|
||||
// Item TF spawnpoints!
|
||||
else if(spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Item TF spawn")
|
||||
var/list/items = list()
|
||||
var/list/item_names = list()
|
||||
var/list/carriers = list()
|
||||
for(var/obj/item/item_spawnpoint in GLOB.item_tf_spawnpoints)
|
||||
if(LAZYLEN(item_spawnpoint.ckeys_allowed_itemspawn))
|
||||
if(!(spawn_client.ckey in item_spawnpoint.ckeys_allowed_itemspawn))
|
||||
continue
|
||||
var/atom/item_loc = item_spawnpoint.loc
|
||||
var/mob/living/carrier
|
||||
while(!isturf(item_loc))
|
||||
if(isliving(item_loc))
|
||||
carrier = item_loc
|
||||
break
|
||||
else
|
||||
item_loc = item_loc.loc
|
||||
if(istype(carrier))
|
||||
if(!(carrier.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
if(carrier.stat == UNCONSCIOUS || carrier.stat == DEAD || carrier.client.is_afk(10 MINUTES))
|
||||
continue
|
||||
carriers += carrier
|
||||
else
|
||||
if(!(item_loc.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
carriers += null
|
||||
|
||||
if(istype(item_spawnpoint, /obj/item/capture_crystal))
|
||||
if(carrier)
|
||||
items += item_spawnpoint
|
||||
var/obj/item/capture_crystal/cryst = item_spawnpoint
|
||||
if(cryst.spawn_mob_type)
|
||||
item_names += "\a [cryst.spawn_mob_name] inside of [carrier]'s [item_spawnpoint.name] ([item_spawnpoint.loc.name])"
|
||||
else
|
||||
item_names += "Inside of [carrier]'s [item_spawnpoint.name] ([item_spawnpoint.loc.name])"
|
||||
else if(item_spawnpoint.name == initial(item_spawnpoint.name))
|
||||
items += item_spawnpoint
|
||||
if(carrier)
|
||||
item_names += "[carrier]'s [item_spawnpoint.name] ([item_spawnpoint.loc.name])"
|
||||
else
|
||||
item_names += "[item_spawnpoint.name] ([item_spawnpoint.loc.name])"
|
||||
else
|
||||
items += item_spawnpoint
|
||||
if(carrier)
|
||||
item_names += "[carrier]'s [item_spawnpoint.name] (\a [initial(item_spawnpoint.name)] at [item_spawnpoint.loc.name])"
|
||||
else
|
||||
item_names += "[item_spawnpoint.name] (\a [initial(item_spawnpoint.name)] at [item_spawnpoint.loc.name])"
|
||||
if(LAZYLEN(items))
|
||||
var/backup = tgui_alert(spawn_client, "Do you want a mind backup?", "Confirm", list("Yes", "No"))
|
||||
if(backup == "Yes")
|
||||
backup = TRUE
|
||||
var/item_name = tgui_input_list(spawn_client, "Choose an Item to spawn as.", "Item TF Spawnpoint", item_names)
|
||||
if(!item_name)
|
||||
return
|
||||
var/index = item_names.Find(item_name)
|
||||
var/obj/item/item = items[index]
|
||||
|
||||
var/mob/living/carrier = carriers[index]
|
||||
if(istype(carrier))
|
||||
to_chat(spawn_client, span_boldwarning("[carrier] has received your spawn request. Please wait."))
|
||||
log_and_message_admins("[key_name(spawn_client)] has requested to item spawn into [key_name(carrier)]'s possession")
|
||||
|
||||
var/confirm = tgui_alert(carrier, "[spawn_client.prefs.read_preference(/datum/preference/name/real_name)] is attempting to join as the [item_name] in your possession.", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(spawn_client, span_warning("[carrier] has declined your spawn request."))
|
||||
var/message = tgui_input_text(carrier,"Do you want to leave them a message?", "Notify Spawner", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(spawn_client, span_notice("[carrier] message : [message]"))
|
||||
return
|
||||
if(carrier.stat == UNCONSCIOUS || carrier.stat == DEAD)
|
||||
to_chat(spawn_client, span_warning("[carrier] is not conscious."))
|
||||
to_chat(carrier, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(carrier.z in using_map.vorespawn_levels))
|
||||
to_chat(spawn_client, span_warning("[carrier] is no longer in station grounds."))
|
||||
to_chat(carrier, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
log_and_message_admins("[key_name(spawn_client)] has item spawned onto [key_name(carrier)]")
|
||||
item_to_be = item
|
||||
item_carrier = carrier
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), spawn_client), 5 SECONDS)
|
||||
else
|
||||
var/confirm = tgui_alert(spawn_client, "\The [item.name] is currently not in any character's possession! Do you still want to spawn as it?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
log_and_message_admins("[key_name(spawn_client)] has item spawned into \a [item.name] that was not held by anyone")
|
||||
item_to_be = item
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), spawn_client), 5 SECONDS)
|
||||
if(istype(item, /obj/item/capture_crystal))
|
||||
var/obj/item/capture_crystal/cryst = item
|
||||
if(cryst.spawn_mob_type)
|
||||
var/confirm = tgui_alert(spawn_client, "Do you want to spawn with your slot's vore organs and prefs?", "Confirm", list("No", "Yes"))
|
||||
if(confirm == "Yes")
|
||||
vorgans = TRUE
|
||||
else
|
||||
to_chat(spawn_client, span_warning("No items were available to accept you."))
|
||||
return
|
||||
else
|
||||
if(!(spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) in using_map.allowed_spawns))
|
||||
if(fail_deadly)
|
||||
to_chat(spawn_client, span_warning("Your chosen spawnpoint is unavailable for this map and your job requires a specific spawnpoint. Please correct your spawn point choice."))
|
||||
return
|
||||
else
|
||||
to_chat(spawn_client, span_warning("Your chosen spawnpoint ([spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead."))
|
||||
spawnpos = null
|
||||
else
|
||||
spawnpos = GLOB.spawntypes[spawn_client.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]
|
||||
|
||||
//We will return a list key'd by "turf" and "msg"
|
||||
. = list("turf","msg", "voreny", "prey", "itemtf", "vorgans", "carrier") // Item TF spawnpoints, spawn as mob
|
||||
if(vore_spawn_gut)
|
||||
.["voreny"] = vore_spawn_gut
|
||||
.["absorb"] = absorb_choice
|
||||
if(prey_to_nomph)
|
||||
.["prey"] = prey_to_nomph //We pass this on later to reverse the vorespawn in new_player.dm
|
||||
// Item TF spawnpoints
|
||||
if(item_to_be)
|
||||
.["carrier"] = item_carrier
|
||||
.["vorgans"] = vorgans
|
||||
.["itemtf"] = item_to_be
|
||||
if(spawnpos && istype(spawnpos) && length(spawnpos.turfs))
|
||||
if(spawnpos.check_job_spawning(rank))
|
||||
.["turf"] = spawnpos.get_spawn_position()
|
||||
.["msg"] = spawnpos.msg
|
||||
.["channel"] = spawnpos.announce_channel
|
||||
else
|
||||
var/datum/job/job_rank = SSjob.get_job(rank)
|
||||
if(fail_deadly || job_rank?.offmap_spawn)
|
||||
to_chat(spawn_client, span_warning("Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Please correct your spawn point choice."))
|
||||
return
|
||||
to_chat(spawn_client, span_filter_warning("Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."))
|
||||
var/spawning = pick(GLOB.latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
.["msg"] = "will arrive at the station shortly"
|
||||
else if(!fail_deadly)
|
||||
var/spawning = pick(GLOB.latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
.["msg"] = "has arrived on the station"
|
||||
|
||||
/datum/controller/subsystem/job/proc/m_backup_client(client/target_client) //Same as m_backup, but takes a client entry. Used for vore late joining.
|
||||
if(!ishuman(target_client.mob))
|
||||
return
|
||||
var/mob/living/carbon/human/target_human = target_client.mob
|
||||
SStranscore.m_backup(target_human.mind, target_human.nif, TRUE)
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_all_jobs()
|
||||
var/list/all_jobs = list()
|
||||
for(var/datum/job/current_job as anything in occupation_with_excludes)
|
||||
all_jobs += current_job.title
|
||||
return all_jobs
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_all_centcom_jobs()
|
||||
return list("VIP Guest",
|
||||
"Custodian",
|
||||
"Thunderdome Overseer",
|
||||
"Intel Officer",
|
||||
"Medical Officer",
|
||||
"Death Commando",
|
||||
"Research Officer",
|
||||
"BlackOps Commander",
|
||||
"Supreme Commander",
|
||||
"Emergency Response Team",
|
||||
"Emergency Response Team Leader")
|
||||
|
||||
@@ -108,10 +108,10 @@ SUBSYSTEM_DEF(persist)
|
||||
if(R) // We found someone with a record.
|
||||
var/recorded_rank = R.fields["real_rank"]
|
||||
if(recorded_rank)
|
||||
. = GLOB.job_master.GetJob(recorded_rank)
|
||||
. = SSjob.get_job(recorded_rank)
|
||||
if(.) return
|
||||
|
||||
// They have a custom title, aren't crew, or someone deleted their record, so we need a fallback method.
|
||||
// Let's check the mind.
|
||||
if(M.mind && M.mind.assigned_role)
|
||||
. = GLOB.job_master.GetJob(M.mind.assigned_role)
|
||||
. = SSjob.get_job(M.mind.assigned_role)
|
||||
|
||||
@@ -312,16 +312,16 @@ SUBSYSTEM_DEF(ticker)
|
||||
to_chat(world, span_boldannounce("Serious error in mode setup! Reverting to pregame lobby.")) //Uses setup instead of set up due to computational context.
|
||||
return 0
|
||||
|
||||
GLOB.job_master.ResetOccupations()
|
||||
SSjob.reset_occupations()
|
||||
src.mode.create_antagonists()
|
||||
src.mode.pre_setup()
|
||||
GLOB.job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
|
||||
SSjob.divide_occupations() // Apparently important for new antagonist system to register specific job antags properly.
|
||||
|
||||
if(!src.mode.can_start())
|
||||
to_chat(world, span_filter_system(span_bold("Unable to start [mode.name].") + " Not enough players readied, [CONFIG_GET(keyed_list/player_requirements)[mode.config_tag]] players needed. Reverting to pregame lobby."))
|
||||
mode.fail_setup()
|
||||
mode = null
|
||||
GLOB.job_master.ResetOccupations()
|
||||
SSjob.reset_occupations()
|
||||
return 0
|
||||
|
||||
if(hide_mode)
|
||||
@@ -367,7 +367,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
// Ask their new_player mob to spawn them
|
||||
if(!player.spawn_checks_vr(player.mind.assigned_role))
|
||||
var/datum/job/job_datum = GLOB.job_master.GetJob(J.title)
|
||||
var/datum/job/job_datum = SSjob.get_job(J.title)
|
||||
job_datum.current_positions--
|
||||
player.mind.assigned_role = null
|
||||
continue //VOREStation Add
|
||||
@@ -404,7 +404,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(player.mind.assigned_role == JOB_SITE_MANAGER)
|
||||
captainless=0
|
||||
if(!SSantag_job.player_is_antag(player.mind, only_offstation_roles = 1))
|
||||
GLOB.job_master.EquipRank(player, player.mind.assigned_role, 0)
|
||||
SSjob.equip_rank(player, player.mind.assigned_role, 0)
|
||||
UpdateFactionList(player)
|
||||
//equip_custom_items(player) //VOREStation Removal
|
||||
//player.apply_traits() //VOREStation Removal
|
||||
|
||||
+1
-1
@@ -194,7 +194,7 @@
|
||||
if(antag) antag.place_mob(src.current)
|
||||
|
||||
else if (href_list["role_edit"])
|
||||
var/new_role = tgui_input_list(usr, "Select new role", "Assigned role", assigned_role, GLOB.joblist)
|
||||
var/new_role = tgui_input_list(usr, "Select new role", "Assigned role", assigned_role, SSjob.occupations_by_name)
|
||||
if (!new_role) return
|
||||
assigned_role = new_role
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/obj/item/card/id/C = ..()
|
||||
if(!C)
|
||||
return
|
||||
var/datum/job/J = GLOB.job_master.GetJob(rank)
|
||||
var/datum/job/J = SSjob.get_job(rank)
|
||||
if(J)
|
||||
C.access = J.get_access()
|
||||
if(H.mind)
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
return C.registered_name
|
||||
|
||||
/proc/get_all_job_icons() //For all existing HUD icons
|
||||
return GLOB.joblist + GLOB.alt_titles_with_icons + list("Prisoner")
|
||||
return SSjob.occupations_by_name + GLOB.alt_titles_with_icons + list("Prisoner")
|
||||
|
||||
/obj/proc/GetJobName() //Used in secHUD icon generation
|
||||
var/obj/item/card/id/I = GetID()
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
return message
|
||||
|
||||
/datum/job/proc/get_job_icon()
|
||||
if(!GLOB.job_master.job_icons[title])
|
||||
if(!SSjob.job_icon_cache[title])
|
||||
var/mob/living/carbon/human/dummy/mannequin/mannequin = get_mannequin("#job_icon")
|
||||
dress_mannequin(mannequin)
|
||||
mannequin.dir = SOUTH
|
||||
@@ -181,9 +181,9 @@
|
||||
var/icon/preview_icon = getFlatIcon(mannequin)
|
||||
|
||||
preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser.
|
||||
GLOB.job_master.job_icons[title] = preview_icon
|
||||
SSjob.job_icon_cache[title] = preview_icon
|
||||
|
||||
return GLOB.job_master.job_icons[title]
|
||||
return SSjob.job_icon_cache[title]
|
||||
|
||||
/datum/job/proc/dress_mannequin(var/mob/living/carbon/human/dummy/mannequin/mannequin)
|
||||
mannequin.delete_inventory(TRUE)
|
||||
|
||||
@@ -1,986 +0,0 @@
|
||||
GLOBAL_DATUM(job_master, /datum/controller/occupations)
|
||||
|
||||
/datum/controller/occupations
|
||||
//List of all jobs
|
||||
var/list/occupations = list()
|
||||
//Players who need jobs
|
||||
var/list/unassigned = list()
|
||||
//Debug info
|
||||
var/list/job_debug = list()
|
||||
//Cache of icons for job info window
|
||||
var/list/job_icons = list()
|
||||
|
||||
/datum/controller/occupations/proc/SetupOccupations(var/faction = FACTION_STATION)
|
||||
occupations = list()
|
||||
//var/list/all_jobs = typesof(/datum/job)
|
||||
var/list/all_jobs = list(/datum/job/assistant) | using_map.allowed_jobs
|
||||
if(!all_jobs.len)
|
||||
to_chat(world, span_boldannounce("Error setting up jobs, no job datums found!"))
|
||||
return 0
|
||||
for(var/J in all_jobs)
|
||||
var/datum/job/job = new J()
|
||||
if(!job) continue
|
||||
if(job.faction != faction) continue
|
||||
occupations += job
|
||||
sortTim(occupations, GLOBAL_PROC_REF(cmp_job_datums))
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/datum/controller/occupations/proc/Debug(var/text)
|
||||
if(!GLOB.Debug2) return 0
|
||||
job_debug.Add(text)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/controller/occupations/proc/GetJob(var/rank)
|
||||
if(!rank) return null
|
||||
for(var/datum/job/J in occupations)
|
||||
if(!J) continue
|
||||
if(J.title == rank) return J
|
||||
return null
|
||||
|
||||
/datum/controller/occupations/proc/GetPlayerAltTitle(mob/new_player/player, rank)
|
||||
return player.client.prefs.GetPlayerAltTitle(GetJob(rank))
|
||||
|
||||
/datum/controller/occupations/proc/AssignRole(var/mob/new_player/player, var/rank, var/latejoin = 0)
|
||||
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
|
||||
if(player && player.mind && rank)
|
||||
var/datum/job/job = GetJob(rank)
|
||||
if(!job)
|
||||
return 0
|
||||
if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
return 0
|
||||
if(jobban_isbanned(player, rank))
|
||||
return 0
|
||||
if(!job.player_old_enough(player.client))
|
||||
return 0
|
||||
//VOREStation Add
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
return 0
|
||||
if(!is_job_whitelisted(player, rank))
|
||||
return 0
|
||||
//VOREStation Add End
|
||||
|
||||
var/position_limit = job.total_positions
|
||||
if(!latejoin)
|
||||
position_limit = job.spawn_positions
|
||||
if((job.current_positions < position_limit) || position_limit == -1)
|
||||
Debug("Player: [player] is now Rank: [rank], JCP:[job.current_positions], JPL:[position_limit]")
|
||||
player.mind.assigned_role = rank
|
||||
player.mind.role_alt_title = GetPlayerAltTitle(player, rank)
|
||||
unassigned -= player
|
||||
job.current_positions++
|
||||
return 1
|
||||
Debug("AR has failed, Player: [player], Rank: [rank]")
|
||||
return 0
|
||||
|
||||
/datum/controller/occupations/proc/FreeRole(var/rank) //making additional slot on the fly
|
||||
var/datum/job/job = GetJob(rank)
|
||||
if(job && job.total_positions != -1)
|
||||
job.total_positions++
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/controller/occupations/proc/update_limit(var/rank, var/comperator)
|
||||
var/datum/job/job = GetJob(rank)
|
||||
if(job && job.total_positions != -1)
|
||||
job.update_limit(comperator)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/controller/occupations/proc/FindOccupationCandidates(datum/job/job, level, flag)
|
||||
Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
|
||||
var/list/candidates = list()
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(jobban_isbanned(player, job.title))
|
||||
Debug("FOC isbanned failed, Player: [player]")
|
||||
continue
|
||||
if(!job.player_old_enough(player.client))
|
||||
Debug("FOC player not old enough, Player: [player]")
|
||||
continue
|
||||
if(job.minimum_character_age && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
Debug("FOC character not old enough, Player: [player]")
|
||||
continue
|
||||
//VOREStation Code Start
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
Debug("FOC character not enough playtime, Player: [player]")
|
||||
continue
|
||||
if(!is_job_whitelisted(player, job.title))
|
||||
Debug("FOC is_job_whitelisted failed, Player: [player]")
|
||||
continue
|
||||
//VOREStation Code End
|
||||
if(flag && !(player.client.prefs.be_special & flag))
|
||||
Debug("FOC flag failed, Player: [player], Flag: [flag], ")
|
||||
continue
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
Debug("FOC pass, Player: [player], Level:[level]")
|
||||
candidates += player
|
||||
return candidates
|
||||
|
||||
/datum/controller/occupations/proc/GiveRandomJob(var/mob/new_player/player)
|
||||
Debug("GRJ Giving random job, Player: [player]")
|
||||
for(var/datum/job/job in shuffle(occupations))
|
||||
if(!job)
|
||||
continue
|
||||
|
||||
if((job.minimum_character_age || job.min_age_by_species) && (player.read_preference(/datum/preference/numeric/human/age) < job.get_min_age(player.client.prefs.read_preference(/datum/preference/choiced/species), player.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])))
|
||||
continue
|
||||
|
||||
if(istype(job, GetJob(JOB_ALT_VISITOR))) // We don't want to give him assistant, that's boring! //VOREStation Edit - Visitor not Assistant
|
||||
continue
|
||||
|
||||
if(SSjob.is_job_in_department(job.title, DEPARTMENT_COMMAND)) //If you want a command position, select it!
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
Debug("GRJ isbanned failed, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
Debug("GRJ player not old enough, Player: [player]")
|
||||
continue
|
||||
|
||||
//VOREStation Code Start
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
Debug("GRJ player not enough playtime, Player: [player]")
|
||||
continue
|
||||
if(!is_job_whitelisted(player, job.title))
|
||||
Debug("GRJ player not whitelisted for this job, Player: [player], Job: [job.title]")
|
||||
continue
|
||||
//VOREStation Code End
|
||||
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
Debug("GRJ Random job given, Player: [player], Job: [job]")
|
||||
AssignRole(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
/datum/controller/occupations/proc/ResetOccupations()
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if((player) && (player.mind))
|
||||
player.mind.assigned_role = null
|
||||
player.mind.special_role = null
|
||||
SetupOccupations()
|
||||
unassigned = list()
|
||||
return
|
||||
|
||||
|
||||
///This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until it locates a head or runs out of levels to check
|
||||
/datum/controller/occupations/proc/FillHeadPosition()
|
||||
for(var/level = 1 to 3)
|
||||
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
var/datum/job/job = GetJob(command_position)
|
||||
if(!job) continue
|
||||
var/list/candidates = FindOccupationCandidates(job, level)
|
||||
if(!candidates.len) continue
|
||||
|
||||
// Build a weighted list, weight by age.
|
||||
var/list/weightedCandidates = list()
|
||||
for(var/mob/V in candidates)
|
||||
// Log-out during round-start? What a bad boy, no head position for you!
|
||||
if(!V.client) continue
|
||||
var/age = V.read_preference(/datum/preference/numeric/human/age)
|
||||
|
||||
if(age < job.get_min_age(V.client.prefs.read_preference(/datum/preference/choiced/species), V.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])) // Nope.
|
||||
continue
|
||||
|
||||
var/idealage = job.get_ideal_age(V.client.prefs.read_preference(/datum/preference/choiced/species), V.client.prefs.read_preference(/datum/preference/organ_data)?[O_BRAIN])
|
||||
var/agediff = abs(idealage - age) // Compute the absolute difference in age from target
|
||||
switch(agediff) /// If the math sucks, it's because I almost failed algebra in high school.
|
||||
if(20 to INFINITY)
|
||||
weightedCandidates[V] = 3 // Too far off
|
||||
if(10 to 20)
|
||||
weightedCandidates[V] = 6 // Nearer the mark, but not quite
|
||||
if(0 to 10)
|
||||
weightedCandidates[V] = 10 // On the mark
|
||||
else
|
||||
// If there's ABSOLUTELY NOBODY ELSE
|
||||
if(candidates.len == 1) weightedCandidates[V] = 1
|
||||
|
||||
|
||||
var/mob/new_player/candidate = pickweight(weightedCandidates)
|
||||
if(AssignRole(candidate, command_position))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
///This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
|
||||
/datum/controller/occupations/proc/CheckHeadPositions(var/level)
|
||||
for(var/command_position in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
var/datum/job/job = GetJob(command_position)
|
||||
if(!job) continue
|
||||
var/list/candidates = FindOccupationCandidates(job, level)
|
||||
if(!candidates.len) continue
|
||||
var/mob/new_player/candidate = pick(candidates)
|
||||
AssignRole(candidate, command_position)
|
||||
return
|
||||
|
||||
|
||||
/** Proc DivideOccupations
|
||||
* fills var "assigned_role" for all ready players.
|
||||
* This proc must not have any side effect besides of modifying "assigned_role".
|
||||
**/
|
||||
/datum/controller/occupations/proc/DivideOccupations()
|
||||
//Setup new player list and get the jobs list
|
||||
Debug("Running DO")
|
||||
SetupOccupations()
|
||||
|
||||
//Holder for Triumvirate is stored in the ticker, this just processes it
|
||||
if(SSticker && GLOB.triai)
|
||||
for(var/datum/job/A in occupations)
|
||||
if(A.title == JOB_AI)
|
||||
A.spawn_positions = 3
|
||||
break
|
||||
|
||||
//Get the players who are ready
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(player.ready && player.mind && !player.mind.assigned_role)
|
||||
unassigned += player
|
||||
|
||||
Debug("DO, Len: [unassigned.len]")
|
||||
if(unassigned.len == 0) return 0
|
||||
|
||||
//Shuffle players and jobs
|
||||
unassigned = shuffle(unassigned)
|
||||
|
||||
HandleFeedbackGathering()
|
||||
|
||||
//People who wants to be assistants, sure, go on.
|
||||
Debug("DO, Running Assistant Check 1")
|
||||
var/datum/job/assist = new DEFAULT_JOB_TYPE ()
|
||||
var/list/assistant_candidates = FindOccupationCandidates(assist, 3)
|
||||
Debug("AC1, Candidates: [assistant_candidates.len]")
|
||||
for(var/mob/new_player/player in assistant_candidates)
|
||||
Debug("AC1 pass, Player: [player]")
|
||||
AssignRole(player, JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant
|
||||
assistant_candidates -= player
|
||||
Debug("DO, AC1 end")
|
||||
|
||||
//Select one head
|
||||
Debug("DO, Running Head Check")
|
||||
FillHeadPosition()
|
||||
Debug("DO, Head Check end")
|
||||
|
||||
//Other jobs are now checked
|
||||
Debug("DO, Running Standard Check")
|
||||
|
||||
|
||||
// New job giving system by Donkie
|
||||
// This will cause lots of more loops, but since it's only done once it shouldn't really matter much at all.
|
||||
// Hopefully this will add more randomness and fairness to job giving.
|
||||
|
||||
// Loop through all levels from high to low
|
||||
var/list/shuffledoccupations = shuffle(occupations)
|
||||
// var/list/disabled_jobs = SSticker.mode.disabled_jobs // So we can use .Find down below without a colon.
|
||||
for(var/level = 1 to 3)
|
||||
//Check the head jobs first each level
|
||||
CheckHeadPositions(level)
|
||||
|
||||
// Loop through all unassigned players
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
|
||||
// Loop through all jobs
|
||||
for(var/datum/job/job in shuffledoccupations) // SHUFFLE ME BABY
|
||||
if(!job || SSticker.mode.disabled_jobs.Find(job.title) )
|
||||
continue
|
||||
|
||||
if(jobban_isbanned(player, job.title))
|
||||
Debug("DO isbanned failed, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
if(!job.player_old_enough(player.client))
|
||||
Debug("DO player not old enough, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
//VOREStation Add
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
Debug("DO player not enough playtime, Player: [player]")
|
||||
continue
|
||||
//VOREStation Add End
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
|
||||
// If the job isn't filled
|
||||
if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1)
|
||||
Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
|
||||
AssignRole(player, job.title)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
|
||||
GiveRandomJob(player)
|
||||
/*
|
||||
Old job system
|
||||
for(var/level = 1 to 3)
|
||||
for(var/datum/job/job in occupations)
|
||||
Debug("Checking job: [job]")
|
||||
if(!job)
|
||||
continue
|
||||
if(!unassigned.len)
|
||||
break
|
||||
if((job.current_positions >= job.spawn_positions) && job.spawn_positions != -1)
|
||||
continue
|
||||
var/list/candidates = FindOccupationCandidates(job, level)
|
||||
while(candidates.len && ((job.current_positions < job.spawn_positions) || job.spawn_positions == -1))
|
||||
var/mob/new_player/candidate = pick(candidates)
|
||||
Debug("Selcted: [candidate], for: [job.title]")
|
||||
AssignRole(candidate, job.title)
|
||||
candidates -= candidate*/
|
||||
|
||||
Debug("DO, Standard Check end")
|
||||
|
||||
Debug("DO, Running AC2")
|
||||
|
||||
// For those who wanted to be assistant if their preferences were filled, here you go.
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == BE_ASSISTANT)
|
||||
Debug("AC2 Assistant located, Player: [player]")
|
||||
AssignRole(player, JOB_ALT_VISITOR) //VOREStation Edit - Visitor not Assistant
|
||||
|
||||
//For ones returning to lobby
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
|
||||
player.ready = PLAYER_NOT_READY
|
||||
unassigned -= player
|
||||
return 1
|
||||
|
||||
|
||||
/datum/controller/occupations/proc/EquipRank(var/mob/living/carbon/human/H, var/rank, var/joined_late = 0, var/announce = TRUE)
|
||||
if(!H) return null
|
||||
|
||||
var/datum/job/job = GetJob(rank)
|
||||
var/list/spawn_in_storage = list()
|
||||
|
||||
if(!joined_late)
|
||||
var/obj/S = null
|
||||
var/list/possible_spawns = list()
|
||||
for(var/obj/effect/landmark/start/sloc in GLOB.landmarks_list)
|
||||
if(sloc.name != rank) continue
|
||||
if(locate(/mob/living) in sloc.loc) continue
|
||||
possible_spawns.Add(sloc)
|
||||
if(possible_spawns.len)
|
||||
S = pick(possible_spawns)
|
||||
if(!S)
|
||||
S = locate("start*[rank]") // use old stype
|
||||
if(istype(S, /obj/effect/landmark/start) && istype(S.loc, /turf))
|
||||
H.forceMove(S.loc)
|
||||
else
|
||||
var/list/spawn_props = LateSpawn(H.client, rank)
|
||||
var/turf/T = spawn_props["turf"]
|
||||
if(!T)
|
||||
to_chat(H, span_critical("You were unable to be spawned at your chosen late-join spawnpoint. Please verify your job/spawn point combination makes sense, and try another one."))
|
||||
return
|
||||
else
|
||||
H.forceMove(T)
|
||||
|
||||
// Moving wheelchair if they have one
|
||||
if(H.buckled && istype(H.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
H.buckled.forceMove(H.loc)
|
||||
H.buckled.set_dir(H.dir)
|
||||
|
||||
if(job)
|
||||
|
||||
//Equip custom gear loadout.
|
||||
var/list/custom_equip_slots = list()
|
||||
var/list/custom_equip_leftovers = list()
|
||||
if(H?.client?.prefs && !(job.mob_type & JOB_SILICON))
|
||||
var/list/active_gear_list = LAZYACCESS(H.client.prefs.gear_list, "[H.client.prefs.gear_slot]")
|
||||
for(var/thing in active_gear_list)
|
||||
var/datum/gear/G = GLOB.gear_datums[thing]
|
||||
if(!G) //Not a real gear datum (maybe removed, as this is loaded from their savefile)
|
||||
continue
|
||||
|
||||
var/permitted
|
||||
// Check if it is restricted to certain roles
|
||||
if(G.allowed_roles)
|
||||
for(var/job_name in G.allowed_roles)
|
||||
if(job.title == job_name)
|
||||
permitted = 1
|
||||
else
|
||||
permitted = 1
|
||||
|
||||
// Check if they're whitelisted for this gear (in alien whitelist? seriously?)
|
||||
if(G.whitelisted && !is_alien_whitelisted(H.client, GLOB.all_species[G.whitelisted]))
|
||||
permitted = 0
|
||||
|
||||
// If they aren't, tell them
|
||||
if(!permitted)
|
||||
to_chat(H, span_warning("Your current species, job or whitelist status does not permit you to spawn with [thing]!"))
|
||||
continue
|
||||
|
||||
// Implants get special treatment
|
||||
if(G.slot == "implant")
|
||||
var/obj/item/implant/I = G.spawn_item(H, active_gear_list[G.display_name])
|
||||
I.invisibility = INVISIBILITY_MAXIMUM
|
||||
I.implant_loadout(H)
|
||||
continue
|
||||
|
||||
// Try desperately (and sorta poorly) to equip the item. Now with increased desperation!
|
||||
if(G.slot && !(G.slot in custom_equip_slots))
|
||||
var/metadata = active_gear_list[G.display_name]
|
||||
//if(G.slot == slot_wear_mask || G.slot == slot_wear_suit || G.slot == slot_head)
|
||||
// custom_equip_leftovers += thing
|
||||
//else
|
||||
if(G.slot == slot_wear_suit && H.client?.prefs?.no_jacket)
|
||||
continue
|
||||
if(G.slot == slot_shoes && H.client?.prefs?.shoe_hater) //RS ADD
|
||||
continue
|
||||
if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
|
||||
to_chat(H, span_notice("Equipping you with \the [thing]!"))
|
||||
if(G.slot != slot_tie)
|
||||
custom_equip_slots.Add(G.slot)
|
||||
else
|
||||
custom_equip_leftovers.Add(thing)
|
||||
else
|
||||
spawn_in_storage += thing
|
||||
|
||||
// Set up their account
|
||||
job.setup_account(H)
|
||||
|
||||
// Equip job items.
|
||||
job.equip(H, H.mind ? H.mind.role_alt_title : "")
|
||||
|
||||
// Stick their fingerprints on literally everything
|
||||
job.apply_fingerprints(H)
|
||||
|
||||
// Only non-silicons get post-job-equip equipment and dormant diseases
|
||||
if(!(job.mob_type & JOB_SILICON))
|
||||
H.equip_post_job()
|
||||
H.give_random_dormant_disease(guaranteed_symptoms = job.symptoms)
|
||||
|
||||
// If some custom items could not be equipped before, try again now.
|
||||
for(var/thing in custom_equip_leftovers)
|
||||
var/datum/gear/G = GLOB.gear_datums[thing]
|
||||
if(G.slot == slot_wear_suit && H.client?.prefs?.no_jacket)
|
||||
continue
|
||||
if(G.slot == slot_shoes && H.client?.prefs?.shoe_hater) //RS ADD
|
||||
continue
|
||||
if(G.slot in custom_equip_slots)
|
||||
spawn_in_storage += thing
|
||||
else
|
||||
var/list/active_gear_list = LAZYACCESS(H.client.prefs.gear_list, "[H.client.prefs.gear_slot]")
|
||||
var/metadata = active_gear_list[G.display_name]
|
||||
if(H.equip_to_slot_or_del(G.spawn_item(H, metadata), G.slot))
|
||||
to_chat(H, span_notice("Equipping you with \the [thing]!"))
|
||||
custom_equip_slots.Add(G.slot)
|
||||
else
|
||||
spawn_in_storage += thing
|
||||
|
||||
//Give new players a welcome guide!
|
||||
if(isnum(H.client?.player_age) && H.client.player_age < 10)
|
||||
H.equip_to_slot_or_del(new /obj/item/book/manual/virgo_pamphlet(H), slot_r_hand)
|
||||
else
|
||||
to_chat(H, span_filter_notice("Your job is [rank] and the game just can't handle it! Please report this bug to an administrator."))
|
||||
|
||||
H.job = rank
|
||||
log_game("JOINED [key_name(H)] as \"[rank]\"")
|
||||
log_game("SPECIES [key_name(H)] is a: \"[H.species.name]\"") //VOREStation Add
|
||||
|
||||
// If they're head, give them the account info for their department
|
||||
if(H.mind && job.department_accounts)
|
||||
var/remembered_info = ""
|
||||
for(var/D in job.department_accounts)
|
||||
var/datum/money_account/department_account = GLOB.department_accounts[D]
|
||||
if(department_account)
|
||||
remembered_info += span_bold("Department account number ([D]):") + " #[department_account.account_number]<br>"
|
||||
remembered_info += span_bold("Department account pin ([D]):") + " [department_account.remote_access_pin]<br>"
|
||||
remembered_info += span_bold("Department account funds ([D]):") + " $[department_account.money]<br>"
|
||||
|
||||
H.mind.store_memory(remembered_info)
|
||||
|
||||
var/alt_title = null
|
||||
if(H.mind)
|
||||
H.mind.assigned_role = rank
|
||||
alt_title = H.mind.role_alt_title
|
||||
|
||||
// If we're a silicon, we may be done at this point
|
||||
if(job.mob_type & JOB_SILICON_ROBOT)
|
||||
return H.Robotize()
|
||||
if(job.mob_type & JOB_SILICON_AI)
|
||||
return H
|
||||
|
||||
// TWEET PEEP
|
||||
if(rank == JOB_SITE_MANAGER && announce)
|
||||
var/sound/announce_sound = (SSticker.current_state <= GAME_STATE_SETTING_UP) ? null : sound('sound/misc/boatswain.ogg', volume=20)
|
||||
GLOB.captain_announcement.Announce("All hands, [alt_title ? alt_title : JOB_SITE_MANAGER] [H.real_name] on deck!", new_sound = announce_sound, zlevel = H.z)
|
||||
|
||||
//Deferred item spawning.
|
||||
if(spawn_in_storage && spawn_in_storage.len)
|
||||
var/obj/item/storage/B
|
||||
for(var/obj/item/storage/S in H.contents)
|
||||
B = S
|
||||
break
|
||||
|
||||
var/list/active_gear_list = LAZYACCESS(H.client.prefs.gear_list, "[H.client.prefs.gear_slot]")
|
||||
if(!isnull(B))
|
||||
for(var/thing in spawn_in_storage)
|
||||
to_chat(H, span_notice("Placing \the [thing] in your [B.name]!"))
|
||||
var/datum/gear/G = GLOB.gear_datums[thing]
|
||||
var/metadata = active_gear_list[G.display_name]
|
||||
G.spawn_item(B, metadata)
|
||||
else
|
||||
to_chat(H, span_danger("Failed to locate a storage object on your mob, either you spawned with no arms and no backpack or this is a bug."))
|
||||
|
||||
if(istype(H)) //give humans wheelchairs, if they need them.
|
||||
var/obj/item/organ/external/l_foot = H.get_organ(BP_L_FOOT)
|
||||
var/obj/item/organ/external/r_foot = H.get_organ(BP_R_FOOT)
|
||||
var/obj/item/storage/S = locate() in H.contents
|
||||
var/obj/item/wheelchair/R
|
||||
if(S)
|
||||
R = locate() in S.contents
|
||||
if(!l_foot || !r_foot || R)
|
||||
var/wheelchair_type = R?.unfolded_type || /obj/structure/bed/chair/wheelchair
|
||||
var/obj/structure/bed/chair/wheelchair/W = new wheelchair_type(H.loc)
|
||||
W.buckle_mob(H)
|
||||
H.update_canmove()
|
||||
W.set_dir(H.dir)
|
||||
W.add_fingerprint(H)
|
||||
if(R)
|
||||
W.color = R.color
|
||||
qdel(R)
|
||||
|
||||
to_chat(H, span_filter_notice(span_bold("You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank].")))
|
||||
|
||||
if(job.supervisors)
|
||||
to_chat(H, span_filter_notice(span_bold("As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.")))
|
||||
if(job.has_headset)
|
||||
H.equip_to_slot_or_del(new /obj/item/radio/headset(H), slot_l_ear)
|
||||
to_chat(H, span_filter_notice(span_bold("To speak on your department's radio channel use :h. For the use of other channels, examine your headset.")))
|
||||
|
||||
if(job.req_admin_notify)
|
||||
to_chat(H, span_filter_notice(span_bold("You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.")))
|
||||
|
||||
// EMAIL GENERATION
|
||||
// Email addresses will be created under this domain name. Mostly for the looks.
|
||||
var/domain = "freemail.nt"
|
||||
if(using_map && LAZYLEN(using_map.usable_email_tlds))
|
||||
domain = using_map.usable_email_tlds[1]
|
||||
var/sanitized_name = sanitize(replacetext(replacetext(lowertext(H.real_name), " ", "."), "'", ""))
|
||||
var/complete_login = "[sanitized_name]@[domain]"
|
||||
|
||||
// It is VERY unlikely that we'll have two players, in the same round, with the same name and branch, but still, this is here.
|
||||
// If such conflict is encountered, a random number will be appended to the email address. If this fails too, no email account will be created.
|
||||
if(GLOB.ntnet_global.does_email_exist(complete_login))
|
||||
complete_login = "[sanitized_name][random_id(/datum/computer_file/data/email_account/, 100, 999)]@[domain]"
|
||||
|
||||
// If even fallback login generation failed, just don't give them an email. The chance of this happening is astronomically low.
|
||||
if(GLOB.ntnet_global.does_email_exist(complete_login))
|
||||
to_chat(H, span_filter_notice("You were not assigned an email address."))
|
||||
H.mind.store_memory("You were not assigned an email address.")
|
||||
else
|
||||
var/datum/computer_file/data/email_account/EA = new/datum/computer_file/data/email_account()
|
||||
EA.password = GenerateKey()
|
||||
EA.login = complete_login
|
||||
to_chat(H, span_filter_notice("Your email account address is <b>[EA.login]</b> and the password is <b>[EA.password]</b>. This information has also been placed into your notes."))
|
||||
H.mind.store_memory("Your email account address is [EA.login] and the password is [EA.password].")
|
||||
// END EMAIL GENERATION
|
||||
|
||||
//Gives glasses to the vision impaired
|
||||
if(H.disabilities & NEARSIGHTED)
|
||||
var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses)
|
||||
if(equipped != 1)
|
||||
var/obj/item/clothing/glasses/G = H.glasses
|
||||
G.prescription = TRUE
|
||||
|
||||
BITSET(H.hud_updateflag, ID_HUD)
|
||||
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
|
||||
BITSET(H.hud_updateflag, SPECIALROLE_HUD)
|
||||
return H
|
||||
|
||||
/datum/controller/occupations/proc/LoadJobs(jobsfile) //ran during round setup, reads info from jobs.txt -- Urist
|
||||
if(!CONFIG_GET(flag/load_jobs_from_txt))
|
||||
return 0
|
||||
|
||||
var/list/jobEntries = world.file2list(jobsfile)
|
||||
|
||||
for(var/job in jobEntries)
|
||||
if(!job)
|
||||
continue
|
||||
|
||||
job = trim(job)
|
||||
if (!length(job))
|
||||
continue
|
||||
|
||||
var/pos = findtext(job, "=")
|
||||
var/name = null
|
||||
var/value = null
|
||||
|
||||
if(pos)
|
||||
name = copytext(job, 1, pos)
|
||||
value = copytext(job, pos + 1)
|
||||
else
|
||||
continue
|
||||
|
||||
if(name && value)
|
||||
var/datum/job/J = GetJob(name)
|
||||
if(!J) continue
|
||||
J.total_positions = text2num(value)
|
||||
J.spawn_positions = text2num(value)
|
||||
if(J.mob_type & JOB_SILICON)
|
||||
J.total_positions = 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/datum/controller/occupations/proc/HandleFeedbackGathering()
|
||||
for(var/datum/job/job in occupations)
|
||||
var/tmp_str = "|[job.title]|"
|
||||
|
||||
var/level1 = 0 //high
|
||||
var/level2 = 0 //medium
|
||||
var/level3 = 0 //low
|
||||
var/level4 = 0 //never
|
||||
var/level5 = 0 //banned
|
||||
var/level6 = 0 //account too young
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(!(player.ready && player.mind && !player.mind.assigned_role))
|
||||
continue //This player is not ready
|
||||
if(jobban_isbanned(player, job.title))
|
||||
level5++
|
||||
continue
|
||||
if(!job.player_old_enough(player.client))
|
||||
level6++
|
||||
continue
|
||||
//VOREStation Add
|
||||
if(!job.player_has_enough_playtime(player.client))
|
||||
level6++
|
||||
continue
|
||||
//VOREStation Add End
|
||||
if(player.client.prefs.GetJobDepartment(job, 1) & job.flag)
|
||||
level1++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag)
|
||||
level2++
|
||||
else if(player.client.prefs.GetJobDepartment(job, 3) & job.flag)
|
||||
level3++
|
||||
else level4++ //not selected
|
||||
|
||||
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
|
||||
feedback_add_details("job_preferences",tmp_str)
|
||||
|
||||
/datum/controller/occupations/proc/LateSpawn(var/client/C, var/rank)
|
||||
|
||||
var/datum/spawnpoint/spawnpos
|
||||
var/fail_deadly = FALSE
|
||||
var/obj/belly/vore_spawn_gut
|
||||
var/absorb_choice = FALSE // Ability to start absorbed with vorespawn
|
||||
var/mob/living/prey_to_nomph
|
||||
var/obj/item/item_to_be // Item TF spawning
|
||||
var/mob/living/item_carrier // Capture crystal spawning
|
||||
var/vorgans = FALSE // capture crystal simplemob spawning
|
||||
|
||||
// Remove fail_deadly addition on offmap_spawn
|
||||
|
||||
//Spawn them at their preferred one
|
||||
if(C && C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint))
|
||||
if(C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Vorespawn - Prey")
|
||||
var/list/preds = list()
|
||||
var/list/pred_names = list() //This is cringe
|
||||
for(var/client/V in GLOB.clients)
|
||||
if(!isliving(V.mob))
|
||||
continue
|
||||
var/mob/living/M = V.mob
|
||||
if(M.stat == UNCONSCIOUS || M.stat == DEAD || (M.client.is_afk(10 MINUTES) && !M.no_latejoin_vore_warning))
|
||||
continue
|
||||
if(!M.latejoin_vore)
|
||||
continue
|
||||
if(!(M.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
preds += M
|
||||
pred_names += M.real_name //very cringe
|
||||
|
||||
if(preds.len)
|
||||
var/pred_name = tgui_input_list(C, "Choose a Predator.", "Pred Spawnpoint", pred_names)
|
||||
if(!pred_name)
|
||||
return
|
||||
var/index = pred_names.Find(pred_name)
|
||||
var/mob/living/pred = preds[index]
|
||||
var/list/available_bellies = list()
|
||||
for(var/obj/belly/Y in pred.vore_organs)
|
||||
if(Y.vorespawn_blacklist)
|
||||
continue
|
||||
if(LAZYLEN(Y.vorespawn_whitelist) && !(C.ckey in Y.vorespawn_whitelist))
|
||||
continue
|
||||
available_bellies += Y
|
||||
var/backup = tgui_alert(C, "Do you want a mind backup?", "Confirm", list("Yes", "No"))
|
||||
if(backup == "Yes")
|
||||
backup = 1
|
||||
vore_spawn_gut = tgui_input_list(C, "Choose a Belly.", "Belly Spawnpoint", available_bellies)
|
||||
if(!vore_spawn_gut)
|
||||
return
|
||||
if(vore_spawn_gut.vorespawn_absorbed & VS_FLAG_ABSORB_YES)
|
||||
absorb_choice = TRUE
|
||||
if(vore_spawn_gut.vorespawn_absorbed & VS_FLAG_ABSORB_PREY)
|
||||
if(tgui_alert(C, "Do you want to start absorbed into [pred]'s [vore_spawn_gut]?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
absorb_choice = FALSE
|
||||
else if(tgui_alert(C, "[pred]'s [vore_spawn_gut] will start with you absorbed. Continue?", "Confirm", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
to_chat(C, span_boldwarning("[pred] has received your spawn request. Please wait."))
|
||||
log_admin("[key_name(C)] has requested to vore spawn into [key_name(pred)]")
|
||||
message_admins("[key_name(C)] has requested to vore spawn into [key_name(pred)]")
|
||||
|
||||
var/confirm
|
||||
var/spawner_name = C.prefs.read_preference(/datum/preference/name/real_name)
|
||||
if(pred.no_latejoin_vore_warning)
|
||||
if(pred.no_latejoin_vore_warning_time > 0)
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn absorbed as your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), pred.no_latejoin_vore_warning_time SECONDS)
|
||||
else
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn into your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), pred.no_latejoin_vore_warning_time SECONDS)
|
||||
if(!confirm)
|
||||
confirm = "Yes"
|
||||
else
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn absorbed as your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
else
|
||||
confirm = tgui_alert(pred, "[spawner_name] is attempting to spawn into your [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(C, span_warning("[pred] has declined your spawn request."))
|
||||
var/message = tgui_input_text(pred,"Do you want to leave them a message?", "Notify Prey", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(C, span_notice("[pred] message : [message]"))
|
||||
return
|
||||
if(!vore_spawn_gut || QDELETED(vore_spawn_gut))
|
||||
to_chat(C, span_warning("Somehow, the belly you were trying to enter no longer exists."))
|
||||
return
|
||||
if(pred.stat == UNCONSCIOUS || pred.stat == DEAD)
|
||||
to_chat(C, span_warning("[pred] is not conscious."))
|
||||
to_chat(pred, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(pred.z in using_map.vorespawn_levels))
|
||||
to_chat(C, span_warning("[pred] is no longer in station grounds."))
|
||||
to_chat(pred, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), C), 5 SECONDS)
|
||||
log_admin("[key_name(C)] has vore spawned into [key_name(pred)]")
|
||||
message_admins("[key_name(C)] has vore spawned into [key_name(pred)]")
|
||||
to_chat(C, span_notice("You have been spawned via vore. You are free to roleplay how you got there as you please, such as teleportation or having had already been there."))
|
||||
if(vore_spawn_gut.entrance_logs)
|
||||
to_chat(pred, span_notice("Your prey has spawned via vore. You are free to roleplay this how you please, such as teleportation or having had already been there."))
|
||||
else
|
||||
to_chat(C, span_warning("No predators were available to accept you."))
|
||||
return
|
||||
spawnpos = GLOB.spawntypes[C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]
|
||||
if(C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Vorespawn - Pred") //Same as above, but in reverse!
|
||||
var/list/preys = list()
|
||||
var/list/prey_names = list() //This is still cringe
|
||||
for(var/client/V in GLOB.clients)
|
||||
if(!isliving(V.mob))
|
||||
continue
|
||||
var/mob/living/M = V.mob
|
||||
if(M.stat == UNCONSCIOUS || M.stat == DEAD || (M.client.is_afk(10 MINUTES) && !M.no_latejoin_prey_warning))
|
||||
continue
|
||||
if(!M.latejoin_prey)
|
||||
continue
|
||||
if(!(M.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
preys += M
|
||||
prey_names += M.real_name
|
||||
if(preys.len)
|
||||
var/prey_name = tgui_input_list(C, "Choose a Prey to spawn nom.", "Prey Spawnpoint", prey_names)
|
||||
if(!prey_name)
|
||||
return
|
||||
var/index = prey_names.Find(prey_name)
|
||||
var/mob/living/prey = preys[index]
|
||||
var/list/available_bellies = list()
|
||||
|
||||
var/datum/vore_preferences/P = C.prefs_vr
|
||||
for(var/Y in P.belly_prefs)
|
||||
available_bellies += Y["name"]
|
||||
vore_spawn_gut = tgui_input_list(C, "Choose your Belly.", "Belly Spawnpoint", available_bellies)
|
||||
if(!vore_spawn_gut)
|
||||
return
|
||||
if(alert(C, "Do you want to instantly absorb them?", "Confirm", "Yes", "No") == "Yes")
|
||||
absorb_choice = TRUE
|
||||
to_chat(C, span_boldwarning("[prey] has received your spawn request. Please wait."))
|
||||
log_admin("[key_name(C)] has requested to pred spawn onto [key_name(prey)]")
|
||||
message_admins("[key_name(C)] has requested to pred spawn onto [key_name(prey)]")
|
||||
|
||||
var/confirm
|
||||
var/spawner_name = C.prefs.read_preference(/datum/preference/name/real_name)
|
||||
if(prey.no_latejoin_prey_warning)
|
||||
if(prey.no_latejoin_prey_warning_time > 0)
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore and instantly absorb you with their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), prey.no_latejoin_prey_warning_time SECONDS)
|
||||
else
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore you into their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"), prey.no_latejoin_prey_warning_time SECONDS)
|
||||
if(!confirm)
|
||||
confirm = "Yes"
|
||||
else
|
||||
if(absorb_choice)
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore and instantly absorb you with their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
else
|
||||
confirm = tgui_alert(prey, "[spawner_name] is attempting to televore you into their [vore_spawn_gut]. Let them?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(C, span_warning("[prey] has declined your spawn request."))
|
||||
var/message = tgui_input_text(prey,"Do you want to leave them a message?", "Notify Pred", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(C, span_notice("[prey] message : [message]"))
|
||||
return
|
||||
if(prey.stat == UNCONSCIOUS || prey.stat == DEAD)
|
||||
to_chat(C, span_warning("[prey] is not conscious."))
|
||||
to_chat(prey, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(prey.z in using_map.vorespawn_levels))
|
||||
to_chat(C, span_warning("[prey] is no longer in station grounds."))
|
||||
to_chat(prey, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
log_admin("[key_name(C)] has pred spawned onto [key_name(prey)]")
|
||||
message_admins("[key_name(C)] has pred spawned onto [key_name(prey)]")
|
||||
prey_to_nomph = prey
|
||||
else
|
||||
to_chat(C, span_warning("No prey were available to accept you."))
|
||||
return
|
||||
// Item TF spawnpoints!
|
||||
else if(C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) == "Item TF spawn")
|
||||
var/list/items = list()
|
||||
var/list/item_names = list()
|
||||
var/list/carriers = list()
|
||||
for(var/obj/item/I in GLOB.item_tf_spawnpoints)
|
||||
if(LAZYLEN(I.ckeys_allowed_itemspawn))
|
||||
if(!(C.ckey in I.ckeys_allowed_itemspawn))
|
||||
continue
|
||||
var/atom/item_loc = I.loc
|
||||
var/mob/living/carrier
|
||||
while(!isturf(item_loc))
|
||||
if(isliving(item_loc))
|
||||
carrier = item_loc
|
||||
break
|
||||
else
|
||||
item_loc = item_loc.loc
|
||||
if(istype(carrier))
|
||||
if(!(carrier.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
if(carrier.stat == UNCONSCIOUS || carrier.stat == DEAD || carrier.client.is_afk(10 MINUTES))
|
||||
continue
|
||||
carriers += carrier
|
||||
else
|
||||
if(!(item_loc.z in using_map.vorespawn_levels))
|
||||
continue
|
||||
carriers += null
|
||||
|
||||
if(istype(I, /obj/item/capture_crystal))
|
||||
if(carrier)
|
||||
items += I
|
||||
var/obj/item/capture_crystal/cryst = I
|
||||
if(cryst.spawn_mob_type)
|
||||
item_names += "\a [cryst.spawn_mob_name] inside of [carrier]'s [I.name] ([I.loc.name])"
|
||||
else
|
||||
item_names += "Inside of [carrier]'s [I.name] ([I.loc.name])"
|
||||
else if(I.name == initial(I.name))
|
||||
items += I
|
||||
if(carrier)
|
||||
item_names += "[carrier]'s [I.name] ([I.loc.name])"
|
||||
else
|
||||
item_names += "[I.name] ([I.loc.name])"
|
||||
else
|
||||
items += I
|
||||
if(carrier)
|
||||
item_names += "[carrier]'s [I.name] (\a [initial(I.name)] at [I.loc.name])"
|
||||
else
|
||||
item_names += "[I.name] (\a [initial(I.name)] at [I.loc.name])"
|
||||
if(LAZYLEN(items))
|
||||
var/backup = tgui_alert(C, "Do you want a mind backup?", "Confirm", list("Yes", "No"))
|
||||
if(backup == "Yes")
|
||||
backup = 1
|
||||
var/item_name = tgui_input_list(C, "Choose an Item to spawn as.", "Item TF Spawnpoint", item_names)
|
||||
if(!item_name)
|
||||
return
|
||||
var/index = item_names.Find(item_name)
|
||||
var/obj/item/item = items[index]
|
||||
|
||||
var/mob/living/carrier = carriers[index]
|
||||
if(istype(carrier))
|
||||
to_chat(C, span_boldwarning("[carrier] has received your spawn request. Please wait."))
|
||||
log_and_message_admins("[key_name(C)] has requested to item spawn into [key_name(carrier)]'s possession")
|
||||
|
||||
var/confirm = tgui_alert(carrier, "[C.prefs.read_preference(/datum/preference/name/real_name)] is attempting to join as the [item_name] in your possession.", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
to_chat(C, span_warning("[carrier] has declined your spawn request."))
|
||||
var/message = tgui_input_text(carrier,"Do you want to leave them a message?", "Notify Spawner", max_length = MAX_MESSAGE_LEN)
|
||||
if(message)
|
||||
to_chat(C, span_notice("[carrier] message : [message]"))
|
||||
return
|
||||
if(carrier.stat == UNCONSCIOUS || carrier.stat == DEAD)
|
||||
to_chat(C, span_warning("[carrier] is not conscious."))
|
||||
to_chat(carrier, span_warning("You must be conscious to accept."))
|
||||
return
|
||||
if(!(carrier.z in using_map.vorespawn_levels))
|
||||
to_chat(C, span_warning("[carrier] is no longer in station grounds."))
|
||||
to_chat(carrier, span_warning("You must be within station grounds to accept."))
|
||||
return
|
||||
log_and_message_admins("[key_name(C)] has item spawned onto [key_name(carrier)]")
|
||||
item_to_be = item
|
||||
item_carrier = carrier
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), C), 5 SECONDS)
|
||||
else
|
||||
var/confirm = tgui_alert(C, "\The [item.name] is currently not in any character's possession! Do you still want to spawn as it?", "Confirm", list("No", "Yes"))
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
log_and_message_admins("[key_name(C)] has item spawned into \a [item.name] that was not held by anyone")
|
||||
item_to_be = item
|
||||
if(backup)
|
||||
addtimer(CALLBACK(src, PROC_REF(m_backup_client), C), 5 SECONDS)
|
||||
if(istype(item, /obj/item/capture_crystal))
|
||||
var/obj/item/capture_crystal/cryst = item
|
||||
if(cryst.spawn_mob_type)
|
||||
var/confirm = tgui_alert(C, "Do you want to spawn with your slot's vore organs and prefs?", "Confirm", list("No", "Yes"))
|
||||
if(confirm == "Yes")
|
||||
vorgans = TRUE
|
||||
else
|
||||
to_chat(C, span_warning("No items were available to accept you."))
|
||||
return
|
||||
else
|
||||
if(!(C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint) in using_map.allowed_spawns))
|
||||
if(fail_deadly)
|
||||
to_chat(C, span_warning("Your chosen spawnpoint is unavailable for this map and your job requires a specific spawnpoint. Please correct your spawn point choice."))
|
||||
return
|
||||
else
|
||||
to_chat(C, span_warning("Your chosen spawnpoint ([C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]) is unavailable for the current map. Spawning you at one of the enabled spawn points instead."))
|
||||
spawnpos = null
|
||||
else
|
||||
spawnpos = GLOB.spawntypes[C.prefs.read_preference(/datum/preference/choiced/living/spawnpoint)]
|
||||
|
||||
//We will return a list key'd by "turf" and "msg"
|
||||
. = list("turf","msg", "voreny", "prey", "itemtf", "vorgans", "carrier") // Item TF spawnpoints, spawn as mob
|
||||
if(vore_spawn_gut)
|
||||
.["voreny"] = vore_spawn_gut
|
||||
.["absorb"] = absorb_choice
|
||||
if(prey_to_nomph)
|
||||
.["prey"] = prey_to_nomph //We pass this on later to reverse the vorespawn in new_player.dm
|
||||
// Item TF spawnpoints
|
||||
if(item_to_be)
|
||||
.["carrier"] = item_carrier
|
||||
.["vorgans"] = vorgans
|
||||
.["itemtf"] = item_to_be
|
||||
if(spawnpos && istype(spawnpos) && length(spawnpos.turfs))
|
||||
if(spawnpos.check_job_spawning(rank))
|
||||
.["turf"] = spawnpos.get_spawn_position()
|
||||
.["msg"] = spawnpos.msg
|
||||
.["channel"] = spawnpos.announce_channel
|
||||
else
|
||||
var/datum/job/J = SSjob.get_job(rank)
|
||||
if(fail_deadly || J?.offmap_spawn)
|
||||
to_chat(C, span_warning("Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Please correct your spawn point choice."))
|
||||
return
|
||||
to_chat(C, span_filter_warning("Your chosen spawnpoint ([spawnpos.display_name]) is unavailable for your chosen job. Spawning you at the Arrivals shuttle instead."))
|
||||
var/spawning = pick(GLOB.latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
.["msg"] = "will arrive at the station shortly"
|
||||
else if(!fail_deadly)
|
||||
var/spawning = pick(GLOB.latejoin)
|
||||
.["turf"] = get_turf(spawning)
|
||||
.["msg"] = "has arrived on the station"
|
||||
|
||||
/datum/controller/occupations/proc/m_backup_client(var/client/C) //Same as m_backup, but takes a client entry. Used for vore late joining.
|
||||
if(!ishuman(C.mob))
|
||||
return
|
||||
var/mob/living/carbon/human/CM = C.mob
|
||||
SStranscore.m_backup(CM.mind, CM.nif, TRUE)
|
||||
@@ -35,7 +35,7 @@ ADMIN_VERB(open_whitelist_editor, R_ADMIN|R_SERVER, "Open Whitelist Editor", "Op
|
||||
|
||||
/datum/whitelist_editor/tgui_static_data(mob/user)
|
||||
var/list/whitelist_jobs = list()
|
||||
for(var/datum/job/our_job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/our_job in SSjob.occupations)
|
||||
if(our_job.whitelist_only)
|
||||
whitelist_jobs += our_job.title
|
||||
|
||||
@@ -75,7 +75,7 @@ ADMIN_VERB(open_whitelist_editor, R_ADMIN|R_SERVER, "Open Whitelist Editor", "Op
|
||||
var/role = params["role"]
|
||||
switch(kind)
|
||||
if("job")
|
||||
var/datum/job/job = GLOB.job_master.GetJob(role)
|
||||
var/datum/job/job = SSjob.get_job(role)
|
||||
if(!job)
|
||||
to_chat(ui.user, span_warning("Error, invalid job entered. Check spelling and capitalization."))
|
||||
return FALSE
|
||||
@@ -292,7 +292,7 @@ ADMIN_VERB(open_whitelist_editor, R_ADMIN|R_SERVER, "Open Whitelist Editor", "Op
|
||||
|
||||
/proc/is_job_whitelisted(mob/M, var/rank)
|
||||
// Check if the job actually requires a whitelist
|
||||
var/datum/job/job = GLOB.job_master.GetJob(rank)
|
||||
var/datum/job/job = SSjob.get_job(rank)
|
||||
if(!job.whitelist_only)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -403,7 +403,7 @@
|
||||
answer = text2num(answer)
|
||||
|
||||
if(field == "rank")
|
||||
if(answer in GLOB.joblist)
|
||||
if(answer in SSjob.occupations_by_name)
|
||||
active1.fields["real_rank"] = answer
|
||||
|
||||
if(field == "criminal")
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
data["card"] = "[card]"
|
||||
data["assignment"] = card.assignment
|
||||
data["card_cooldown"] = getCooldown()
|
||||
var/datum/job/job = GLOB.job_master.GetJob(card.rank)
|
||||
var/datum/job/job = SSjob.get_job(card.rank)
|
||||
if(job)
|
||||
data["job_datum"] = list(
|
||||
"title" = job.title,
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
/obj/machinery/computer/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department)
|
||||
var/list/available_jobs = list()
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(isOpenOnDutyJob(user, department, job))
|
||||
available_jobs[job.title] = list(job.title)
|
||||
if(job.alt_titles)
|
||||
@@ -167,8 +167,8 @@
|
||||
&& job.timeoff_factor > 0
|
||||
|
||||
/obj/machinery/computer/timeclock/proc/makeOnDuty(var/newrank, var/newassignment, var/mob/user)
|
||||
var/datum/job/oldjob = GLOB.job_master.GetJob(card.rank)
|
||||
var/datum/job/newjob = GLOB.job_master.GetJob(newrank)
|
||||
var/datum/job/oldjob = SSjob.get_job(card.rank)
|
||||
var/datum/job/newjob = SSjob.get_job(newrank)
|
||||
if(!oldjob || !isOpenOnDutyJob(user, oldjob.pto_type, newjob))
|
||||
return
|
||||
if(newassignment != newjob.title && !(newassignment in newjob.alt_titles))
|
||||
@@ -189,12 +189,12 @@
|
||||
return
|
||||
|
||||
/obj/machinery/computer/timeclock/proc/makeOffDuty(var/mob/user)
|
||||
var/datum/job/foundjob = GLOB.job_master.GetJob(card.rank)
|
||||
var/datum/job/foundjob = SSjob.get_job(card.rank)
|
||||
if(!foundjob)
|
||||
return
|
||||
var/new_dept = foundjob.pto_type || PTO_CIVILIAN
|
||||
var/datum/job/ptojob = null
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job.pto_type == new_dept && job.timeoff_factor < 0)
|
||||
ptojob = job
|
||||
break
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
|
||||
//Handle job slot/tater cleanup.
|
||||
var/job = to_despawn.mind.assigned_role
|
||||
GLOB.job_master.FreeRole(job)
|
||||
SSjob.free_role(job)
|
||||
to_despawn.mind.assigned_role = null
|
||||
|
||||
if(to_despawn.mind.objectives.len)
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
antag_data.add_antagonist(P.mind)
|
||||
antag_data.place_mob(P)
|
||||
P.mind.assigned_role = charjob
|
||||
P.mind.role_alt_title = GLOB.job_master.GetPlayerAltTitle(P, charjob)
|
||||
P.mind.role_alt_title = SSjob.get_player_alt_title(P, charjob)
|
||||
|
||||
//no need to be particularly thorough about language handover, we can safely assume that they were allowed to have it if they had it to begin with
|
||||
P.languages.Cut()
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
if(spawn_with_clothing)
|
||||
GLOB.job_master.EquipRank(avatar,"Visitor", 1, FALSE)
|
||||
SSjob.equip_rank(avatar,"Visitor", 1, FALSE)
|
||||
add_verb(avatar,/mob/living/carbon/human/proc/perform_exit_vr)
|
||||
avatar.virtual_reality_mob = FALSE //THIS IS THE BIG DIFFERENCE WITH ALIEN VR PODS. THEY ARE NOT VR, THEY ARE REAL.
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
occupant.enter_vr(avatar)
|
||||
if(spawn_with_clothing)
|
||||
GLOB.job_master.EquipRank(avatar,"Visitor", 1, FALSE)
|
||||
SSjob.equip_rank(avatar,"Visitor", 1, FALSE)
|
||||
add_verb(avatar,/mob/living/carbon/human/proc/perform_exit_vr)
|
||||
add_verb(avatar,/mob/living/carbon/human/proc/vr_transform_into_mob)
|
||||
add_verb(avatar,/mob/living/proc/set_size)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
|
||||
avatar.regenerate_icons()
|
||||
avatar.update_transform()
|
||||
GLOB.job_master.EquipRank(avatar,JOB_VR, 1, FALSE)
|
||||
SSjob.equip_rank(avatar,JOB_VR, 1, FALSE)
|
||||
add_verb(avatar,/mob/living/carbon/human/proc/fake_exit_vr)
|
||||
add_verb(avatar,/mob/living/carbon/human/proc/vr_transform_into_mob)
|
||||
add_verb(avatar,/mob/living/proc/set_size)
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
/obj/item/card/id/Initialize(mapload)
|
||||
. = ..()
|
||||
var/datum/job/J = GLOB.job_master.GetJob(rank)
|
||||
var/datum/job/J = SSjob.get_job(rank)
|
||||
if(J)
|
||||
access = J.get_access()
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@
|
||||
name = "[initial(name)] for [recipient.name] ([current_title])"
|
||||
recipient_ref = WEAKREF(recipient)
|
||||
|
||||
var/datum/job/this_job = SSjob.name_occupations[recipient.assigned_role]
|
||||
var/datum/job/this_job = SSjob.occupations_by_name[recipient.assigned_role]
|
||||
|
||||
var/list/goodies = generic_goodies
|
||||
if(this_job)
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
new_character.mind.loaded_from_ckey = picked_ckey
|
||||
new_character.mind.loaded_from_slot = picked_slot
|
||||
|
||||
GLOB.job_master.EquipRank(new_character, JOB_MAINT_LURKER, 1)
|
||||
SSjob.equip_rank(new_character, JOB_MAINT_LURKER, 1)
|
||||
|
||||
for(var/lang in new_character.client.prefs.alternate_languages)
|
||||
var/datum/language/chosen_language = GLOB.all_languages[lang]
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
new_character.mind.loaded_from_ckey = picked_ckey
|
||||
new_character.mind.loaded_from_slot = picked_slot
|
||||
|
||||
GLOB.job_master.EquipRank(new_character, JOB_MAINT_LURKER, 1)
|
||||
SSjob.equip_rank(new_character, JOB_MAINT_LURKER, 1)
|
||||
|
||||
for(var/lang in new_character.client.prefs.alternate_languages)
|
||||
var/datum/language/chosen_language = GLOB.all_languages[lang]
|
||||
|
||||
@@ -172,12 +172,8 @@ GLOBAL_VAR(restart_counter)
|
||||
log_test("If you did not intend to enable this please check code/__defines/unit_testing.dm")
|
||||
#endif
|
||||
|
||||
GLOB.master_controller = new /datum/controller/game_controller()
|
||||
Master.Initialize(10, FALSE, TRUE) // VOREStation Edit
|
||||
|
||||
spawn(1)
|
||||
GLOB.master_controller.setup()
|
||||
|
||||
RunUnattendedFunctions()
|
||||
|
||||
spawn(3000) //so we aren't adding to the round-start lag
|
||||
|
||||
@@ -357,17 +357,17 @@ ADMIN_VERB(shuttle_panel, R_ADMIN|R_EVENT, "Shuttle Control Panel", "Access the
|
||||
|
||||
ADMIN_VERB(free_slot, R_ADMIN|R_FUN|R_EVENT, "Free Job Slot", "Frees another job slot.", ADMIN_CATEGORY_EVENTS)
|
||||
var/list/jobs = list()
|
||||
for (var/datum/job/current_job in GLOB.job_master.occupations)
|
||||
if (current_job.current_positions >= current_job.total_positions && current_job.total_positions != -1)
|
||||
jobs += current_job.title
|
||||
if (!length(jobs))
|
||||
to_chat(user, "There are no fully staffed jobs.")
|
||||
for(var/datum/job/J in SSjob.occupations)
|
||||
if (J.current_positions >= J.total_positions && J.total_positions != -1)
|
||||
jobs += J.title
|
||||
if(!jobs.len)
|
||||
to_chat(usr, "There are no fully staffed jobs.")
|
||||
return
|
||||
var/job = tgui_input_list(user, "Please select job slot to free", "Free job slot", jobs)
|
||||
if (!job)
|
||||
var/job = tgui_input_list(usr, "Please select job slot to free", "Free job slot", jobs)
|
||||
if(job)
|
||||
SSjob.free_role(job)
|
||||
message_admins("A job slot for [job] has been opened by [key_name_admin(usr)]")
|
||||
return
|
||||
GLOB.job_master.FreeRole(job)
|
||||
message_admins("A job slot for [job] has been opened by [key_name_admin(user)]")
|
||||
|
||||
ADMIN_VERB(toggleghostwriters, R_ADMIN|R_FUN|R_EVENT, "Toggle ghost writers", "Toggles ghost writing.", ADMIN_CATEGORY_SERVER_GAME)
|
||||
if(!config)
|
||||
|
||||
+22
-22
@@ -257,7 +257,7 @@
|
||||
if(!M.ckey) //sanity
|
||||
to_chat(usr, span_filter_adminlog("This mob has no ckey"))
|
||||
return
|
||||
if(!GLOB.job_master)
|
||||
if(!SSjob)
|
||||
to_chat(usr, span_filter_adminlog("Job Master has not been setup!"))
|
||||
return
|
||||
|
||||
@@ -278,7 +278,7 @@
|
||||
jobs += "<tr align='center' bgcolor='ccccff'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=commanddept;jobban4=\ref[M]'>Command Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -298,7 +298,7 @@
|
||||
jobs += "<tr bgcolor='ffddf0'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=securitydept;jobban4=\ref[M]'>Security Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -318,7 +318,7 @@
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=engineeringdept;jobban4=\ref[M]'>Engineering Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -338,7 +338,7 @@
|
||||
jobs += "<tr bgcolor='fff5cc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=cargodept;jobban4=\ref[M]'>Cargo Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -358,7 +358,7 @@
|
||||
jobs += "<tr bgcolor='ffeef0'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=medicaldept;jobban4=\ref[M]'>Medical Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -378,7 +378,7 @@
|
||||
jobs += "<tr bgcolor='e79fff'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=sciencedept;jobban4=\ref[M]'>Science Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -398,7 +398,7 @@
|
||||
jobs += "<tr bgcolor='ebb8fc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_PLANET))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=explorationdept;jobban4=\ref[M]'>Exploration Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_PLANET))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -422,7 +422,7 @@
|
||||
jobs += "<tr bgcolor='00ffff'><th colspan='[length(offmap_jobs)]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=offmapdept;jobban4=\ref[M]'>Offmap Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in offmap_jobs)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -442,7 +442,7 @@
|
||||
jobs += "<tr bgcolor='dddddd'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=civiliandept;jobban4=\ref[M]'>Civilian Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -467,7 +467,7 @@
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))]'><a href='byond://?src=\ref[src];[HrefToken()];jobban3=nonhumandept;jobban4=\ref[M]'>Synthetic Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/job = SSjob.get_job(jobPos)
|
||||
if(!job) continue
|
||||
|
||||
if(jobban_isbanned(M, job.title))
|
||||
@@ -547,7 +547,7 @@
|
||||
tgui_alert_async(usr, "You cannot perform this action. You must be of a higher administrative rank!")
|
||||
return
|
||||
|
||||
if(!GLOB.job_master)
|
||||
if(!SSjob)
|
||||
to_chat(usr, span_filter_adminlog("Job Master has not been setup!"))
|
||||
return
|
||||
|
||||
@@ -557,63 +557,63 @@
|
||||
if("commanddept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_COMMAND))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("securitydept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SECURITY))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("engineeringdept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_ENGINEERING))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("cargodept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CARGO))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("medicaldept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_MEDICAL))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("sciencedept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_RESEARCH))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("explorationdept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_PLANET))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("offmapdept")
|
||||
for(var/dept in GLOB.offmap_departments)
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(dept))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("civiliandept")
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_CIVILIAN))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
if("nonhumandept")
|
||||
joblist += "pAI"
|
||||
for(var/jobPos in SSjob.get_job_titles_in_department(DEPARTMENT_SYNTHETIC))
|
||||
if(!jobPos) continue
|
||||
var/datum/job/temp = GLOB.job_master.GetJob(jobPos)
|
||||
var/datum/job/temp = SSjob.get_job(jobPos)
|
||||
if(!temp) continue
|
||||
joblist += temp.title
|
||||
else
|
||||
|
||||
@@ -57,8 +57,8 @@ ADMIN_VERB(camera_view, R_DEBUG, "Camera Range Display", "Globally changes the c
|
||||
|
||||
ADMIN_VERB_VISIBILITY(sec_camera_report, ADMIN_VERB_VISIBLITY_FLAG_LOCALHOST)
|
||||
ADMIN_VERB(sec_camera_report, R_DEBUG, "Camera Report", "Gives a report of the camera state (Only use on a test server).", ADMIN_CATEGORY_MAPPING_TESTS)
|
||||
if(!GLOB.master_controller)
|
||||
tgui_alert_async(user,"Master_controller not found.","Sec Camera Report")
|
||||
if(!SSticker.HasRoundStarted())
|
||||
tgui_alert_async(user,"Game init not ready.","Sec Camera Report")
|
||||
return 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
@@ -390,7 +390,7 @@ ADMIN_VERB(respawn_character, (R_ADMIN|R_REJUVINATE), "Spawn Character", "(Re)Sp
|
||||
|
||||
//Well you're not reloading their job or they never had one.
|
||||
if(!charjob)
|
||||
var/pickjob = tgui_input_list(src, "Pick a job to assign them (or none).","Job Select", GLOB.joblist.Copy() + "-No Job-", "-No Job-")
|
||||
var/pickjob = tgui_input_list(src, "Pick a job to assign them (or none).","Job Select", SSjob.occupations_by_name.Copy() + "-No Job-", "-No Job-")
|
||||
if(!pickjob)
|
||||
return
|
||||
if(pickjob != "-No Job-")
|
||||
@@ -521,10 +521,10 @@ ADMIN_VERB(respawn_character, (R_ADMIN|R_REJUVINATE), "Spawn Character", "(Re)Sp
|
||||
//If desired, apply equipment.
|
||||
if(equipment)
|
||||
if(charjob)
|
||||
GLOB.job_master.EquipRank(new_character, charjob, 1)
|
||||
SSjob.equip_rank(new_character, charjob, 1)
|
||||
if(new_character.mind)
|
||||
new_character.mind.assigned_role = charjob
|
||||
new_character.mind.role_alt_title = GLOB.job_master.GetPlayerAltTitle(new_character, charjob)
|
||||
new_character.mind.role_alt_title = SSjob.get_player_alt_title(new_character, charjob)
|
||||
|
||||
//If customised job title, modify here.
|
||||
if(custom_job && custom_job_title)
|
||||
@@ -652,8 +652,8 @@ ADMIN_VERB_AND_CONTEXT_MENU(cmd_admin_delete, R_FUN|R_ADMIN, "Delete", "Delete t
|
||||
user.admin_delete(atom_target)
|
||||
|
||||
ADMIN_VERB(cmd_admin_list_open_jobs, R_HOLDER, "List free slots", "Show available job slots.", ADMIN_CATEGORY_INVESTIGATE)
|
||||
if(GLOB.job_master)
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
if(SSjob)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
to_chat(user, "[job.title]: [job.total_positions]")
|
||||
feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.")
|
||||
return
|
||||
|
||||
if(GLOB.job_master && SSticker)
|
||||
var/datum/job/job = GLOB.job_master.GetJob(JOB_AI)
|
||||
if(SSjob && SSticker)
|
||||
var/datum/job/job = SSjob.get_job(JOB_AI)
|
||||
if(!job)
|
||||
to_chat(usr, "Unable to locate the AI job")
|
||||
return
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
//VOREStation Add End
|
||||
if(!(pref.player_alt_titles)) pref.player_alt_titles = new()
|
||||
|
||||
if(!GLOB.job_master)
|
||||
if(!SSjob)
|
||||
return
|
||||
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
var/alt_title = pref.player_alt_titles[job.title]
|
||||
if(alt_title && !(alt_title in job.alt_titles))
|
||||
pref.player_alt_titles -= job.title
|
||||
@@ -173,7 +173,7 @@
|
||||
|
||||
if("job_info")
|
||||
var/rank = params["rank"]
|
||||
var/datum/job/job = GLOB.job_master.GetJob(rank)
|
||||
var/datum/job/job = SSjob.get_job(rank)
|
||||
if(!istype(job))
|
||||
return TOPIC_NOACTION
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
pref.player_alt_titles[job.title] = new_title
|
||||
|
||||
/datum/category_item/player_setup_item/occupation/proc/SetJob(mob/user, role, level)
|
||||
var/datum/job/job = GLOB.job_master.GetJob(role)
|
||||
var/datum/job/job = SSjob.get_job(role)
|
||||
if(!job)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(prevent_respawns)
|
||||
|
||||
//Job slot cleanup
|
||||
var/job = src.mind.assigned_role
|
||||
GLOB.job_master.FreeRole(job)
|
||||
SSjob.free_role(job)
|
||||
|
||||
//Their objectives cleanup
|
||||
if(src.mind.objectives.len)
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
//Handle job slot/tater cleanup.
|
||||
var/job = mind.assigned_role
|
||||
|
||||
GLOB.job_master.FreeRole(job)
|
||||
SSjob.free_role(job)
|
||||
|
||||
if(mind.objectives.len)
|
||||
qdel(mind.objectives)
|
||||
|
||||
@@ -471,7 +471,7 @@
|
||||
|
||||
//Job slot cleanup
|
||||
var/job = mind.assigned_role
|
||||
GLOB.job_master.FreeRole(job)
|
||||
SSjob.free_role(job)
|
||||
|
||||
//Their objectives cleanup
|
||||
if(mind.objectives.len)
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
return timer - world.time
|
||||
|
||||
/mob/new_player/proc/IsJobAvailable(rank)
|
||||
var/datum/job/job = GLOB.job_master.GetJob(rank)
|
||||
var/datum/job/job = SSjob.get_job(rank)
|
||||
if(!job)
|
||||
return 0
|
||||
if(!job.is_position_available())
|
||||
@@ -232,7 +232,7 @@
|
||||
return 0
|
||||
|
||||
//Find our spawning point.
|
||||
var/list/join_props = GLOB.job_master.LateSpawn(client, rank)
|
||||
var/list/join_props = SSjob.late_spawn(client, rank)
|
||||
|
||||
if(!join_props)
|
||||
return
|
||||
@@ -271,10 +271,10 @@
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
GLOB.job_master.AssignRole(src, rank, 1)
|
||||
SSjob.assign_role(src, rank, 1)
|
||||
|
||||
var/mob/living/character = create_character(T) //creates the human and transfers vars and mind
|
||||
character = GLOB.job_master.EquipRank(character, rank, 1) //equips the human
|
||||
character = SSjob.equip_rank(character, rank, 1) //equips the human
|
||||
UpdateFactionList(character)
|
||||
|
||||
var/datum/job/J = SSjob.get_job(rank)
|
||||
|
||||
@@ -192,11 +192,11 @@
|
||||
var/datum/job/previewJob
|
||||
// Determine what job is marked as 'High' priority, and dress them up as such.
|
||||
if(job_civilian_low & ASSISTANT)
|
||||
previewJob = GLOB.job_master.GetJob(JOB_ALT_VISITOR)
|
||||
previewJob = SSjob.get_job(JOB_ALT_VISITOR)
|
||||
else if(client && ispAI(client.mob))
|
||||
pass() //Don't do anything!
|
||||
else
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
var/job_flag
|
||||
switch(job.department_flag)
|
||||
if(CIVILIAN)
|
||||
@@ -257,9 +257,9 @@
|
||||
var/datum/job/highJob
|
||||
// Determine what job is marked as 'High' priority, and dress them up as such.
|
||||
if(job_civilian_low & ASSISTANT)
|
||||
highJob = GLOB.job_master.GetJob(JOB_ALT_ASSISTANT)
|
||||
highJob = SSjob.get_job(JOB_ALT_ASSISTANT)
|
||||
else
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
var/job_flag
|
||||
switch(job.department_flag)
|
||||
if(CIVILIAN)
|
||||
|
||||
@@ -209,9 +209,9 @@ GLOBAL_LIST_EMPTY(active_autoresleevers)
|
||||
//If desired, apply equipment.
|
||||
if(equip_body)
|
||||
if(charjob)
|
||||
GLOB.job_master.EquipRank(new_character, charjob, 1)
|
||||
SSjob.equip_rank(new_character, charjob, 1)
|
||||
new_character.mind.assigned_role = charjob
|
||||
new_character.mind.role_alt_title = GLOB.job_master.GetPlayerAltTitle(new_character, charjob)
|
||||
new_character.mind.role_alt_title = SSjob.get_player_alt_title(new_character, charjob)
|
||||
|
||||
//A redraw for good measure
|
||||
new_character.regenerate_icons()
|
||||
|
||||
@@ -408,7 +408,7 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
|
||||
|
||||
if(action == "help")
|
||||
var/list/whitelist_jobs = list()
|
||||
for(var/datum/job/our_job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/our_job in SSjob.occupations)
|
||||
if(our_job.whitelist_only)
|
||||
whitelist_jobs += our_job.title
|
||||
var/list/whitelisted_language = list()
|
||||
@@ -456,7 +456,7 @@ GLOBAL_LIST_EMPTY(pending_discord_registrations)
|
||||
if("add")
|
||||
switch(kind)
|
||||
if("job")
|
||||
var/datum/job/job = GLOB.job_master.GetJob(role)
|
||||
var/datum/job/job = SSjob.get_job(role)
|
||||
if(!job)
|
||||
message.text = "Error, invalid job entered. Check spelling and capitalization."
|
||||
return message
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
var/list/jobs = list()
|
||||
|
||||
for(var/datum/job/job in GLOB.job_master.occupations)
|
||||
for(var/datum/job/job in SSjob.occupations)
|
||||
if(job && user.IsJobAvailable(job.title))
|
||||
// Check for jobs with minimum age requirements
|
||||
if(!character_old_enough_for_job(user.client.prefs, job))
|
||||
|
||||
@@ -545,7 +545,6 @@
|
||||
#include "code\controllers\hooks-defs.dm"
|
||||
#include "code\controllers\hooks.dm"
|
||||
#include "code\controllers\master.dm"
|
||||
#include "code\controllers\master_controller.dm"
|
||||
#include "code\controllers\subsystem.dm"
|
||||
#include "code\controllers\configuration\config_entry.dm"
|
||||
#include "code\controllers\configuration\configuration.dm"
|
||||
@@ -1239,7 +1238,6 @@
|
||||
#include "code\game\gamemodes\wizard\wizard.dm"
|
||||
#include "code\game\jobs\access.dm"
|
||||
#include "code\game\jobs\access_datum.dm"
|
||||
#include "code\game\jobs\job_controller.dm"
|
||||
#include "code\game\jobs\jobs.dm"
|
||||
#include "code\game\jobs\whitelist.dm"
|
||||
#include "code\game\jobs\job\_alt_title.dm"
|
||||
|
||||
Reference in New Issue
Block a user