From e3c646443b01ba4ede6e20487ee87e19ff8fbdc4 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:39:58 +0100 Subject: [PATCH 01/14] placeholder sprites --- icons/overwatch.dmi | Bin 0 -> 1189 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 icons/overwatch.dmi diff --git a/icons/overwatch.dmi b/icons/overwatch.dmi new file mode 100644 index 0000000000000000000000000000000000000000..9dc21f64414397dac49590480b723bdef664024a GIT binary patch literal 1189 zcmV;W1X}xvP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#GJQVVkOD^pXHxHwZXi;5L&6%4sJ(~1&vQz2})!qPlKN|hB{ z{ah4Wd_B1UjxQ)U9iU{w000B%NklnIF5=|whNU0x)wnB*d zVp!+si#`ZJp*~nE)uI(OTEq{GR*F@rN{}M0528dU#uvXIq-`F~X{$)3rGy%aNKE@u z#Y&Bhg_>m7hwPfWH`(1glg32q?&Uw4A{uNz1BjG88_E8_pKiJdau108b5Oa%xpLCK)HSS68Nzfj(-I4)Ry>E zsE~T>+hd(^L}L!R2L}g_tbh0+E^b;(U*Cs|MdX6exFN5>>k5U!;V6o7siAE^mzfnq z#biZ9MuEmeSC6Vb9TLm?C~RhfaU2)oIHt9=mG<^_+S=OgFtf-1jfXGsSE~JBXdv$u zAR-%pw^H3FffcHHJXDCs{1I@5>BsmMRjs*M&V<(r5Rs+8n~ARSH{Jy7@|`@8mCSsH z`6MKmZwYKpO`cqOD@CL`M1&_-Gra@=ZWfWo8TxDDn}B-~_JFGP0?D)B%OY~2uLw_u zf%6jWWHMg&4VF0pB61a#JMUekzpI!${lVlN;jA2jYOov_Pqh0J_JnURpB3fND%vVK$h6ZWX8_9O>Y^$?S_S?2ywK^ZV$W6AEJvK+jrn*b5n4=hS_-B88# zSi*j6Hlk{ws(%7+0G9&Ys#>V?k($&j0TEdT+?43rtg1g$asLLmrDQJ?k&9II)NI66 zqx8_fo{d;lSAd9|4{T3#4XNr&HDYaL>TLj%`@({!RtapO@_k!v=>wpuKLZC7T^mFs zePLQ~)Ji~e!rrK=zh{Wom5SX}&2gbnH36!+2KX4*qN=ZC38t#w0=rAiGr-ua70xk1 zzYEkuMBW7kRW*HUTyV@u0{%;!^S=%LpMd!mFyH(Q02m{h@mLVN00000NkvXXu0mjf DbUQ9$ literal 0 HcmV?d00001 From 197d5a116e5e47a59f5e3c0aa89bfc1e7550399a Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:40:25 +0100 Subject: [PATCH 02/14] global list --- code/_globalvars/misc.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index c4528ed7ec8a..b70b96cecd50 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -132,3 +132,5 @@ GLOBAL_VAR(obfs_z) /// List of giant lizards that are alive. GLOBAL_LIST_EMPTY(giant_lizards_alive) +/// List of F5CT Field Camera Tripods +GLOBAL_LIST_EMPTY(deployed_tripod_cameras) From be501e21bbee1362460981f62b43cdffdb89bc87 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:40:54 +0100 Subject: [PATCH 03/14] F5CT Field Camera Tripod and Overwatch Code --- code/modules/cm_marines/equipment/gear.dm | 195 ++++++++++++++++++++++ code/modules/cm_marines/overwatch.dm | 128 ++++++++++---- 2 files changed, 288 insertions(+), 35 deletions(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index 33fb84c2942d..a0ca9150ae27 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -357,3 +357,198 @@ /obj/item/device/overwatch_camera/see_emote(mob/living/sourcemob, emote, audible) SEND_SIGNAL(src, COMSIG_BROADCAST_SEE_EMOTE, sourcemob, emote, audible, loc == sourcemob && audible) + +/obj/item/device/overwatch_camera/tripod + name = "FC5T Tripod Camera" + desc = "A Motoca-430-T deployable tripod camera that connects to the overwatch network. It can be renamed and deployed." + icon = 'icons/overwatch.dmi' // ToDO: Get real sprites + icon_state = "undeployed" + var/label = null + var/datum/squad/squad = null + +/obj/item/device/overwatch_camera/tripod/Initialize(mapload, ...) + . = ..() + camera = new /obj/structure/machinery/camera/overwatch(src) + AddComponent(/datum/component/overwatch_console_control) + +/obj/item/device/overwatch_camera/tripod/Destroy() + QDEL_NULL(camera) + return ..() + +/obj/item/device/overwatch_camera/tripod/attack_self(mob/user) + ..() + var/choice = tgui_alert(user, "What would you like to do with [src]?", "Tripod Camera", list("Rename", "Deploy", "Cancel")) + switch(choice) + if("Cancel") + return + if("Rename") + var/new_name = tgui_input_text(user, "Enter new name for the camera:", "Rename Camera", label ? label : initial(name), MAX_NAME_LEN, ui_state=GLOB.not_incapacitated_state, encode=FALSE) + if(!new_name) + return + new_name = trim_right(replace_non_alphanumeric_plus(new_name)) + if(!length(new_name)) + to_chat(user, SPAN_WARNING("Invalid name.")) + return + label = new_name + name = new_name + if(camera) + camera.c_tag = new_name + to_chat(user, SPAN_NOTICE("Camera renamed to [name].")) + return + if("Deploy") + deploy_tripod(user) + +/obj/item/device/overwatch_camera/tripod/proc/deploy_tripod(mob/user) + var/turf/deploy_turf = get_turf(user) + if(!deploy_turf) + return + + var/area/deploy_area = get_area(deploy_turf) + if(!deploy_area.allow_construction) + to_chat(user, SPAN_WARNING("You cannot deploy [src] here!")) + return + if(istype(deploy_area, /area/shuttle)) + to_chat(user, SPAN_WARNING("You cannot deploy [src] in a shuttle area.")) + return + if(!istype(deploy_turf, /turf/open)) + to_chat(user, SPAN_WARNING("[src] must be placed on a solid surface!")) + return + + for(var/obj/blocking_object in deploy_turf) + if(blocking_object.density && blocking_object != src) + to_chat(user, SPAN_WARNING("[blocking_object] is blocking the deployment spot!")) + return + + if(!do_after(user, 3 SECONDS, INTERRUPT_ALL, BUSY_ICON_BUILD)) + to_chat(user, SPAN_WARNING("You must stand still while deploying the tripod.")) + return + + var/datum/squad/user_squad = null // find squad + if(ishuman(user)) + var/mob/living/carbon/human/human_user = user + user_squad = human_user.assigned_squad + + var/base_label = label ? label : initial(name) + var/final_label = user_squad ? "[user_squad.name] - [base_label]" : base_label + + var/obj/structure/overwatch_camera_tripod/deployed_structure = new(deploy_turf) // transform to new struc + deployed_structure.label = final_label + deployed_structure.name = final_label + deployed_structure.squad = user_squad + deployed_structure.icon_state = "deployed" + + if(camera) + camera.forceMove(deployed_structure) + camera.c_tag = final_label + camera.status = TRUE + deployed_structure.camera = camera + src.camera = null + + to_chat(user, SPAN_NOTICE("You deploy [src].")) + user.drop_held_item() + qdel(src) + +/obj/structure/overwatch_camera_tripod + name = "FC5T Tripod Camera" + desc = "A Motoca-430-T deployed tripod camera connected to the overwatch network." + icon = 'icons/overwatch.dmi' // ToDO: Get real sprites + icon_state = "deployed" + density = TRUE + anchored = TRUE + layer = OBJ_LAYER + var/label = "Tripod Camera" + var/obj/structure/machinery/camera/camera + var/datum/squad/squad = null + var/slash_count = 0 // tracks xeno slashes 4 breaking + +/obj/structure/overwatch_camera_tripod/Initialize(mapload) + . = ..() + icon_state = "deployed" + camera = new /obj/structure/machinery/camera/overwatch(src) + camera.c_tag = label + camera.status = TRUE + AddComponent(/datum/component/overwatch_console_control) + GLOB.deployed_tripod_cameras += src + +/obj/structure/overwatch_camera_tripod/Destroy() + GLOB.deployed_tripod_cameras -= src + QDEL_NULL(camera) + return ..() + +/obj/structure/overwatch_camera_tripod/examine(mob/user) + . = ..() + to_chat(user, SPAN_INFO("The label label reads: [label]")) // ToDO: This maybe should be in the description box I just don't know how to add it atm + if(squad) + to_chat(user, SPAN_INFO("It is currently assigned to squad: [squad.name]")) // ToDO: This maybe should be in the description box I just don't know how to add it atm + +/obj/structure/overwatch_camera_tripod/attack_hand(mob/user) + if(user.a_intent != INTENT_HELP) // I've left this in just in case maints want me to change the tgui menu to intent handling or smth. + return ..() + var/choice = tgui_alert(user, "What would you like to do with [src]?", "Tripod Camera", list("Rename", "Pick Up", "Cancel")) + switch(choice) + if("Cancel") + return + if("Rename") + var/new_name = tgui_input_text(user, "Enter new label for the camera:", "Rename Camera", label, MAX_NAME_LEN, ui_state=GLOB.not_incapacitated_state, encode=FALSE) + if(!new_name) + return + new_name = trim_right(replace_non_alphanumeric_plus(new_name)) + if(!length(new_name)) + to_chat(user, SPAN_WARNING("Invalid name.")) + return + label = new_name + name = new_name + if(camera) + camera.c_tag = new_name + to_chat(user, SPAN_NOTICE("[src] renamed to [name].")) + return + if("Pick Up") + if(!user.Adjacent(src)) + to_chat(user, SPAN_WARNING("You must be closer to pick up [src].")) + return + if(!do_after(user, 2 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) + to_chat(user, SPAN_WARNING("You were interrupted while picking up the [src].")) + return + // Create a new tripod item from the structure + undeploy(user) + return // not sure if i need this here + +/obj/structure/overwatch_camera_tripod/attack_alien(mob/living/carbon/xenomorph/Xeno) + if(islarva(Xeno)) + return + slash_count++ + Xeno.animation_attack_on(src) + Xeno.flick_attack_overlay(src, "slash") + playsound(loc, 'sound/weapons/slash.ogg', 25, 1) + if(slash_count >= 3) + Xeno.visible_message(SPAN_DANGER("[Xeno] slashes [src] apart!"), + SPAN_DANGER("You tear through [src]!")) + undeploy() + else + Xeno.visible_message(SPAN_DANGER("[Xeno] slashes [src]!"), + SPAN_DANGER("You slash [src]!")) + return XENO_ATTACK_ACTION + +/obj/structure/overwatch_camera_tripod/proc/undeploy(mob/user) + var/obj/item/device/overwatch_camera/tripod/new_tripod = new(get_turf(src)) + new_tripod.label = label + new_tripod.name = label + new_tripod.squad = squad + if(camera) + camera.forceMove(new_tripod) + camera.c_tag = label + camera.status = TRUE + new_tripod.camera = camera + src.camera = null + if(user && ishuman(user)) + user.put_in_hands(new_tripod) + to_chat(user, SPAN_NOTICE("You disassemble [src].")) + else + new_tripod.visible_message(SPAN_WARNING("[new_tripod] falls to the floor.")) + GLOB.deployed_tripod_cameras -= src + qdel(src) + +/obj/structure/overwatch_camera_tripod/ex_act(severity) + if(severity >= EXPLOSION_THRESHOLD_LOW) // no idea if i need to add this or it's inherited from parent somewhere + visible_message(SPAN_DANGER("[src] is blown over!")) + undeploy() diff --git a/code/modules/cm_marines/overwatch.dm b/code/modules/cm_marines/overwatch.dm index 02e8f2502a28..9c170fe368c1 100644 --- a/code/modules/cm_marines/overwatch.dm +++ b/code/modules/cm_marines/overwatch.dm @@ -360,6 +360,40 @@ GLOBAL_LIST_EMPTY_TYPED(active_overwatch_consoles, /obj/structure/machinery/comp leader_count++ marine_count-- + for(var/obj/structure/overwatch_camera_tripod/tripod_camera in GLOB.deployed_tripod_cameras) // add cameras to list o' marines + if(current_squad && current_squad.name != "Root") + if(!tripod_camera.squad || tripod_camera.squad != current_squad) // tldr: show cameras in root squad if placed by non-squad marines + continue + if(!tripod_camera.camera || !tripod_camera.camera.can_use()) // skip broken (code) or damaged (in-game) cameras + continue // ToDO: There should be an error log if camera is missing camera comp. + if(!tripod_camera.loc) // skip null location cameras + continue // ToDO: Error Log if camera has no LOC + var/turf/camera_turf = get_turf(tripod_camera) + if(!camera_turf) + continue // ToDO: Error Log if camera has no turf. + switch(z_hidden) + if(HIDE_ALMAYER) + if(is_mainship_level(camera_turf.z)) + continue + if(HIDE_GROUND) + if(is_ground_level(camera_turf.z)) + continue + var/area/camera_area = get_area(tripod_camera) + var/camera_area_name = camera_area ? sanitize_area(camera_area.name) : "Unknown" + var/list/camera_data = list( + "name" = tripod_camera.label, + "state" = "Active", + "has_helmet" = TRUE, // can't click the button in OW if set to false + "role" = "Tripod Camera", + "acting_sl" = "", // not sure if i need to null these or not + "fteam" = "", + "distance" = "N/A", + "area_name" = camera_area_name, + "ref" = REF(tripod_camera), + "rank" = "", + ) + data["marines"] += list(camera_data) + data["total_deployed"] = leader_count + ftl_count + spec_count + medic_count + engi_count + smart_count + marine_count data["living_count"] = leaders_alive + ftl_alive + spec_alive + medic_alive + engi_alive + smart_alive + marines_alive @@ -785,47 +819,62 @@ GLOBAL_LIST_EMPTY_TYPED(active_overwatch_consoles, /obj/structure/machinery/comp return if(!params["target_ref"]) return - if(current_squad) - var/mob/living/carbon/human/cam_target = locate(params["target_ref"]) + if(!current_squad) + return - if(!istype(cam_target)) - return + var/atom/target_ref = locate(params["target_ref"]) + var/obj/structure/machinery/camera/new_cam = null + var/obj/item/new_holder = null + var/atom/cam_target = null - var/obj/item/new_holder = cam_target.get_camera_holder() - var/obj/structure/machinery/camera/new_cam + if(istype(target_ref, /mob/living/carbon/human)) + var/mob/living/carbon/human/Human = target_ref + cam_target = Human + new_holder = Human.get_camera_holder() if(new_holder) new_cam = new_holder.get_camera() - if(user.interactee != src) //if we multitasking - user.set_interaction(src) - if(cam == new_cam) //if we switch to a console that is already watching this cam - return - if(!new_cam || !new_cam.can_use()) - to_chat(user, "[icon2html(src, user)] [SPAN_WARNING("Searching for camera. No camera found for this marine! Tell your squad to put their cameras on!")]") - else if(cam && cam == new_cam)//click the camera you're watching a second time to stop watching. - visible_message("[icon2html(src, viewers(src))] [SPAN_BOLDNOTICE("Stopping camera view of [cam_target].")]") - for(var/datum/weakref/user_ref in concurrent_users) - var/mob/concurrent = user_ref.resolve() - if(!concurrent) - continue - stop_watching_camera(concurrent) + else if(istype(target_ref, /obj/structure/overwatch_camera_tripod)) + var/obj/structure/overwatch_camera_tripod/tripod_camera = target_ref + if(tripod_camera.camera) + new_cam = tripod_camera.camera + cam_target = tripod_camera + else + to_chat(user, "[icon2html(src, user)] [SPAN_WARNING("Invalid target.")]") + return + + if(user.interactee != src) //if we multitasking + user.set_interaction(src) + if(cam == new_cam) //if we switch to a console that is already watching this cam + return + if(!new_cam || !new_cam.can_use()) + to_chat(user, "[icon2html(src, user)] [SPAN_WARNING("Searching for camera. No camera found for this target!")]") + else if(cam && cam == new_cam)//click the camera you're watching a second time to stop watching. + visible_message("[icon2html(src, viewers(src))] [SPAN_BOLDNOTICE("Stopping camera view.")]") + for(var/datum/weakref/user_ref in concurrent_users) + var/mob/concurrent = user_ref.resolve() + if(!concurrent) + continue + stop_watching_camera(concurrent) + concurrent.UnregisterSignal(cam, COMSIG_PARENT_QDELETING) + disconnect_holder() + cam = null + else if(user.client.view != GLOB.world_view_size) + to_chat(user, SPAN_WARNING("You're too busy peering through binoculars.")) + else + for(var/datum/weakref/user_ref in concurrent_users) + var/mob/concurrent = user_ref.resolve() + if(!concurrent) + continue + if(cam) concurrent.UnregisterSignal(cam, COMSIG_PARENT_QDELETING) - disconnect_holder() - cam = null - else if(user.client.view != GLOB.world_view_size) - to_chat(user, SPAN_WARNING("You're too busy peering through binoculars.")) - else - for(var/datum/weakref/user_ref in concurrent_users) - var/mob/concurrent = user_ref.resolve() - if(!concurrent) - continue - if(cam) - concurrent.UnregisterSignal(cam, COMSIG_PARENT_QDELETING) - start_watching_camera(concurrent, new_cam) + start_watching_camera(concurrent, new_cam) + if(cam_target) set_onscreen_text(concurrent, cam_target) - concurrent.RegisterSignal(new_cam, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob, reset_observer_view_on_deletion)) - if(camera_holder) - disconnect_holder() - cam = new_cam + concurrent.RegisterSignal(new_cam, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/mob, reset_observer_view_on_deletion)) + if(camera_holder) + disconnect_holder() + cam = new_cam + if(new_holder) connect_holder(new_holder) if("change_operator") @@ -1569,6 +1618,15 @@ GLOBAL_LIST_EMPTY_TYPED(active_overwatch_consoles, /obj/structure/machinery/comp watcher.hud_used.overwatch_text.maptext = name_part + location_part + job_part + living_part + else if(istype(target, /obj/structure/overwatch_camera_tripod)) // on-screen text - in theory you can't click on a downed camera + var/obj/structure/overwatch_camera_tripod/tripod = target + var/area/current_area = get_area(tripod) + var/area_name = current_area ? sanitize_area(current_area.name) : "Unknown" + var/name_part = "[tripod.label]
" + var/location_part = "[area_name]
" + var/job_part = "Tripod Camera" + watcher.hud_used.overwatch_text.maptext = name_part + location_part + job_part + /obj/structure/machinery/computer/overwatch/almayer density = FALSE icon = 'icons/obj/structures/machinery/computer.dmi' From d5e34e50be228af7f29ba368fb264f1b52da09e0 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:42:28 +0100 Subject: [PATCH 04/14] rename --- code/modules/cm_marines/equipment/gear.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index a0ca9150ae27..9d1aeced0800 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -359,7 +359,7 @@ SEND_SIGNAL(src, COMSIG_BROADCAST_SEE_EMOTE, sourcemob, emote, audible, loc == sourcemob && audible) /obj/item/device/overwatch_camera/tripod - name = "FC5T Tripod Camera" + name = "FTC Tripod Camera" desc = "A Motoca-430-T deployable tripod camera that connects to the overwatch network. It can be renamed and deployed." icon = 'icons/overwatch.dmi' // ToDO: Get real sprites icon_state = "undeployed" @@ -449,7 +449,7 @@ qdel(src) /obj/structure/overwatch_camera_tripod - name = "FC5T Tripod Camera" + name = "FTC Tripod Camera" desc = "A Motoca-430-T deployed tripod camera connected to the overwatch network." icon = 'icons/overwatch.dmi' // ToDO: Get real sprites icon_state = "deployed" From 1d625855e7ff49bbb034f13c3071b69c4bc34969 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:50:16 +0100 Subject: [PATCH 05/14] change type check to ishuman check --- code/modules/cm_marines/overwatch.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cm_marines/overwatch.dm b/code/modules/cm_marines/overwatch.dm index 9c170fe368c1..4c5ec5fb0041 100644 --- a/code/modules/cm_marines/overwatch.dm +++ b/code/modules/cm_marines/overwatch.dm @@ -827,7 +827,7 @@ GLOBAL_LIST_EMPTY_TYPED(active_overwatch_consoles, /obj/structure/machinery/comp var/obj/item/new_holder = null var/atom/cam_target = null - if(istype(target_ref, /mob/living/carbon/human)) + if(ishuman(target_ref)) // not strict since synths can be placed in OW squads var/mob/living/carbon/human/Human = target_ref cam_target = Human new_holder = Human.get_camera_holder() From b893cd1556766a4de4b83e9873dc166bf260257f Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 15:53:06 +0100 Subject: [PATCH 06/14] more comments --- code/modules/cm_marines/equipment/gear.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index 9d1aeced0800..49599a784772 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -408,7 +408,7 @@ to_chat(user, SPAN_WARNING("You cannot deploy [src] here!")) return if(istype(deploy_area, /area/shuttle)) - to_chat(user, SPAN_WARNING("You cannot deploy [src] in a shuttle area.")) + to_chat(user, SPAN_WARNING("You cannot deploy [src] in a shuttle area.")) // i copied this from M2C so idk if this is necessary? return if(!istype(deploy_turf, /turf/open)) to_chat(user, SPAN_WARNING("[src] must be placed on a solid surface!")) @@ -424,7 +424,7 @@ return var/datum/squad/user_squad = null // find squad - if(ishuman(user)) + if(ishuman(user)) // synths can place so not strict check var/mob/living/carbon/human/human_user = user user_squad = human_user.assigned_squad From 0a27834e7bddeba32fe50cfa471959ec816e0a81 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:02:47 +0100 Subject: [PATCH 07/14] add to Comtech vendor --- .../machinery/vending/vendor_types/squad_prep/squad_engineer.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm index 50ecbef3b1a7..f020079ca865 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm @@ -83,6 +83,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list( list("Motion Detector", 8, /obj/item/device/motiondetector, null, VENDOR_ITEM_REGULAR), list("Whistle", 3, /obj/item/clothing/accessory/device/whistle, null, VENDOR_ITEM_REGULAR), list("Synthetic Reset Key", 10, /obj/item/device/defibrillator/synthetic, null, VENDOR_ITEM_REGULAR), + list("FCT - Field Camera Tripod", 5 /obj/item/device/overwatch_camera/tripod, null, VENDOR_ITEM_REGULAR), list("BINOCULARS", 0, null, null, null), list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), From f5f800a0ef83f44368bc44915d195cbd8df5888b Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:03:40 +0100 Subject: [PATCH 08/14] remove double explo message --- code/modules/cm_marines/equipment/gear.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index 49599a784772..a4dfd25bb384 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -550,5 +550,4 @@ /obj/structure/overwatch_camera_tripod/ex_act(severity) if(severity >= EXPLOSION_THRESHOLD_LOW) // no idea if i need to add this or it's inherited from parent somewhere - visible_message(SPAN_DANGER("[src] is blown over!")) undeploy() From 12be3bc05ffc5319821b2e202dc8c13cebb5f730 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:09:37 +0100 Subject: [PATCH 09/14] fix vendor --- .../machinery/vending/vendor_types/squad_prep/squad_engineer.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm index f020079ca865..9d685e9a5647 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm @@ -83,7 +83,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list( list("Motion Detector", 8, /obj/item/device/motiondetector, null, VENDOR_ITEM_REGULAR), list("Whistle", 3, /obj/item/clothing/accessory/device/whistle, null, VENDOR_ITEM_REGULAR), list("Synthetic Reset Key", 10, /obj/item/device/defibrillator/synthetic, null, VENDOR_ITEM_REGULAR), - list("FCT - Field Camera Tripod", 5 /obj/item/device/overwatch_camera/tripod, null, VENDOR_ITEM_REGULAR), + list("FCT - Field Camera Tripod", 5, /obj/item/device/overwatch_camera/tripod, null, VENDOR_ITEM_REGULAR), list("BINOCULARS", 0, null, null, null), list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), From bfc83256b29b811a6b8b8c361b40d4e7ae9f8c56 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:36:41 +0100 Subject: [PATCH 10/14] lore update --- code/modules/cm_marines/equipment/gear.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index a4dfd25bb384..b87c727db159 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -363,6 +363,7 @@ desc = "A Motoca-430-T deployable tripod camera that connects to the overwatch network. It can be renamed and deployed." icon = 'icons/overwatch.dmi' // ToDO: Get real sprites icon_state = "undeployed" + desc_lore = "Following modernisation efforts in the Marine'70 program, USCM Platoons were shrunk and squads re-organised to emphasise individual firepower and mobility. The Motoca-430-T, the precursor to the Motoca-500 Helmet Camera, was commissioned by the Department of Defense to be utilised by Colonial Marine squads in establishing secure perimeters and watching rear areas remotely through the Overwatch system." var/label = null var/datum/squad/squad = null @@ -456,6 +457,7 @@ density = TRUE anchored = TRUE layer = OBJ_LAYER + desc_lore = "Following modernisation efforts in the Marine'70 program, USCM Platoons were shrunk and squads re-organised to emphasise individual firepower and mobility. The Motoca-430-T, the precursor to the Motoca-500 Helmet Camera, was commissioned by the Department of Defense to be utilised by Colonial Marine squads in establishing secure perimeters and watching rear areas remotely through the Overwatch system." var/label = "Tripod Camera" var/obj/structure/machinery/camera/camera var/datum/squad/squad = null From 1212b573ed924b7c4c6fd6bc3dc996c6a1b27093 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Fri, 26 Jun 2026 12:17:42 +0100 Subject: [PATCH 11/14] Apply suggestions Co-authored-by: fira --- code/_globalvars/misc.dm | 2 +- code/modules/cm_marines/equipment/gear.dm | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index b70b96cecd50..f9b5d2d64f46 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -133,4 +133,4 @@ GLOBAL_VAR(obfs_z) /// List of giant lizards that are alive. GLOBAL_LIST_EMPTY(giant_lizards_alive) /// List of F5CT Field Camera Tripods -GLOBAL_LIST_EMPTY(deployed_tripod_cameras) +GLOBAL_LIST_EMPTY_TYPED(deployed_tripod_cameras, /obj/structure/overwatch_camera_tripod) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index b87c727db159..755c9e1d7a56 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -364,8 +364,8 @@ icon = 'icons/overwatch.dmi' // ToDO: Get real sprites icon_state = "undeployed" desc_lore = "Following modernisation efforts in the Marine'70 program, USCM Platoons were shrunk and squads re-organised to emphasise individual firepower and mobility. The Motoca-430-T, the precursor to the Motoca-500 Helmet Camera, was commissioned by the Department of Defense to be utilised by Colonial Marine squads in establishing secure perimeters and watching rear areas remotely through the Overwatch system." - var/label = null - var/datum/squad/squad = null + var/label + var/datum/squad/squad /obj/item/device/overwatch_camera/tripod/Initialize(mapload, ...) . = ..() @@ -446,7 +446,7 @@ src.camera = null to_chat(user, SPAN_NOTICE("You deploy [src].")) - user.drop_held_item() + user.temp_drop_inv_item() qdel(src) /obj/structure/overwatch_camera_tripod @@ -460,7 +460,7 @@ desc_lore = "Following modernisation efforts in the Marine'70 program, USCM Platoons were shrunk and squads re-organised to emphasise individual firepower and mobility. The Motoca-430-T, the precursor to the Motoca-500 Helmet Camera, was commissioned by the Department of Defense to be utilised by Colonial Marine squads in establishing secure perimeters and watching rear areas remotely through the Overwatch system." var/label = "Tripod Camera" var/obj/structure/machinery/camera/camera - var/datum/squad/squad = null + var/datum/squad/squad var/slash_count = 0 // tracks xeno slashes 4 breaking /obj/structure/overwatch_camera_tripod/Initialize(mapload) From 61f1a12ca50c5c37c271d89ab38cbd0abe92ee3b Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:16:34 +0100 Subject: [PATCH 12/14] Apply suggestions. Co-authored-by: fira --- code/modules/cm_marines/equipment/gear.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index 755c9e1d7a56..bb64af811de5 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -547,7 +547,6 @@ to_chat(user, SPAN_NOTICE("You disassemble [src].")) else new_tripod.visible_message(SPAN_WARNING("[new_tripod] falls to the floor.")) - GLOB.deployed_tripod_cameras -= src qdel(src) /obj/structure/overwatch_camera_tripod/ex_act(severity) From f37461a0e43f2e9df3f882bf65ea063b7d3f93d3 Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:29:47 +0100 Subject: [PATCH 13/14] isyautja checks --- code/modules/cm_marines/equipment/gear.dm | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index bb64af811de5..903190710a8b 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -400,6 +400,15 @@ deploy_tripod(user) /obj/item/device/overwatch_camera/tripod/proc/deploy_tripod(mob/user) + var/datum/squad/user_squad = null // find squad for addition to label + + if(ishuman(user)) // synths can place so not strict check + var/mob/living/carbon/human/human_user = user + user_squad = human_user.assigned_squad + if(isyautja(user)) + to_chat(user, SPAN_WARNING("You can't think of a reason to interact with [src] and decide to leave it alone.")) + return + var/turf/deploy_turf = get_turf(user) if(!deploy_turf) return @@ -424,11 +433,6 @@ to_chat(user, SPAN_WARNING("You must stand still while deploying the tripod.")) return - var/datum/squad/user_squad = null // find squad - if(ishuman(user)) // synths can place so not strict check - var/mob/living/carbon/human/human_user = user - user_squad = human_user.assigned_squad - var/base_label = label ? label : initial(name) var/final_label = user_squad ? "[user_squad.name] - [base_label]" : base_label @@ -491,6 +495,9 @@ if("Cancel") return if("Rename") + if(isyautja(user)) + to_chat(user, SPAN_WARNING("You can't think of a reason to interact with [src] and decide to leave it alone.")) + return var/new_name = tgui_input_text(user, "Enter new label for the camera:", "Rename Camera", label, MAX_NAME_LEN, ui_state=GLOB.not_incapacitated_state, encode=FALSE) if(!new_name) return @@ -505,6 +512,9 @@ to_chat(user, SPAN_NOTICE("[src] renamed to [name].")) return if("Pick Up") + if(isyautja(user)) + to_chat(user, SPAN_WARNING("You can't think of a reason to interact with [src] and decide to leave it alone.")) + return if(!user.Adjacent(src)) to_chat(user, SPAN_WARNING("You must be closer to pick up [src].")) return From 472447496cc5efa20dc46dc1222fd3965e6d1e2e Mon Sep 17 00:00:00 2001 From: Danger Revolution! <142105406+DangerRevolution@users.noreply.github.com> Date: Sat, 27 Jun 2026 13:23:21 +0100 Subject: [PATCH 14/14] checks --- code/modules/cm_marines/equipment/gear.dm | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/modules/cm_marines/equipment/gear.dm b/code/modules/cm_marines/equipment/gear.dm index 903190710a8b..ba4ea6f5e1b5 100644 --- a/code/modules/cm_marines/equipment/gear.dm +++ b/code/modules/cm_marines/equipment/gear.dm @@ -408,6 +408,11 @@ if(isyautja(user)) to_chat(user, SPAN_WARNING("You can't think of a reason to interact with [src] and decide to leave it alone.")) return + if(user.is_mob_incapacitated()) + return + // if(user. != src) + // to_chat(user, SPAN_WARNING("You need to hold [src] in your hand to deploy it!")) + // return var/turf/deploy_turf = get_turf(user) if(!deploy_turf) @@ -433,6 +438,13 @@ to_chat(user, SPAN_WARNING("You must stand still while deploying the tripod.")) return + if(user.stat != CONCIOUS || user.is_mob_incapacitated()) //not sure if this is the same check or not :D + return + + if(user.get_active_hand() != src) + to_chat(user, SPAN_WARNING("You must hold [src] in your hand to deploy it!")) + return + var/base_label = label ? label : initial(name) var/final_label = user_squad ? "[user_squad.name] - [base_label]" : base_label