mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Updates latejoin menu to use TGUI (#17309)
* First work * Add job icons * Update FA 2 3 * Add job descriptions * Fix tooltip color * Misc changes * Fix unavailable reason and random job button * Real fix * Remove double import * huh * Use tgui_alert
This commit is contained in:
@@ -51,6 +51,9 @@
|
||||
#define JOB_UNAVAILABLE_ACCOUNTAGE 4
|
||||
#define JOB_UNAVAILABLE_SLOTFULL 5
|
||||
|
||||
/// Used when the `get_job_unavailable_error_message` proc can't make sense of a given code.
|
||||
#define GENERIC_JOB_UNAVAILABLE_ERROR "Error: Unknown job availability."
|
||||
|
||||
#define DEFAULT_RELIGION "Christianity"
|
||||
#define DEFAULT_DEITY "Space Jesus"
|
||||
|
||||
@@ -123,3 +126,5 @@
|
||||
#define IS_SCIENCE(target) (find_job(target) in GLOB.science_positions)
|
||||
#define IS_CARGO(target) (find_job(target) in GLOB.supply_positions)
|
||||
#define IS_SECURITY(target) (find_job(target) in GLOB.security_positions)
|
||||
|
||||
#define DEPARTMENT_UNASSIGNED "No Department"
|
||||
|
||||
@@ -474,17 +474,17 @@ SUBSYSTEM_DEF(ticker)
|
||||
/datum/controller/subsystem/ticker/proc/check_queue()
|
||||
if(!queued_players.len)
|
||||
return
|
||||
var/hpc = CONFIG_GET(number/hard_popcap)
|
||||
var/hard_popcap = CONFIG_GET(number/hard_popcap)
|
||||
//yogs start -- fixes queue when extreme is set but not hard
|
||||
if(!hpc)
|
||||
hpc = CONFIG_GET(number/extreme_popcap)
|
||||
if(!hard_popcap)
|
||||
hard_popcap = CONFIG_GET(number/extreme_popcap)
|
||||
//yogs end
|
||||
if(!hpc)
|
||||
if(!hard_popcap)
|
||||
listclearnulls(queued_players)
|
||||
for (var/mob/dead/new_player/NP in queued_players)
|
||||
to_chat(NP, span_userdanger("The alive players limit has been released!<br><a href='?src=[REF(NP)];late_join=override'>[html_encode(">>Join Game<<")]</a>"))
|
||||
SEND_SOUND(NP, sound('sound/misc/notice1.ogg'))
|
||||
NP.LateChoices()
|
||||
for (var/mob/dead/new_player/new_player in queued_players)
|
||||
to_chat(new_player, span_userdanger("The alive players limit has been released!<br><a href='?src=[REF(new_player)];late_join=override'>[html_encode(">>Join Game<<")]</a>"))
|
||||
SEND_SOUND(new_player, sound('sound/misc/notice1.ogg'))
|
||||
GLOB.latejoin_menu.ui_interact(new_player)
|
||||
queued_players.len = 0
|
||||
queue_delay = 0
|
||||
return
|
||||
@@ -495,11 +495,11 @@ SUBSYSTEM_DEF(ticker)
|
||||
switch(queue_delay)
|
||||
if(5) //every 5 ticks check if there is a slot available
|
||||
listclearnulls(queued_players)
|
||||
if(living_player_count() < hpc)
|
||||
if(living_player_count() < hard_popcap)
|
||||
if(next_in_line && next_in_line.client)
|
||||
to_chat(next_in_line, span_userdanger("A slot has opened! You have approximately 20 seconds to join. <a href='?src=[REF(next_in_line)];late_join=override'>\>\>Join Game\<\<</a>"))
|
||||
SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg'))
|
||||
next_in_line.LateChoices()
|
||||
next_in_line.ui_interact(next_in_line)
|
||||
return
|
||||
queued_players -= next_in_line //Client disconnected, remove he
|
||||
queue_delay = 0 //No vacancy: restart timer
|
||||
|
||||
@@ -158,10 +158,9 @@
|
||||
/datum/asset/simple/namespaced/fontawesome
|
||||
legacy = TRUE
|
||||
assets = list(
|
||||
"fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot',
|
||||
"fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff',
|
||||
"fa-solid-900.eot" = 'html/font-awesome/webfonts/fa-solid-900.eot',
|
||||
"fa-solid-900.woff" = 'html/font-awesome/webfonts/fa-solid-900.woff',
|
||||
"fa-regular-400.ttf" = 'html/font-awesome/webfonts/fa-regular-400.ttf',
|
||||
"fa-solid-900.ttf" = 'html/font-awesome/webfonts/fa-solid-900.ttf',
|
||||
"fa-v4compatibility.ttf" = 'html/font-awesome/webfonts/fa-v4compatibility.ttf',
|
||||
"v4shim.css" = 'html/font-awesome/css/v4-shims.min.css'
|
||||
)
|
||||
parents = list("font-awesome.css" = 'html/font-awesome/css/all.min.css')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job
|
||||
/// The name of the job used for preferences, bans, etc.
|
||||
var/title = "NOPE"
|
||||
/// The description of the job, used for preferences menu.
|
||||
/// Keep it short and useful. Avoid in-jokes, these are for new players.
|
||||
var/description
|
||||
/// This job comes with these accesses by default
|
||||
var/list/base_access = list()
|
||||
/// Additional accesses for the job if config.jobs_have_minimal_access is set to false
|
||||
@@ -68,6 +71,9 @@
|
||||
///The text a person using olfaction will see for the job of the target's scent
|
||||
var/smells_like = "a freeloader"
|
||||
|
||||
/// Icons to be displayed in the orbit ui. Source: FontAwesome v5.
|
||||
var/orbit_icon
|
||||
|
||||
/*
|
||||
If you want to change a job on a specific map with this system, you will want to go onto that job datum
|
||||
and add said map's name to the changed_maps list, like so:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/ai
|
||||
title = "AI"
|
||||
description = "Assist the crew, follow your laws, coordinate your cyborgs."
|
||||
flag = AI_JF
|
||||
orbit_icon = "eye"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_SILICON|DEADMIN_POSITION_CRITICAL
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/artist
|
||||
title = "Artist"
|
||||
description = "Create unique pieces of art for display by the crew around the station."
|
||||
flag = ARTIST
|
||||
orbit_icon = "paintbrush"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -3,7 +3,9 @@ Assistant
|
||||
*/
|
||||
/datum/job/assistant
|
||||
title = "Assistant"
|
||||
description = "Get your space legs, assist people, ask the HoP to give you a job."
|
||||
flag = ASSISTANT
|
||||
orbit_icon = "toolbox"
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = 5
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/atmos
|
||||
title = "Atmospheric Technician"
|
||||
description = "Ensure the air is breathable on the station, fill oxygen tanks, fight fires, purify the air."
|
||||
flag = ATMOSTECH
|
||||
orbit_icon = "fire-extinguisher"
|
||||
department_head = list("Chief Engineer")
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/bartender
|
||||
title = "Bartender"
|
||||
description = "Serve booze, mix drinks, keep the crew drunk."
|
||||
flag = BARTENDER
|
||||
orbit_icon = "cocktail"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/hydro
|
||||
title = "Botanist"
|
||||
description = "Grow plants for the cook, for medicine, and for recreation."
|
||||
flag = BOTANIST
|
||||
orbit_icon = "seedling"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/job/captain
|
||||
title = "Captain"
|
||||
description = "Be responsible for the station, manage your Heads of Staff, \
|
||||
keep the crew alive, be prepared to do anything and everything or die \
|
||||
horribly trying."
|
||||
flag = CAPTAIN
|
||||
orbit_icon = "crown"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY|DEADMIN_POSITION_CRITICAL
|
||||
department_head = list("CentCom")
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/job/cargo_tech
|
||||
title = "Cargo Technician"
|
||||
description = "Distribute supplies to the departments that ordered them, \
|
||||
collect empty crates, load and unload the supply shuttle, \
|
||||
ship bounty cubes."
|
||||
flag = CARGOTECH
|
||||
orbit_icon = "box"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/chaplain
|
||||
title = "Chaplain"
|
||||
description = "Hold services and funerals, cremate people, preach your \
|
||||
religion, protect the crew against cults."
|
||||
flag = CHAPLAIN
|
||||
orbit_icon = "cross"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/chemist
|
||||
title = "Chemist"
|
||||
description = "Supply the doctors with chemicals, make medicine, as well as \
|
||||
less likable substances in the comfort of a fully reinforced room."
|
||||
flag = CHEMIST
|
||||
orbit_icon = "prescription-bottle"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/chief_engineer
|
||||
title = "Chief Engineer"
|
||||
description = "Coordinate engineering, ensure equipment doesn't get stolen, \
|
||||
make sure the Supermatter doesn't blow up, maintain telecommunications."
|
||||
flag = CHIEF
|
||||
orbit_icon = "user-astronaut"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD
|
||||
department_head = list("Captain")
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/cmo
|
||||
title = "Chief Medical Officer"
|
||||
description = "Coordinate doctors and other medbay employees, ensure they \
|
||||
know how to save lives, check for injuries on the crew monitor."
|
||||
flag = CMO_JF
|
||||
orbit_icon = "user-md"
|
||||
department_head = list("Captain")
|
||||
department_flag = MEDSCI
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/clown
|
||||
title = "Clown"
|
||||
description = "Entertain the crew, make bad jokes, go on a holy quest to find bananium, HONK!"
|
||||
flag = CLOWN
|
||||
orbit_icon = "face-grin-tears"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/cook
|
||||
title = "Cook"
|
||||
description = "Serve food, cook meat, keep the crew fed."
|
||||
flag = COOK
|
||||
orbit_icon = "utensils"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/curator
|
||||
title = "Curator"
|
||||
description = "Read and write books and hand them to people, stock \
|
||||
bookshelves, report on station news."
|
||||
flag = CURATOR
|
||||
orbit_icon = "book"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/cyborg
|
||||
title = "Cyborg"
|
||||
description = "Assist the crew, follow your laws, obey your AI."
|
||||
flag = CYBORG
|
||||
orbit_icon = "robot"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_SILICON
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/detective
|
||||
title = "Detective"
|
||||
description = "Investigate crimes, gather evidence, perform interrogations, \
|
||||
look badass, smoke cigarettes."
|
||||
flag = DETECTIVE
|
||||
orbit_icon = "user-secret"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY
|
||||
department_head = list("Head of Security")
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/geneticist
|
||||
title = "Geneticist"
|
||||
description = "Alter genomes, turn monkeys into humans (and vice-versa), and make DNA backups."
|
||||
flag = GENETICIST
|
||||
orbit_icon = "dna"
|
||||
department_head = list("Chief Medical Officer", "Research Director")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/hop
|
||||
title = "Head of Personnel"
|
||||
description = "Alter access on ID cards, manage civil and supply departments, \
|
||||
protect Ian, run the station when the captain dies."
|
||||
flag = HOP
|
||||
orbit_icon = "dog"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD
|
||||
department_head = list("Captain")
|
||||
department_flag = CIVILIAN
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/hos
|
||||
title = "Head of Security"
|
||||
description = "Coordinate security personnel, ensure they are not corrupt, \
|
||||
make sure every department is protected."
|
||||
flag = HOS
|
||||
orbit_icon = "user-shield"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD|DEADMIN_POSITION_SECURITY|DEADMIN_POSITION_CRITICAL
|
||||
department_head = list("Captain")
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/janitor
|
||||
title = "Janitor"
|
||||
description = "Clean up trash and blood, replace broken lights and slip people over."
|
||||
flag = JANITOR
|
||||
orbit_icon = "broom"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/lawyer
|
||||
title = "Lawyer"
|
||||
description = "Advocate for prisoners, create law-binding contracts, \
|
||||
ensure Security is following protocol and Space Law."
|
||||
flag = LAWYER
|
||||
orbit_icon = "gavel"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/doctor
|
||||
title = "Medical Doctor"
|
||||
description = "Save lives, run around the station looking for victims, \
|
||||
scan everyone in sight"
|
||||
flag = DOCTOR
|
||||
orbit_icon = "staff-snake"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/mime
|
||||
title = "Mime"
|
||||
description = "..."
|
||||
flag = MIME
|
||||
orbit_icon = "comment-slash"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/qm
|
||||
title = "Quartermaster"
|
||||
description = "Coordinate cargo technicians and shaft miners, assist with \
|
||||
economical purchasing."
|
||||
flag = QUARTERMASTER
|
||||
orbit_icon = "sack-dollar"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/job/rd
|
||||
title = "Research Director"
|
||||
description = "Supervise research efforts, ensure Robotics is in working \
|
||||
order, make sure the AI and its Cyborgs aren't rogue, replacing them if \
|
||||
they are"
|
||||
flag = RD_JF
|
||||
orbit_icon = "user-graduate"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_HEAD
|
||||
department_head = list("Captain")
|
||||
department_flag = MEDSCI
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/roboticist
|
||||
title = "Roboticist"
|
||||
description = "Build and repair the AI and cyborgs, create mechs."
|
||||
flag = ROBOTICIST
|
||||
orbit_icon = "battery-half"
|
||||
department_head = list("Research Director")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/scientist
|
||||
title = "Scientist"
|
||||
description = "Do experiments, perform research, feed the slimes, make bombs."
|
||||
flag = SCIENTIST
|
||||
orbit_icon = "flask"
|
||||
department_head = list("Research Director")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/officer
|
||||
title = "Security Officer"
|
||||
description = "Protect company assets, follow Space Law\
|
||||
, eat donuts."
|
||||
flag = OFFICER
|
||||
orbit_icon = "shield-halved"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY
|
||||
department_head = list("Head of Security")
|
||||
department_flag = ENGSEC
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/mining
|
||||
title = "Shaft Miner"
|
||||
description = "Travel to strange lands. Mine ores. \
|
||||
Meet strange creatures. Kill them for their gold."
|
||||
flag = MINER
|
||||
orbit_icon = "digging"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/engineer
|
||||
title = "Station Engineer"
|
||||
description = "Start the Supermatter, wire the solars, repair station hull \
|
||||
and wiring damage."
|
||||
flag = ENGINEER
|
||||
orbit_icon = "gears"
|
||||
department_head = list("Chief Engineer")
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/datum/job/virologist
|
||||
title = "Virologist"
|
||||
description = "Study the effects of various diseases and synthesize a \
|
||||
vaccine for them. Engineer beneficial viruses."
|
||||
flag = VIROLOGIST
|
||||
orbit_icon = "virus"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/datum/job/warden
|
||||
title = "Warden"
|
||||
description = "Watch over the Brig and Prison Wing, release prisoners when \
|
||||
their time is up, issue equipment to security, be a security officer when \
|
||||
they all eventually die."
|
||||
flag = WARDEN
|
||||
orbit_icon = "handcuffs"
|
||||
auto_deadmin_role_flags = DEADMIN_POSITION_SECURITY
|
||||
department_head = list("Head of Security")
|
||||
department_flag = ENGSEC
|
||||
|
||||
208
code/modules/mob/dead/new_player/latejoin_menu.dm
Normal file
208
code/modules/mob/dead/new_player/latejoin_menu.dm
Normal file
@@ -0,0 +1,208 @@
|
||||
#define JOB_CHOICE_YES "Yes"
|
||||
#define JOB_CHOICE_REROLL "Reroll"
|
||||
#define JOB_CHOICE_CANCEL "Cancel"
|
||||
|
||||
GLOBAL_DATUM_INIT(latejoin_menu, /datum/latejoin_menu, new)
|
||||
|
||||
/// Makes a list of jobs and pushes them to a DM list selector. Just in case someone did a special kind of fucky-wucky with TGUI.
|
||||
/datum/latejoin_menu/proc/fallback_ui(mob/dead/new_player/user)
|
||||
var/list/jobs = list()
|
||||
for(var/datum/job/job as anything in SSjob.occupations)
|
||||
jobs += job.title
|
||||
|
||||
var/input_contents = input(user, "Pick a job to join as:", "Latejoin Job Selection") as null|anything in jobs
|
||||
|
||||
if(!input_contents)
|
||||
return
|
||||
|
||||
user.AttemptLateSpawn(input_contents)
|
||||
|
||||
/datum/latejoin_menu/ui_close(mob/dead/new_player/user)
|
||||
. = ..()
|
||||
if(istype(user))
|
||||
user.jobs_menu_mounted = TRUE // Don't flood a user's chat if they open and close the UI.
|
||||
|
||||
/datum/latejoin_menu/ui_interact(mob/dead/new_player/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
// In case they reopen the GUI
|
||||
// FIXME: this can cause a runtime since user can be a living mob
|
||||
if(istype(user))
|
||||
user.jobs_menu_mounted = FALSE
|
||||
addtimer(CALLBACK(src, PROC_REF(scream_at_player), user), 5 SECONDS)
|
||||
|
||||
ui = new(user, src, "JobSelection", "Latejoin Menu")
|
||||
ui.open()
|
||||
|
||||
/datum/latejoin_menu/proc/scream_at_player(mob/dead/new_player/player)
|
||||
if(!player.jobs_menu_mounted)
|
||||
to_chat(player, span_notice("If the late join menu isn't showing, hold CTRL while clicking the join button!"))
|
||||
|
||||
/datum/latejoin_menu/ui_data(mob/user)
|
||||
var/mob/dead/new_player/owner = user
|
||||
var/list/departments = list()
|
||||
var/list/data = list(
|
||||
"disable_jobs_for_non_observers" = SSticker.late_join_disabled,
|
||||
"round_duration" = DisplayTimeText(world.time - SSticker.round_start_time, round_seconds_to = 1),
|
||||
"departments" = departments,
|
||||
)
|
||||
if(SSshuttle.emergency)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_ESCAPE)
|
||||
data["shuttle_status"] = "The station has been evacuated."
|
||||
if(SHUTTLE_CALL, SHUTTLE_DOCKED, SHUTTLE_IGNITING, SHUTTLE_ESCAPE)
|
||||
if(!SSshuttle.canRecall())
|
||||
data["shuttle_status"] = "The station is currently undergoing evacuation procedures."
|
||||
|
||||
for(var/datum/job/prioritized_job in SSjob.prioritized_jobs)
|
||||
if(prioritized_job.current_positions >= prioritized_job.total_positions)
|
||||
SSjob.prioritized_jobs -= prioritized_job
|
||||
|
||||
for(var/list/category in list(GLOB.command_positions) + list(GLOB.engineering_positions) + list(GLOB.supply_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.science_positions) + list(GLOB.security_positions) + list(GLOB.medical_positions) )
|
||||
var/cat_name = SSjob.name_occupations_all[category[1]].exp_type_department
|
||||
|
||||
var/list/department_jobs = list()
|
||||
var/list/department_data = list(
|
||||
"jobs" = department_jobs,
|
||||
"open_slots" = 0,
|
||||
)
|
||||
departments[cat_name] = department_data
|
||||
for(var/job in category)
|
||||
var/datum/job/job_datum = SSjob.name_occupations[job]
|
||||
if (!job_datum)
|
||||
continue
|
||||
|
||||
var/job_availability = owner.IsJobUnavailable(job_datum.title, latejoin = TRUE)
|
||||
|
||||
var/list/job_data = list(
|
||||
"prioritized" = (job_datum in SSjob.prioritized_jobs),
|
||||
"used_slots" = job_datum.current_positions,
|
||||
"open_slots" = job_datum.total_positions < 0 ? "∞" : job_datum.total_positions,
|
||||
)
|
||||
|
||||
if(job_availability != JOB_AVAILABLE)
|
||||
job_data["unavailable_reason"] = get_job_unavailable_error_message(job_availability, job_datum.title)
|
||||
|
||||
if(job_datum.total_positions < 0)
|
||||
department_data["open_slots"] = "∞"
|
||||
|
||||
if(department_data["open_slots"] != "∞")
|
||||
if(job_datum.total_positions - job_datum.current_positions > 0)
|
||||
department_data["open_slots"] += job_datum.total_positions - job_datum.current_positions
|
||||
|
||||
department_jobs[job_datum.title] = job_data
|
||||
|
||||
return data
|
||||
|
||||
/datum/latejoin_menu/ui_static_data(mob/user)
|
||||
var/list/departments = list()
|
||||
|
||||
for(var/list/category in list(GLOB.command_positions) + list(GLOB.engineering_positions) + list(GLOB.supply_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.science_positions) + list(GLOB.security_positions) + list(GLOB.medical_positions) )
|
||||
var/cat_color = SSjob.name_occupations_all[category[1]].selection_color
|
||||
var/cat_name = SSjob.name_occupations_all[category[1]].exp_type_department
|
||||
|
||||
var/list/department_jobs = list()
|
||||
var/list/department_data = list(
|
||||
"jobs" = department_jobs,
|
||||
"color" = cat_color,
|
||||
)
|
||||
departments[cat_name] = department_data
|
||||
|
||||
for(var/job in category)
|
||||
var/datum/job/job_datum = SSjob.name_occupations[job]
|
||||
if (!job_datum)
|
||||
continue
|
||||
|
||||
var/is_command = (job in GLOB.command_positions)
|
||||
|
||||
var/list/job_data = list(
|
||||
"command" = is_command,
|
||||
"description" = job_datum.description,
|
||||
"icon" = job_datum.orbit_icon,
|
||||
)
|
||||
|
||||
department_jobs[job_datum.title] = job_data
|
||||
|
||||
return list("departments_static" = departments)
|
||||
|
||||
// we can't use GLOB.new_player_state here since it also allows any admin to see the ui, which will cause runtimes
|
||||
/datum/latejoin_menu/ui_status(mob/user)
|
||||
return isnewplayer(user) ? UI_INTERACTIVE : UI_CLOSE
|
||||
|
||||
/datum/latejoin_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
|
||||
if(!ui.user.client || !isnewplayer(ui.user))
|
||||
return TRUE
|
||||
|
||||
var/mob/dead/new_player/owner = ui.user
|
||||
|
||||
switch(action)
|
||||
if("ui_mounted_with_no_bluescreen")
|
||||
owner.jobs_menu_mounted = TRUE
|
||||
if("select_job")
|
||||
if(params["job"] == "Random")
|
||||
var/job = get_random_job(owner)
|
||||
if(!job)
|
||||
tgui_alert(owner, "There is no randomly assignable job at this time. Please manually choose one of the other possible options.")
|
||||
return TRUE
|
||||
|
||||
params["job"] = job
|
||||
|
||||
if(!SSticker?.IsRoundInProgress())
|
||||
tgui_alert(owner, "The round is either not ready, or has already finished...", "Oh No!")
|
||||
return TRUE
|
||||
|
||||
if(!GLOB.enter_allowed || SSticker.late_join_disabled)
|
||||
tgui_alert(owner, "There is an administrative lock on entering the game for non-observers!", "Oh No!")
|
||||
return TRUE
|
||||
|
||||
//Determines Relevent Population Cap
|
||||
var/relevant_cap
|
||||
var/hard_popcap = CONFIG_GET(number/hard_popcap)
|
||||
var/extreme_popcap = CONFIG_GET(number/extreme_popcap)
|
||||
if(hard_popcap && extreme_popcap)
|
||||
relevant_cap = min(hard_popcap, extreme_popcap)
|
||||
else
|
||||
relevant_cap = max(hard_popcap, extreme_popcap)
|
||||
|
||||
if(SSticker.queued_players.len)
|
||||
if((living_player_count() >= relevant_cap) || (owner != SSticker.queued_players[1]))
|
||||
tgui_alert(owner, "The server is full!", "Oh No!")
|
||||
return TRUE
|
||||
|
||||
// SAFETY: AttemptLateSpawn has it's own sanity checks. This is perfectly safe.
|
||||
owner.AttemptLateSpawn(params["job"])
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Gives the user a random job that they can join as, and prompts them if they'd actually like to keep it, rerolling if not. Cancellable by the user.
|
||||
/// WARNING: BLOCKS THREAD!
|
||||
/datum/latejoin_menu/proc/get_random_job(mob/dead/new_player/owner)
|
||||
var/attempts = 0
|
||||
while(TRUE)
|
||||
if (attempts > 10)
|
||||
// Give it a few attempts before giving up
|
||||
return
|
||||
|
||||
var/datum/job/random_job = SSjob.GetRandomJob(owner)
|
||||
if (!random_job)
|
||||
return
|
||||
|
||||
if (owner.IsJobUnavailable(random_job.title, latejoin = TRUE) != JOB_AVAILABLE)
|
||||
attempts++
|
||||
continue
|
||||
|
||||
attempts = 0
|
||||
|
||||
var/list/random_job_options = list(JOB_CHOICE_YES, JOB_CHOICE_REROLL, JOB_CHOICE_CANCEL)
|
||||
var/choice = tgui_alert(owner, "Do you want to play as \a [random_job.title]?", "Random Job", random_job_options)
|
||||
|
||||
if(choice == JOB_CHOICE_CANCEL)
|
||||
return
|
||||
if(choice == JOB_CHOICE_YES)
|
||||
return random_job.title
|
||||
|
||||
#undef JOB_CHOICE_YES
|
||||
#undef JOB_CHOICE_REROLL
|
||||
#undef JOB_CHOICE_CANCEL
|
||||
@@ -16,6 +16,9 @@
|
||||
//Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
|
||||
var/ineligible_for_roles = FALSE
|
||||
|
||||
/// Used to track if the player's jobs menu sent a message saying it successfully mounted.
|
||||
var/jobs_menu_mounted = FALSE
|
||||
|
||||
/mob/dead/new_player/Initialize()
|
||||
if(client && SSticker.state == GAME_STATE_STARTUP)
|
||||
var/atom/movable/screen/splash/S = new(client, TRUE, TRUE)
|
||||
@@ -140,14 +143,14 @@
|
||||
return
|
||||
|
||||
if(href_list["late_join"] == "override")
|
||||
LateChoices()
|
||||
GLOB.latejoin_menu.ui_interact(src)
|
||||
return
|
||||
|
||||
if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.permissions.admin_datums)))
|
||||
//yogs start -- donors bypassing the queue
|
||||
if(ckey(key) in get_donators())
|
||||
to_chat(usr, span_notice("Because you are a donator, you have bypassed the queue! Thank you for donating!"))
|
||||
LateChoices()
|
||||
GLOB.latejoin_menu.ui_interact(src)
|
||||
return
|
||||
//yogs end
|
||||
to_chat(usr, span_danger("[CONFIG_GET(string/hard_popcap_message)]"))
|
||||
@@ -161,37 +164,14 @@
|
||||
SSticker.queued_players += usr
|
||||
to_chat(usr, span_notice("You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len]."))
|
||||
return
|
||||
LateChoices()
|
||||
|
||||
// TODO: Fallback menu
|
||||
GLOB.latejoin_menu.ui_interact(usr)
|
||||
|
||||
|
||||
if(href_list["manifest"])
|
||||
ViewManifest()
|
||||
|
||||
if(href_list["SelectedJob"])
|
||||
|
||||
if(!SSticker || !SSticker.IsRoundInProgress())
|
||||
to_chat(usr, span_danger("The round is either not ready, or has already finished..."))
|
||||
return
|
||||
|
||||
if(!GLOB.enter_allowed)
|
||||
to_chat(usr, span_notice("There is an administrative lock on entering the game!"))
|
||||
return
|
||||
|
||||
if(SSticker.queued_players.len && !(ckey(key) in GLOB.permissions.admin_datums))
|
||||
if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
|
||||
to_chat(usr, span_warning("Server is full."))
|
||||
return
|
||||
|
||||
// Check if random role is requested
|
||||
if(href_list["SelectedJob"] == "Random")
|
||||
var/datum/job/job = SSjob.GetRandomJob(src)
|
||||
if(!job)
|
||||
to_chat(usr, span_warning("There is no randomly assignable Job at this time. Please manually choose one of the other possible options."))
|
||||
return
|
||||
href_list["SelectedJob"] = job.title
|
||||
|
||||
AttemptLateSpawn(href_list["SelectedJob"])
|
||||
return
|
||||
|
||||
else if(!href_list["late_join"])
|
||||
new_player_panel()
|
||||
|
||||
@@ -332,7 +312,8 @@
|
||||
return "Your account is not old enough for [jobtitle]."
|
||||
if(JOB_UNAVAILABLE_SLOTFULL)
|
||||
return "[jobtitle] is already filled to capacity."
|
||||
return "Error: Unknown job availability."
|
||||
|
||||
return GENERIC_JOB_UNAVAILABLE_ERROR
|
||||
|
||||
/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE)
|
||||
var/datum/job/job = SSjob.GetJob(rank)
|
||||
@@ -452,60 +433,8 @@
|
||||
employmentCabinet.addFile(employee)
|
||||
|
||||
|
||||
/mob/dead/new_player/proc/LateChoices()
|
||||
var/list/dat = list("<div class='notice'>Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]</div>")
|
||||
if(SSshuttle.emergency)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
if(SHUTTLE_ESCAPE)
|
||||
dat += "<div class='notice red'>The station has been evacuated.</div><br>"
|
||||
if(SHUTTLE_CALL)
|
||||
if(!SSshuttle.canRecall())
|
||||
dat += "<div class='notice red'>The station is currently undergoing evacuation procedures.</div><br>"
|
||||
for(var/datum/job/prioritized_job in SSjob.prioritized_jobs)
|
||||
if(prioritized_job.current_positions >= prioritized_job.total_positions)
|
||||
SSjob.prioritized_jobs -= prioritized_job
|
||||
dat += "<table><tr><td valign='top'>"
|
||||
var/column_counter = 0
|
||||
for(var/list/category in list(GLOB.command_positions) + list(GLOB.engineering_positions) + list(GLOB.supply_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.science_positions) + list(GLOB.security_positions) + list(GLOB.medical_positions) )
|
||||
var/cat_color = SSjob.name_occupations_all[category[1]].selection_color
|
||||
dat += "<fieldset style='width: 185px; border: 2px solid [cat_color]; display: inline'>"
|
||||
dat += "<legend align='center' style='color: [cat_color]'>[SSjob.name_occupations_all[category[1]].exp_type_department]</legend>"
|
||||
var/list/dept_dat = list()
|
||||
for(var/job in category)
|
||||
var/datum/job/job_datum = SSjob.name_occupations[job]
|
||||
if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE)
|
||||
var/command_bold = ""
|
||||
if(job in GLOB.command_positions)
|
||||
command_bold = " command"
|
||||
if(job_datum in SSjob.prioritized_jobs)
|
||||
dept_dat += "<a class='job[command_bold]' href='byond://?src=[REF(src)];SelectedJob=[job_datum.title]'>[span_priority("[job_datum.title] ([job_datum.current_positions])")]</a>"
|
||||
else
|
||||
dept_dat += "<a class='job[command_bold]' href='byond://?src=[REF(src)];SelectedJob=[job_datum.title]'>[job_datum.title] ([job_datum.current_positions])</a>"
|
||||
if(!dept_dat.len)
|
||||
dept_dat += span_nopositions("No positions open.")
|
||||
dat += jointext(dept_dat, "")
|
||||
dat += "</fieldset><br>"
|
||||
column_counter++
|
||||
if(column_counter > 0 && (column_counter % 3 == 0))
|
||||
dat += "</td><td valign='top'>"
|
||||
|
||||
// Random Job Section
|
||||
dat += "<fieldset style='width: 185px; border: 2px solid #f0ebe2; display: inline'>"
|
||||
dat += "<legend align='center' style='color: #f0ebe2'>Random</legend>"
|
||||
dat += "<a class='job' href='byond://?src=[REF(src)];SelectedJob=Random'>Random Job</a>"
|
||||
// TODO could add random job selection to be based on player preferences too
|
||||
dat += "</fieldset><br>"
|
||||
|
||||
// Table end
|
||||
dat += "</td></tr></table></center>"
|
||||
dat += "</div></div>"
|
||||
var/datum/browser/popup = new(src, "latechoices", "Choose Profession", 680, 580)
|
||||
popup.add_stylesheet("playeroptions", 'html/browser/playeroptions.css')
|
||||
popup.set_content(jointext(dat, ""))
|
||||
popup.open(FALSE) // 0 is passed to open so that it doesn't use the onclose() proc
|
||||
|
||||
/mob/dead/new_player/proc/create_character(transfer_after)
|
||||
spawning = 1
|
||||
spawning = TRUE
|
||||
close_spawn_windows()
|
||||
|
||||
var/mob/living/carbon/human/H = new(loc)
|
||||
@@ -571,12 +500,9 @@
|
||||
|
||||
|
||||
/mob/dead/new_player/proc/close_spawn_windows()
|
||||
|
||||
src << browse(null, "window=latechoices") //closes late choices window
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
src << browse(null, "window=preferences") //closes job selection
|
||||
src << browse(null, "window=mob_occupation")
|
||||
src << browse(null, "window=latechoices") //closes late job selection
|
||||
|
||||
// Used to make sure that a player has a valid job preference setup, used to knock players out of eligibility for anything if their prefs don't make sense.
|
||||
// A "valid job preference setup" in this situation means at least having one job set to low, or not having "return to lobby" enabled
|
||||
|
||||
@@ -725,7 +725,7 @@ GLOBAL_LIST_EMPTY(vending_products)
|
||||
.["user"]["department"] = C.registered_account.account_job.paycheck_department
|
||||
else
|
||||
.["user"]["job"] = "No Job"
|
||||
.["user"]["department"] = "No Department"
|
||||
.["user"]["department"] = DEPARTMENT_UNASSIGNED
|
||||
.["stock"] = list()
|
||||
for (var/datum/data/vending_product/R in product_records + coin_records + hidden_records)
|
||||
.["stock"][R.name] = R.amount
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Due to the fact browse_rsc can't create subdirectories, every time you update font-awesome you'll need to change relative webfont references in all.min.css
|
||||
eg ../webfonts/fa-regular-400.ttf => fa-regular-400.ttf (or whatever you call it in asset datum)
|
||||
|
||||
Second change is ripping out file types other than woff and eot(ie8) from the css
|
||||
Second change is ripping out file types other than ~~ woff and eot(ie8)~~ ttf from the css
|
||||
|
||||
Finally, removing brand related css.
|
||||
Finally, removing brand related css.
|
||||
|
||||
5
html/font-awesome/css/all.min.css
vendored
5
html/font-awesome/css/all.min.css
vendored
File diff suppressed because one or more lines are too long
5
html/font-awesome/css/v4-shims.min.css
vendored
5
html/font-awesome/css/v4-shims.min.css
vendored
File diff suppressed because one or more lines are too long
BIN
html/font-awesome/webfonts/fa-regular-400.ttf
Normal file
BIN
html/font-awesome/webfonts/fa-regular-400.ttf
Normal file
Binary file not shown.
BIN
html/font-awesome/webfonts/fa-solid-900.ttf
Normal file
BIN
html/font-awesome/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
html/font-awesome/webfonts/fa-v4compatibility.ttf
Normal file
BIN
html/font-awesome/webfonts/fa-v4compatibility.ttf
Normal file
Binary file not shown.
@@ -269,3 +269,25 @@ export const zip = (...arrays) => {
|
||||
export const zipWith = iterateeFn => (...arrays) => {
|
||||
return map(values => iterateeFn(...values))(zip(...arrays));
|
||||
};
|
||||
|
||||
|
||||
const isObject = (obj: unknown) => typeof obj === 'object' && obj !== null;
|
||||
|
||||
// Does a deep merge of two objects. DO NOT FEED CIRCULAR OBJECTS!!
|
||||
export const deepMerge = (...objects: any[]): any => {
|
||||
const target = {};
|
||||
for (const object of objects) {
|
||||
for (const key of Object.keys(object)) {
|
||||
const targetValue = target[key];
|
||||
const objectValue = object[key];
|
||||
if (Array.isArray(targetValue) && Array.isArray(objectValue)) {
|
||||
target[key] = [...targetValue, ...objectValue];
|
||||
} else if (isObject(targetValue) && isObject(objectValue)) {
|
||||
target[key] = deepMerge(targetValue, objectValue);
|
||||
} else {
|
||||
target[key] = objectValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
@@ -17,6 +17,23 @@ export class Color {
|
||||
toString() {
|
||||
return `rgba(${this.r | 0}, ${this.g | 0}, ${this.b | 0}, ${this.a | 0})`;
|
||||
}
|
||||
|
||||
// Darkens a color by a given percent. Returns a color, which can have toString called to get it's rgba() css value.
|
||||
darken(percent) {
|
||||
percent /= 100;
|
||||
return new Color(
|
||||
this.r - this.r * percent,
|
||||
this.g - this.g * percent,
|
||||
this.b - this.b * percent,
|
||||
this.a
|
||||
);
|
||||
}
|
||||
|
||||
// Brightens a color by a given percent. Returns a color, which can have toString called to get it's rgba() css value.
|
||||
lighten(percent) {
|
||||
// No point in rewriting code we already have.
|
||||
return this.darken(-percent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,8 +37,8 @@ export { RestrictedInput } from './RestrictedInput';
|
||||
export { RoundGauge } from './RoundGauge';
|
||||
export { Section } from './Section';
|
||||
export { Slider } from './Slider';
|
||||
export { StyleableSection } from './StyleableSection';
|
||||
export { Stack } from './Stack';
|
||||
export { StyleableSection } from './StyleableSection';
|
||||
export { Table } from './Table';
|
||||
export { Tabs } from './Tabs';
|
||||
export { TextArea } from './TextArea';
|
||||
|
||||
200
tgui/packages/tgui/interfaces/JobSelection.tsx
Normal file
200
tgui/packages/tgui/interfaces/JobSelection.tsx
Normal file
@@ -0,0 +1,200 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, StyleableSection, Icon, Stack, NoticeBox } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { Color } from 'common/color';
|
||||
import { SFC } from 'inferno';
|
||||
import { JobToIcon } from './common/JobToIcon';
|
||||
import { deepMerge } from 'common/collections';
|
||||
import { BooleanLike } from 'common/react';
|
||||
|
||||
type Job = {
|
||||
unavailable_reason: string | null;
|
||||
command: BooleanLike;
|
||||
open_slots: number;
|
||||
used_slots: number;
|
||||
icon: string;
|
||||
prioritized: BooleanLike;
|
||||
description: string;
|
||||
};
|
||||
|
||||
type Department = {
|
||||
color: string;
|
||||
jobs: Record<string, Job>;
|
||||
open_slots: number;
|
||||
};
|
||||
|
||||
type Data = {
|
||||
departments_static: Record<string, Department>;
|
||||
departments: Record<string, Department>;
|
||||
alert_state: string;
|
||||
shuttle_status: string;
|
||||
disable_jobs_for_non_observers: BooleanLike;
|
||||
priority: BooleanLike;
|
||||
round_duration: string;
|
||||
};
|
||||
|
||||
export const JobEntry: SFC<{
|
||||
jobName: string;
|
||||
job: Job;
|
||||
department: Department;
|
||||
onClick: () => void;
|
||||
}> = (data) => {
|
||||
const jobName = data.jobName;
|
||||
const job = data.job;
|
||||
const department = data.department;
|
||||
const jobIcon = job.icon || JobToIcon[jobName] || null;
|
||||
return (
|
||||
<Button
|
||||
fluid
|
||||
style={{
|
||||
// Try not to think too hard about this one.
|
||||
'background-color': job.unavailable_reason
|
||||
? '#949494' // Grey background
|
||||
: job.prioritized
|
||||
? '#16fc0f' // Bright green background
|
||||
: Color.fromHex(department.color)
|
||||
.darken(10)
|
||||
.toString(),
|
||||
'color': job.unavailable_reason
|
||||
? '#616161' // Dark grey font
|
||||
: Color.fromHex(department.color)
|
||||
.darken(90)
|
||||
.toString(),
|
||||
'font-size': '1.1rem',
|
||||
'cursor': job.unavailable_reason ? 'initial' : 'pointer',
|
||||
}}
|
||||
tooltip={
|
||||
job.unavailable_reason ||
|
||||
(job.prioritized ? (
|
||||
<>
|
||||
<p style={{ 'margin-top': '0px' }}>
|
||||
<b>The station is looking for more personnel to fill this position!</b>
|
||||
</p>
|
||||
{job.description}
|
||||
</>
|
||||
) : (
|
||||
job.description
|
||||
))
|
||||
}
|
||||
onClick={() => {
|
||||
!job.unavailable_reason && data.onClick();
|
||||
}}>
|
||||
<>
|
||||
{jobIcon && <Icon name={jobIcon} />}
|
||||
{job.command ? <b>{jobName}</b> : jobName}
|
||||
<span
|
||||
style={{
|
||||
'white-space': 'nowrap',
|
||||
'position': 'absolute',
|
||||
'right': '0.5em',
|
||||
}}>
|
||||
{job.used_slots} / {job.open_slots}
|
||||
</span>
|
||||
</>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
export const JobSelection = (props, context) => {
|
||||
const { act, data } = useBackend<Data>(context);
|
||||
if (!data?.departments_static) {
|
||||
return null; // Stop TGUI whitescreens with TGUI-dev!
|
||||
}
|
||||
const departments: Record<string, Department> = deepMerge(
|
||||
data.departments,
|
||||
data.departments_static
|
||||
);
|
||||
|
||||
return (
|
||||
<Window
|
||||
width={1012}
|
||||
height={data.shuttle_status ? 720 : 700}
|
||||
onComponentDidMount={() => {
|
||||
// Send a heartbeat back to DM to let it know the window is alive and well
|
||||
act('ui_mounted_with_no_bluescreen');
|
||||
}}>
|
||||
<Window.Content scrollable>
|
||||
<StyleableSection
|
||||
title={
|
||||
<>
|
||||
{data.shuttle_status && (
|
||||
<NoticeBox info>{data.shuttle_status}</NoticeBox>
|
||||
)}
|
||||
<span style={{ 'color': 'grey' }}>
|
||||
It is currently {data.round_duration} into the shift.
|
||||
</span>
|
||||
<Button
|
||||
style={{ 'position': 'absolute', 'right': '1em' }}
|
||||
onClick={() => act('select_job', { 'job': 'Random' })}
|
||||
content="Random Job!"
|
||||
tooltip="Roll target random job. You can re-roll or cancel your random job if you don't like it."
|
||||
/>
|
||||
</>
|
||||
}
|
||||
titleStyle={{ 'min-height': '3.4em' }}>
|
||||
<Box wrap="wrap" style={{ 'columns': '20em' }}>
|
||||
{Object.entries(departments).map((departmentEntry) => {
|
||||
const departmentName = departmentEntry[0];
|
||||
const entry = departmentEntry[1];
|
||||
return (
|
||||
<Box key={departmentName} minWidth="30%">
|
||||
<StyleableSection
|
||||
title={
|
||||
<>
|
||||
{departmentName}
|
||||
<span
|
||||
style={{
|
||||
'font-size': '1rem',
|
||||
'white-space': 'nowrap',
|
||||
'position': 'absolute',
|
||||
'right': '1em',
|
||||
'color': Color.fromHex(entry.color)
|
||||
.darken(60)
|
||||
.toString(),
|
||||
}}>
|
||||
{entry.open_slots +
|
||||
(entry.open_slots === 1 ? ' slot' : ' slots') +
|
||||
' available'}
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
style={{
|
||||
'background-color': entry.color,
|
||||
'margin-bottom': '1em',
|
||||
'break-inside': 'avoid-column',
|
||||
}}
|
||||
titleStyle={{
|
||||
'border-bottom-color': Color.fromHex(entry.color)
|
||||
.darken(50)
|
||||
.toString(),
|
||||
}}
|
||||
textStyle={{
|
||||
'color': Color.fromHex(entry.color)
|
||||
.darken(80)
|
||||
.toString(),
|
||||
}}>
|
||||
<Stack vertical>
|
||||
{Object.entries(entry.jobs).map((job) => (
|
||||
<Stack.Item key={job[0]}>
|
||||
<JobEntry
|
||||
key={job[0]}
|
||||
jobName={job[0]}
|
||||
job={job[1]}
|
||||
department={entry}
|
||||
onClick={() => {
|
||||
act('select_job', { job: job[0] });
|
||||
}}
|
||||
/>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</StyleableSection>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</StyleableSection>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
4
tgui/packages/tgui/interfaces/common/JobToIcon.ts
Normal file
4
tgui/packages/tgui/interfaces/common/JobToIcon.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// Used to handle jobs that don't have a trim.
|
||||
export const JobToIcon = {
|
||||
'Personal AI': 'mobile-alt',
|
||||
} as const;
|
||||
@@ -2367,6 +2367,7 @@
|
||||
#include "code\modules\mob\update_icons.dm"
|
||||
#include "code\modules\mob\camera\camera.dm"
|
||||
#include "code\modules\mob\dead\dead.dm"
|
||||
#include "code\modules\mob\dead\new_player\latejoin_menu.dm"
|
||||
#include "code\modules\mob\dead\new_player\login.dm"
|
||||
#include "code\modules\mob\dead\new_player\logout.dm"
|
||||
#include "code\modules\mob\dead\new_player\new_player.dm"
|
||||
@@ -3790,7 +3791,6 @@
|
||||
#include "yogstation\code\modules\jobs\job_types\network_admin.dm"
|
||||
#include "yogstation\code\modules\jobs\job_types\paramedic.dm"
|
||||
#include "yogstation\code\modules\jobs\job_types\psychiatrist.dm"
|
||||
#include "yogstation\code\modules\jobs\job_types\space_bartender.dm"
|
||||
#include "yogstation\code\modules\jobs\job_types\tourist.dm"
|
||||
#include "yogstation\code\modules\language\darkspeak.dm"
|
||||
#include "yogstation\code\modules\language\japanese.dm"
|
||||
|
||||
@@ -33,6 +33,6 @@
|
||||
for (var/mob/dead/new_player/NP in queue)
|
||||
to_chat(NP, span_userdanger("The alive players limit has been released!<br><a href='?src=[REF(NP)];late_join=override'>[html_encode(">>Join Game<<")]</a>"))
|
||||
SEND_SOUND(NP, sound('sound/misc/notice1.ogg'))
|
||||
NP.LateChoices()
|
||||
GLOB.latejoin_menu.ui_interact(NP)
|
||||
queue.len = 0
|
||||
SSticker.queue_delay = 0
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/brigphysician
|
||||
title = "Brig Physician"
|
||||
description = "Watch over the Brig and Prison Wing to ensure prisoners receive medical attention when needed."
|
||||
flag = BRIGPHYS
|
||||
orbit_icon = "suitcase-medical"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/clerk
|
||||
title = "Clerk"
|
||||
description = "Set up shop on the station and unique sell trinkets to the crew for a profit."
|
||||
flag = CLERK
|
||||
orbit_icon = "basket-shopping"
|
||||
department_head = list("Head of Personnel")
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/miningmedic
|
||||
title = "Mining Medic"
|
||||
description = "Watch over the Shaft Miners and they all inevitably die in Lavaland."
|
||||
flag = MMEDIC
|
||||
orbit_icon = "kit-medical"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/network_admin
|
||||
title = "Network Admin"
|
||||
description = "Maintain and upgrade the AI, try not to break radio communications."
|
||||
flag = NETWORKADMIN
|
||||
orbit_icon = "satellite-dish"
|
||||
department_head = list("Chief Engineer", "Research Director")
|
||||
department_flag = ENGSEC
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/paramedic
|
||||
title = "Paramedic"
|
||||
description = "Constantly reminder the crew about their suit sensor. Come to their aid when they die."
|
||||
flag = PARAMEDIC
|
||||
orbit_icon = "truck-medical"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/datum/job/psych
|
||||
title = "Psychiatrist"
|
||||
description = "Diagnose crew members with psychological issues and aid their treatment."
|
||||
flag = PSYCH
|
||||
orbit_icon = "brain"
|
||||
department_head = list("Chief Medical Officer")
|
||||
department_flag = MEDSCI
|
||||
faction = "Station"
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/datum/job/bartender/space
|
||||
title = "Space Bartender"
|
||||
flag = null
|
||||
faction = "A cold beer and the outstreched depths of space"
|
||||
department_head = null
|
||||
department_flag = null
|
||||
base_access = list(ACCESS_BAR, ACCESS_KITCHEN)
|
||||
total_positions = 0
|
||||
spawn_positions = 0
|
||||
department_head = null
|
||||
department_flag = null
|
||||
|
||||
smells_like = "ethanol and isolation"
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/job/tourist
|
||||
title = "Tourist"
|
||||
flag = TOUR
|
||||
orbit_icon = "camera-retro"
|
||||
department_flag = CIVILIAN
|
||||
faction = "Station"
|
||||
total_positions = -1
|
||||
|
||||
Reference in New Issue
Block a user