Add a timeclock app to the PDA (#9650)

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
NickBelmont
2024-12-29 19:10:44 -06:00
committed by GitHub
parent a889708423
commit d60da3a6d1
11 changed files with 629 additions and 47 deletions

View File

@@ -117,6 +117,7 @@
// CHOMPAdd Start/area
#define PHASE_SHIELDED 0x200000 // A less rough way to prevent phase shifting without blocking access
#define AREA_LIMIT_DARK_RESPITE 0x400000// Shadekin will die normally in those areas
#define AREA_ALLOW_CLOCKOUT 0x800000 //The PDA timeclock app can only be used in these areas
// CHOMPAdd End
// OnTopic return values

View File

@@ -1,6 +1,6 @@
/area/surface/outpost/main/dorms
name = "\improper Main Outpost Dorms"
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/dorms/dorm_1
name = "\improper Main Outpost Dorm One"
@@ -20,11 +20,17 @@
/area/surface/outpost/main/dorms/dorm_6
name = "\improper Main Outpost Dorm Six"
/area/library
flags = AREA_ALLOW_CLOCKOUT
/area/crew_quarters
flags = AREA_ALLOW_CLOCKOUT
/area/crew_quarters/cafeteria
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/coffee_shop
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/kitchen
flags = RAD_SHIELDED
@@ -33,7 +39,7 @@
flags = RAD_SHIELDED
/area/crew_quarters/sleep
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/sleep/vistor_room_1
@@ -61,7 +67,7 @@
/area/medical/cryo/autoresleeve
name = "\improper Medical Autoresleeving"
flags = AREA_FORBID_EVENTS
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/rnd/research/particleaccelerator
name = "\improper Particle Accelerator Lab"
@@ -72,7 +78,7 @@
icon_state = "blue"
requires_power = 0
ambience = AMBIENCE_OTHERWORLDLY
flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT | BLUE_SHIELDED | AREA_ALLOW_LARGE_SIZE | AREA_LIMIT_DARK_RESPITE
flags = RAD_SHIELDED | AREA_FLAG_IS_NOT_PERSISTENT | BLUE_SHIELDED | AREA_ALLOW_LARGE_SIZE | AREA_LIMIT_DARK_RESPITE | AREA_ALLOW_CLOCKOUT
/area/security/nuke_storage
flags = PHASE_SHIELDED
@@ -185,4 +191,224 @@
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_BLOCK_TRACKING | AREA_BLOCK_SUIT_SENSORS
/area/crew_quarters/toilet/firstdeck
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_BLOCK_TRACKING | AREA_BLOCK_SUIT_SENSORS
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_BLOCK_TRACKING | AREA_BLOCK_SUIT_SENSORS | AREA_ALLOW_CLOCKOUT
/area/maintenance
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/maintenance/solars
flags = RAD_SHIELDED
/area/maintenance/substation
flags = RAD_SHIELDED
/area/hallway
flags = AREA_ALLOW_CLOCKOUT
/area/hallway/secondary/entry
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/hallway/secondary/entry/D1
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/hallway/secondary/entry/D2
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/hallway/secondary/entry/D3
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/teleporter/firstdeck
flags = AREA_ALLOW_CLOCKOUT
/area/holodeck_control
flags = AREA_ALLOW_CLOCKOUT
/area/holodeck/alphadeck
flags = AREA_ALLOW_CLOCKOUT | AREA_FLAG_IS_NOT_PERSISTENT | AREA_FORBID_EVENTS
/area/turbolift
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/surface/outpost/civilian
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outside
flags = AREA_FLAG_IS_NOT_PERSISTENT | AREA_ALLOW_CLOCKOUT
/area/surface/cave
flags = AREA_FLAG_IS_NOT_PERSISTENT | AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/corridor
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/pool
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/restroom
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/showers
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/gym
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/crew_quarters
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/gateway
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/laundry
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/dorms
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/bar
flags = AREA_ALLOW_CLOCKOUT
/area/surface/outpost/main/airlock
flags = AREA_ALLOW_CLOCKOUT
/area/medical/foyer
flags = AREA_ALLOW_CLOCKOUT
/area/medical/first_aid_station
flags = AREA_ALLOW_CLOCKOUT
/area/rnd/research_foyer
flags = AREA_ALLOW_CLOCKOUT
/area/engineering/foyer
flags = AREA_ALLOW_CLOCKOUT
/area/security/lobby
flags = AREA_ALLOW_CLOCKOUT
/area/quartermaster/foyer
flags = AREA_ALLOW_CLOCKOUT
/area/hangar/two
flags = AREA_ALLOW_CLOCKOUT
/area/hangar/three
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/stationshuttle
flags = AREA_ALLOW_CLOCKOUT
/area/storage/primary
flags = AREA_ALLOW_CLOCKOUT
/area/storage/auxillary
flags = AREA_ALLOW_CLOCKOUT
/area/storage/emergency_storage
flags = AREA_ALLOW_CLOCKOUT | RAD_SHIELDED
//Carrier Areas
/area/expoutpost/suite1
flags = AREA_ALLOW_CLOCKOUT | RAD_SHIELDED
/area/expoutpost/suite2
flags = AREA_ALLOW_CLOCKOUT | RAD_SHIELDED
/area/expoutpost/slingcarrierdock
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/staginghangar
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/uppersternhallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/medbaylobby
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/rndlobby
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/midsternhallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/lowersternhallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/breakroom
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/starbowhallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portbowhallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/restrooms
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/bar
flags = AREA_ALLOW_CLOCKOUT | RAD_SHIELDED
/area/expoutpost/washroom
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/civaccesshallway
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/eva
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/botany
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/starboardbowairlock
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portbowairlock
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portqpadjunction
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/starqpadjunction
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/stationqpad
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portuppermaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portexplomaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/portlowermaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/staruppermaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/starsciencemaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/starlowermaint
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangarone
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangartwo
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangarthree
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangarfour
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangarfive
flags = AREA_ALLOW_CLOCKOUT
/area/expoutpost/hangarsix
flags = AREA_ALLOW_CLOCKOUT

View File

@@ -69,6 +69,7 @@ var/global/list/obj/item/pda/PDAs = list()
var/list/programs = list(
new/datum/data/pda/app/main_menu,
new/datum/data/pda/app/notekeeper,
new/datum/data/pda/app/timeclock, //CHOMPEdit: Add the timeclock to default apps
new/datum/data/pda/app/news,
new/datum/data/pda/app/messenger,
new/datum/data/pda/app/manifest,

View File

@@ -0,0 +1,170 @@
/datum/data/pda/app/timeclock
name = "Timeclock"
icon = "clock"
template = "pda_timeclock"
var/channel = "Common"
var/obj/item/radio/intercom/announce
/datum/data/pda/app/timeclock/start()
. = ..()
//Initialize an intercom to announce going on/off duty
if(!announce)
announce = new /obj/item/radio/intercom(src)
/datum/data/pda/app/timeclock/update_ui(mob/user as mob, list/data)
//Because tgui_data seems a bit weird with pda apps
// Okay, data for showing the user's OWN PTO stuff
if(user.client)
data["department_hours"] = SANITIZE_LIST(user.client.department_hours)
data["user_name"] = "[user]"
data["is_human"] = ishuman(user)
data["area_clockout"] = isAllowedAreaClockout(user)
// Data about the card that we put into it.
data["card"] = null
data["assignment"] = null
data["job_datum"] = null
data["allow_change_job"] = null
data["job_choices"] = null
if(pda.id)
data["card"] = "[pda.id]"
data["assignment"] = pda.id.assignment
data["card_cooldown"] = getCooldown()
var/datum/job/job = job_master.GetJob(pda.id.rank)
if(job)
data["job_datum"] = list(
"title" = job.title,
"departments" = english_list(job.departments),
"selection_color" = job.selection_color,
"economic_modifier" = job.economic_modifier,
"timeoff_factor" = job.timeoff_factor,
"pto_department" = job.pto_type
)
if(CONFIG_GET(flag/time_off) && CONFIG_GET(flag/pto_job_change))
data["allow_change_job"] = TRUE
if(job && job.timeoff_factor < 0) // Currently are Off Duty, so gotta lookup what on-duty jobs are open
data["job_choices"] = getOpenOnDutyJobs(user, job.pto_type)
/datum/data/pda/app/timeclock/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
if(..())
return TRUE
switch(action)
if("switch-to-onduty-rank")
if(checkFace(ui.user))
if(checkCardCooldown(ui.user))
makeOnDuty(ui.user, params["switch-to-onduty-rank"], params["switch-to-onduty-assignment"])
return TRUE
if("switch-to-offduty")
if(checkFace(ui.user))
if(checkCardCooldown(ui.user))
makeOffDuty(ui.user)
return TRUE
/datum/data/pda/app/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department)
var/list/available_jobs = list()
for(var/datum/job/job in job_master.occupations)
if(isOpenOnDutyJob(user, department, job))
available_jobs[job.title] = list(job.title)
if(job.alt_titles)
for(var/alt_job in job.alt_titles)
if(alt_job != job.title)
available_jobs[job.title] += alt_job
return available_jobs
/datum/data/pda/app/timeclock/proc/isOpenOnDutyJob(var/mob/user, var/department, var/datum/job/job)
return job \
&& job.is_position_available() \
&& !job.whitelist_only \
&& !jobban_isbanned(user,job.title) \
&& job.player_old_enough(user.client) \
&& job.player_has_enough_playtime(user.client) \
&& job.pto_type == department \
&& !job.disallow_jobhop \
&& job.timeoff_factor > 0
/datum/data/pda/app/timeclock/proc/makeOnDuty(mob/user, var/newrank, var/newassignment)
var/datum/job/oldjob = job_master.GetJob(pda.id.rank)
var/datum/job/newjob = job_master.GetJob(newrank)
if(!oldjob || !isOpenOnDutyJob(user, oldjob.pto_type, newjob))
return
if(newassignment != newjob.title && !(newassignment in newjob.alt_titles))
return
if(newjob.camp_protection && round_duration_in_ds < CONFIG_GET(number/job_camp_time_limit))
if(SSjob.restricted_keys.len)
var/list/check = SSjob.restricted_keys[newjob.title]
if(user.client.ckey in check)
to_chat(user,span_danger("[newjob.title] is not presently selectable because you played as it last round. It will become available to you in [round((CONFIG_GET(number/job_camp_time_limit) - round_duration_in_ds) / 600)] minutes, if slots remain open."))
return
if(newjob)
newjob.register_shift_key(user.client.ckey)
pda.id.access = newjob.get_access()
pda.id.rank = newjob.title
pda.id.assignment = newassignment
pda.id.name = text("[pda.id.registered_name]'s ID Card ([pda.id.assignment])")
data_core.manifest_modify(pda.id.registered_name, pda.id.assignment, pda.id.rank)
pda.id.last_job_switch = world.time
callHook("reassign_employee", list(pda.id))
newjob.current_positions++
user.mind.assigned_role = pda.id.rank
user.mind.role_alt_title = pda.id.assignment
announce.autosay("[pda.id.registered_name] has moved On-Duty as [pda.id.assignment].", "Employee Oversight", channel, zlevels = using_map.get_map_levels(get_z(src)))
return
/datum/data/pda/app/timeclock/proc/makeOffDuty(mob/user)
var/datum/job/foundjob = job_master.GetJob(pda.id.rank)
if(!foundjob)
return
//If we're not in an area that allows clockout and not in a belly, shouldn't be able to clock out.
if(!isAllowedAreaClockout(user))
to_chat(user, span_notice("You cannot clock out from your PDA in this area"))
return
var/new_dept = foundjob.pto_type || PTO_CIVILIAN
var/datum/job/ptojob = null
for(var/datum/job/job in job_master.occupations)
if(job.pto_type == new_dept && job.timeoff_factor < 0)
ptojob = job
break
if(ptojob)
var/oldtitle = pda.id.assignment
pda.id.access = ptojob.get_access()
pda.id.rank = ptojob.title
pda.id.assignment = ptojob.title
pda.id.name = text("[pda.id.registered_name]'s ID Card ([pda.id.assignment])")
data_core.manifest_modify(pda.id.registered_name, pda.id.assignment, pda.id.rank)
pda.id.last_job_switch = world.time
callHook("reassign_employee", list(pda.id))
user.mind.assigned_role = ptojob.title
user.mind.role_alt_title = ptojob.title
foundjob.current_positions--
announce.autosay("[pda.id.registered_name], [oldtitle], has moved Off-Duty.", "Employee Oversight", channel, zlevels = using_map.get_map_levels(get_z(src)))
return
/datum/data/pda/app/timeclock/proc/isAllowedAreaClockout(mob/user)
return (get_area(user).flag_check(AREA_ALLOW_CLOCKOUT) || isbelly(user.loc))
/datum/data/pda/app/timeclock/proc/checkCardCooldown(mob/user)
if(!pda.id)
return FALSE
var/time_left = getCooldown()
if(time_left > 0)
to_chat(user, span_notice("You need to wait another [round((time_left/10)/60, 1)] minute\s before you can switch."))
return FALSE
return TRUE
/datum/data/pda/app/timeclock/proc/getCooldown()
return 1 MINUTES - (world.time - pda.id.last_job_switch)
/datum/data/pda/app/timeclock/proc/checkFace(mob/user)
var/turf/location = get_turf(user)
if(!pda.id)
to_chat(user, span_notice("No ID is inserted."))
return FALSE
if(pda.id.registered_name != user.real_name)
to_chat(user, span_notice("This does not appear to be your ID"))
return FALSE
else
message_admins("[key_name_admin(user)] has modified '[pda.id.registered_name]' 's ID with a pda timeclock. [ADMIN_JMP(location)]")
log_game("[key_name_admin(user)] has modified '[pda.id.registered_name]' 's ID with a pda timeclock.")
return TRUE

View File

@@ -60,7 +60,6 @@
/area/surface/outside
ambience = AMBIENCE_THOR
always_unpowered = TRUE
flags = AREA_FLAG_IS_NOT_PERSISTENT
outdoors = OUTDOORS_YES
// The area near the outpost, so POIs don't show up right next to the outpost.
@@ -130,7 +129,6 @@
name = "Sesquehanna River"
icon_state = "bluenew"
/area/surface/cave
flags = RAD_SHIELDED
always_unpowered = TRUE
/area/surface/cave
@@ -666,7 +664,6 @@ z
icon_state = "shuttle"
requires_power = 0
dynamic_lighting = 1
flags = RAD_SHIELDED
/area/turbolift/start
name = "\improper Turbolift Start"
@@ -880,7 +877,6 @@ z
name = "\improper First Deck First-Aid Station"
/area/storage/emergency_storage/
flags = RAD_SHIELDED
name = "Emergency Storage"
icon_state = "emergencystorage"

View File

@@ -22,7 +22,6 @@
icon_state = "shuttle"
requires_power = 0
dynamic_lighting = 1
flags = RAD_SHIELDED
/area/turbolift/start
name = "\improper Turbolift Start"
@@ -172,6 +171,7 @@
/area/hallway/primary/firstdeck/elevator
name = "\improper First Deck Central Elevator Access"
icon_state = "hallC"
/area/rnd/xenobiology/xenoflora_isolation
name = "\improper Xenoflora Isolation"
icon_state = "xeno_f_store"
@@ -732,18 +732,15 @@
/area/expoutpost/bar
name = "\improper Bar"
flags = RAD_SHIELDED
/area/expoutpost/starbowhallway
name = "\improper Starboard Bow Hallway"
/area/expoutpost/suite1
name = "\improper Suite One"
flags = RAD_SHIELDED
/area/expoutpost/suite2
name = "\improper Suite Two"
flags = RAD_SHIELDED
/area/expoutpost/pathfinderroom
name = "\improper Pathfinder's Ready-Room"
@@ -1812,12 +1809,12 @@
/area/crew_quarters/Midnight_Bar
name = "\improper Midnight Bar"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/Midnight_Kitchen
name = "\improper Midnight Kitchen"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/Gallery
name = "\improper Gallery"
@@ -1853,31 +1850,31 @@
/area/crew_quarters/Central_Restroom
name = "\improper Central Restroom"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/For_Restroom
name = "\improper For Restroom"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Star_Restroom
name = "\improper Star Restroom"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Aft_Restroom
name = "\improper Aft Restroom"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Port_Restroom
name = "\improper Port Restroom"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Library
@@ -1906,12 +1903,12 @@
/area/crew_quarters/Chomp_Hydroponics
name = "\improper Chomp Hydroponics"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/Chomp_Stage
name = "\improper Chomp Convention Stage"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/Chomp_Kitchen
name = "\improper Chomp Kitchen"
@@ -1921,19 +1918,19 @@
/area/crew_quarters/Chomp_Dinner_1
name = "\improper Chomp Dinner 1"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Chomp_Dinner_2
name = "\improper Chomp Dinner 2"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 1
/area/crew_quarters/Chomp_Lounge
name = "\improper Chomp Lounge"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
/area/crew_quarters/Public_Hydroponics
name = "\improper Public Hydroponics"
@@ -1956,7 +1953,7 @@
icon_state = "gaming"
/area/crew_quarters/sleep
flags = RAD_SHIELDED | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO
flags = RAD_SHIELDED | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_SOUNDPROOF | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT
lightswitch = 0
icon_state = "gaming"
@@ -2082,7 +2079,7 @@
/area/hallway/Star_Transit_Foyer
name = "\improper Star Transit Foyer"
icon_state = "hallA"
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/hallway/Aft_Transit_Lobby
name = "\improper Aft Transit Lobby"
@@ -2091,7 +2088,7 @@
/area/hallway/Port_Transit_Foyer
name = "\improper Port Transit Foyer"
icon_state = "hallA"
flags = RAD_SHIELDED
flags = RAD_SHIELDED | AREA_ALLOW_CLOCKOUT
/area/hallway/For_1_Deck_Stairwell
name = "\improper For 1 Deck Stairwell"
@@ -2421,7 +2418,6 @@
/area/maintenance
icon_state = "fsmaint"
flags = RAD_SHIELDED
ambience = AMBIENCE_MAINTENANCE
sound_env = SOUND_ENVIRONMENT_SEWER_PIPE

View File

@@ -22,7 +22,6 @@
icon_state = "shuttle"
requires_power = 0
dynamic_lighting = 1
flags = RAD_SHIELDED
/area/turbolift/start
name = "\improper Turbolift Start"
@@ -212,7 +211,7 @@
/area/hallway/primary/firstdeck/auxdockaft
name = "\improper First Deck Aft Auxiliary Dock"
icon_state = "docking_hallway"
flags = AREA_FORBID_EVENTS
flags = AREA_FORBID_EVENTS | AREA_ALLOW_CLOCKOUT
/area/hallway/primary/firstdeck/auxdockfore
name = "\improper First Deck Fore Auxiliary Dock"
@@ -292,7 +291,6 @@
name = "\improper First Deck First-Aid Station"
/area/storage/emergency_storage/
flags = RAD_SHIELDED
name = "Emergency Storage"
icon_state = "emergencystorage"
@@ -432,7 +430,7 @@
/area/crew_quarters/thirddeck/vrroom
name = "\improper Virtual Reality Room"
icon_state = "gaming"
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO //Depending on the video game, you might still get figuative cancer
flags = RAD_SHIELDED | AREA_FORBID_EVENTS | AREA_FORBID_SINGULO | AREA_ALLOW_CLOCKOUT //Depending on the video game, you might still get figuative cancer
//CHOMPStation Edit End
@@ -725,6 +723,7 @@
/area/maintenance/thirddeck/dormsstarboard/maintbar
name = "Third Deck Aft Starboard Speakeasy"
icon_state = "asmaint"
//CHOMPedit end
/area/maintenance/thirddeck/dormsaft
name = "Third Deck Aft Starboard Maintenance"
@@ -1348,18 +1347,15 @@ End Chompstation Edit*/
/area/expoutpost/bar
name = "\improper Bar"
flags = RAD_SHIELDED
/area/expoutpost/starbowhallway
name = "\improper Starboard Bow Hallway"
/area/expoutpost/suite1
name = "\improper Suite One"
flags = RAD_SHIELDED
/area/expoutpost/suite2
name = "\improper Suite Two"
flags = RAD_SHIELDED
/area/expoutpost/pathfinderroom
name = "\improper Pathfinder's Ready-Room"
@@ -1702,7 +1698,7 @@ End Chompstation Edit*/
/area/maintenance/bar/dorms
name = "Maintenance Bar Dorms"
icon_state = "Sleep"
flags = RAD_SHIELDED | AREA_SOUNDPROOF |AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING
flags = RAD_SHIELDED | AREA_SOUNDPROOF |AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_ALLOW_CLOCKOUT
/area/maintenance/bar/dorms/dorm_1
name = "Maintenance Deck Bar Dorms 1"

View File

@@ -43,7 +43,6 @@
/area/surface/outside
ambience = AMBIENCE_SIF
always_unpowered = TRUE
flags = AREA_FLAG_IS_NOT_PERSISTENT
outdoors = OUTDOORS_YES
// The area near the outpost, so POIs don't show up right next to the outpost.
@@ -130,7 +129,6 @@
/area/surface/cave
flags = RAD_SHIELDED
always_unpowered = TRUE
/area/surface/cave
@@ -173,7 +171,7 @@
/area/surface/outpost/shelter/dorms
name = "Wilderness Shelter Dorms"
icon_state = "Sleep"
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING
flags = RAD_SHIELDED | AREA_SOUNDPROOF | AREA_ALLOW_LARGE_SIZE | AREA_BLOCK_SUIT_SENSORS | AREA_BLOCK_TRACKING | AREA_ALLOW_CLOCKOUT
/area/surface/outpost/shelter/exterior
name = "Wilderness Shelter Exterior"

View File

@@ -25,17 +25,27 @@ type Data = {
};
const requirePdaInterface = require.context('./pda_screens', false, /\.tsx$/);
// CHOMPEdit Start - Add check for chompstation pda_screens
const requirePdaInterfaceCh = require.context(
'../chompstation/Pda/pda_screens',
false,
/\.tsx$/,
);
function getPdaApp(name: string) {
let appModule: __WebpackModuleApi.RequireContext;
try {
appModule = requirePdaInterface(`./${name}.tsx`);
appModule = requirePdaInterfaceCh(`./${name}.tsx`);
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
return routingError('notFound', name);
try {
appModule = requirePdaInterface(`./${name}.tsx`);
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
return routingError('notFound', name);
}
throw err;
}
throw err;
}
// CHOMPEdit End
const Component: () => React.JSX.Element = appModule[name];
if (!Component) {
return routingError('missingExport', name);

View File

@@ -0,0 +1,187 @@
import { toFixed } from 'common/math';
import { BooleanLike } from 'common/react';
import { useBackend } from 'tgui/backend';
import {
Box,
Button,
Flex,
LabeledList,
NoticeBox,
Section,
} from 'tgui/components';
import { formatTime } from 'tgui/format';
import { RankIcon } from '../../../common/RankIcon';
type Data = {
card: string | null;
department_hours: Record<string, number> | undefined;
user_name: string;
assignment: string | null;
card_cooldown: number;
area_clockout: boolean | false;
is_human: boolean | false;
job_datum: {
title: string;
departments: string;
selection_color: string;
economic_modifier: number;
timeoff_factor: number;
pto_department: string;
} | null;
allow_change_job: BooleanLike;
job_choices: Record<string, string[]> | null;
};
export const pda_timeclock = (props) => {
const { act, data } = useBackend<Data>();
const {
department_hours,
user_name,
is_human,
area_clockout,
card,
card_cooldown,
assignment,
job_datum,
allow_change_job,
job_choices,
} = data;
return (
<Box>
<Section title="PDA Timeclock">
<NoticeBox>
OOC Note: PTO acquired is account-wide and shared across all
characters. Info listed below is not IC information.
</NoticeBox>
<Section title={'Time Off Balance for ' + user_name}>
<LabeledList>
{!!department_hours &&
Object.keys(department_hours).map((key) => (
<LabeledList.Item
key={key}
label={key}
color={
department_hours[key] > 6
? 'good'
: department_hours[key] > 1
? 'average'
: 'bad'
}
>
{toFixed(department_hours[key], 1)}{' '}
{department_hours[key] === 1 ? 'hour' : 'hours'}
</LabeledList.Item>
))}
</LabeledList>
</Section>
</Section>
<Section title="Employee Info">
<LabeledList>
<LabeledList.Item label="Employee ID">
{card || 'Insert ID'}
</LabeledList.Item>
{!!job_datum && (
<>
<LabeledList.Item label="Rank">
<Box backgroundColor={job_datum.selection_color} p={0.8}>
<Flex justify="space-between" align="center">
<Flex.Item>
<Box ml={1}>
<RankIcon color="white" rank={job_datum.title} />
</Box>
</Flex.Item>
<Flex.Item>
<Box fontSize={1.5} inline mr={1}>
{job_datum.title}
</Box>
</Flex.Item>
</Flex>
</Box>
</LabeledList.Item>
<LabeledList.Item label="Departments">
{job_datum.departments}
</LabeledList.Item>
<LabeledList.Item label="Pay Scale">
{job_datum.economic_modifier}
</LabeledList.Item>
<LabeledList.Item label="PTO Elegibility">
{(job_datum.timeoff_factor > 0 && (
<Box>Earns PTO - {job_datum.pto_department}</Box>
)) ||
(job_datum.timeoff_factor < 0 && (
<Box>Requires PTO - {job_datum.pto_department}</Box>
)) || <Box>Neutral</Box>}
</LabeledList.Item>
</>
)}
</LabeledList>
</Section>
{!!(
allow_change_job &&
job_datum &&
job_datum.timeoff_factor !== 0 &&
assignment !== 'Dismissed' &&
is_human
) && (
<Section title="Employment Actions">
{(job_datum.timeoff_factor > 0 &&
((!!department_hours &&
department_hours[job_datum.pto_department] > 0 && (
<Button
fluid
disabled={card_cooldown > 0 || !area_clockout}
tooltip={
card_cooldown > 0
? "You've recently modified your card, please wait " +
formatTime(card_cooldown, 'short')
: area_clockout
? 'Clock out!'
: 'You cannot clock out in this area'
}
icon="exclamation-triangle"
onClick={() => act('switch-to-offduty')}
>
Go Off-Duty
</Button>
)) || (
<Box color="bad">
Warning: You do not have enough accrued time off to go off-duty.
</Box>
))) ||
(!!job_choices &&
Object.keys(job_choices).length &&
Object.keys(job_choices).map((job) => {
let alt_titles = job_choices[job];
return alt_titles.map((title) => (
<Button
key={title}
disabled={card_cooldown > 0}
tooltip={
card_cooldown > 0
? "You've recently modified your card, please wait " +
formatTime(card_cooldown, 'short')
: 'Clock in!'
}
icon="suitcase"
onClick={() =>
act('switch-to-onduty-rank', {
'switch-to-onduty-rank': job,
'switch-to-onduty-assignment': title,
})
}
>
{title}
</Button>
));
})) || (
<Box color="bad">No Open Positions - See Head Of Personnel</Box>
)}
</Section>
)}
</Box>
);
};

View File

@@ -5106,6 +5106,7 @@
#include "modular_chomp\code\modules\paperwork\faxmachine.dm"
#include "modular_chomp\code\modules\paperwork\filingcabinet.dm"
#include "modular_chomp\code\modules\paperwork\pen.dm"
#include "modular_chomp\code\modules\pda\core_apps.dm"
#include "modular_chomp\code\modules\planet\sif.dm"
#include "modular_chomp\code\modules\planet\tyr.dm"
#include "modular_chomp\code\modules\planet\smokestar\turf.dm"