diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index df34c74b3ee..e719912f3bf 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -281,6 +281,7 @@ datum/objective/steal
"the nuclear authentication disk" = /obj/item/weapon/disk/nuclear,
"an ablative armor vest" = /obj/item/clothing/suit/armor/laserproof,
"the reactive teleport armor" = /obj/item/clothing/suit/armor/reactive,
+ "a laser pointer" = /obj/item/device/laser_pointer,
/*
Nobody takes these seriously anyways -- Ikki
"a captain's jumpsuit" = /obj/item/clothing/under/rank/captain,
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index e58de3f4eb7..cef085d72b7 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -292,6 +292,7 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/librarian(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/weapon/barcodescanner(H), slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/device/laser_pointer(H), slot_l_store)
return 1
@@ -324,6 +325,7 @@ var/global/lawyer = 0//Checks for another lawyer
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/lawyer(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase(H), slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/device/laser_pointer(H), slot_l_store)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index f6835c5184f..1a953fc0d8b 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -27,6 +27,7 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/labcoat(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
+ H.equip_to_slot_or_del(new /obj/item/device/laser_pointer(H), slot_l_store)
return 1
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index f0ef6f1907b..6f6db8ad4ec 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -182,6 +182,9 @@
playsound(loc, "sparks", 50, 1)
visible_message("\blue The camera has been sliced apart by [] with an energy blade!")
del(src)
+ else if(istype(W, /obj/item/device/laser_pointer))
+ var/obj/item/device/laser_pointer/L = W
+ L.laser_act(src, user)
else
..()
return
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
new file mode 100644
index 00000000000..3e98a0fe200
--- /dev/null
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -0,0 +1,183 @@
+
+/obj/item/device/laser_pointer
+ name = "laser pointer"
+ desc = "Don't shine it in your eyes!"
+ icon = 'icons/obj/device.dmi'
+ icon_state = "pointer"
+ item_state = "pen"
+ var/pointer_icon_state
+ flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
+ slot_flags = SLOT_BELT
+ m_amt = 500
+ g_amt = 500
+ w_class = 1.0
+ origin_tech = "combat=1"
+ origin_tech = "magnets=2"
+ var/turf/pointer_loc
+ var/energy = 5
+ var/max_energy = 5
+ var/recharging = 0
+ var/recharge_locked = 0
+
+/obj/item/device/laser_pointer/red
+ pointer_icon_state = "red_laser"
+/obj/item/device/laser_pointer/green
+ pointer_icon_state = "green_laser"
+/obj/item/device/laser_pointer/blue
+ pointer_icon_state = "blue_laser"
+/obj/item/device/laser_pointer/purple
+ pointer_icon_state = "purple_laser"
+
+/obj/item/device/laser_pointer/New()
+ ..()
+ if(!pointer_icon_state)
+ pointer_icon_state = pick("red_laser","green_laser","blue_laser","purple_laser")
+
+/obj/item/device/laser_pointer/attack(mob/living/M, mob/user)
+ laser_act(M, user)
+
+/obj/item/device/laser_pointer/afterattack(var/atom/target, var/mob/living/user, flag, params)
+ if(flag) //we're placing the object on a table or in backpack
+ return
+ laser_act(target, user)
+
+/obj/item/device/laser_pointer/proc/laser_act(var/atom/target, var/mob/living/user)
+ if( !(user in (viewers(7,target))) )
+ return
+ if (!user.IsAdvancedToolUser())
+ user << "You don't have the dexterity to do this!"
+ return
+ if(user.has_mutation(HULK))
+ user << "Your meaty finger is too large for the button!"
+ return
+ if(iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(C.is_mutantrace("adamantine"))
+ user << "Your metal fingers can't press the button!"
+ return
+
+ add_fingerprint(user)
+
+ //nothing happens if the battery is drained
+ if(recharge_locked)
+ user << "You point [src] at [target], but it's still charging."
+ return
+
+ var/outmsg
+ var/turf/targloc = get_turf(target)
+
+ //human/alien mobs
+ if(iscarbon(target))
+ if(user.zone_sel.selecting == "eyes")
+ var/mob/living/carbon/C = target
+
+ //20% chance to actually hit the eyes
+ if(prob(20))
+ C.attack_log += text("\[[time_stamp()]\] Has had a laser pointer shone in their eyes by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Shone a laser pointer in the eyes of [C.name] ([C.ckey])")
+ log_attack("[user.name] ([user.ckey]) Shone a laser pointer in the eyes of [C.name] ([C.ckey])")
+
+ //eye target check
+ outmsg = "You blind [C] by shining [src] in their eyes."
+ var/eye_prot = C.eyecheck()
+ if(C.blinded || eye_prot >= 2)
+ eye_prot = 4
+ var/severity = 3 - eye_prot
+ if(prob(33))
+ severity += 1
+ else if(prob(50))
+ severity -= 1
+ severity = min(max(severity, 0), 4)
+
+ switch(severity)
+ if(0)
+ //no effect
+ C << "A small, bright dot appears in your vision."
+ if(1)
+ //industrial grade eye protection
+ C.eye_stat += rand(0, 2)
+ C << "Something bright flashes in the corner of your vision!"
+ if(2)
+ //basic eye protection (sunglasses)
+ flick("flash", C.flash)
+ C.eye_stat += rand(1, 6)
+ C << "Your eyes were blinded!"
+ if(3)
+ //no eye protection
+ if(prob(2))
+ C.Weaken(1)
+ flick("e_flash", C.flash)
+ C.eye_stat += rand(3, 7)
+ C << "Your eyes were blinded!"
+ if(4)
+ //the effect has been worsened by something
+ if(prob(5))
+ C.Weaken(1)
+ flick("e_flash", C.flash)
+ C.eye_stat += rand(5, 10)
+ C << "Your eyes were blinded!"
+ else
+ outmsg = "You fail to blind [C] by shining [src] at their eyes."
+
+ //robots and AI
+ else if(issilicon(target))
+ var/mob/living/silicon/S = target
+ //20% chance to actually hit the sensors
+ if(prob(20))
+ S.Weaken(rand(5,10))
+ S << "Your sensors were overloaded by a laser!"
+ outmsg = "You overload [S] by shining [src] at their sensors."
+
+ S.attack_log += text("\[[time_stamp()]\] Has had a laser pointer shone in their eyes by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Shone a laser pointer in the eyes of [S.name] ([S.ckey])")
+ log_attack("[user.name] ([user.ckey]) Shone a laser pointer in the eyes of [S.name] ([S.ckey])")
+ else
+ outmsg = "You fail to overload [S] by shining [src] at their sensors."
+
+ //cameras
+ else if(istype(target, /obj/machinery/camera))
+ var/obj/machinery/camera/C = target
+ if(prob(20))
+ C.emp_act(1)
+ outmsg = "You hit the lens of [C] with [src], temporarily disabling the camera!"
+
+ log_admin("\[[time_stamp()]\] [user.name] ([user.ckey]) EMPd a camera with a laser pointer")
+ user.attack_log += text("\[[time_stamp()]\] [user.name] ([user.ckey]) EMPd a camera with a laser pointer")
+ else
+ outmsg = "You missed the lens of [C] with [src]."
+
+ //laser pointer image
+ icon_state = "pointer_[pointer_icon_state]"
+ var/list/showto = list()
+ for(var/mob/M in range(7,targloc))
+ if(M.client)
+ showto.Add(M.client)
+ var/image/I = image('icons/obj/projectiles.dmi',targloc,pointer_icon_state,10)
+ I.pixel_x = target.pixel_x + rand(-5,5)
+ I.pixel_y = target.pixel_y + rand(-5,5)
+
+ if(outmsg)
+ user << outmsg
+ else
+ user << "You point [src] at [target]."
+
+ energy -= 1
+ if(energy <= max_energy)
+ if(!recharging)
+ recharging = 1
+ processing_objects.Add(src)
+ if(energy <= 0)
+ user << "You've overused the battery of [src], now it needs time to recharge!"
+ recharge_locked = 1
+
+ flick_overlay(I, showto, 10)
+ icon_state = "pointer"
+
+/obj/item/device/laser_pointer/process()
+ if(prob(20 - recharge_locked*5))
+ energy += 1
+ if(energy >= max_energy)
+ energy = max_energy
+ recharging = 0
+ recharge_locked = 0
+ ..()
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
index dc515019ed4..63c020eb9e5 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -47,4 +47,5 @@
new /obj/item/clothing/mask/gas(src)
new /obj/item/clothing/suit/armor/reactive(src)
new /obj/item/device/flash(src)
+ new /obj/item/device/laser_pointer(src)
return
\ No newline at end of file
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 5fbeebf0eff..f1acede2711 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index e46afd477bd..2844889a4da 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/tgstation.dme b/tgstation.dme
index 1e73f208e6f..3748c773430 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -436,6 +436,7 @@
#include "code\game\objects\items\devices\chameleonproj.dm"
#include "code\game\objects\items\devices\flash.dm"
#include "code\game\objects\items\devices\flashlight.dm"
+#include "code\game\objects\items\devices\laserpointer.dm"
#include "code\game\objects\items\devices\lightreplacer.dm"
#include "code\game\objects\items\devices\multitool.dm"
#include "code\game\objects\items\devices\paicard.dm"