[MIRROR] Convert late spawn UI to TGUI (#9272)

Co-authored-by: ShadowLarkens <shadowlarkens@gmail.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2
2024-10-20 14:08:39 -07:00
committed by GitHub
parent 45025bd128
commit a0379d1b79
5 changed files with 415 additions and 84 deletions

View File

@@ -8,6 +8,8 @@
var/show_hidden_jobs = 0 //Show jobs that are set to "Never" in preferences
var/has_respawned = FALSE //Determines if we're using RESPAWN_MESSAGE
var/datum/browser/panel
var/datum/tgui_module/crew_manifest/manifest = null
var/datum/tgui_module/late_choices/late_choices_dialog = null
universal_speak = 1
invisibility = 101
@@ -35,6 +37,10 @@
/mob/new_player/Destroy()
if(panel)
QDEL_NULL(panel)
if(manifest)
QDEL_NULL(manifest)
if(late_choices_dialog)
QDEL_NULL(late_choices_dialog)
. = ..()
/mob/new_player/verb/new_player_panel()
@@ -241,37 +247,6 @@
if(href_list["manifest"])
ViewManifest()
if(href_list["SelectedJob"])
/* Vorestation Removal Start
//Prevents people rejoining as same character.
for (var/mob/living/carbon/human/C in mob_list)
var/char_name = client.prefs.real_name
if(char_name == C.real_name)
to_chat(usr, span_notice("There is a character that already exists with the same name - <b>[C.real_name]</b>, please join with a different one, or use Quit the Round with the previous character.")) //VOREStation Edit
return
*/ //Vorestation Removal End
if(!CONFIG_GET(flag/enter_allowed)) // CHOMPEdit
to_chat(usr, span_notice("There is an administrative lock on entering the game!"))
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
to_chat(usr, span_danger("The station is currently exploding. Joining would go poorly."))
return
if(!is_alien_whitelisted(src, GLOB.all_species[client.prefs.species]))
tgui_alert(src, "You are currently not whitelisted to play [client.prefs.species].")
return 0
var/datum/species/S = GLOB.all_species[client.prefs.species]
if(!(S.spawn_flags & SPECIES_CAN_JOIN))
tgui_alert_async(src,"Your current species, [client.prefs.species], is not available for play on the station.")
return 0
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
return
if(href_list["privacy_poll"])
establish_db_connection()
if(!SSdbcore.IsConnected()) //CHOMPEdit TGSQL
@@ -641,57 +616,9 @@
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer", channel, zlevels)
/mob/new_player/proc/LateChoices()
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
var/dat = "<html><body><center>"
dat += span_bold("Welcome, [name].<br>")
dat += "Round Duration: [roundduration2text()]<br>"
if(emergency_shuttle) //In case NanoTrasen decides reposess CentCom's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to CentCom, not recalled
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
dat += "<font color='red'>The station is currently undergoing evacuation procedures.</font><br>"
else // Crew transfer initiated
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
dat += "Choose from the following open/valid positions:<br>"
dat += "<a href='byond://?src=\ref[src];hidden_jobs=1'>[show_hidden_jobs ? "Hide":"Show"] Hidden Jobs.</a><br>"
var/deferred = ""
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
// Checks for jobs with minimum age requirements
if((job.minimum_character_age || job.min_age_by_species) && (client.prefs.age < job.get_min_age(client.prefs.species, client.prefs.organ_data["brain"])))
continue
//CHOMPEdit Begin - Check species job bans... (Only used for shadekin)
if(job.is_species_banned(client.prefs.species, client.prefs.organ_data["brain"]))
continue
//CHOMPEdit End
// Checks for jobs set to "Never" in preferences //TODO: Figure out a better way to check for this
if(!(client.prefs.GetJobDepartment(job, 1) & job.flag))
if(!(client.prefs.GetJobDepartment(job, 2) & job.flag))
if(!(client.prefs.GetJobDepartment(job, 3) & job.flag))
if(!show_hidden_jobs && job.title != JOB_ALT_ASSISTANT) // Assistant is always an option
continue
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) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 MINUTES)
active++
var/string = "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
if(job.offmap_spawn) //At the bottom
deferred += string
else
dat += string
dat += deferred
dat += "</center>"
src << browse(dat, "window=latechoices;size=300x640;can_close=1")
if(!late_choices_dialog)
late_choices_dialog = new(src)
late_choices_dialog.tgui_interact(src)
/mob/new_player/proc/create_character(var/turf/T)
spawning = 1
@@ -776,13 +703,16 @@
return new_character
/mob/new_player/proc/ViewManifest()
var/datum/tgui_module/crew_manifest/self_deleting/S = new(src)
S.tgui_interact(src)
if(!manifest)
manifest = new(src)
manifest.tgui_interact(src)
/mob/new_player/Move()
return 0
/mob/new_player/proc/close_spawn_windows()
manifest?.close_ui()
late_choices_dialog?.close_ui()
src << browse(null, "window=latechoices") //closes late choices window
src << browse(null, "window=preferences_window") //VOREStation Edit?

