diff --git a/code/controllers/configuration_vr.dm b/code/controllers/configuration_vr.dm index 804fbc4ec8c..673cff74fc2 100644 --- a/code/controllers/configuration_vr.dm +++ b/code/controllers/configuration_vr.dm @@ -5,6 +5,7 @@ /datum/configuration var/list/engine_map // Comma separated list of engines to choose from. Blank means fully random. var/time_off = FALSE + var/pto_job_change = FALSE var/limit_interns = -1 //Unlimited by default var/limit_visitors = -1 //Unlimited by default var/pto_cap = 100 //Hours @@ -52,5 +53,7 @@ config.pto_cap = text2num(value) if ("time_off") config.time_off = TRUE + if ("pto_job_change") + config.pto_job_change = TRUE return 1 diff --git a/code/game/jobs/job/offduty_vr.dm b/code/game/jobs/job/offduty_vr.dm index 420943c5621..d246c013d8c 100644 --- a/code/game/jobs/job/offduty_vr.dm +++ b/code/game/jobs/job/offduty_vr.dm @@ -3,7 +3,7 @@ // /datum/job/offduty_civilian - title = "Off-Duty Worker" + title = "Off-duty Worker" latejoin_only = TRUE timeoff_factor = -1 total_positions = -1 diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index caeecb2e27b..64a42c98cb1 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -18,6 +18,12 @@ clicksound = null var/obj/item/weapon/card/id/card // Inserted Id card + var/obj/item/device/radio/intercom/announce // Integreated announcer + + +/obj/machinery/computer/timeclock/New() + announce = new /obj/item/device/radio/intercom(src) + ..() /obj/machinery/computer/timeclock/Destroy() if(card) @@ -84,9 +90,10 @@ "head_position" = job.head_position, "timeoff_factor" = job.timeoff_factor ) - // TODO - Once job changing is implemented, we will want to list jobs to change into. - // 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.department) + if(config.time_off && config.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.department) ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) @@ -101,7 +108,7 @@ src.add_fingerprint(usr) if (href_list["id"]) - if (card) + if(card) usr.put_in_hands(card) card = null else @@ -110,8 +117,103 @@ I.forceMove(src) card = I update_icon() + return 1 + if(href_list["switch-to-onduty"]) + if(card) + if(checkCardCooldown()) + makeOnDuty(href_list["switch-to-onduty"]) + usr.put_in_hands(card) + card = null + update_icon() + return 1 + if(href_list["switch-to-offduty"]) + if(card) + if(checkCardCooldown()) + makeOffDuty() + usr.put_in_hands(card) + card = null + update_icon() + return 1 return 1 // Return 1 to update UI +/obj/machinery/computer/timeclock/proc/getOpenOnDutyJobs(var/mob/user, var/department) + var/list/available_jobs = list() + for(var/datum/job/job in job_master.occupations) + if(job && job.is_position_available() && !job.whitelist_only && !jobban_isbanned(user,job.title) && job.player_old_enough(user.client)) + if(job.department == department && !job.head_position && job.timeoff_factor > 0 && !(job.title == "Internal Affairs Agent")) + available_jobs += job.title + if(job.alt_titles) + for(var/alt_job in job.alt_titles) + available_jobs += alt_job + return available_jobs + +/obj/machinery/computer/timeclock/proc/makeOnDuty(var/newjob) + var/datum/job/foundjob = null + for(var/datum/job/job in job_master.occupations) + if(newjob == job.title) + foundjob = job + break + if(newjob in job.alt_titles) + foundjob = job + break + if(!newjob in getOpenOnDutyJobs(usr, job_master.GetJob(card.rank).department)) + return + if(foundjob && card) + card.access = foundjob.get_access() + card.rank = foundjob.title + card.assignment = newjob + card.name = text("[card.registered_name]'s ID Card ([card.assignment])") + data_core.manifest_modify(card.registered_name, card.assignment) + card.last_job_switch = world.time + callHook("reassign_employee", list(card)) + foundjob.current_positions++ + announce.autosay("[card.registered_name] has moved On-Duty as [card.assignment].", "Employee Oversight") + return + +/obj/machinery/computer/timeclock/proc/makeOffDuty() + var/datum/job/foundjob = null + for(var/datum/job/job in job_master.occupations) + if(card.rank == job.title) + foundjob = job + break + if(!foundjob) + return + var/real_dept = foundjob.department + if(real_dept && real_dept == "Command") + real_dept = "Civilian" + var/datum/job/ptojob = null + for(var/datum/job/job in job_master.occupations) + if(job.department == real_dept && job.timeoff_factor < 0) + ptojob = job + break + if(ptojob && card) + var/oldtitle = card.assignment + card.access = ptojob.get_access() + card.rank = ptojob.title + card.assignment = ptojob.title + card.name = text("[card.registered_name]'s ID Card ([card.assignment])") + data_core.manifest_modify(card.registered_name, card.assignment) + card.last_job_switch = world.time + callHook("reassign_employee", list(card)) + foundjob.current_positions-- + announce.autosay("[card.registered_name], [oldtitle], has moved Off-Duty.", "Employee Oversight") + return + +/obj/machinery/computer/timeclock/proc/checkCardCooldown() + if(!card) + return FALSE + if((world.time - card.last_job_switch) < 15 MINUTES) + to_chat(usr, "You need to wait at least 15 minutes after last duty switch.") + return FALSE + return TRUE + +/obj/item/weapon/card/id + var/last_job_switch + +/obj/item/weapon/card/id/New() + .=..() + last_job_switch = world.time + // // Frame type for construction // @@ -144,4 +246,4 @@ /obj/machinery/computer/timeclock/premade/west dir = 4 - pixel_x = -26 + pixel_x = -26 \ No newline at end of file diff --git a/config/example/config.txt b/config/example/config.txt index 5b316f8df2e..7e47fd7248e 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -413,6 +413,9 @@ ENGINE_MAP Supermatter Engine,Edison's Bane # Controls if the 'time off' system is used for determining if players can play 'Off-Duty' jobs (requires SQL) # TIME_OFF +# If 'time off' system is on, controls whether or not players can switch on/off duty midround using timeclocks +# PTO_JOB_CHANGE + # Applies a limit to the number of assistants and visitors respectively # LIMIT_INTERNS 6 # LIMIT_VISITORS 6 diff --git a/nano/templates/timeclock_vr.tmpl b/nano/templates/timeclock_vr.tmpl index 0ca409a1d2a..19cbffe33fa 100644 --- a/nano/templates/timeclock_vr.tmpl +++ b/nano/templates/timeclock_vr.tmpl @@ -56,24 +56,21 @@ {{/if}} -{{if data.allow_change_job && data.job_datum && data.job_datum.timeoff_factor != 0 }} +{{if data.allow_change_job && data.job_datum && data.job_datum.timeoff_factor != 0 && !(data.assignment == "Terminated")}}