From 01889aae109054c12e7849e238b983c34eb9da14 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:28:56 -0400 Subject: [PATCH] Buffs the Camera bug by adding hidden cameras (#21618) * LETS GOOOOOo * desc * steel review * ASYNC MAGIC! * lewcc review * i cant spell * async --- code/_onclick/other_mobs.dm | 3 + code/datums/components/sticky.dm | 118 ++++++++++++++++++ code/datums/uplink_items/uplink_general.dm | 4 +- code/game/machinery/camera/camera.dm | 1 + code/game/objects/items/devices/camera_bug.dm | 62 ++++++++- code/game/objects/items/weapons/dice.dm | 2 +- .../items/weapons/storage/uplink_kits.dm | 9 ++ icons/obj/device.dmi | Bin 52732 -> 52774 bytes paradise.dme | 1 + 9 files changed, 193 insertions(+), 7 deletions(-) create mode 100644 code/datums/components/sticky.dm diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 3667dca5804..f8193e8d4c1 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -22,6 +22,9 @@ if(S.prevents_buckled_mobs_attacking()) return + if(SEND_SIGNAL(A, COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, src) & COMPONENT_CANCEL_ATTACK_CHAIN) + return + A.attack_hand(src) /atom/proc/attack_hand(mob/user as mob) diff --git a/code/datums/components/sticky.dm b/code/datums/components/sticky.dm new file mode 100644 index 00000000000..dcb05ab2a22 --- /dev/null +++ b/code/datums/components/sticky.dm @@ -0,0 +1,118 @@ +// kinda like duct tape but not shit (just kidding, its shit but in a different way) +/datum/component/sticky + /// The atom we are stickied to + var/atom/attached_to + /// Our priority overlay put on top of attached_to + var/icon/overlay + /// Do we drop on attached_to's destroy? If not, we qdel + var/drop_on_attached_destroy = FALSE + +/datum/component/sticky/Initialize(_drop_on_attached_destroy = FALSE) + if(!isitem(parent)) + stack_trace("/datum/component/sticky's parent is not an item, its [parent.type]") + return COMPONENT_INCOMPATIBLE + + drop_on_attached_destroy = _drop_on_attached_destroy + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(stick_to_it)) + +/datum/component/sticky/proc/stick_to_it(obj/item/I, atom/target, mob/user, params) + SIGNAL_HANDLER + if(!in_range(I, target)) + return + if(isstorage(target)) + var/obj/item/storage/S = target + if(S.can_be_inserted(parent)) + return + if(target.GetComponent(/datum/component/sticky)) + return + if(!user.canUnEquip(I)) + return + + INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, unEquip), I) + + var/list/click_params = params2list(params) + //Center the icon where the user clicked. + if(!click_params || !click_params["icon-x"] || !click_params["icon-y"]) + return + + attached_to = target + move_to_the_thing(parent) + if(user) + to_chat(user, "You attach [parent] to [attached_to].") + + overlay = icon(I.icon, I.icon_state) + //Clamp it so that the icon never moves more than 16 pixels in either direction + overlay.Shift(EAST, clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2)) + overlay.Shift(NORTH, clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2)) + + attached_to.add_overlay(overlay, priority = TRUE) + I.invisibility = INVISIBILITY_ABSTRACT + + RegisterSignal(attached_to, COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, PROC_REF(pick_up)) + RegisterSignal(attached_to, COMSIG_PARENT_EXAMINE, PROC_REF(add_sticky_text)) + RegisterSignal(attached_to, COMSIG_PARENT_QDELETING, PROC_REF(on_attached_destroy)) + if(ismovable(attached_to)) + RegisterSignal(attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + START_PROCESSING(SSobj, src) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/sticky/proc/pick_up(atom/A, mob/living/carbon/human/user) + SIGNAL_HANDLER + if(!attached_to) + return + if(user.a_intent != INTENT_GRAB) + return + if(user.get_active_hand()) + return + attached_to.cut_overlay(overlay, priority = TRUE) + + var/obj/item/I = parent + I.pixel_x = initial(I.pixel_x) + I.pixel_y = initial(I.pixel_y) + move_to_the_thing(parent) + INVOKE_ASYNC(user, TYPE_PROC_REF(/mob, put_in_hands), I) + if(user) + to_chat(user, "You take [parent] off of [attached_to].") + + + I.invisibility = initial(I.invisibility) + UnregisterSignal(attached_to, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY, COMSIG_PARENT_EXAMINE)) + STOP_PROCESSING(SSobj, src) + attached_to = null + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/sticky/proc/add_sticky_text(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + if(!in_range(user, attached_to)) + return + examine_list += "There is [parent] attached to [source], grab [attached_to.p_them()] to remove it." + +/datum/component/sticky/proc/on_move(datum/source, oldloc, move_dir) + SIGNAL_HANDLER + if(!attached_to) + stack_trace("/datum/component/sticky was called on_move, but without an attached atom") + return + move_to_the_thing(parent) + +/datum/component/sticky/process() // because sometimes the item can move inside something, like a crate + if(!attached_to) + return PROCESS_KILL + move_to_the_thing(parent) + +/datum/component/sticky/proc/on_attached_destroy(datum/source) + SIGNAL_HANDLER + if(!drop_on_attached_destroy) + qdel(parent) + return + + var/turf/T = get_turf(source) + if(!T) + T = get_turf(parent) + move_to_the_thing(parent, T) + +/datum/component/sticky/proc/move_to_the_thing(obj/item/I, turf/target) + if(!istype(I)) + return // only items should be able to have the sticky component + if(!target) + target = get_turf(attached_to) + INVOKE_ASYNC(I, TYPE_PROC_REF(/atom/movable, forceMove), target) diff --git a/code/datums/uplink_items/uplink_general.dm b/code/datums/uplink_items/uplink_general.dm index b1dd0135e29..625531234a7 100644 --- a/code/datums/uplink_items/uplink_general.dm +++ b/code/datums/uplink_items/uplink_general.dm @@ -464,9 +464,9 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/stealthy_tools/camera_bug name = "Camera Bug" - desc = "Enables you to view all cameras on the network to track a target." + desc = "Enables you to view all cameras on the network to track a target. Also has 5 sticky hidden cameras, allowing you remote view of any object you can stick a camera on." reference = "CB" - item = /obj/item/camera_bug + item = /obj/item/storage/box/syndie_kit/camera_bug cost = 1 surplus = 90 diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 7fffc5358c5..141144dc750 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -406,6 +406,7 @@ return TRUE /obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets. + start_active = TRUE // theres no real way to reactivate these, so never break them when they init var/turf/prev_turf /obj/machinery/camera/portable/Initialize(mapload) diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index 88bfa0ed9bf..389e3da2694 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -3,14 +3,15 @@ name = "camera bug" desc = "For illicit snooping through the camera network." icon = 'icons/obj/device.dmi' - icon_state = "camera_bug" - w_class = WEIGHT_CLASS_TINY - item_state = "camera_bug" + icon_state = "camera_bug" + w_class = WEIGHT_CLASS_TINY + item_state = "camera_bug" throw_speed = 4 throw_range = 20 origin_tech = "syndicate=1;engineering=3" /// Integrated camera console to serve UI data var/obj/machinery/computer/security/camera_bug/integrated_console + var/connections = 0 /obj/machinery/computer/security/camera_bug name = "invasive camera utility" @@ -22,7 +23,7 @@ . = ..() integrated_console = new(src) integrated_console.parent = src - integrated_console.network = list("SS13") + integrated_console.network = list("SS13", "camera_bug[UID()]") /obj/item/camera_bug/Destroy() QDEL_NULL(integrated_console) @@ -43,3 +44,56 @@ . = ..() integrated_console.network = list("ERT") +/obj/item/wall_bug + name = "\improper small camera" + desc = "A camera with a sticky backside." + icon = 'icons/obj/device.dmi' + icon_state = "wall_bug" + w_class = WEIGHT_CLASS_TINY + var/obj/machinery/camera/portable/camera + var/index = "REPORT THIS TO CODERS" + +/obj/item/wall_bug/Initialize(mapload, obj/item/camera_bug/the_bug) + . = ..() + link_to_camera(the_bug) + AddComponent(/datum/component/sticky) + +/obj/item/wall_bug/Destroy() + QDEL_NULL(camera) + . = ..() + +/obj/item/wall_bug/examine(mob/user) + . = ..() + if(in_range(user, src)) + . += "It has a small label on it reading \"[index]\"." + +/obj/item/wall_bug/proc/link_to_camera(obj/item/camera_bug/camera_bug) + if(!istype(camera_bug)) + return + if(camera) // we can't link twice + return + camera_bug.connections++ + index = camera_bug.connections + + camera = new /obj/machinery/camera/portable(src) + camera.network = list("camera_bug[camera_bug.UID()]") + camera.c_tag = "Hidden Camera [index]" + +/obj/item/paper/camera_bug + name = "Camera Bug Guide" + icon_state = "paper" + info = {"Instructions on your new invasive camera utility
+
+ This camera bug can access all default cameras on the station, along with the hidden cameras provided in this kit.
+
+ The cameras in this kit have a sticky backside, allowing you to attach them to literally anything, even people.
+
+ You may remove the cameras from said objects by grabbing them with an empty hand.
+
+ You can view these hidden cameras by looking up "Hidden Camera" on your camera bug.
+
+ Only the camera bug provided in this kit can see these hidden cameras.
+
+ Other Camera bugs cannot see your hidden cameras.
+
+ There is no other way to get these hidden cameras, so make sure to not lose them!
"} diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm index 59ae3a2fa75..9af05a5019e 100644 --- a/code/game/objects/items/weapons/dice.dm +++ b/code/game/objects/items/weapons/dice.dm @@ -252,7 +252,7 @@ /obj/item/storage/toolbox/syndicate, /obj/item/storage/backpack/clown/syndie, /obj/item/storage/backpack/satchel_flat, - /obj/item/camera_bug, + /obj/item/storage/box/syndie_kit/camera_bug, /obj/item/storage/belt/military/traitor, /obj/item/clothing/glasses/chameleon/thermal, /obj/item/borg/upgrade/modkit/indoors, diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index af25037ff74..00d249bfd12 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -374,3 +374,12 @@ To apply, hold the injector a short distance away from the outer thigh before ap new /obj/item/gun/projectile/automatic/pistol(src) new /obj/item/ammo_box/magazine/m10mm(src) new /obj/item/ammo_box/magazine/m10mm(src) + +/obj/item/storage/box/syndie_kit/camera_bug + name = "\improper Camera Bug kit" + +/obj/item/storage/box/syndie_kit/camera_bug/populate_contents() + var/camera = new /obj/item/camera_bug(src) + new /obj/item/paper/camera_bug(src) + for(var/i in 1 to 5) + new /obj/item/wall_bug(src, camera) diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 212df4631b63f2c31d9f10145d831ddc243a5d52..abf40126598481500ec59a5b326386495edfa0d6 100644 GIT binary patch delta 10140 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 diff --git a/paradise.dme b/paradise.dme index 1af32ce2f5c..5d4bcf5629d 100644 --- a/paradise.dme +++ b/paradise.dme @@ -379,6 +379,7 @@ #include "code\datums\components\spooky.dm" #include "code\datums\components\squeak.dm" #include "code\datums\components\squish.dm" +#include "code\datums\components\sticky.dm" #include "code\datums\components\surgery_initiator.dm" #include "code\datums\components\swarming.dm" #include "code\datums\discord\discord_manager.dm"