View File

@@ -93,3 +93,6 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff
/datum/tgui_module/proc/relaymove(mob/user, direction)
return FALSE
/datum/tgui_module/proc/close_ui()
SStgui.close_uis(src)

View File

@@ -0,0 +1,140 @@
/datum/tgui_module/late_choices
name = "Late Join"
tgui_id = "LateChoices"
/datum/tgui_module/late_choices/tgui_status(mob/user, datum/tgui_state/state)
if(!isnewplayer(user))
return STATUS_CLOSE
return STATUS_INTERACTIVE
/proc/get_user_job_priority(mob/user, datum/job/job)
. = 0
if(!user?.client?.prefs)
return
if(user.client.prefs.GetJobDepartment(job, 1) & job.flag)
. = 1
else if(user.client.prefs.GetJobDepartment(job, 2) & job.flag)
. = 2
else if(user.client.prefs.GetJobDepartment(job, 3) & job.flag)
. = 3
/proc/department_flag_to_name(department)
switch(department)
if(DEPARTMENT_COMMAND)
. = "Command"
if(DEPARTMENT_SECURITY)
. = "Security"
if(DEPARTMENT_ENGINEERING)
. = "Engineering"
if(DEPARTMENT_MEDICAL)
. = "Medical"
if(DEPARTMENT_RESEARCH)
. = "Research"
if(DEPARTMENT_CARGO)
. = "Supply"
if(DEPARTMENT_CIVILIAN)
. = "Service"
if(DEPARTMENT_PLANET)
. = "Expedition"
if(DEPARTMENT_SYNTHETIC)
. = "Silicon"
if(DEPARTMENT_TALON)
. = "Offmap"
else
. = "Unknown"
/proc/character_old_enough_for_job(datum/preferences/prefs, datum/job/job)
if(!job.minimum_character_age && !job.min_age_by_species)
return TRUE
var/min_age = job.get_min_age(prefs.species, prefs.organ_data["brain"])
if(prefs.age >= min_age)
return TRUE
return FALSE
/datum/tgui_module/late_choices/tgui_data(mob/new_player/user)
var/list/data = ..()
var/name = user.client.prefs.be_random_name ? "friend" : user.client.prefs.real_name
data["name"] = name
data["duration"] = roundduration2text()
if(emergency_shuttle?.going_to_centcom())
data["evac"] = "Gone"
else if(emergency_shuttle?.online())
if(emergency_shuttle.evac)
data["evac"] = "Emergency"
else
data["evac"] = "Crew Transfer"
else
data["evac"] = "None"
var/list/jobs = list()
for(var/datum/job/job in job_master.occupations)
if(job && user.IsJobAvailable(job.title))
// Check for jobs with minimum age requirements
if(!character_old_enough_for_job(user.client.prefs, job))
continue
//CHOMPEdit Begin - Check species job bans... (Only used for shadekin)
if(job.is_species_banned(user.client.prefs.species, user.client.prefs.organ_data["brain"]))
continue
//CHOMPEdit End
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)
if(M.mind?.assigned_role == job.title && M.client?.inactivity <= 10 MINUTES)
active++
// Figure out departments
var/list/departments = list()
for(var/department in job.departments)
departments += department_flag_to_name(department)
UNTYPED_LIST_ADD(jobs, list(
"title" = job.title,
"priority" = get_user_job_priority(user, job),
"departments" = departments,
"current_positions" = job.current_positions,
"active" = active,
"offmap" = job.offmap_spawn,
))
data["jobs"] = jobs
return data
/datum/tgui_module/late_choices/tgui_act(action, params)
. = ..()
if(.)
return
var/mob/new_player/user = usr
switch(action)
if("join")
var/job = params["job"]
if(!CONFIG_GET(flag/enter_allowed)) // CHOMPEdit
to_chat(user, span_notice("There is an administrative lock on entering the game!"))
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
to_chat(user, span_danger("The station is currently exploding. Joining would go poorly."))
return
var/datum/species/S = GLOB.all_species[user.client.prefs.species]
if(!is_alien_whitelisted(user, S))
tgui_alert(user, "You are currently not whitelisted to play [user.client.prefs.species].")
return 0
if(!(S.spawn_flags & SPECIES_CAN_JOIN))
tgui_alert_async(user,"Your current species, [user.client.prefs.species], is not available for play on the station.")
return 0
user.AttemptLateSpawn(job, user.client.prefs.spawnpoint)

View File

