diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 86dd2443803..ef02944be57 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -45122,7 +45122,7 @@ /obj/structure/rack, /obj/effect/spawner/random/armory/riot_helmet, /obj/effect/spawner/random/armory/bulletproof_helmet, -/obj/item/gun/energy/e_gun/dragnet, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) "qaV" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index f399c25d3b1..9f1a266b185 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -882,11 +882,8 @@ pixel_x = 3 }, /obj/structure/window/reinforced/spawner/directional/north, -/obj/item/gun/energy/e_gun/dragnet{ - pixel_y = 4 - }, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "alG" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 09525a5fa06..9e5ecd8c048 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -30518,15 +30518,12 @@ "jko" = ( /obj/structure/railing, /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet{ - pixel_y = 4 - }, -/obj/item/gun/energy/e_gun/dragnet, /obj/structure/cable, /obj/machinery/door/firedoor/border_only, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/security/armory/upper) "jkx" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 24c017ab71b..6cd01a35c9d 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -32130,12 +32130,11 @@ /area/station/maintenance/fore) "loY" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/blue/half/contrasted{ dir = 4 }, /obj/machinery/light/small/directional/west, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "lpo" = ( diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 0f9faf9338b..7ce411f102f 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -57668,7 +57668,7 @@ /area/station/science/lower) "oOW" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "oOY" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 4015dbf2ad3..a8b81413f9c 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -28696,10 +28696,9 @@ /area/station/cargo/storage) "jlQ" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/item/radio/intercom/directional/north, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "jlX" = ( diff --git a/_maps/map_files/wawastation/wawastation.dmm b/_maps/map_files/wawastation/wawastation.dmm index 8bec8ecfae0..f06276d3e9f 100644 --- a/_maps/map_files/wawastation/wawastation.dmm +++ b/_maps/map_files/wawastation/wawastation.dmm @@ -13544,12 +13544,11 @@ /area/station/maintenance/department/medical) "eQJ" = ( /obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, /obj/item/radio/intercom/directional/south, +/obj/effect/spawner/random/armory/dragnet, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "eQQ" = ( diff --git a/code/game/objects/effects/spawners/random/armory.dm b/code/game/objects/effects/spawners/random/armory.dm index 5292ca6ad09..dfb71ff10d5 100644 --- a/code/game/objects/effects/spawners/random/armory.dm +++ b/code/game/objects/effects/spawners/random/armory.dm @@ -45,6 +45,16 @@ icon_state = "shotgun" loot = list(/obj/item/gun/ballistic/shotgun/riot) +/obj/effect/spawner/random/armory/dragnet + name = "DRAGnet spawner" + icon_state = "dragnet" + loot = list(/obj/item/gun/energy/e_gun/dragnet) + spawn_loot_count = 2 + +/obj/effect/spawner/random/armory/dragnet/spawn_loot(lootcount_override) + . = ..() + new /obj/item/dragnet_beacon(get_turf(src)) //And give them a beacon too! + // Armor /obj/effect/spawner/random/armory/bulletproof_helmet name = "bulletproof helmet spawner" diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index e36f9f84cac..05360fe913f 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -214,9 +214,12 @@ /datum/supply_pack/security/armory/dragnet name = "DRAGnet Crate" desc = "Contains three \"Dynamic Rapid-Apprehension of the Guilty\" netting devices, \ - a recent breakthrough in law enforcement prisoner management technology." + a recent breakthrough in law enforcement prisoner management technology. Includes a DRAGnet beacon." cost = CARGO_CRATE_VALUE * 5 - contains = list(/obj/item/gun/energy/e_gun/dragnet = 3) + contains = list( + /obj/item/gun/energy/e_gun/dragnet = 3, + /obj/item/dragnet_beacon = 1 + ) crate_name = "\improper DRAGnet crate" /datum/supply_pack/security/armory/energy diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index fec816b1e76..78e75d1f306 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -86,7 +86,7 @@ /obj/item/gun/energy/e_gun/dragnet name = "\improper DRAGnet" - desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology." + desc = "The \"Dynamic Rapid-Apprehension of the Guilty\" net is a revolution in law enforcement technology. Can by synced with a DRAGnet beacon to set a teleport destination for snare rounds." icon_state = "dragnet" inhand_icon_state = "dragnet" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' @@ -95,10 +95,35 @@ modifystate = FALSE w_class = WEIGHT_CLASS_NORMAL ammo_x_offset = 1 + ///A dragnet beacon set to be the teleport destination for snare teleport rounds. + var/obj/item/dragnet_beacon/linked_beacon /obj/item/gun/energy/e_gun/dragnet/add_seclight_point() return +/obj/item/gun/energy/e_gun/dragnet/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/dragnet_beacon)) + link_beacon(user, tool) + +///Sets the linked_beacon var on the dragnet, which becomes the snare round's teleport destination. +/obj/item/gun/energy/e_gun/dragnet/proc/link_beacon(mob/living/user, obj/item/dragnet_beacon/our_beacon) + if(linked_beacon) + if(our_beacon == linked_beacon) + balloon_alert(user, "already synced!") + return + else + UnregisterSignal(linked_beacon, COMSIG_QDELETING) //You're getting overridden dude. + + linked_beacon = our_beacon + balloon_alert(user, "beacon synced") + RegisterSignal(our_beacon, COMSIG_QDELETING, PROC_REF(handle_beacon_disable)) + +///Handles clearing the linked_beacon reference in the event that it is deleted. +/obj/item/gun/energy/e_gun/dragnet/proc/handle_beacon_disable(datum/source) + SIGNAL_HANDLER + visible_message(span_warning("A light on the [src] flashes, indicating that it is no longer linked with a DRAGnet beacon!")) + linked_beacon = null + /obj/item/gun/energy/e_gun/dragnet/snare name = "Energy Snare Launcher" desc = "Fires an energy snare that slows the target down." diff --git a/code/modules/projectiles/projectile/energy/net_snare.dm b/code/modules/projectiles/projectile/energy/net_snare.dm index 1bb7988e4ba..ac35fb5503e 100644 --- a/code/modules/projectiles/projectile/energy/net_snare.dm +++ b/code/modules/projectiles/projectile/energy/net_snare.dm @@ -11,10 +11,15 @@ SpinAnimation() /obj/projectile/energy/net/on_hit(atom/target, blocked = 0, pierce_hit) + var/obj/item/dragnet_beacon/destination_beacon = null + var/obj/item/gun/energy/e_gun/dragnet/our_dragnet = fired_from + if(our_dragnet && istype(our_dragnet)) + destination_beacon = our_dragnet.linked_beacon + if(isliving(target)) var/turf/Tloc = get_turf(target) if(!locate(/obj/effect/nettingportal) in Tloc) - new /obj/effect/nettingportal(Tloc) + new /obj/effect/nettingportal(Tloc, destination_beacon) . = ..() /obj/projectile/energy/net/on_range() @@ -29,26 +34,18 @@ light_range = 3 anchored = TRUE -/obj/effect/nettingportal/Initialize(mapload) +/obj/effect/nettingportal/Initialize(mapload, destination_beacon) . = ..() - var/obj/item/beacon/teletarget = null - for(var/obj/machinery/computer/teleporter/com as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/computer/teleporter)) - var/atom/target = com.target_ref?.resolve() - if(target) - if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) - teletarget = target - else - com.target_ref = null - + var/obj/item/dragnet_beacon/teletarget = destination_beacon addtimer(CALLBACK(src, PROC_REF(pop), teletarget), 3 SECONDS) /obj/effect/nettingportal/proc/pop(teletarget) if(teletarget) - for(var/mob/living/L in get_turf(src)) - do_teleport(L, teletarget, 2, channel = TELEPORT_CHANNEL_BLUESPACE)//teleport what's in the tile to the beacon + for(var/mob/living/living_mob in get_turf(src)) + do_teleport(living_mob, get_turf(teletarget), 1, channel = TELEPORT_CHANNEL_BLUESPACE) //Teleport what's in the tile to the beacon else - for(var/mob/living/L in get_turf(src)) - do_teleport(L, L, 15, channel = TELEPORT_CHANNEL_BLUESPACE) //Otherwise it just warps you off somewhere. + for(var/mob/living/living_mob in get_turf(src)) + do_teleport(living_mob, get_turf(living_mob), 15, channel = TELEPORT_CHANNEL_BLUESPACE) //Otherwise it just warps you off somewhere. qdel(src) @@ -58,6 +55,66 @@ /obj/effect/nettingportal/singularity_pull() return +/obj/item/dragnet_beacon + name = "\improper DRAGnet beacon" + desc = "Can be synced with a DRAGnet to set it as a designated teleporting point." + icon = 'icons/obj/devices/tracker.dmi' + icon_state = "dragnet_beacon" + inhand_icon_state = "beacon" + lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + ///Has a security ID been used to lock this in place? + var/locked = FALSE + +/obj/item/dragnet_beacon/item_interaction(mob/living/user, obj/item/tool, list/modifiers) + if(istype(tool, /obj/item/gun/energy/e_gun/dragnet)) + var/obj/item/gun/energy/e_gun/dragnet/dragnet_to_link = tool + dragnet_to_link.link_beacon(user, src) + return + + if(isidcard(tool)) + if(!anchored) + balloon_alert(user, "wrench the beacon first!") + return + + if(obj_flags & EMAGGED) + balloon_alert(user, "the access control is fried!") + return + + var/obj/item/card/id/id_card = tool + if((ACCESS_SECURITY in id_card.GetAccess())) + locked = !locked + balloon_alert(user, "beacon [locked ? "locked" : "unlocked"]") + else + balloon_alert(user, "no access!") + +/obj/item/dragnet_beacon/wrench_act(mob/living/user, obj/item/tool) + if(user.is_holding(src)) + balloon_alert(user, "put it down first!") + return ITEM_INTERACT_BLOCKING + + if(anchored && locked) + balloon_alert(user, "must be unlocked first!") + return ITEM_INTERACT_BLOCKING + + if(isinspace() && !anchored) + balloon_alert(user, "nothing to anchor to!") + return ITEM_INTERACT_BLOCKING + + set_anchored(!anchored) + tool.play_tool_sound(src, 75) + user.balloon_alert_to_viewers("[anchored ? "anchored" : "unanchored"]") + +/obj/item/dragnet_beacon/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + obj_flags |= EMAGGED + locked = FALSE + set_anchored(FALSE) + do_sparks(3, TRUE, src) + balloon_alert(user, "beacon unlocked") + return TRUE + /obj/projectile/energy/trap name = "energy snare" icon_state = "e_snare" diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 8ae869220de..0ea6c41e164 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -818,6 +818,19 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SECURITY + +/datum/design/dragnet_beacon + name = "DRAGnet Beacon" + desc = "A beacon that can be used as a teleport destination for DRAGnet snare rounds. Remember to sync it with your DRAGnet first!" + id = "dragnet_beacon" + build_type = PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 2) + build_path = /obj/item/dragnet_beacon + category = list( + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_SECURITY + ) + departmental_flags = DEPARTMENT_BITFLAG_SECURITY + /datum/design/inspector name = "N-Spect Scanner" desc = "Central Command-issued inspection device. Performs inspections according to Nanotrasen protocols when activated, then prints an encrypted report regarding the maintenance of the station. Definitely not giving you cancer." diff --git a/code/modules/research/techweb/nodes/security_nodes.dm b/code/modules/research/techweb/nodes/security_nodes.dm index 97092f2682a..8b931fd2273 100644 --- a/code/modules/research/techweb/nodes/security_nodes.dm +++ b/code/modules/research/techweb/nodes/security_nodes.dm @@ -32,6 +32,7 @@ "scanner_gate", "turret_control", "pepperspray", + "dragnet_beacon", "inspector", "evidencebag", "handcuffs_s", diff --git a/icons/effects/random_spawners.dmi b/icons/effects/random_spawners.dmi index ddd6fd6f608..ed6c0c8702e 100644 Binary files a/icons/effects/random_spawners.dmi and b/icons/effects/random_spawners.dmi differ diff --git a/icons/obj/devices/tracker.dmi b/icons/obj/devices/tracker.dmi index 59884c0aff8..39be63ef4de 100644 Binary files a/icons/obj/devices/tracker.dmi and b/icons/obj/devices/tracker.dmi differ