diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 759e0b49860..7eb0105ce22 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -323,6 +323,7 @@ /obj/item/sample/print, /obj/item/forensics/swab, /obj/item/forensics/sample_kit, + /obj/item/fine_scanner, ) /obj/item/storage/belt/security/full/populate_contents() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm b/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm index f89e99fd640..13f7ae53c64 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security_lockers.dm @@ -67,6 +67,7 @@ new /obj/item/reagent_containers/drinks/flask/barflask(src) new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/autosurgeon/organ/one_use/sec_hud(src) + new /obj/item/fine_scanner(src) /obj/structure/closet/secure_closet/warden name = "warden's locker" @@ -89,6 +90,7 @@ new /obj/item/storage/box/holobadge(src) new /obj/item/clothing/gloves/color/black/krav_maga/sec(src) new /obj/item/clothing/mask/gas/sechailer(src) + new /obj/item/fine_scanner(src) /obj/structure/closet/secure_closet/security name = "security officer's locker" @@ -110,6 +112,7 @@ new /obj/item/flashlight/seclite(src) new /obj/item/clothing/head/helmet(src) new /obj/item/clothing/suit/armor/secjacket(src) + new /obj/item/fine_scanner(src) /obj/structure/closet/secure_closet/evidence name = "evidence locker" @@ -211,6 +214,7 @@ new /obj/item/storage/box/tapes(src) new /obj/item/taperecorder(src) new /obj/item/storage/briefcase/crimekit(src) + new /obj/item/fine_scanner(src) /obj/structure/closet/secure_closet/injection name = "lethal injections locker" diff --git a/code/modules/economy/economy_machinery/fines.dm b/code/modules/economy/economy_machinery/fines.dm new file mode 100644 index 00000000000..fb25b86c5ed --- /dev/null +++ b/code/modules/economy/economy_machinery/fines.dm @@ -0,0 +1,109 @@ +/obj/item/fine_scanner + name = "fine scanner" + desc = "Swipe an ID card to issue a fine." + icon = 'icons/obj/device.dmi' + icon_state = "fine_scanner" + w_class = WEIGHT_CLASS_SMALL + slot_flags = ITEM_SLOT_BELT + materials = list(MAT_METAL = 300, MAT_GLASS = 140) + new_attack_chain = TRUE + /// Built in radio used to message about crime + var/obj/item/radio/radio + /// The set fine amount + var/fine_amount = 250 + /// linked money account database to this scanner. Usually the station database + var/datum/money_account_database/main_station/account_database + /// The linked account. This will usually be security unless admins tinker + var/linked_account + /// The sound the machine makes on a success + var/fine_sound = 'sound/machines/chime.ogg' + /// The sound the machine makes on a fail + var/fail_sound = 'sound/machines/synth_no.ogg' + +/obj/item/fine_scanner/Initialize(mapload) + . = ..() + account_database = GLOB.station_money_database + linked_account = account_database.get_account_by_department(DEPARTMENT_SECURITY) + radio = new /obj/item/radio(src) + radio.listening = FALSE + radio.config(list("Security" = 0)) + radio.follow_target = src + +/obj/item/fine_scanner/Destroy() + linked_account = null + return ..() + +/obj/item/fine_scanner/activate_self(mob/user) + . = ..() + if(!Adjacent(user)) + return + var/minutes = tgui_input_number(user, "Select the number of minutes that would be served (1-10):", "Issue Fine", 5, 10, 1) + if(!minutes) + return + fine_amount = minutes * 50 + +/obj/item/fine_scanner/item_interaction(mob/living/user, obj/item/used, list/modifiers) + . = ..() + if(istype(used, /obj/item/card/id)) + var/crime_string = tgui_input_text(user, "Enter the crime a fine is being issued for.", "Issue Fine") + if(!Adjacent(user)) + return + if(!account_database) + account_database = GLOB.station_money_database + linked_account = account_database.get_account_by_department(DEPARTMENT_SECURITY) + // Needs to ensure it actually is connected, in case there is no database. + if(account_database) + linked_account = account_database.get_account_by_department(DEPARTMENT_SECURITY) + issue_fine(user, used, crime_string) + +/obj/item/fine_scanner/proc/issue_fine(mob/living/user, obj/item/card/id/C, crime_string) + if(!crime_string || crime_string == "") + crime_string = "(NO CRIME LISTED)" + visible_message(SPAN_NOTICE("[user] swipes a card through [src].")) + var/datum/money_account/D = GLOB.station_money_database.find_user_account(C.associated_account_number, include_departments = FALSE) + if(!D) + visible_message("[bicon(src)][SPAN_WARNING("[src] buzzes as its display flashes \"Invalid account link.\"")]", SPAN_NOTICE("You hear something buzz.")) + playsound(src, fail_sound, 50, TRUE) + return + if(!GLOB.station_money_database.charge_account(D, fine_amount, "Security Fine", user.name, FALSE, FALSE)) + visible_message("[bicon(src)][SPAN_WARNING("[src] buzzes as its display flashes \"Insufficient funds.\"")]", SPAN_NOTICE("You hear something buzz.")) + playsound(src, fail_sound, 50, TRUE) + return + GLOB.station_money_database.credit_account(linked_account, fine_amount, "Security Fine", user.name, FALSE) + playsound(src, fine_sound, 50, TRUE) + radio.autosay("[C.registered_name] has paid a fine of [fine_amount] credits for the crime of [crime_string]. Fine issued by [user.name].", "Automatic Fine System", "Security") + print_report(user, C, crime_string) + var/datum/data/record/R = find_security_record("name", C.registered_name) + if(istype(R)) + R.fields["criminal"] = SEC_RECORD_STATUS_RELEASED + R.fields["comments"] += "Fined [fine_amount] credits for the crime of [crime_string]. Fine issued by [user.name] at [station_time_timestamp()]." + update_all_mob_security_hud() + +/obj/item/fine_scanner/proc/print_report(mob/living/user, obj/item/card/id/card, crime_string) + for(var/obj/machinery/computer/prisoner/C in GLOB.prisoncomputer_list) + var/obj/item/paper/P = new /obj/item/paper(C.loc) + P.name = "Fine log - [card.registered_name] [station_time_timestamp()]" + P.info = "