@@ -0,0 +1,257 @@
import { Window } from 'tgui/layouts';
import { Box, Button, NoticeBox, Section, Stack } from 'tgui-core/components';
import { useBackend } from '../backend';
enum Evac {
Gone = 'Gone',
Emergency = 'Emergency',
CrewTransfer = 'Crew Transfer',
None = 'None',
}
enum Department {
Command = 'Command',
Security = 'Security',
Engineering = 'Engineering',
Medical = 'Medical',
Research = 'Research',
Supply = 'Supply',
Service = 'Service',
Expedition = 'Expedition',
Silicon = 'Silicon',
Offmap = 'Offmap',
Unknown = 'Unknown',
}
type Job = {
title: string;
priority: number;
departments: Department[];
current_positions: number;
active: number;
offmap: boolean;
};
type Data = {
name: string;
duration: number;
evac: Evac;
jobs: Job[];
};
const splitJobs = (
jobs: Job[],
): { favorites: Job[]; departments: { [key: string]: Job[] } } => {
let favorites: Job[] = [];
let departments: { [key: string]: Job[] } = {};
for (let job of jobs) {
if (job.priority !== 0) {
favorites.push(job);
} else {
for (let department of job.departments) {
if (department in departments) {
departments[department].push(job);
} else {
departments[department] = [job];
}
}
}
}
favorites.sort((a, b) => a.priority - b.priority);
return {
favorites,
departments,
};
};
export const LateChoices = (props) => {
const { act, data } = useBackend<Data>();
const { name, duration, evac, jobs } = data;
const { favorites, departments } = splitJobs(jobs);
return (
<Window width={300} height={660}>
<Window.Content>
<Stack fill vertical>
<Stack.Item>
<Section title="Late Join">
<Box fontSize={1.4} textAlign="center">
Welcome, {name}
</Box>
<Box fontSize={1.2} textAlign="center">
Round Duration: {duration}
</Box>
</Section>
</Stack.Item>
<Stack.Item grow>
<Section title="Choose a position" fill scrollable>
{favorites.length ? (
<Section title={<DepartmentTitle department="Favorites" />}>
{favorites.map((job) => (
<JobButton key={job.title} job={job} />
))}
</Section>
) : null}
{Object.entries(departments)
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([dept, jobs]) => (
<Section
title={<DepartmentTitle department={dept} />}
key={dept}
>
{jobs.map((job) => (
<JobButton key={job.title} job={job} />
))}
</Section>
))}
</Section>
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};
const Evacuation = (props: { evac: Evac }) => {
const { evac } = props;
switch (evac) {
case Evac.None:
return null;
case Evac.CrewTransfer:
return (
<NoticeBox warning>
The vessel is currently undergoing crew transfer procedures.
</NoticeBox>
);
case Evac.Emergency:
return (
<NoticeBox danger>
The vessel is currently undergoing evacuation procedures.
</NoticeBox>
);
case Evac.Gone:
return <NoticeBox danger>The vessel has been evacuated.</NoticeBox>;
default:
return null;
}
};
const priorityToColor = (priority: number): string => {
switch (priority) {
case 1:
return 'good';
case 2:
return 'average';
case 3:
return 'bad';
default:
return '';
}
};
const JobButton = (props: { job: Job }) => {
const { act } = useBackend();
const { job } = props;
return (
<Button
fluid
color={priorityToColor(job.priority)}
onClick={() => act('join', { job: job.title })}
>
<Stack>
<Stack.Item grow>{job.title}</Stack.Item>
<Stack.Item>
({job.current_positions}) (Active: {job.active})
</Stack.Item>
</Stack>
</Button>
);
};
const DepartmentTitle = (props: { department: string }) => {
const { department } = props;
switch (department) {
case 'Favorites':
return (
<Box backgroundColor="#4d9121" p={1} m={-1}>
{department}
</Box>
);
case Department.Command:
return (
<Box backgroundColor="#2f2f7f" p={1} m={-1}>
{department}
</Box>
);
case Department.Security:
return (
<Box backgroundColor="#8e2929" p={1} m={-1}>
{department}
</Box>
);
case Department.Engineering:
return (
<Box backgroundColor="#7f6e2c" p={1} m={-1}>
{department}
</Box>
);
case Department.Medical:
return (
<Box backgroundColor="#026865" p={1} m={-1}>
{department}
</Box>
);
case Department.Research:
return (
<Box backgroundColor="#ad6bad" p={1} m={-1}>
{department}
</Box>
);
case Department.Supply:
return (
<Box backgroundColor="#9b633e" p={1} m={-1}>
{department}
</Box>
);
case Department.Service:
return (
<Box backgroundColor="#515151" p={1} m={-1}>
{department}
</Box>
);
case Department.Expedition:
return (
<Box backgroundColor="#515151" p={1} m={-1}>
{department}
</Box>
);
case Department.Silicon:
return (
<Box backgroundColor="#3f823f" p={1} m={-1}>
{department}
</Box>
);
case Department.Offmap:
return (
<Box p={1} m={-1}>
{department}
</Box>
);
case Department.Unknown:
return (
<Box p={1} m={-1}>
{department}
</Box>
);
default:
return department;
}
};

View File

@@ -4428,6 +4428,7 @@
#include "code\modules\tgui\modules\crew_manifest.dm"
#include "code\modules\tgui\modules\crew_monitor.dm"
#include "code\modules\tgui\modules\gyrotron_control.dm"
#include "code\modules\tgui\modules\late_choices.dm"
#include "code\modules\tgui\modules\law_manager.dm"
#include "code\modules\tgui\modules\overmap.dm"
#include "code\modules\tgui\modules\power_monitor.dm"