-
Notifications
You must be signed in to change notification settings - Fork 925
FCT - Field Camera Tripod #12504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
FCT - Field Camera Tripod #12504
Changes from all commits
e3c6464
197d5a1
be501e2
d5e34e5
1d62585
b893cd1
b3cf6d1
0a27834
0dc3ab0
f5f800a
12be3bc
bfc8325
1212b57
61f1a12
f37461a
4724474
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -357,3 +357,220 @@ | |
|
|
||
| /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 = "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" | ||
| 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 | ||
| var/datum/squad/squad | ||
|
|
||
| /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/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 | ||
| 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) | ||
| 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.")) // 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!")) | ||
| 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 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, check conditions are still valid after do_after, at least that the item still exists and the user is valid |
||
|
|
||
| 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 | ||
|
|
||
| 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.temp_drop_inv_item() | ||
| qdel(src) | ||
|
|
||
| /obj/structure/overwatch_camera_tripod | ||
| 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" | ||
| 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 | ||
| 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")) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same goes here regarding checking after tgui_alert. This is even more important cause in this situation, if there's no error, it's possible for several people to click on it and all undeploy it, duplicating the item |
||
| switch(choice) | ||
| 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 | ||
| 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(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 | ||
| 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.")) | ||
| 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 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's ok here since |
||
| undeploy() | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -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 | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| 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 | ||||||
|
|
||||||
|
|
@@ -788,47 +822,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(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() | ||||||
| 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") | ||||||
|
|
@@ -1580,6 +1629,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 = "<span class='langchat langchat_yell'>[tripod.label]</span><br>" | ||||||
| var/location_part = "<span class='langchat' style='font-size: 7px;'>[area_name]</span><br>" | ||||||
| var/job_part = "<span class='langchat' style='font-size: 6px;'>Tripod Camera</span>" | ||||||
| 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' | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for deletion after tgui_alert - the item can have been deleted in the meantime the user selecting. This is important if you're gonna deploy it.
Ideally should check the user is still holding it and conscious and such aswell, but that's bonus, at least check for deletion