Categorized latejoin menu and made it into VueUI, improved crew manifest logic and made Verb manifest same as VueUI program, Job fixes (#10470)

This commit is contained in:
Jiří Barouš
2020-11-12 17:08:31 +01:00
committed by GitHub
parent 6d9241f194
commit 37cbb8fdb8
42 changed files with 856 additions and 483 deletions
+1
View File
@@ -268,6 +268,7 @@
#include "code\datums\computerfiles.dm"
#include "code\datums\datum.dm"
#include "code\datums\feedback.dm"
#include "code\datums\late_choices.dm"
#include "code\datums\mind.dm"
#include "code\datums\mixed.dm"
#include "code\datums\modules.dm"
+29
View File
@@ -105,3 +105,32 @@
#define RECORD_LOCKED 8
#define RECORD_WARRANT 16
#define RECORD_VIRUS 32
// - SSjobs --
// departments
#define DEPARTMENT_COMMAND "Command"
#define DEPARTMENT_SECURITY "Security"
#define DEPARTMENT_ENGINEERING "Engineering"
#define DEPARTMENT_MEDICAL "Medical"
#define DEPARTMENT_SCIENCE "Science"
#define DEPARTMENT_CARGO "Cargo"
#define DEPARTMENT_CIVILIAN "Civilian"
#define DEPARTMENT_EQUIPMENT "Equipment"
#define DEPARTMENT_MISCELLANEOUS "Miscellaneous"
#define DEPARTMENTS_LIST_INIT list(\
DEPARTMENT_COMMAND = list(),\
DEPARTMENT_SECURITY = list(),\
DEPARTMENT_ENGINEERING = list(),\
DEPARTMENT_MEDICAL = list(),\
DEPARTMENT_SCIENCE = list(),\
DEPARTMENT_CARGO = list(),\
DEPARTMENT_CIVILIAN = list(),\
DEPARTMENT_EQUIPMENT = list(),\
DEPARTMENT_MISCELLANEOUS = list(),\
)
// job roles within departments
#define JOBROLE_DEFAULT 0 // This is the default "job role", no special meaning.
#define JOBROLE_SUPERVISOR (1 << 0) // Indicates that the job is a supervisory position, i.e a head of department.
#define SIMPLEDEPT(dept) list(dept = JOBROLE_DEFAULT)
+9
View File
@@ -93,6 +93,15 @@
return TRUE
return FALSE
// Checks that all of the values are in the given list
/proc/all_in_list(var/list/values, var/list/L)
if(!istype(values) || !istype(L))
return FALSE
for(var/value in values)
if(!(value in L))
return FALSE
return TRUE
/proc/is_path_in_list(var/check_path, var/list/L)
for(var/path in L)
if(ispath(check_path, path))
@@ -87,8 +87,7 @@
/obj/screen/ai/crew_manifest/Click()
if (isAI(usr))
var/windowname = open_crew_manifest(usr)
onclose(usr, windowname)
SSrecords.open_manifest_vueui(usr)
/obj/screen/ai/alerts
name = "Show Alerts"
@@ -584,7 +584,6 @@
SearchVar(MERCHANT)
SearchVar(ASSISTANT)
SearchVar(CONSULAR)
SearchVar(assistant_occupations)
SearchVar(command_positions)
SearchVar(engineering_positions)
SearchVar(medical_positions)
+24 -27
View File
@@ -12,10 +12,10 @@
init_order = SS_INIT_JOBS
// Vars.
var/list/occupations = list()
var/list/name_occupations = list() //Dict of all jobs, keys are titles
var/list/type_occupations = list() //Dict of all jobs, keys are types
var/list/unassigned = list()
var/list/datum/job/occupations = list()
var/list/datum/job/name_occupations = list() //Dict of all jobs, keys are titles
var/list/datum/job/type_occupations = list() //Dict of all jobs, keys are types
var/list/mob/abstract/new_player/unassigned = list()
var/list/job_debug = list()
var/list/factions = list()
@@ -104,9 +104,9 @@
to_chat(player, "<span class='warning'>Your character is too young!</span>")
return FALSE
var/position_limit = job.total_positions
var/position_limit = job.get_total_positions()
if(!latejoin)
position_limit = job.spawn_positions
position_limit = job.get_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
@@ -117,14 +117,12 @@
Debug("AR has failed, Player: [player], Rank: [rank]")
return FALSE
/datum/controller/subsystem/jobs/proc/FreeRole(rank)
/datum/controller/subsystem/jobs/proc/FreeRole(var/rank)
var/datum/job/job = GetJob(rank)
if(!istype(job))
return
if (job && job.current_positions >= job.total_positions && job.total_positions != -1)
job.total_positions++
return TRUE
return FALSE
job.current_positions--
/datum/controller/subsystem/jobs/proc/FindOccupationCandidates(datum/job/job, level, flag)
Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
@@ -278,7 +276,7 @@
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)
if((job.current_positions < job.get_spawn_positions()) || job.get_spawn_positions() == -1)
Debug("DO pass, Player: [player], Level:[level], Job:[job.title]")
AssignRole(player, job.title)
unassigned -= player
@@ -348,16 +346,16 @@
H.buckled.forceMove(H.loc)
H.buckled.set_dir(H.dir)
// If they're head, give them the account info for their department
if(H.mind && job.head_position)
if(H.mind)
// If they're a department supervisor/head give them the account info for that department
var/remembered_info = ""
var/datum/money_account/department_account = SSeconomy.get_department_account(job.department)
if(department_account)
remembered_info += "<b>Your department's account number is:</b> #[department_account.account_number]<br>"
remembered_info += "<b>Your department's account pin is:</b> [department_account.remote_access_pin]<br>"
remembered_info += "<b>Your department's account funds are:</b> $[department_account.money]<br>"
for(var/department in job.departments)
if(job.departments[department] & JOBROLE_SUPERVISOR)
var/datum/money_account/department_account = SSeconomy.get_department_account(department)
if(department_account)
remembered_info += "<b>[department] department's account number is:</b> #[department_account.account_number]<br>"
remembered_info += "<b>[department] department's account pin is:</b> [department_account.remote_access_pin]<br>"
remembered_info += "<b>[department] department's account funds are:</b> $[department_account.money]<br>"
H.mind.store_memory(remembered_info)
var/alt_title = null
@@ -381,7 +379,7 @@
if(H.needs_wheelchair())
H.equip_wheelchair()
to_chat(H, "<B>You are [job.total_positions == 1 ? "the" : "a"] [alt_title ? alt_title : rank].</B>")
to_chat(H, "<B>You are [job.get_total_positions() == 1 ? "the" : "a"] [alt_title ? alt_title : rank].</B>")
if(job.supervisors)
to_chat(H, "<b>As [job.intro_prefix] [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
@@ -541,7 +539,7 @@
var/obj/item/clothing/glasses/G = H.glasses
G.prescription = 7
G.autodrobe_no_remove = TRUE
if(H.species && !H.species_items_equipped)
H.species.equip_later_gear(H)
H.species_items_equipped = TRUE
@@ -585,11 +583,10 @@
if(name && value)
var/datum/job/J = GetJob(name)
if(!J) continue
if(!istype(J))
continue
J.total_positions = text2num(value)
J.spawn_positions = text2num(value)
if(name == "AI" || name == "Cyborg")//I dont like this here but it will do for now // 6 years later and it's still not changed. Hue.
J.total_positions = 0
return TRUE
+41 -89
View File
@@ -10,7 +10,6 @@
var/list/warrants
var/list/viruses
var/list/nameMap
var/list/excluded_fields
var/list/localized_fields
@@ -38,7 +37,6 @@
excluded_fields = list()
localized_fields = list()
manifest = list()
nameMap = list("heads" = "Heads", "sec" = "Security", "eng" = "Engineering", "med" = "Medical", "sci" = "Science", "car" = "Cargo", "civ" = "Civilian", "misc" = "Miscellaneous", "bot" = "Equipment")
NEW_SS_GLOBAL(SSrecords)
var/datum/D = new()
for(var/v in D.vars)
@@ -181,54 +179,27 @@
/datum/controller/subsystem/records/proc/reset_manifest()
manifest.Cut()
// The one and only method for showing a pop-up crew manifest (browser) window
/proc/open_crew_manifest(var/mob/user, var/OOC = FALSE)
if(!user)
return
var/const/windowname = "manifest"
var/dat = {"<h2 style="text-align: center">Crew Manifest</h2>"}
dat += SSrecords.get_manifest(OOC)
send_theme_resources(user)
user << browse(enable_ui_theme(user, dat), "window=[windowname];size=450x600")
return windowname
/datum/controller/subsystem/records/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state) // this is needed because VueUI closes otherwise
if(isnewplayer(user))
return STATUS_INTERACTIVE
if(isobserver(user))
return STATUS_INTERACTIVE
if(issilicon(user)) // silicons have the show manifest verb
return STATUS_INTERACTIVE
return ..()
/datum/controller/subsystem/records/proc/get_manifest(var/OOC = FALSE)
var/const/style = {"
.manifest {border-collapse: collapse; width: 100%}
.manifest td, th {border: 1px solid #DEF; background-color: white; color:black; padding: .25em}
.manifest th {height: 2em; background-color: #3F668F; color: white}
.manifest tr.head th {background-color: #006E7A;}
.manifest td:first-child {text-align: right}
.manifest tr.alt td {background-color: #DEF}
"}
var/dat = {"
<head><style>[style]</style></head>
<table class="manifest">
<tr class='head'><th>Name</th><th>Rank</th><th>Activity</th></tr>
"}
var/even = 0
var/list/isactive = new()
for(var/mob/M in player_list)
if (OOC)
if(M.client && M.client.inactivity <= 10 * 60 * 10)
isactive[M.real_name] = "Active"
else
isactive[M.real_name] = "Inactive"
else
isactive[M.real_name] = 0
/datum/controller/subsystem/records/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
. = ..()
data = . || data || list()
var/manifest = get_manifest_list()
for(var/dep in manifest)
var/list/depI = manifest[dep]
if(depI.len > 0)
dat += "<tr><th colspan=3>[nameMap[dep]]</th></tr>"
for(var/list/item in depI)
dat += "<tr[even ? " class='alt'" : ""]><td>[item["name"]]</td><td>[item["rank"]]</td><td>[isactive[item["name"]] ? isactive[item["name"]] : item["active"]]</td></tr>"
even = !even
dat += "</table>"
dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly
dat = replacetext(dat, "\t", "")
return dat
VUEUI_SET_CHECK_LIST(data["manifest"], SSrecords.get_manifest_list(), ., data)
/datum/controller/subsystem/records/proc/open_manifest_vueui(mob/user)
var/datum/vueui/ui = SSvueui.get_open_ui(user, src)
if (!ui)
ui = new(user, src, "manifest", 450, 600, "Crew Manifest")
ui.header = "minimal"
ui.open()
/datum/controller/subsystem/records/proc/get_manifest_text()
var/dat = "<h2>Crew Manifest</h2><em>as of [worlddate2text()] [worldtime2text()]</em>"
@@ -239,56 +210,38 @@
var/depDat
for(var/list/item in depI)
depDat += "<li><strong>[item["name"]]</strong> - [item["rank"]] ([item["active"]])</li>"
dat += "<h3>[nameMap[dep]]</h3><ul>[depDat]</ul>"
dat += "<h3>[dep]</h3><ul>[depDat]</ul>"
return dat
/datum/controller/subsystem/records/proc/get_manifest_list()
if(manifest.len)
return manifest
manifest = list(
"heads" = list(),
"sec" = list(),
"eng" = list(),
"med" = list(),
"sci" = list(),
"car" = list(),
"civ" = list(),
"bot" = list(),
"misc" = list()
)
var/positions = list(
"heads" = command_positions,
"sec" = security_positions,
"eng" = engineering_positions,
"med" = medical_positions,
"sci" = science_positions,
"car" = cargo_positions,
"civ" = civilian_positions,
"bot" = nonhuman_positions
)
if(!SSjobs)
error("SSjobs not available, cannot build manifest")
return
manifest = DEPARTMENTS_LIST_INIT
for(var/datum/record/general/t in records)
var/name = sanitize(t.name, encode = FALSE)
var/rank = sanitize(t.rank, encode = FALSE)
var/real_rank = make_list_rank(t.real_rank)
var/datum/job/job = SSjobs.GetJob(real_rank)
var/isactive = t.physical_status
var/department = 0
var/depthead = 0 // Department Heads will be placed at the top of their lists.
for(var/positionType in positions)
var/typesPositions = positions[positionType]
if(real_rank in typesPositions)
manifest[positionType][++manifest[positionType].len] = list("name" = name, "rank" = rank, "active" = isactive)
department = 1
if ((depthead || rank == "Captain") && manifest[positionType].len != 1)
manifest[positionType].Swap(1, manifest[positionType].len)
manifest[positionType][1]["head"] = TRUE
if(positionType == "head")
depthead = 1
var/list/departments
if(job.departments.len > 0 && all_in_list(job.departments, manifest))
departments = job.departments
else // no department set or there's something weird
departments = list(DEPARTMENT_MISCELLANEOUS = JOBROLE_DEFAULT)
if(!department && !(name in manifest["heads"]))
manifest["misc"][++manifest["misc"].len] = list("name" = name, "rank" = rank, "active" = isactive)
for(var/department in departments) // add them to their departments
var/supervisor = departments[department] & JOBROLE_SUPERVISOR
manifest[department][++manifest[department].len] = list("name" = name, "rank" = rank, "active" = isactive, "head" = supervisor)
if(supervisor) // they are a supervisor/head, put them on top
manifest[department].Swap(1, manifest[department].len)
// silicons are not in records, we need to add them manually
var/dept = DEPARTMENT_EQUIPMENT
for(var/mob/living/silicon/S in player_list)
if(istype(S, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = S
@@ -297,12 +250,11 @@
var/selected_module = "Default Module"
if(R.module)
selected_module = capitalize_first_letters(R.module.name)
manifest["bot"][++manifest["bot"].len] = list("name" = sanitize(R.name), "rank" = selected_module, "active" = "Online")
if(istype(S, /mob/living/silicon/ai))
manifest[dept][++manifest[dept].len] = list("name" = sanitize(R.name), "rank" = selected_module, "active" = "Online", "head" = FALSE)
else if(istype(S, /mob/living/silicon/ai))
var/mob/living/silicon/ai/A = S
manifest["bot"][++manifest["bot"].len] = list("name" = sanitize(A.name), "rank" = "Station Intelligence", "active" = "Online")
if(manifest["bot"].len != 1)
manifest["bot"].Swap(1, manifest["bot"].len)
manifest[dept][++manifest[dept].len] = list("name" = sanitize(A.name), "rank" = "Station Intelligence", "active" = "Online", "head" = TRUE)
manifest[dept].Swap(1, manifest[dept].len)
manifest_json = json_encode(manifest)
return manifest
+114
View File
@@ -0,0 +1,114 @@
// This datum holds the late choices UI for a new player
/datum/late_choices
var/datum/vueui/ui = null
var/update_icon_on_next_open = TRUE
var/mob/abstract/new_player/NP
/datum/late_choices/New(var/mob/abstract/new_player/NP)
if(!istype(NP))
return
src.NP = NP
/datum/late_choices/Destroy(force)
NP.late_choices_ui = null
ui.close()
QDEL_NULL(ui)
return ..()
/datum/late_choices/CanUseTopic(var/mob/user, var/datum/topic_state/state = default_state) // this is needed because VueUI closes otherwise
if(isnewplayer(user))
return STATUS_INTERACTIVE
return ..()
/datum/late_choices/Topic(href, href_list)
// proxy Topic calls back to the user
NP.Topic(href, href_list)
/datum/late_choices/proc/ui_open()
if(!istype(ui))
ui = new(NP, src, "late-choices", 330, 720, "Late-Join Choices")
ui.header = "minimal"
ui.auto_update_content = TRUE
if (update_icon_on_next_open)
do_update_character_icon(FALSE)
ui.open()
/datum/late_choices/proc/ui_refresh()
ui.check_for_change()
/datum/late_choices/proc/update_character_icon()
if(ui.status > STATUS_CLOSE)
do_update_character_icon(TRUE)
else
update_icon_on_next_open = TRUE
/datum/late_choices/proc/do_update_character_icon(var/send)
update_icon_on_next_open = FALSE
var/mob/mannequin = NP.client.prefs.update_mannequin()
ui.add_asset("character", getFlatIcon(mannequin, SOUTH))
if(send)
ui.send_asset("character")
ui.push_change(null)
/datum/late_choices/vueui_data_change(var/list/data, var/mob/user, var/datum/vueui/ui)
. = ..()
data = . || data || list()
data["round_duration"] = get_round_duration_formatted()
data["alert_level"] = capitalize(get_security_level())
data["character_name"] = user.client.prefs.real_name
var/shuttle_status = ""
if(emergency_shuttle) //In case Nanotrasen decides to reposess CentComm's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
shuttle_status = "post-evac"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
shuttle_status = "evac"
else // Crew transfer initiated
shuttle_status = "transfer"
data["shuttle_status"] = shuttle_status
var/unique_role_available = FALSE
for(var/ghost_role in SSghostroles.spawners)
var/datum/ghostspawner/G = SSghostroles.spawners[ghost_role]
if(!G.show_on_job_select)
continue
if(G.cant_see(NP))
continue
unique_role_available = TRUE
break
data["unique_role_available"] = unique_role_available
var/jobs_available = 0
var/list/list/datum/job/jobs_by_department = DEPARTMENTS_LIST_INIT
for(var/datum/job/job in SSjobs.occupations)
if(NP.IsJobAvailable(job.title))
jobs_available++
var/list/departments
if(job.departments.len > 0 && all_in_list(job.departments, jobs_by_department))
departments = job.departments
else // no department set or there's something weird
departments = list(DEPARTMENT_MISCELLANEOUS = JOBROLE_DEFAULT)
for(var/department in departments)
if(departments[department] & JOBROLE_SUPERVISOR) // they are a supervisor/head, put them on top
jobs_by_department[department] = list(job) + jobs_by_department[department]
else
jobs_by_department[department] += job // add them to their departments
data["jobs_available"] = jobs_available
LAZYINITLIST(data["jobs_list"])
for(var/department in jobs_by_department)
LAZYINITLIST(data["jobs_list"][department])
for(var/datum/job/job in jobs_by_department[department])
LAZYINITLIST(data["jobs_list"][department][job.title])
data["jobs_list"][department][job.title]["title"] = job.title
data["jobs_list"][department][job.title]["head"] = job.departments[department] & JOBROLE_SUPERVISOR
data["jobs_list"][department][job.title]["total_positions"] = job.get_total_positions()
data["jobs_list"][department][job.title]["current_positions"] = job.current_positions
return data
+5 -6
View File
@@ -502,24 +502,23 @@ var/global/list/additional_antag_types = list()
var/evil = 0
if(man.client.prefs.nanotrasen_relation == COMPANY_OPPOSED || man.client.prefs.nanotrasen_relation == COMPANY_SKEPTICAL)
evil = 1
switch(job.department)
if("Civilian" || "Cargo")
if((DEPARTMENT_CIVILIAN in job.departments) || (DEPARTMENT_CARGO in job.departments))
civ += 1
if(evil)
civ_suspect += 1
if("Engineering")
if(DEPARTMENT_ENGINEERING in job.departments)
eng += 1
if(evil)
eng_suspect += 1
if("Security")
if(DEPARTMENT_SECURITY in job.departments)
sec += 1
if(evil)
sec_suspect += 1
if("Medical")
if(DEPARTMENT_MEDICAL in job.departments)
med +=1
if(evil)
med_suspect += 1
if("Science")
if(DEPARTMENT_SCIENCE in job.departments)
sci += 1
if(evil)
sci_suspect += 1
+7 -7
View File
@@ -1,14 +1,14 @@
/datum/job/assistant
title = "Assistant"
flag = ASSISTANT
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = -1
spawn_positions = -1
intro_prefix = "an"
supervisors = "absolutely everyone"
selection_color = "#C0C0C0"
selection_color = "#90524b"
economic_modifier = 1
access = list() //See /datum/job/assistant/get_access()
minimal_access = list() //See /datum/job/assistant/get_access()
@@ -30,16 +30,16 @@
/datum/job/visitor
title = "Visitor"
flag = VISITOR
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = -1
spawn_positions = -1
supervisors = "any authority figure"
selection_color = "#3d3d3d"
selection_color = "#90524b"
economic_modifier = 1
access = list()
minimal_access = list()
access = list()
minimal_access = list()
outfit = /datum/outfit/job/visitor
/datum/outfit/job/visitor
@@ -47,4 +47,4 @@
jobtype = /datum/job/visitor
uniform = /obj/item/clothing/under/color/black
shoes = /obj/item/clothing/shoes/black
shoes = /obj/item/clothing/shoes/black
+4 -6
View File
@@ -3,15 +3,14 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
/datum/job/captain
title = "Captain"
flag = CAPTAIN
department = "Command"
head_position = 1
departments = list(DEPARTMENT_COMMAND = JOBROLE_SUPERVISOR)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "company officials and Corporate Regulations"
selection_color = "#4747FF"
selection_color = "#114dc1"
access = list() //See get_access()
minimal_access = list() //See get_access()
minimal_player_age = 14
@@ -71,15 +70,14 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
/datum/job/hop
title = "Head of Personnel"
flag = HOP
department = "Civilian"
head_position = 1
departments = list(DEPARTMENT_CIVILIAN = JOBROLE_SUPERVISOR, DEPARTMENT_COMMAND)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "the captain"
selection_color = "#9696FF"
selection_color = "#90524b"
minimal_player_age = 10
economic_modifier = 10
ideal_character_age = 50
+18 -19
View File
@@ -2,13 +2,13 @@
/datum/job/bartender
title = "Bartender"
flag = BARTENDER
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
minimum_character_age = 18
@@ -32,13 +32,13 @@
/datum/job/chef
title = "Chef"
flag = CHEF
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
minimum_character_age = 18
@@ -67,13 +67,13 @@
/datum/job/hydro
title = "Gardener"
flag = BOTANIST
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
minimum_character_age = 18
@@ -113,14 +113,13 @@
/datum/job/qm
title = "Quartermaster"
flag = QUARTERMASTER
head_position = 1
department = "Cargo"
departments = list(DEPARTMENT_CARGO = JOBROLE_SUPERVISOR)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
economic_modifier = 5
minimum_character_age = 22
@@ -149,13 +148,13 @@
/datum/job/cargo_tech
title = "Cargo Technician"
flag = CARGOTECH
department = "Cargo"
departments = SIMPLEDEPT(DEPARTMENT_CARGO)
department_flag = CIVILIAN
faction = "Station"
total_positions = 4
spawn_positions = 4
supervisors = "the quartermaster and the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
minimum_character_age = 18
@@ -179,13 +178,13 @@
/datum/job/mining
title = "Shaft Miner"
flag = MINER
department = "Cargo"
departments = SIMPLEDEPT(DEPARTMENT_CARGO)
department_flag = CIVILIAN
faction = "Station"
total_positions = 4
spawn_positions = 4
supervisors = "the quartermaster and the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
economic_modifier = 5
minimum_character_age = 18
@@ -228,13 +227,13 @@
/datum/job/janitor
title = "Janitor"
flag = JANITOR
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
access = list(access_janitor, access_maint_tunnels, access_engine, access_research, access_sec_doors, access_medical)
minimal_access = list(access_janitor, access_engine, access_research, access_sec_doors, access_medical)
outfit = /datum/outfit/job/janitor
@@ -253,13 +252,13 @@
/datum/job/journalist
title = "Corporate Reporter"
flag = JOURNALIST
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
minimum_character_age = 20
@@ -303,13 +302,13 @@
/datum/job/librarian
title = "Librarian"
flag = LIBRARIAN
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
access = list(access_library, access_maint_tunnels)
minimal_access = list(access_library)
alt_titles = list("Curator", "Tech Support")
+3 -3
View File
@@ -2,13 +2,13 @@
/datum/job/chaplain
title = "Chaplain"
flag = CHAPLAIN
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of personnel"
selection_color = "#C0C0C0"
selection_color = "#90524b"
access = list(access_morgue, access_chapel_office, access_crematorium, access_maint_tunnels)
minimal_access = list(access_morgue, access_chapel_office, access_crematorium)
alt_titles = list("Presbyter","Rabbi","Imam","Priest","Shaman","Counselor")
@@ -47,4 +47,4 @@
SSticker.Bible_icon_state = religion.book_sprite
SSticker.Bible_item_state = religion.book_sprite
SSticker.Bible_name = religion.book_name
return 1
return 1
+9 -9
View File
@@ -1,15 +1,14 @@
/datum/job/chief_engineer
title = "Chief Engineer"
flag = CHIEF
head_position = TRUE
department = "Engineering"
departments = list(DEPARTMENT_ENGINEERING = JOBROLE_SUPERVISOR, DEPARTMENT_COMMAND)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "the captain"
selection_color = "#FFD737"
selection_color = "#c67519"
economic_modifier = 10
minimum_character_age = 30
@@ -70,13 +69,13 @@
/datum/job/engineer
title = "Station Engineer"
flag = ENGINEER
department = "Engineering"
departments = SIMPLEDEPT(DEPARTMENT_ENGINEERING)
department_flag = ENGSEC
faction = "Station"
total_positions = 5
spawn_positions = 5
supervisors = "the chief engineer"
selection_color = "#FFEA95"
selection_color = "#c67519"
economic_modifier = 5
minimum_character_age = 25
@@ -116,14 +115,14 @@
/datum/job/atmos
title = "Atmospheric Technician"
flag = ATMOSTECH
department = "Engineering"
departments = SIMPLEDEPT(DEPARTMENT_ENGINEERING)
department_flag = ENGSEC
faction = "Station"
total_positions = 3
spawn_positions = 2
intro_prefix = "an"
supervisors = "the chief engineer"
selection_color = "#FFEA95"
selection_color = "#c67519"
economic_modifier = 5
minimum_character_age = 25
@@ -164,13 +163,14 @@
/datum/job/intern_eng
title = "Engineering Apprentice"
flag = INTERN_ENG
departments = SIMPLEDEPT(DEPARTMENT_ENGINEERING)
department_flag = ENGSEC
faction = "Station"
total_positions = 2
spawn_positions = 2
intro_prefix = "an"
supervisors = "the Chief Engineer"
selection_color = "#FFEA95"
selection_color = "#c67519"
access = list(access_maint_tunnels, access_construction, access_engine_equip, access_engine)
minimal_access = list(access_maint_tunnels, access_construction, access_engine_equip, access_engine)
outfit = /datum/outfit/job/intern_eng
@@ -198,4 +198,4 @@
backpack = /obj/item/storage/backpack/industrial
satchel = /obj/item/storage/backpack/satchel_eng
dufflebag = /obj/item/storage/backpack/duffel/eng
messengerbag = /obj/item/storage/backpack/messenger/engi
messengerbag = /obj/item/storage/backpack/messenger/engi
+22 -15
View File
@@ -1,37 +1,37 @@
/datum/job
//The name of the job
var/title = "NOPE"
var/title = "NOPE" //The name of the job
//Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
var/list/minimal_access = list() // Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
var/list/access = list() // Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
var/flag = 0 // Bitflags for the job
var/department_flag = 0
var/flag = 0 // Bitflags for the job
var/department_flag = 0 // Used to tell which set of job bitflags to use to determine the actual job (since there are too many jobs to fit in a single bit flag)
var/faction = "None" // Players will be allowed to spawn in as jobs that are set to "Station"
var/total_positions = 0 // How many players can be this job
var/spawn_positions = 0 // How many players can spawn in as this job
var/current_positions = 0 // How many players have this job
var/intro_prefix = "a"
var/supervisors = null // Supervisors, who this person answers to directly
var/selection_color = "#888888" // Selection screen color
var/selection_color = "#5d6a67" // Selection screen color
var/list/departments = list() // List of departments this job is a part of. Keys are departments, values are a bit field that indicate special roles of that job within the department (like whether they are a head/supervisor of that department).
var/list/alt_titles // List of alternate titles, if any
var/list/title_accesses // A map of title -> list of accesses to add if the person has this title.
var/minimal_player_age = 0 // If you have use_age_restriction_for_jobs config option enabled and the database set up, this option will add a requirement for players to be at least minimal_player_age days old. (meaning they first signed in at least that many days before.)
var/department = null // Does this position have a department tag?
var/head_position = 0 // Is this position Command?
var/minimum_character_age = 17
var/list/alt_ages = null // assoc list of alt titles to minimum character ages
var/list/alt_ages = null // assoc list of alt titles to minimum character ages
var/ideal_character_age = 30
var/latejoin_at_spawnpoints = FALSE //If this job should use roundstart spawnpoints for latejoin (offstation jobs etc)
var/latejoin_at_spawnpoints = FALSE //If this job should use roundstart spawnpoints for latejoin (offstation jobs etc)
var/account_allowed = 1 // Does this job type come with a station account?
var/economic_modifier = 2 // With how much does this job modify the initial account amount?
var/create_record = 1 // Do we announce/make records for people who spawn on this job?
var/account_allowed = TRUE // Does this job type come with a station account?
var/economic_modifier = 2 // With how much does this job modify the initial account amount?
var/create_record = TRUE // Do we announce/make records for people who spawn on this job?
var/datum/outfit/outfit = null
var/list/alt_outfits = null // A list of special outfits for the alt titles list("alttitle" = /datum/outfit)
var/list/blacklisted_species = null // A blacklist of species that can't be this job
var/list/blacklisted_species = null // A blacklist of species that can't be this job
//Only override this proc
/datum/job/proc/after_spawn(mob/living/carbon/human/H)
@@ -123,8 +123,15 @@
if (LAZYLEN(title_accesses) && title_accesses[selected_title])
. += title_accesses[selected_title]
/datum/job/proc/get_total_positions()
return total_positions
/datum/job/proc/get_spawn_positions()
return spawn_positions
/datum/job/proc/is_position_available()
return (current_positions < total_positions) || (total_positions == -1)
var/total = get_total_positions()
return (current_positions < total) || (total == -1)
/datum/job/proc/fetch_age_restriction()
if (!config.age_restrictions_from_file)
+14 -14
View File
@@ -1,15 +1,14 @@
/datum/job/cmo
title = "Chief Medical Officer"
flag = CMO
head_position = 1
department = "Medical"
departments = list(DEPARTMENT_MEDICAL = JOBROLE_SUPERVISOR, DEPARTMENT_COMMAND)
department_flag = MEDSCI
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "the captain"
selection_color = "#FF56B4"
selection_color = "#15903a"
economic_modifier = 10
minimum_character_age = 35
@@ -52,13 +51,13 @@
/datum/job/doctor
title = "Physician"
flag = DOCTOR
department = "Medical"
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 4
spawn_positions = 4
supervisors = "the chief medical officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
economic_modifier = 7
minimum_character_age = 25
@@ -70,11 +69,11 @@
/datum/job/surgeon
title = "Surgeon"
flag = SURGEON
department = "Medical"
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
supervisors = "the chief medical officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
economic_modifier = 7
spawn_positions = 2
@@ -127,13 +126,13 @@
/datum/job/pharmacist
title = "Pharmacist"
flag = CHEMIST
department = "Medical"
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the chief medical officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
economic_modifier = 5
minimum_character_age = 26
@@ -163,7 +162,7 @@
/datum/job/psychiatrist
title = "Psychiatrist"
flag = PSYCHIATRIST
department = "Medical"
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 1
@@ -173,7 +172,7 @@
minimum_character_age = 30
supervisors = "the chief medical officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
access = list(access_medical, access_medical_equip, access_morgue, access_surgery, access_pharmacy, access_virology, access_genetics, access_psychiatrist)
minimal_access = list(access_medical, access_medical_equip, access_psychiatrist)
alt_titles = list("Psychologist")
@@ -201,13 +200,13 @@
/datum/job/med_tech
title = "Emergency Medical Technician"
flag = MED_TECH
department = "Medical"
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the chief medical officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
economic_modifier = 4
minimum_character_age = 20
@@ -243,12 +242,13 @@
/datum/job/intern_med
title = "Medical Intern"
flag = INTERN_MED
departments = SIMPLEDEPT(DEPARTMENT_MEDICAL)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the Chief Medical Officer"
selection_color = "#FF97D1"
selection_color = "#15903a"
access = list(access_medical, access_surgery, access_medical_equip)
minimal_access = list(access_medical, access_surgery, access_medical_equip)
minimum_character_age = 18
-2
View File
@@ -1,13 +1,11 @@
/datum/job/merchant
title = "Merchant"
faction = "Station"
department = "Civilian"
flag = MERCHANT
department_flag = CIVILIAN
total_positions = 0
spawn_positions = 0
supervisors = "yourself and the market"
selection_color = "#515151"
minimal_player_age = 10
economic_modifier = 5
ideal_character_age = 30
@@ -1,13 +1,13 @@
/datum/job/representative
title = "Corporate Liaison"
flag = LAWYER
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "company officials"
selection_color = "#C0C0C0"
selection_color = "#90524b"
economic_modifier = 7
latejoin_at_spawnpoints = TRUE
@@ -81,13 +81,13 @@
/datum/job/consular
title = "Consular Officer"
flag = CONSULAR
department = "Civilian"
departments = SIMPLEDEPT(DEPARTMENT_CIVILIAN)
department_flag = CIVILIAN
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "your embassy"
selection_color = "#C0C0C0"
selection_color = "#90524b"
economic_modifier = 7
latejoin_at_spawnpoints = TRUE
@@ -121,4 +121,4 @@
var/datum/citizenship/citizenship = SSrecords.citizenships[H.citizenship]
if(citizenship)
rep_objectives = citizenship.get_objectives(mission_level, H)
return rep_objectives
return rep_objectives
+10 -10
View File
@@ -1,15 +1,14 @@
/datum/job/rd
title = "Research Director"
flag = RD
head_position = 1
department = "Science"
departments = list(DEPARTMENT_SCIENCE = JOBROLE_SUPERVISOR, DEPARTMENT_COMMAND)
department_flag = MEDSCI
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "the captain"
selection_color = "#FF40FF"
selection_color = "#a44799"
economic_modifier = 15
minimum_character_age = 35
@@ -53,13 +52,13 @@
/datum/job/scientist
title = "Scientist"
flag = SCIENTIST
department = "Science"
departments = SIMPLEDEPT(DEPARTMENT_SCIENCE)
department_flag = MEDSCI
faction = "Station"
total_positions = 5
spawn_positions = 3
supervisors = "the research director"
selection_color = "#FFAAFF"
selection_color = "#a44799"
economic_modifier = 7
minimum_character_age = 30
@@ -97,13 +96,13 @@
/datum/job/xenobiologist
title = "Xenobiologist"
flag = XENOBIOLOGIST
department = "Science"
departments = SIMPLEDEPT(DEPARTMENT_SCIENCE)
department_flag = MEDSCI
faction = "Station"
total_positions = 3
spawn_positions = 2
supervisors = "the research director"
selection_color = "#FFAAFF"
selection_color = "#a44799"
economic_modifier = 7
minimum_character_age = 30
@@ -129,13 +128,13 @@
/datum/job/roboticist
title = "Roboticist"
flag = ROBOTICIST
department = "Science"
departments = SIMPLEDEPT(DEPARTMENT_SCIENCE)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "research director"
selection_color = "#FFAAFF"
selection_color = "#a44799"
economic_modifier = 5
minimum_character_age = 25
@@ -179,12 +178,13 @@
/datum/job/intern_sci
title = "Lab Assistant"
flag = INTERN_SCI
departments = SIMPLEDEPT(DEPARTMENT_SCIENCE)
department_flag = MEDSCI
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the Research Director"
selection_color = "#FFAAFF"
selection_color = "#a44799"
access = list(access_research, access_tox)
minimal_access = list(access_research, access_tox)
outfit = /datum/outfit/job/intern_sci
+12 -11
View File
@@ -1,15 +1,14 @@
/datum/job/hos
title = "Head of Security"
flag = HOS
head_position = 1
department = "Security"
departments = list(DEPARTMENT_SECURITY = JOBROLE_SUPERVISOR, DEPARTMENT_COMMAND)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
intro_prefix = "the"
supervisors = "the captain"
selection_color = "#FF6363"
selection_color = "#991818"
economic_modifier = 10
minimum_character_age = 30
@@ -68,13 +67,13 @@
/datum/job/warden
title = "Warden"
flag = WARDEN
department = "Security"
departments = SIMPLEDEPT(DEPARTMENT_SECURITY)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#FFA4A4"
selection_color = "#991818"
economic_modifier = 5
minimum_character_age = 25
@@ -119,13 +118,13 @@
/datum/job/detective
title = "Detective"
flag = DETECTIVE
department = "Security"
departments = SIMPLEDEPT(DEPARTMENT_SECURITY)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#FFA4A4"
selection_color = "#991818"
economic_modifier = 5
minimum_character_age = 25
@@ -163,12 +162,13 @@
/datum/job/forensics
title = "Forensic Technician"
flag = FORENSICS
departments = SIMPLEDEPT(DEPARTMENT_SECURITY)
department_flag = ENGSEC
faction = "Station"
total_positions = 1
spawn_positions = 1
supervisors = "the head of security"
selection_color = "#FFA4A4"
selection_color = "#991818"
economic_modifier = 5
minimum_character_age = 25
@@ -214,13 +214,13 @@
/datum/job/officer
title = "Security Officer"
flag = OFFICER
department = "Security"
departments = SIMPLEDEPT(DEPARTMENT_SECURITY)
department_flag = ENGSEC
faction = "Station"
total_positions = 4
spawn_positions = 4
supervisors = "the head of security"
selection_color = "#FFA4A4"
selection_color = "#991818"
economic_modifier = 4
minimum_character_age = 18
@@ -263,12 +263,13 @@
/datum/job/intern_sec
title = "Security Cadet"
flag = INTERN_SEC
departments = SIMPLEDEPT(DEPARTMENT_SECURITY)
department_flag = ENGSEC
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the Head of Security"
selection_color = "#FFA4A4"
selection_color = "#991818"
access = list(access_security, access_sec_doors, access_maint_tunnels)
minimal_access = list(access_security, access_sec_doors)
outfit = /datum/outfit/job/intern_sec
+21 -5
View File
@@ -1,11 +1,12 @@
/datum/job/ai
title = "AI"
flag = AI
departments = list(DEPARTMENT_EQUIPMENT = JOBROLE_SUPERVISOR)
department_flag = ENGSEC
faction = "Station"
total_positions = 0 // Not used for AI, see is_position_available below and modules/mob/living/silicon/ai/latejoin.dm
spawn_positions = 1
selection_color = "#00ff00"
total_positions = null // Not used by AI, see get_total_positions and is_position_available below
spawn_positions = null // Not used by AI, see get_spawn_positions below
selection_color = "#6c5b73"
intro_prefix = "the"
supervisors = "your laws"
minimal_player_age = 7
@@ -16,8 +17,22 @@
if(!H) return 0
return 1
/datum/job/ai/get_spawn_positions()
var/spawnpoints = 0
for(var/obj/effect/landmark/start/sloc in landmarks_list)
if (sloc.name == "AI")
spawnpoints++
return spawnpoints
/datum/job/ai/get_total_positions()
var/active_ai_count = 0
for(var/mob/living/silicon/ai/ai in silicon_mob_list)
if(ai.client)
active_ai_count++
return empty_playable_ai_cores.len + active_ai_count
/datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0)
return empty_playable_ai_cores.len > 0
/datum/job/ai/equip_preview(mob/living/carbon/human/H)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/straight_jacket(H), slot_wear_suit)
@@ -27,12 +42,13 @@
/datum/job/cyborg
title = "Cyborg"
flag = CYBORG
departments = SIMPLEDEPT(DEPARTMENT_EQUIPMENT)
department_flag = ENGSEC
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "your laws and the AI" //Nodrak
selection_color = "#4dff4d"
selection_color = "#6c5b73"
minimal_player_age = 1
alt_titles = list("Android", "Robot")
account_allowed = 0
-3
View File
@@ -53,9 +53,6 @@ var/const/JOURNALIST =(1<<14)
var/const/ASSISTANT =(1<<15)
var/list/assistant_occupations = list() //Leaving this on one line stops Travis complaining ~Scopes
var/list/command_positions = list(
"Captain",
"Head of Personnel",
+9 -6
View File
@@ -1034,16 +1034,19 @@ var/list/admin_verbs_cciaa = list(
if(holder)
var/list/jobs = list()
for (var/datum/job/J in SSjobs.occupations)
if (J.current_positions >= J.total_positions && J.total_positions != -1)
if (J.current_positions >= J.get_total_positions() && J.get_total_positions() != -1)
jobs += J.title
if (!jobs.len)
to_chat(usr, "There are no fully staffed jobs.")
to_chat(usr, SPAN_NOTICE("There are no fully staffed jobs."))
return
var/job = input("Please select job slot to free", "Free job slot") as null|anything in jobs
var/job = input("Please select job slot to free", "Free job slot") as null|anything in jobs
if (job)
SSjobs.FreeRole(job)
message_admins("A job slot for [job] has been opened by [key_name_admin(usr)]")
return
var/datum/job/J = SSjobs.GetJob(job)
if(istype(J))
J.total_positions++
message_admins("A job slot for [job] has been added by [key_name_admin(usr)]. The total is now [J.get_total_positions()] with [J.current_positions] positions occupied.")
else
to_chat(usr, SPAN_DANGER("Failed to increase total positions in job [job]."))
/client/proc/toggleattacklogs()
set name = "Toggle Attack Log Messages"
@@ -5,4 +5,4 @@
. = ..()
if(!.)
return
open_crew_manifest(user)
SSrecords.open_manifest_vueui(user)
+1 -1
View File
@@ -680,7 +680,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
for(var/datum/job/job in SSjobs.occupations)
to_chat(src, "[job.title]: [job.total_positions]")
to_chat(src, "[job.title]: [job.get_total_positions() == -1 ? "unlimited" : job.get_total_positions()]")
feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in range(world.view))
@@ -143,6 +143,7 @@
return "<center><large>Jobs controller not initialized yet. Please wait a bit and reload this section.</large></center>"
var/list/dat = list(
"<style>span.none{color: black} span.low{color: #DDD} span.med{color: yellow} span.high{color: lime} a:hover span{color: #40628a !important}</style>",
"<center><b>Character faction</b><br>",
"<small>This will influence the jobs you can select from, and the starting equipment.</small><br>",
"<b><a href='?src=\ref[src];faction_preview=[html_encode(pref.faction)]'>[pref.faction]</a></b></center><br><hr>"
@@ -156,20 +157,16 @@
)
var/index = -1
//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
var/datum/job/lastJob
var/datum/faction/faction = SSjobs.name_factions[pref.faction] || SSjobs.default_faction
for(var/datum/job/job in faction.get_occupations())
index += 1
if((index >= limit) || (job.title in splitJobs))
dat += "</table></td><td width='20%'><table width='100%' cellpadding='1' cellspacing='0'>"
index = 0
dat += "<tr style='background-color: [hex2cssrgba(job.selection_color, 0.4)];'><td width='60%' align='right'>"
var/rank = job.title
lastJob = job
var/head = (rank in command_positions) || (rank == "AI")
dat += "<tr style='background-color: [hex2cssrgba(job.selection_color, head ? 1 : 0.5)];'><td width='60%' align='right'>"
var/list/available = pref.GetValidTitles(job)
var/dispRank = LAZYLEN(available) ? LAZYACCESS(available, 1) : rank
@@ -197,11 +194,11 @@
dat += "<del>[dispRank]</del></td><td><b> \[SPECIES RESTRICTED]</b></td></tr>"
continue
if(job.alt_titles && (LAZYLEN(pref.GetValidTitles(job)) > 1))
dispRank = "<span style='background-color: [hex2cssrgba(lastJob.selection_color, 0.4)];' width='60%' align='center'>&nbsp<a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></span>"
dispRank = "<span width='60%' align='center'>&nbsp<a href='?src=\ref[src];select_alt_title=\ref[job]'>\[[pref.GetPlayerAltTitle(job)]\]</a></span>"
if((pref.job_civilian_low & ASSISTANT) && (rank != "Assistant"))
dat += "<font color=orange>[dispRank]</font></td><td></td></tr>"
dat += "<span class='none'>[dispRank]</span></td><td></td></tr>"
continue
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
if(head)//Bold head jobs
dat += "<b>[dispRank]</b>"
else
dat += "[dispRank]"
@@ -212,20 +209,20 @@
if(rank == "Assistant")//Assistant is special
if(pref.job_civilian_low & ASSISTANT)
dat += " <font color=green>\[Yes]</font>"
dat += " <span class='high'>\[Yes]</span>"
else
dat += " <font color=red>\[No]</font>"
dat += " <span class='none'>\[No]</span>"
dat += "</a></td></tr>"
continue
if(pref.GetJobDepartment(job, 1) & job.flag)
dat += " <font color=blue>\[High]</font>"
dat += " <span class='high'>\[High]</span>"
else if(pref.GetJobDepartment(job, 2) & job.flag)
dat += " <font color=green>\[Medium]</font>"
dat += " <span class='med'>\[Medium]</span>"
else if(pref.GetJobDepartment(job, 3) & job.flag)
dat += " <font color=orange>\[Low]</font>"
dat += " <span class='low'>\[Low]</span>"
else
dat += " <font color=red>\[NEVER]</font>"
dat += " <span class='none'>\[NEVER]</span>"
dat += "</a></td></tr>"
dat += "</td'></tr></table>"
@@ -234,9 +231,9 @@
switch(pref.alternate_option)
if(BE_ASSISTANT)
dat += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><span class='attack'>Be assistant if preference unavailable</span></a></u></center><br>"
dat += "<center><br><u><a href='?src=\ref[src];job_alternative=1'>Be assistant if preference unavailable</a></u></center><br>"
if(RETURN_TO_LOBBY)
dat += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><font color=purple>Return to lobby if preference unavailable</font></a></u></center><br>"
dat += "<center><br><u><a href='?src=\ref[src];job_alternative=1'><span class='high'>Return to lobby if preference unavailable</span></a></u></center><br>"
dat += "<center><a href='?src=\ref[src];reset_jobs=1'>\[Reset\]</a></center>"
dat += "</tt>"
+4
View File
@@ -286,6 +286,10 @@ datum/preferences
if(!client)
return
var/mob/abstract/new_player/NP = client.mob
if(istype(NP) && istype(NP.late_choices_ui)) // update character icon in late-choices UI
NP.late_choices_ui.update_character_icon()
var/obj/screen/BG= LAZYACCESS(char_render_holders, "BG")
if(!BG)
BG = new
@@ -2,9 +2,10 @@
/mob/abstract/new_player
var/ready = 0
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
var/totalPlayers = 0 //Player counts for the Lobby tab
var/spawning = 0 //Referenced when you want to delete the new_player later on in the code
var/totalPlayers = 0 //Player counts for the Lobby tab
var/totalPlayersReady = 0
var/datum/late_choices/late_choices_ui = null
universal_speak = 1
invisibility = 101
@@ -22,6 +23,10 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
. = ..()
dead_mob_list -= src
/mob/abstract/new_player/Destroy()
QDEL_NULL(late_choices_ui)
return ..()
/mob/abstract/new_player/Stat()
..()
@@ -295,50 +300,11 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
/mob/abstract/new_player/proc/LateChoices()
var/name = client.prefs.real_name
var/dat = "<center>"
dat += "<b>Welcome, [name].<br></b>"
dat += "Round Duration: [get_round_duration_formatted()]<br>"
dat += "Alert Level: [capitalize(get_security_level())]<br>"
if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
dat += "<span class='warning'><b>The station has been evacuated.</b></span><br>"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
dat += "<span class='warning'>The station is currently undergoing evacuation procedures.</span><br>"
else // Crew transfer initiated
dat += "<span class='warning'>The station is currently undergoing crew transfer procedures.</span><br>"
var/unique_role_available = FALSE
for(var/ghost_role in SSghostroles.spawners)
var/datum/ghostspawner/G = SSghostroles.spawners[ghost_role]
if(!G.show_on_job_select)
continue
if(G.cant_see(src))
continue
unique_role_available = TRUE
break
if(unique_role_available)
dat += "<font color='[COLOR_BRIGHT_GREEN]'><b>A unique ghost role is available:</b></font><br>"
dat += "<a href='byond://?src=\ref[src];ghostspawner=1'>Ghost Spawner Menu</A><br>"
dat += "Choose from the following open/valid positions:<br>"
for(var/datum/job/job in SSjobs.occupations)
if(job && IsJobAvailable(job.title))
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) //Added isliving check here, so it won't check ghosts and qualify them as active
if(isliving(M) && M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 MINUTES)
active++
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[client.prefs.GetPlayerAltTitle(job)] ([job.current_positions]) (Active: [active])</a><br>"
dat += "</center>"
send_theme_resources(src)
src << browse(enable_ui_theme(src, dat), "window=latechoices;size=300x640;can_close=1")
if(!istype(late_choices_ui))
late_choices_ui = new(src)
else // if the UI exists force refresh it
late_choices_ui.ui_refresh()
late_choices_ui.ui_open()
/mob/abstract/new_player/proc/create_character()
spawning = 1
@@ -408,14 +374,13 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
return new_character
/mob/abstract/new_player/proc/ViewManifest()
open_crew_manifest(src, OOC = TRUE)
SSrecords.open_manifest_vueui(src)
/mob/abstract/new_player/Move()
return 0
/mob/abstract/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=playersetup") //closes the player setup window
/mob/abstract/new_player/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
@@ -221,11 +221,11 @@
var/list/leftovers = list()
var/list/used_slots = list()
if((equip_preview_mob & EQUIP_PREVIEW_LOADOUT) && !(previewJob && (equip_preview_mob & EQUIP_PREVIEW_JOB) && (previewJob.type == /datum/job/ai || previewJob.type == /datum/job/cyborg)))
SSjobs.EquipCustom(mannequin, previewJob, src, leftovers, null, used_slots)
if((equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob)
if((equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob)
previewJob.equip_preview(mannequin, player_alt_titles[previewJob.title])
if(equip_preview_mob & EQUIP_PREVIEW_LOADOUT && leftovers.len)
@@ -237,11 +237,15 @@
else
mannequin.update_icon()
/datum/preferences/proc/update_preview_icon()
/datum/preferences/proc/update_mannequin()
var/mob/living/carbon/human/dummy/mannequin/mannequin = SSmob.get_mannequin(client.ckey)
mannequin.delete_inventory(TRUE)
mannequin.species.create_organs(mannequin)
if(gender)
mannequin.change_gender(gender)
dress_preview_mob(mannequin)
update_character_previews(new /mutable_appearance(mannequin))
return mannequin
/datum/preferences/proc/update_preview_icon()
var/mannequin = update_mannequin()
update_character_previews(new /mutable_appearance(mannequin))
@@ -585,7 +585,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/abstract/observer/verb/view_manifest()
set name = "Show Crew Manifest"
set category = "Ghost"
open_crew_manifest(src, OOC = TRUE)
SSrecords.open_manifest_vueui(usr)
//This is called when a ghost is drag clicked to something.
/mob/abstract/observer/MouseDrop(atom/over)
+1 -2
View File
@@ -384,8 +384,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/ai_roster()
set category = "AI Commands"
set name = "Show Crew Manifest"
var/windowname = open_crew_manifest(src)
onclose(src, windowname)
SSrecords.open_manifest_vueui(usr)
//AI Examine code
/mob/living/silicon/ai/proc/ai_examine(atom/A as mob|obj|turf in view(src.eyeobj))
@@ -400,8 +400,7 @@
/mob/living/silicon/robot/verb/cmd_station_manifest()
set category = "Robot Commands"
set name = "Show Crew Manifest"
var/windowname = open_crew_manifest(src)
onclose(src, windowname)
SSrecords.open_manifest_vueui(usr)
/mob/living/silicon/robot/proc/self_diagnosis()
if(!is_component_functioning("diagnosis unit"))
@@ -13,7 +13,6 @@
/datum/nano_module/program/card_mod
name = "ID card modification program"
var/mod_mode = TRUE
var/is_centcom = FALSE
var/show_assignments = FALSE
@@ -22,19 +21,15 @@
data["src"] = "\ref[src]"
data["station_name"] = station_name()
data["manifest"] = SSrecords.get_manifest()
data["assignments"] = show_assignments
if(program?.computer)
data["have_id_slot"] = !!program.computer.card_slot
data["have_printer"] = !!program.computer.nano_printer
data["authenticated"] = program.can_run(user)
if(!program.computer.card_slot)
mod_mode = FALSE //We can't modify IDs when there is no card reader
else
data["have_id_slot"] = 0
data["have_printer"] = 0
data["authenticated"] = 0
data["mmode"] = mod_mode
data["centcom_access"] = is_centcom
if(program && program.computer && program.computer.card_slot)
@@ -114,46 +109,34 @@
var/obj/item/card/id/id_card = computer.card_slot.stored_card
var/datum/nano_module/program/card_mod/module = NM
switch(href_list["action"])
if("switchm")
if(href_list["target"] == "mod")
module.mod_mode = TRUE
else if (href_list["target"] == "manifest")
module.mod_mode = FALSE
if("togglea")
if(module.show_assignments)
module.show_assignments = FALSE
else
module.show_assignments = TRUE
if("print")
if(computer?.nano_printer) //This option should never be called if there is no printer
if(module.mod_mode)
if(can_run(user, 1))
var/contents = {"<h4>Access Report</h4>
<u>Prepared By:</u> [user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br>
<u>For:</u> [id_card.registered_name ? id_card.registered_name : "Unregistered"]<br>
<hr>
<u>Assignment:</u> [id_card.assignment]<br>
<u>Account Number:</u> #[id_card.associated_account_number]<br>
<u>Blood Type:</u> [id_card.blood_type]<br><br>
<u>Access:</u><br>
"}
if(computer?.nano_printer && can_run(user, 1)) //This option should never be called if there is no printer
var/contents = {"<h4>Access Report</h4>
<u>Prepared By:</u> [user_id_card.registered_name ? user_id_card.registered_name : "Unknown"]<br>
<u>For:</u> [id_card.registered_name ? id_card.registered_name : "Unregistered"]<br>
<hr>
<u>Assignment:</u> [id_card.assignment]<br>
<u>Account Number:</u> #[id_card.associated_account_number]<br>
<u>Blood Type:</u> [id_card.blood_type]<br><br>
<u>Access:</u><br>
"}
var/known_access_rights = get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM)
for(var/A in id_card.access)
if(A in known_access_rights)
contents += " [get_access_desc(A)]"
var/known_access_rights = get_access_ids(ACCESS_TYPE_STATION|ACCESS_TYPE_CENTCOM)
for(var/A in id_card.access)
if(A in known_access_rights)
contents += " [get_access_desc(A)]"
if(!computer.nano_printer.print_text(contents,"access report"))
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
computer.visible_message(SPAN_NOTICE("\The [computer] prints out paper."))
if(!computer.nano_printer.print_text(contents,"access report"))
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
if(!computer.nano_printer.print_text(SSrecords.get_manifest_text(), text("crew manifest ([])", worldtime2text())))
to_chat(usr, SPAN_WARNING(">Hardware error: Printer was unable to print the file. It may be out of paper."))
return
else
computer.visible_message(SPAN_NOTICE("\The [computer] prints out paper."))
computer.visible_message(SPAN_NOTICE("\The [computer] prints out paper."))
if("eject")
if(computer && computer.card_slot)
if(id_card)
@@ -30,11 +30,19 @@
data["_PC"] = headerdata
. = data
VUEUI_SET_CHECK(data["manifest"], SSrecords.get_manifest_list(), ., data)
VUEUI_SET_CHECK_IFNOTSET(data["allow_printing"], !isnull(computer?.nano_printer), ., data)
VUEUI_SET_CHECK_LIST(data["manifest"], SSrecords.get_manifest_list(), ., data)
/datum/computer_file/program/manifest/Topic(href, href_list)
. = ..()
if(href_list["action"] == "print" && can_run(usr, 1) && !isnull(computer?.nano_printer))
if(!computer.nano_printer.print_text(SSrecords.get_manifest_text(), text("crew manifest ([])", worldtime2text())))
to_chat(usr, SPAN_WARNING("Hardware error: Printer was unable to print the file. It might be out of paper."))
return
else
computer.visible_message(SPAN_NOTICE("\The [computer] prints out a paper."))
if(!istype(computer, /obj/item/modular_computer/silicon))
return
var/obj/item/modular_computer/silicon/true_computer = computer
@@ -42,4 +50,4 @@
return
var/mob/living/silicon/pai/host = true_computer.computer_host
host.radio.Topic(href, href_list)
host.radio.Topic(href, href_list)
+14
View File
@@ -0,0 +1,14 @@
author: Amunak
delete-after: True
changes:
- rscadd: "Latejoin menu is now VueUI and more similar to crew manifest - it is divided to sections and uses crew manifest colors. It shows a preview of your character. It no longer distinguishes active but AFK players."
- rscadd: "Crew Manifest now uses VueUI (the exact same one as the modular computers program). This means that crew manifest will no longer indicate AFK players as inactive for ghosts and lobby sitters."
- rscadd: "Crew Manifest program can now print the manifest with a button in the UI."
- rscdel: "The ID modification program no longer shows the crew manifest or is able to print it."
- tweak: "Crew Manifest, Latejoin menu and occupation selection in character creation have been made prettier and more readable with a common color palette for departments."
- bugfix: "All departmental jobs now have a department assigned (intern jobs and forensic technician). This slightly changed the antagonist report generated, but now it's especially needed for the latejoin menu sorting to work."
- bugfix: "Leaving the round now actually decreases the job count for a given job, freeing up the slot for others. This also fixes wrong people counters in latejoin menu. As a result AIs now use different logic to check if they can spawn/latejoin and their numbers are also correct."
- backend: "Added SCSS style utilities inspired by Bootstrap for easier UI styling with the use of just classes."
- refactor: "Department names are now defines, crew manifest logic has been simplified to accommodate this. The 'Heads' section is now called 'Command'."
- refactor: "Jobs now store departments as a list so Command is no longer magic. Flags can be assigned to each department (like 'this is a supervisor/head of this department).'"
- refactor: "Moved Vue departmental colors into a separate Sass file, making it available to all either as a universal map or as predefined classes for text color (.text-dept-medical) and background (.bg-dept-medical)."
+2 -14
View File
@@ -1,15 +1,5 @@
{{if data.have_id_slot}}{{:helper.link('Access Modification', 'home', {'action' : 'switchm', 'target' : 'mod'}, data.mmode ? 'disabled' : null)}}{{/if}}
{{:helper.link('Crew Manifest', 'folder-open', {'action' : 'switchm', 'target' : 'manifest'}, !data.mmode ? 'disabled' : null)}}
{{if data.have_printer}}{{:helper.link('Print', 'print', {'action' : 'print'}, (!data.mmode || data.has_id) ? null : 'disabled')}}{{/if}}
{{if data.have_printer}}{{:helper.link('Print', 'print', {'action' : 'print'}, data.has_id ? null : 'disabled')}}{{/if}}
{{if !data.mmode}}
<div class='item'>
<h2>Crew Manifest</h2>
</div>
<div class='item'>
{{:data.manifest}}
</div>
{{else}}
<div class='item'>
<h2>Access Modification</h2>
</div>
@@ -51,7 +41,6 @@
{{:helper.link(data.id_account_number, 'pencil', {'action' : 'edit', 'account' : 1})}}
</div>
</div>
<div class='item'>
<div class='itemLabel'>
@@ -68,7 +57,7 @@
{{:helper.link(data.assignments ? "Hide assignments" : "Show assignments", 'gear', {'action' : 'togglea'})}}
<div class='item'>
<span id='allvalue.jobsslot'>
</span>
</div>
<div class='item'>
@@ -188,4 +177,3 @@
{{/if}}
{{/if}}
{{/if}}
{{/if}}
+23
View File
@@ -0,0 +1,23 @@
$departmental-colors: (
"Command": #114dc1,
"Security": #991818,
"Engineering": #c67519,
"Medical": #15903a,
"Science": #a44799,
"Cargo": #593616,
"Civilian": #90524b,
"Equipment": #6c5b73,
"Miscellaneous": #5d6a67,
);
@each $dept, $color in $departmental-colors {
.text-dept-#{to-lower-case($dept)} {
color: $color !important;
}
.bg-dept-#{to-lower-case($dept)} {
background-color: $color !important;
}
.border-dept-#{to-lower-case($dept)} {
border-color: $color !important;
}
}
+5 -2
View File
@@ -1,6 +1,9 @@
@import 'icons.scss';
@import 'variables.scss';
@import 'utilities.scss';
@import 'theme-basic.scss';
@import 'theme-nano.scss';
@import 'departmental.scss';
.dark-theme {
color: #ffffff;
@@ -8,7 +11,7 @@
// A global stylesheet to make all thing look decent
body {
font-size: 14px;
font-size: map-get($font-sizes, 'normal');
margin: 0px;
padding: 8px;
font-family: Arial, Helvetica, sans-serif;
@@ -142,4 +145,4 @@ a, .button, button, input[type=submit], input[type=button], input[type=reset], i
.highlight {
color: darkblue;
}
}
+233
View File
@@ -0,0 +1,233 @@
// This file is a simplified version of Bootstrap 5 Utilities (https://v5.getbootstrap.com/docs/5.0/utilities/), Licensed under MIT License
// Mostly just text, spacing, font and block/visibility utilities are available.
$utilities: (
"clear": (
property: clear,
values: left right both none,
),
"align": (
property: vertical-align,
class: align,
values: baseline top middle bottom text-bottom text-top,
),
"float": (
responsive: true,
property: float,
values: left right none,
),
"display": (
responsive: true,
print: true,
property: display,
class: d,
values: inline inline-block block none,
),
// Margin utilities
"margin": (
responsive: true,
property: margin,
class: m,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-x": (
responsive: true,
property: margin-right margin-left,
class: mx,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-y": (
responsive: true,
property: margin-top margin-bottom,
class: my,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-top": (
responsive: true,
property: margin-top,
class: mt,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-right": (
responsive: true,
property: margin-right,
class: mr,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-bottom": (
responsive: true,
property: margin-bottom,
class: mb,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
"margin-left": (
responsive: true,
property: margin-left,
class: ml,
values:
map-merge(
$spacers,
(
auto: auto,
)
),
),
// Padding utilities
"padding": (
responsive: true,
property: padding,
class: p,
values: $spacers,
),
"padding-x": (
responsive: true,
property: padding-right padding-left,
class: px,
values: $spacers,
),
"padding-y": (
responsive: true,
property: padding-top padding-bottom,
class: py,
values: $spacers,
),
"padding-top": (
responsive: true,
property: padding-top,
class: pt,
values: $spacers,
),
"padding-right": (
responsive: true,
property: padding-right,
class: pr,
values: $spacers,
),
"padding-bottom": (
responsive: true,
property: padding-bottom,
class: pb,
values: $spacers,
),
"padding-left": (
responsive: true,
property: padding-left,
class: pl,
values: $spacers,
),
// Text
"font-size": (
rfs: true,
property: font-size,
class: fs,
values: $font-sizes,
),
"font-style": (
property: font-style,
class: fst,
values: italic normal,
),
"font-weight": (
property: font-weight,
class: fw,
values: (
light: light,
lighter: lighter,
normal: normal,
bold: bold,
bolder: bolder,
),
),
"text-transform": (
property: text-transform,
class: text,
values: lowercase uppercase capitalize,
),
"text-align": (
responsive: true,
property: text-align,
class: text,
values: left right center,
),
"text-decoration": (
property: text-decoration,
values: none underline line-through,
),
"visibility": (
property: visibility,
class: null,
values: (
visible: visible,
invisible: hidden,
),
),
);
@each $key, $utility in $utilities {
$values: map-get($utility, values);
// If the values are a list or string, convert it into a map
@if type-of($values) == "string" or type-of(nth($values, 1)) != "list" {
$values: zip($values, $values);
}
@each $key, $value in $values {
$properties: map-get($utility, property);
// Multiple properties are possible, for example with vertical or horizontal margins or paddings
@if type-of($properties) == "string" {
$properties: append((), $properties);
}
// Use custom class if present
$property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));
$property-class: if($property-class == null, "", $property-class);
// Don't prefix if value key is null (eg. with shadow class)
$property-class-modifier: if($key, if($property-class == "", "", "-") + $key, "");
@if $value != null {
.#{$property-class + $property-class-modifier} {
@each $property in $properties {
#{$property}: $value !important;
}
}
}
}
}
+16
View File
@@ -0,0 +1,16 @@
$font-sizes: (
'small': 12px,
'normal': 14px,
'large': 16px,
'largest': 18px,
);
$spacer: 1rem;
$spacers: (
0: 0,
1: $spacer / 4,
2: $spacer / 2,
3: $spacer,
4: $spacer * 1.5,
5: $spacer * 3,
);
+100
View File
@@ -0,0 +1,100 @@
<template>
<div>
<div class="clear-both">
<vui-img name="character" class="character-image"/>
<p>
Welcome, <strong>{{ character_name }}</strong>.<br>
Round duration: <strong>{{ round_duration }}</strong><br>
Alert level: <strong :style="{color: alertLevelColor }">{{ alert_level }}</strong><br>
</p>
</div>
<div class="clear-both">
<strong v-if="shuttleStatusMessage">{{ shuttleStatusMessage }}</strong><br>
Choose from the following available positions:
</div>
<div v-if="unique_role_available">
<div class="gs-block">
<div class="dept">A unique role is available!</div>
<vui-button :params="{ ghostspawner: 1 }" class="d-block m-1" icon="ghost">Ghost Spawner Menu</vui-button>
</div>
</div>
<div v-else>
<vui-button :params="{ ghostspawner: 1 }" class="d-block" icon="ghost">Ghost Spawner Menu</vui-button>
</div>
<div v-if="jobs_available > 0">
<div v-for="(el, dept) in fixedJobsList" :key="dept" class="mt-2 dept-block" :class="'border-dept-' + dept.toLowerCase()">
<div class="dept mb-1" :class="'bg-dept-' + dept.toLowerCase()">
{{ dept }}
</div>
<div v-for="job in el" :key="job.title">
<vui-button :params="{ SelectedJob: job.title }" class="d-block mx-1">
<span :class="{ 'fw-bold': job.head}">{{ job.title }}</span>
<span v-if="job.total_positions != 1"> ({{ job.current_positions }}<span v-if="job.total_positions > 1"> / {{ job.total_positions }}</span>)</span>
</vui-button>
</div>
</div>
<span class="fs-small fst-italic">Numbers in brackets show current amount of active players out of all available job slots for that job.</span>
</div>
<div v-else class="fst-italic">
No jobs available.
</div>
</div>
</template>
<script>
export default {
data() {
return this.$root.$data.state
},
computed: {
fixedJobsList() {
return Object.fromEntries(Object.entries(this.jobs_list).filter(([, jobs]) => Object.entries(jobs).length > 0))
},
shuttleStatusMessage() {
switch(this.shuttle_status) {
case 'post-evac':
return 'The station has been evacuated.'
case 'evac':
return 'The station is currently undergoing evacuation procedures.'
case 'transfer':
return 'The station is currently undergoing crew transfer procedures.'
}
return null
},
alertLevelColor() {
switch(this.alert_level.toLowerCase()) {
case 'green':
return 'inherit'
case 'blue':
return 'blue'
case 'yellow':
return 'yellow'
}
return 'red'
},
},
}
</script>
<style lang="scss" scoped>
.character-image {
float: left;
height: 64px;
}
.gs-block, .dept-block {
position: relative;
border: 2px solid;
.dept {
text-align: center;
font-weight: bold;
}
}
.gs-block {
$gs-color: #41ff41;
border-color: $gs-color;
.dept {
background-color: $gs-color;
color: black;
}
}
</style>
+31 -112
View File
@@ -1,132 +1,51 @@
<template>
<div>
<table class="pmon">
<tr v-for="el in fixedmanifest" :key="el">
<th v-if="el.header" colspan="3" :class="el.class">{{ el.name }}</th>
<template v-else>
<td>{{el.name}}</td>
<td>{{el.rank}}</td>
<td>{{el.active}}</td>
</template>
</tr>
</table>
<div v-if="manifestLen(fixedmanifest) > 0">
<table v-for="(el, dept) in fixedmanifest" :key="dept" class="mt-2" :class="'border-dept-' + dept.toLowerCase()">
<tr :class="'bg-dept-' + dept.toLowerCase()">
<th colspan="3" class="fw-bold">{{ dept }}</th>
</tr>
<tr v-for="entry in el" :key="entry.name" :class="{'fw-bold': entry.head}">
<td class="pl-2">{{ entry.name }}</td>
<td class="px-1">{{ entry.rank }}</td>
<td class="pr-2 text-right">{{ entry.active }}</td>
</tr>
</table>
</div>
<div v-else class="fst-italic">
There is no crew.
</div>
<div v-if="allow_printing" class="text-center mt-2">
<vui-button :params="{ action: 'print' }" icon="print">Print current manifest</vui-button>
</div>
</div>
</template>
<script>
export default {
data() {
return this.$root.$data.state
let ret = this.$root.$data.state
ret.manifestLen = function(manif) {
let len = 0
Object.values(manif).forEach((val) => len += val.length)
return len
}
return ret
},
computed: {
fixedmanifest() {
var entries = Object.entries(this.manifest)
.filter(([, crew]) => !!crew.length)
.flatMap(([name, crew]) =>
[
{
header: name,
class: this.getClass(name),
name: this.getTitle(name),
},
crew,
].flat()
)
return entries
},
},
methods: {
getTitle(key) {
switch (key) {
case "heads":
return "Command"
case "sec":
return "Security"
case "eng":
return "Engineering"
case "med":
return "Medical"
case "sci":
return "Science"
case "car":
return "Cargo"
case "civ":
return "Civilian"
case "misc":
return "Misc"
case "bot":
return "Equipment"
default:
return "Unknown"
}
},
getClass(key) {
switch (key) {
case "heads":
return "command"
default:
return key
}
return Object.fromEntries(Object.entries(this.manifest).filter(([, crew]) => Object.entries(crew).length > 0))
},
},
}
</script>
<style lang="scss" scoped>
/* Table Stuffs for manifest*/
table {
background-color: rgba(0, 0, 0, 0.4);
border: 2px solid RoyalBlue;
width: 100%;
border-collapse: collapse;
color: white;
background-color: rgba(0, 0, 0, 0.6);
border: 2px solid;
}
table {
td,
th {
border-bottom: 1px dotted black;
padding: 0px 5px 0px 5px;
width: auto;
}
th {
font-weight: bold;
color: #ffffff;
&.command {
background: #3333ff;
}
&.sec {
background: #8e0000;
}
&.med {
background: #006600;
}
&.eng {
background: #b27300;
}
&.sci {
background: #a65ba6;
}
&.car {
background: #bb9040;
}
&.civ {
background: #a32800;
}
&.misc {
background: #666666;
}
&.bot {
background: #1d1d1d;
}
}
}
</style>
</style>