diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index 748a203cc4..ad16bb0416 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -111,6 +111,13 @@
src.loc = null
return ..()
+// Check if target is reasonable for us to operate on.
+/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
+ if(((src in target) && !target_self) || ((!istype(target.loc, /turf)) && (!istype(target, /turf)) && (not_inside)))
+ return FALSE
+ else
+ return TRUE
+
/obj/item/proc/update_twohanding()
update_held_icon()
diff --git a/code/modules/mining/resonator_vr.dm b/code/modules/mining/resonator_vr.dm
new file mode 100644
index 0000000000..a4b20990cb
--- /dev/null
+++ b/code/modules/mining/resonator_vr.dm
@@ -0,0 +1,111 @@
+/**********************Resonator**********************/
+
+/obj/item/resonator
+ name = "resonator"
+ icon = 'icons/obj/mining_vr.dmi'
+ icon_state = "resonator"
+ item_state = "resonator"
+ item_icons = list(
+ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi',
+ slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi',
+ )
+ origin_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 3)
+ desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in low temperature."
+ w_class = ITEMSIZE_NORMAL
+ force = 8
+ throwforce = 10
+ var/cooldown = 0
+ var/fieldsactive = 0
+ var/burst_time = 50
+ var/fieldlimit = 3
+
+/obj/item/resonator/upgraded
+ name = "upgraded resonator"
+ desc = "An upgraded version of the resonator that can produce more fields at once."
+ icon_state = "resonator_u"
+ origin_tech = list(TECH_MATERIAL = 4, TECH_POWER = 3, TECH_MAGNET = 3, TECH_ENGINEERING = 3)
+ fieldlimit = 5
+
+/obj/item/resonator/proc/CreateResonance(var/target, var/creator)
+ var/turf/T = get_turf(target)
+ if(locate(/obj/effect/resonance) in T)
+ return
+ if(fieldsactive < fieldlimit)
+ playsound(src,'sound/weapons/resonator_fire.ogg',50,1)
+ new /obj/effect/resonance(T, creator, burst_time)
+ fieldsactive++
+ spawn(burst_time)
+ fieldsactive--
+
+/obj/item/resonator/attack_self(mob/user)
+ if(burst_time == 50)
+ burst_time = 30
+ to_chat(user, "You set the resonator's fields to detonate after 3 seconds.")
+ else
+ burst_time = 50
+ to_chat(user, "You set the resonator's fields to detonate after 5 seconds.")
+
+/obj/item/resonator/afterattack(atom/target, mob/user, proximity_flag)
+ if(proximity_flag)
+ if(!check_allowed_items(target, 1))
+ return
+ CreateResonance(target, user)
+
+/obj/effect/resonance
+ name = "resonance field"
+ desc = "A resonating field that significantly damages anything inside of it when the field eventually ruptures."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "shield1"
+ plane = MOB_PLANE
+ layer = ABOVE_MOB_LAYER
+ mouse_opacity = 0
+ var/resonance_damage = 20
+
+/obj/effect/resonance/initialize(mapload, var/creator = null, var/timetoburst)
+ . = ..()
+ // Start small and grow to big size as we are about to burst
+ transform = matrix()*0.75
+ animate(src, transform = matrix()*1.5, time = timetoburst)
+ // Queue the actual bursting
+ spawn(timetoburst)
+ if(!QDELETED(src))
+ burst(creator)
+
+/obj/effect/resonance/proc/burst(var/creator = null)
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+ playsound(src, 'sound/weapons/resonator_blast.ogg', 50, 1)
+ // Make the collapsing effect
+ new /obj/effect/temp_visual/resonance_crush(T)
+
+ // Mineral turfs get drilled!
+ if(istype(T, /turf/simulated/mineral))
+ var/turf/simulated/mineral/M = T
+ M.GetDrilled()
+ qdel(src)
+ return
+ // Otherwise we damage mobs! Boost damage if low tempreature
+ var/datum/gas_mixture/environment = T.return_air()
+ if(environment.temperature < 250)
+ name = "strong resonance field"
+ resonance_damage = 50
+
+ for(var/mob/living/L in src.loc)
+ if(creator)
+ add_attack_logs(creator, L, "used a resonator field on")
+ to_chat(L, "\The [src] ruptured with you in it!")
+ L.apply_damage(resonance_damage, BRUTE)
+ qdel(src)
+
+
+/obj/effect/temp_visual/resonance_crush
+ icon_state = "shield1"
+ plane = MOB_PLANE
+ layer = ABOVE_MOB_LAYER
+ duration = 4
+
+/obj/effect/temp_visual/resonance_crush/initialize()
+ . = ..()
+ transform = matrix()*1.5
+ animate(src, transform = matrix()*0.1, alpha = 50, time = 4)
diff --git a/icons/mob/items/lefthand_vr.dmi b/icons/mob/items/lefthand_vr.dmi
new file mode 100644
index 0000000000..8d1397038d
Binary files /dev/null and b/icons/mob/items/lefthand_vr.dmi differ
diff --git a/icons/mob/items/righthand_vr.dmi b/icons/mob/items/righthand_vr.dmi
new file mode 100644
index 0000000000..873478be17
Binary files /dev/null and b/icons/mob/items/righthand_vr.dmi differ
diff --git a/icons/obj/mining_vr.dmi b/icons/obj/mining_vr.dmi
new file mode 100644
index 0000000000..573f7de88e
Binary files /dev/null and b/icons/obj/mining_vr.dmi differ
diff --git a/sound/weapons/resonator_blast.ogg b/sound/weapons/resonator_blast.ogg
new file mode 100644
index 0000000000..7110a716b1
Binary files /dev/null and b/sound/weapons/resonator_blast.ogg differ
diff --git a/sound/weapons/resonator_fire.ogg b/sound/weapons/resonator_fire.ogg
new file mode 100644
index 0000000000..20665e5dd0
Binary files /dev/null and b/sound/weapons/resonator_fire.ogg differ
diff --git a/vorestation.dme b/vorestation.dme
index 1f733cc343..8412af551d 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1851,6 +1851,7 @@
#include "code\modules\mining\money_bag.dm"
#include "code\modules\mining\ore.dm"
#include "code\modules\mining\ore_datum.dm"
+#include "code\modules\mining\resonator_vr.dm"
#include "code\modules\mining\satchel_ore_boxdm.dm"
#include "code\modules\mining\shelter_atoms.dm"
#include "code\modules\mining\shelters.dm"