From e3b3f3295d1e056701f8d0781fc65ed06971f876 Mon Sep 17 00:00:00 2001 From: MysteryMan21333 <51891267+MysteryMan21333@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:10:26 -0600 Subject: [PATCH] V1.0 --- code/__SPLURTCODE/DEFINES/dcs/signals.dm | 3 + code/modules/vending/security.dm | 3 +- .../code/modules/clothing/misc/body_camera.dm | 145 ++++++++++++++++++ modular_splurt/icons/obj/clothing/bodycam.dmi | Bin 0 -> 516 bytes modular_splurt/icons/obj/clothing/neck.dmi | Bin 1952 -> 1681 bytes tgstation.dme | 3 +- 6 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 modular_splurt/code/modules/clothing/misc/body_camera.dm create mode 100644 modular_splurt/icons/obj/clothing/bodycam.dmi diff --git a/code/__SPLURTCODE/DEFINES/dcs/signals.dm b/code/__SPLURTCODE/DEFINES/dcs/signals.dm index f12c163f71..30320d2b1a 100644 --- a/code/__SPLURTCODE/DEFINES/dcs/signals.dm +++ b/code/__SPLURTCODE/DEFINES/dcs/signals.dm @@ -11,3 +11,6 @@ * Used by signals for determining when genitals have been updated */ #define COMSIG_MOB_UPDATE_GENITALS "mob_genitals_updated" + +///called on [/obj/item] AFTER unequip from base of [mob/proc/doUnEquip]: (force, atom/newloc, no_move, invdrop, silent) +#define COMSIG_ITEM_POST_UNEQUIP "item_post_unequip" diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 52fbd7dac4..2f05de6034 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -14,7 +14,8 @@ /obj/item/storage/box/evidence = 6, /obj/item/flashlight/seclite = 4, /obj/item/restraints/legcuffs/bola/energy = 7, - /obj/item/secbat = 5) + /obj/item/secbat = 5, + /obj/item/bodycam_upgrade = 10) contraband = list(/obj/item/clothing/glasses/sunglasses = 2, /obj/item/storage/fancy/donut_box = 2, /obj/item/storage/belt/sabre/secbelt = 1) diff --git a/modular_splurt/code/modules/clothing/misc/body_camera.dm b/modular_splurt/code/modules/clothing/misc/body_camera.dm new file mode 100644 index 0000000000..4d57911f1a --- /dev/null +++ b/modular_splurt/code/modules/clothing/misc/body_camera.dm @@ -0,0 +1,145 @@ + +/obj/item/clothing/suit/armor/Initialize(mapload) + . = ..() + AddComponent(/datum/component/bodycamera_holder) + +/obj/item/clothing/suit/hooded/wintercoat/security/Initialize(mapload) + . = ..() + AddComponent(/datum/component/bodycamera_holder) + +/obj/item/clothing/suit/security/Initialize(mapload) + . = ..() + AddComponent(/datum/component/bodycamera_holder) + +/** + * The bodycamera + * + * This is the item that gets installed into items that have the bodycamera_holder element + */ +/obj/item/bodycam_upgrade + name = "\improper Body camera" + desc = "An armor vest upgrade, there's an instructions tag if you look a little closer..." + icon = 'modular_splurt/icons/obj/clothing/bodycam.dmi' + icon_state = "bodycamera" + ///The camera itself. + var/obj/machinery/camera/builtin_bodycamera + +/obj/item/bodycam_upgrade/examine_more(mob/user) + . = ..() + . += list(span_notice("Use [src] on any valid vest to quickly install.")) + . += list(span_notice("While equipped, use your ID card on the vest to activate/deactivate the camera.")) + . += list(span_notice("When going off duty, make sure to turn of your camera.")) + +/obj/item/bodycam_upgrade/Destroy() + if(builtin_bodycamera) + turn_off() + return ..() + +/obj/item/bodycam_upgrade/proc/is_on() + if(isnull(builtin_bodycamera)) + return FALSE + return TRUE + +/obj/item/bodycam_upgrade/proc/turn_on(mob/user, obj/item/card/id/id_card) + builtin_bodycamera = new(user) + builtin_bodycamera.internal_light = FALSE + builtin_bodycamera.network = list("ss13") + builtin_bodycamera.c_tag = "-Body Camera: [(id_card.registered_name)] ([id_card.assignment])" + playsound(loc, 'sound/machines/beep.ogg', get_clamped_volume(), TRUE, -1) + if(user) + user.balloon_alert(user, "bodycamera activated") + +/obj/item/bodycam_upgrade/proc/turn_off(mob/user) + if(user) + user.balloon_alert(user, "bodycamera deactivated") + playsound(loc, 'sound/machines/beep.ogg', get_clamped_volume(), TRUE, -1) + QDEL_NULL(builtin_bodycamera) + + +/** + * Bodycamera component + * + * Allows anything to have a body camera inserted into it + */ +/datum/component/bodycamera_holder + ///The installed bodycamera + var/obj/item/bodycam_upgrade/bodycamera_installed + ///The clothing part this needs to be on. This could possibly just be done by checking the clothing's slot + var/clothingtype_required = ITEM_SLOT_OCLOTHING + +/datum/component/bodycamera_holder/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/on_attackby) + RegisterSignal(parent, COMSIG_PARENT_EXAMINE_MORE, .proc/on_examine_more) + +/datum/component/bodycamera_holder/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY) + UnregisterSignal(parent, COMSIG_PARENT_EXAMINE) + QDEL_NULL(bodycamera_installed) + return ..() + +/datum/component/bodycamera_holder/proc/turn_camera_on(mob/living/user, obj/item/card) + RegisterSignal(parent, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(on_unequip)) + bodycamera_installed.turn_on(user, card) + +/datum/component/bodycamera_holder/proc/turn_camera_off(mob/living/user) + UnregisterSignal(parent, COMSIG_ITEM_POST_UNEQUIP) + bodycamera_installed.turn_off(user) + +/// When the camera holder is unequipped +/datum/component/bodycamera_holder/proc/on_unequip(mob/living/source, force, atom/newloc, no_move, invdrop, silent) + SIGNAL_HANDLER + turn_camera_off() + +/// When examining +/datum/component/bodycamera_holder/proc/on_examine_more(atom/source, mob/user, list/examine_list) + SIGNAL_HANDLER + + if(bodycamera_installed) + examine_list += span_notice("It has [bodycamera_installed] installed.") + else + examine_list += span_notice("It has a spot to hook up a body camera onto.") + +/// When items are used on it. Bodycamera/ID card +/datum/component/bodycamera_holder/proc/on_attackby(datum/source, obj/item/item, mob/living/user) + SIGNAL_HANDLER + + if(istype(item, /obj/item/bodycam_upgrade)) + if(bodycamera_installed) + user.balloon_alert(user, "camera already installed!") + playsound(source, 'sound/machines/buzz-two.ogg', item.get_clamped_volume(), TRUE, -1) + else + item.forceMove(source) + bodycamera_installed = item + playsound(source, 'sound/items/drill_use.ogg', item.get_clamped_volume(), TRUE, -1) + return + + if(!bodycamera_installed) + return + + var/obj/item/card/id/card = item.GetID() + if(!card) + return + var/obj/item/clothing/suit_slot = user.get_item_by_slot(clothingtype_required) + if(!istype(suit_slot)) + user.balloon_alert(user, "must be wearing suit!") + return + + //Do we have a camera on or off? + if(bodycamera_installed.is_on()) + turn_camera_off(user) + else + turn_camera_on(user, card) + +/// When a screwdriver is used on it +/datum/component/bodycamera_holder/proc/on_screwdriver_act(atom/source, mob/user, obj/item/tool) + SIGNAL_HANDLER + + if(!bodycamera_installed) + return + if(bodycamera_installed.is_on()) + turn_camera_off(user) + playsound(source, 'sound/items/drill_use.ogg', tool.get_clamped_volume(), TRUE, -1) + bodycamera_installed.forceMove(user.loc) + INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), bodycamera_installed) + bodycamera_installed = null diff --git a/modular_splurt/icons/obj/clothing/bodycam.dmi b/modular_splurt/icons/obj/clothing/bodycam.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4047aca61e8ce5350450f59e3a48c71a377a863c GIT binary patch literal 516 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