From 73740b9d6293e68e2cc37b244d3452278ac2e96c Mon Sep 17 00:00:00 2001 From: ManofSausage <134344460+ManofSausage@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:21:03 +0300 Subject: [PATCH] [MIRROR] adds portable radio jammer --- baystation12.dme | 1 + code/datums/uplink/devices and tools.dm | 7 + .../game/objects/items/devices/radio/radio.dm | 29 ++- .../objects/items/devices/radio_jammer.dm | 178 ++++++++++++++++++ icons/obj/radio_jammer.dmi | Bin 0 -> 471 bytes nano/templates/radio_jammer.tmpl | 53 ++++++ 6 files changed, 264 insertions(+), 4 deletions(-) create mode 100644 code/game/objects/items/devices/radio_jammer.dm create mode 100644 icons/obj/radio_jammer.dmi create mode 100644 nano/templates/radio_jammer.tmpl diff --git a/baystation12.dme b/baystation12.dme index 44bc89b5d8efb..83d66505932a3 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -991,6 +991,7 @@ #include "code\game\objects\items\devices\paint_sprayer.dm" #include "code\game\objects\items\devices\personal_shield.dm" #include "code\game\objects\items\devices\powersink.dm" +#include "code\game\objects\items\devices\radio_jammer.dm" #include "code\game\objects\items\devices\slide_projector.dm" #include "code\game\objects\items\devices\spy_bug.dm" #include "code\game\objects\items\devices\suit_cooling.dm" diff --git a/code/datums/uplink/devices and tools.dm b/code/datums/uplink/devices and tools.dm index f0ba350fcbfb1..3d14a4d0c4aae 100644 --- a/code/datums/uplink/devices and tools.dm +++ b/code/datums/uplink/devices and tools.dm @@ -115,6 +115,13 @@ While in hacking mode, this device will grant full access to any airlock in 20 to 40 seconds. \ This device will be able to continuously reaccess the last 6 to 8 airlocks it was used on." +/datum/uplink_item/item/tools/radio_jammer + name = "Portable Radio Jammer" + item_cost = 24 + path = /obj/item/device/radio_jammer + desc = "A pocket sized portable radio jammer that can intercept outgoing radio signals in a given distance. \ + However, radios attempting to send outgoing transmissions will emit a faint buzzing noise. \ + The jammer can be signaled remotely using assembly signalers." /datum/uplink_item/item/tools/space_suit name = "Voidsuit and Tactical Mask" diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 963d292e14d4b..e66e2996b9979 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -329,13 +329,35 @@ return null /obj/item/device/radio/talk_into(mob/living/M, message, channel, verb = "says", datum/language/speaking = null) - if(!on) return 0 // the device has to be on + // the device has to be on + if (!on) + return FALSE // Fix for permacell radios, but kinda eh about actually fixing them. - if(!M || !message) return 0 + if (!M || !message) + return FALSE - if(speaking && (speaking.flags & (NONVERBAL|SIGNLANG))) return 0 + if (speaking && (speaking.flags & (NONVERBAL|SIGNLANG))) + return FALSE if (!broadcasting) + var/list/headset_z_group = GetConnectedZlevels(get_z(src)) + //needs to account for turfs + var/turf/self_turf = get_turf(src) + if (!self_turf) + return FALSE + var/self_x = self_turf.x + var/self_y = self_turf.y + for (var/obj/item/device/radio_jammer/jammer as anything in GLOB.radio_jammers) + var/turf/jammer_turf = get_turf(jammer) + if (!jammer_turf) + continue + var/dx = self_x - jammer_turf.x + var/dy = self_y - jammer_turf.y + if (dx*dx + dy*dy <= jammer.square_radius && (jammer_turf.z in headset_z_group)) + to_chat(M,SPAN_WARNING("Instead of the familiar radio crackle, \the [src] emits a faint buzzing sound.")) + playsound(loc, 'sound/effects/zzzt.ogg', 20, 0, -1) + return FALSE + // Sedation chemical effect should prevent radio use (Chloral and Soporific) var/mob/living/carbon/C = M if (istype(C)) @@ -559,7 +581,6 @@ /obj/item/device/radio/hear_talk(mob/M as mob, msg, verb = "says", datum/language/speaking = null) - if (broadcasting) if(get_dist(src, M) <= canhear_range) talk_into(M, msg,null,verb,speaking) diff --git a/code/game/objects/items/devices/radio_jammer.dm b/code/game/objects/items/devices/radio_jammer.dm new file mode 100644 index 0000000000000..be4c33dc50e14 --- /dev/null +++ b/code/game/objects/items/devices/radio_jammer.dm @@ -0,0 +1,178 @@ +GLOBAL_LIST_EMPTY(radio_jammers) +//adjusted to last a while so it can last conversations +#define JAMMER_POWER_CONSUMPTION(tick_delay) ((max(0.75, range)**2 * tick_delay) / 30) + +/obj/item/device/radio_jammer + name = "small remote" + desc = "A small remote control covered in a number of lights, with several antennae extending from the top." + icon = 'icons/obj/radio_jammer.dmi' + icon_state = "jammer" + w_class = ITEM_SIZE_SMALL + var/is_active = FALSE + var/range = 5 + var/square_radius = 25 + var/code = 23 + var/frequency = 1413 + var/obj/item/cell/bcell = /obj/item/cell/high + +/obj/item/device/radio_jammer/Initialize() + . = ..() + if(ispath(bcell)) + bcell = new bcell(src) + GLOB.listening_objects += src + set_frequency(frequency) + +/obj/item/device/radio_jammer/Destroy() + GLOB.radio_jammers -= src + GLOB.listening_objects -= src + qdel(bcell) + return ..() + +/obj/item/device/radio_jammer/Process(wait) + var/cost = JAMMER_POWER_CONSUMPTION(wait) + if (!bcell?.use(cost)) + STOP_PROCESSING(SSobj, src) + GLOB.radio_jammers -=src + is_active = FALSE + +/obj/item/device/radio_jammer/attack_self(mob/living/user) + ui_interact(user) + +/obj/item/device/radio_jammer/get_cell() + return bcell + +/obj/item/device/radio_jammer/emp_act(severity) + ..() + if(bcell) + bcell.emp_act(severity) + +/obj/item/device/radio_jammer/proc/toggle(mob/user) + if(is_active) + STOP_PROCESSING(SSobj, src) + to_chat(user,SPAN_WARNING("You flick a switch on \the [src], deactivating it.")) + is_active = FALSE + GLOB.radio_jammers -= src + update_icon() + else + START_PROCESSING(SSobj, src) + to_chat(user,SPAN_WARNING("You flick a switch on \the [src], activating it.")) + is_active = TRUE + GLOB.radio_jammers += src + update_icon() + +/obj/item/device/radio_jammer/on_update_icon() + ClearOverlays() + if(bcell) + var/percent = bcell.percent() + switch(percent) + if(0 to 25) + AddOverlays("quarter") + if(25 to 50) + AddOverlays("half") + if(50 to 99) + AddOverlays("full") + else + AddOverlays("four_quarters") + + if(is_active) + AddOverlays("on") + else + AddOverlays("off") + +/obj/item/device/radio_jammer/proc/set_frequency(new_frequency) + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_controller.add_object(src, frequency, RADIO_CHAT) + +/obj/item/device/radio_jammer/receive_signal(datum/signal/signal) + if(signal?.encryption == code) + toggle() + +/obj/item/device/radio_jammer/OnTopic(mob/user, list/href_list, state) + if (href_list["enable_jammer"]) + toggle() + return TOPIC_REFRESH + if (href_list["disable_jammer"]) + toggle() + return TOPIC_REFRESH + if(href_list["increase_range"]) + range = min(range + 1, 10) + square_radius = range ** 2 + return TOPIC_REFRESH + if(href_list["decrease_range"]) + range = max(range - 1, 0) + square_radius = range ** 2 + return TOPIC_REFRESH + if(href_list["set_code"]) + var/adj = text2num(href_list["code"]) + if(!adj) + code = input("Set radio activation code","Radio activation") as num + if (QDELETED(src) || CanUseTopic(user, state, href_list) == STATUS_INTERACTIVE) + return TOPIC_HANDLED + else + code += adj + code = clamp(code,1,100) + return TOPIC_REFRESH + if (href_list["set_frequency"]) + var/adj = text2num(href_list["frequency"]) + if(!adj) + var/temp = input("Set a four digit radio frequency without decimals","Radio activation") as num + set_frequency(sanitize_frequency(temp, RADIO_LOW_FREQ, RADIO_HIGH_FREQ)) + if (QDELETED(src) || CanUseTopic(user, state, href_list) == STATUS_INTERACTIVE) + return TOPIC_HANDLED + return TOPIC_REFRESH + +/obj/item/device/radio_jammer/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + var/list/data = list( + "active" = is_active, + "current_charge" = bcell ? round(bcell.charge, 1) : 0, + "max_charge" = bcell ? bcell.maxcharge : 0, + "range" = range, + "max_range" = 10, + "frequency" = format_frequency(frequency), + "code" = code, + "total_cost" = "[ceil(JAMMER_POWER_CONSUMPTION(10))]" + ) + ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) + if (!ui) + ui = new(user, src, ui_key, "radio_jammer.tmpl", "Portable Radio Jammer", 300, 640) + ui.set_initial_data(data) + ui.open() + ui.set_auto_update(TRUE) + +/obj/item/device/radio_jammer/use_tool(obj/item/tool, mob/living/user, list/click_params) + if (isCrowbar(tool)) + if(is_active) + STOP_PROCESSING(SSobj, src) + is_active = FALSE + GLOB.radio_jammers -= src + if (!bcell) + USE_FEEDBACK_FAILURE("\The [src] has no cell to remove.") + return TRUE + user.put_in_hands(bcell) + user.visible_message( + SPAN_NOTICE("\The [user] removes \a [bcell] from \a [src] with \a [tool]."), + SPAN_NOTICE("You remove \the [bcell] from \the [src] with \the [tool].") + ) + bcell = null + update_icon() + return TRUE + if (istype(tool, /obj/item/cell)) + if (bcell) + USE_FEEDBACK_FAILURE("\The [src] already has \a [bcell] installed.") + return TRUE + if (!user.unEquip(tool, src)) + FEEDBACK_UNEQUIP_FAILURE(user, tool) + return TRUE + bcell = tool + user.visible_message( + SPAN_NOTICE("\The [user] installs \a [tool] into \a [src]."), + SPAN_NOTICE("you install \the [tool] into \the [src].") + ) + update_icon() + return TRUE + + return ..() + + +#undef JAMMER_POWER_CONSUMPTION diff --git a/icons/obj/radio_jammer.dmi b/icons/obj/radio_jammer.dmi new file mode 100644 index 0000000000000000000000000000000000000000..31b67a841378cea172505d821e505aadb89ad75c GIT binary patch literal 471 zcmV;|0Vw{7P)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo` zEh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+D={}WwMdDJGbOXA z7${)K#hF%=n41b=!M^H&&X<|_c5!PiS<`A|otu!YGmm*~aS3ehUfB*pQ zBu)nnX!mRY006s5L_t(oh3%Ky3d0}}MAgl#x!5%M|DUZUv~M+~Fb{z_AP5U*R&*Z> zL5MpO8Pb$KTch{~d&@cf4+flmR{wAZSpF8^W*(1-FXXZBnC4E=lDT`V3;%U^g{2HM z{{qStxAT`0QT?odM_JcWK=X&{U!R5L2Tp&8B!8QL<|h%`1UP8^P#;f?SXj4P1M2)P zwD@-6E1|fGcSS~1HS%W`&0k` N002ovPDHLkV1oaVy7vG8 literal 0 HcmV?d00001 diff --git a/nano/templates/radio_jammer.tmpl b/nano/templates/radio_jammer.tmpl new file mode 100644 index 0000000000000..932d94fc5da26 --- /dev/null +++ b/nano/templates/radio_jammer.tmpl @@ -0,0 +1,53 @@ +
+

Status

+
+ {{:data.active ? "Enabled" : "Disabled"}} +
+
+ {{:helper.link('Enable' , null, {'enable_jammer' : 1}, data.active ? "selected" : null, null)}} + {{:helper.link('Disable' , null, {'disable_jammer' : 1}, data.active ? null : "selected", null)}} +
+
+ +
+

Range

+
+ {{:data.range}} meter(s) +
+
+ {{:helper.link('Decrease' , 'minusthick', {'decrease_range' : 1}, data.range <= 0 ? "disabled" : null, null)}} + {{:helper.link('Increase' , 'plusthick', {'increase_range' : 1}, data.range >= 10 ? "disabled" : null, null)}} +
+
+ +
+

Remote Activation

+
+ {{:helper.link( data.frequency, null, { 'set_frequency': 1})}} +
+
+ {{:helper.link( data.code, null, { 'set_code': 1})}} +
+
+ +
+
+
+ Charge +
+
+ {{:data.current_charge}}/{{:data.max_charge}} W +
+
+
+ {{:helper.displayBar(data.current_charge/data.max_charge, 0, 1, 'average')}} +
+
+
+ Energy Consumption +
+
+ ~{{:data.total_cost}} W +
+
+