diff --git a/code/game/machinery/computer/timeclock_vr.dm b/code/game/machinery/computer/timeclock_vr.dm index d0557cd1f3..c9e8d3ee26 100644 --- a/code/game/machinery/computer/timeclock_vr.dm +++ b/code/game/machinery/computer/timeclock_vr.dm @@ -1,3 +1,4 @@ +//TFF 19/5/19 - Port VOREStation's completed Timeclock code ///////////////////////////////////////////// //Time Clock Terminal//////////////////////// ///////////////////////////////////////////// @@ -17,6 +18,12 @@ circuit = /obj/item/weapon/circuitboard/timeclock 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) @@ -80,12 +87,12 @@ "department" = job.department, "selection_color" = job.selection_color, "economic_modifier" = job.economic_modifier, - "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 = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) @@ -100,7 +107,7 @@ src.add_fingerprint(usr) if (href_list["id"]) - if (card) + if(card) usr.put_in_hands(card) card = null else @@ -109,8 +116,126 @@ I.forceMove(src) card = I update_icon() + return 1 + if(href_list["switch-to-onduty"]) + if(card) + if(checkFace()) + 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(checkFace()) + 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.disallow_jobhop && job.timeoff_factor > 0) + 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++ + var/mob/living/carbon/human/H = usr + H.mind.assigned_role = foundjob.title + 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)) + var/mob/living/carbon/human/H = usr + H.mind.assigned_role = ptojob.title + 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. It has only been [world.time - card.last_job_switch] minutes since you have had your job changed.") + return FALSE + return TRUE + +/obj/machinery/computer/timeclock/proc/checkFace() + if(!card) + to_chat(usr, "No ID is inserted.") + return FALSE + var/mob/living/carbon/human/H = usr + if(!(istype(H))) + to_chat(usr, "Invalid user detected. Access denied.") + return FALSE + else if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE))) //Face hiding bad + to_chat(usr, "Facial recognition scan failed due to physical obstructions. Access denied.") + return FALSE + else if(H.get_face_name() == "Unknown" || !(H.real_name == card.registered_name)) + to_chat(usr, "Facial recognition scan failed. Access denied.") + return FALSE + else + 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 // diff --git a/html/changelogs/TheFurryFeline - Timeclocks Usage Upgrade.yml b/html/changelogs/TheFurryFeline - Timeclocks Usage Upgrade.yml new file mode 100644 index 0000000000..dc60bdedf6 --- /dev/null +++ b/html/changelogs/TheFurryFeline - Timeclocks Usage Upgrade.yml @@ -0,0 +1,6 @@ +author: TheFurryFeline + +delete-after: True + +changes: + - rscadd: "Implements full version of timeclocks: you'll be able to switch off or on duty without needing an HOP on the shift, unless the job is in Command or IAA. For those, you will need the HOP or a CD to change your job." \ No newline at end of file diff --git a/nano/templates/timeclock_vr.tmpl b/nano/templates/timeclock_vr.tmpl index 0ca409a1d2..19cbffe33f 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")}}