diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm
index 87f12d201e6..81b6adc491c 100644
--- a/code/game/jobs/job/security.dm
+++ b/code/game/jobs/job/security.dm
@@ -181,8 +181,7 @@ Security Officer
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(H), slot_wear_suit)
-// H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/sec(H), slot_head)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet(H), slot_head)
+ H.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/sec(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/black(H), slot_gloves)
H.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/device/flash/handheld(H), slot_l_store)
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index 1204393f095..5a6b904683f 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -392,7 +392,14 @@ Auto Patrol: []"},
..()
return
- if(type != /obj/item/clothing/head/helmet) //Eh, but we don't want people making secbots out of space helmets.
+ if(type != /obj/item/clothing/head/helmet/sec) //Eh, but we don't want people making secbots out of space helmets.
+ return
+
+ if(!helmetCam) //I am so sorry for this. I could not think of a less terrible (and lazy) way.
+ user << "[src] needs to have a camera attached first."
+ return
+ if(F) //Has a flashlight. Player must remove it, else it will be lost forever.
+ user << "The mounted flashlight is in the way, remove it first."
return
if(S.secured)
@@ -458,7 +465,7 @@ Auto Patrol: []"},
else if(istype(I, /obj/item/weapon/screwdriver))
if(!build_step)
new /obj/item/device/assembly/signaler(get_turf(src))
- new /obj/item/clothing/head/helmet(get_turf(src))
+ new /obj/item/clothing/head/helmet/sec(get_turf(src))
user << "You disconnect the signaler from the helmet."
qdel(src)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 7429e162871..f93b7f48696 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -331,3 +331,18 @@
return 1
busy = 0
return 0
+
+
+/obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets.
+ var/turf/prev_turf
+
+/obj/machinery/camera/portable/New()
+ ..()
+ assembly.state = 0 //These cameras are portable, and so shall be in the portable state if removed.
+ assembly.anchored = 0
+ assembly.update_icon()
+
+/obj/machinery/camera/portable/process() //Updates whenever the camera is moved.
+ if(cameranet && get_turf(src) != prev_turf)
+ cameranet.updatePortableCamera(src)
+ prev_turf = get_turf(src)
\ No newline at end of file
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 52390b586ab..230efee1fc6 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -9,6 +9,9 @@
righthand_file = 'icons/mob/inhands/clothing_righthand.dmi'
var/alt_desc = null
+ var/obj/item/device/flashlight/F = null
+ var/can_flashlight = 0
+
//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
name = "ears"
@@ -404,3 +407,4 @@ atom/proc/generate_female_clothing(index,t_color,icon,type)
if(!user.stat && user.canmove && !user.restrained())
return 1
return 0
+
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index d1b15282247..a80c9ab289b 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -11,6 +11,28 @@
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
strip_delay = 60
+ var/obj/machinery/camera/portable/helmetCam = null
+ var/spawnWithHelmetCam = 0
+ var/canAttachCam = 0
+
+
+/obj/item/clothing/head/helmet/New()
+ ..()
+ if(spawnWithHelmetCam)
+ helmetCam = new /obj/machinery/camera/portable(src)
+ helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])"
+ helmetCam.network = list("SS13")
+ update_icon()
+
+/obj/item/clothing/head/helmet/emp_act(severity)
+ if(helmetCam) //Transfer the EMP to the camera so you can still disable it this way.
+ helmetCam.emp_act(severity)
+ ..()
+
+/obj/item/clothing/head/helmet/sec
+ spawnWithHelmetCam = 1
+ canAttachCam = 1
+ can_flashlight = 1
/obj/item/clothing/head/helmet/alt
name = "bulletproof helmet"
@@ -115,3 +137,150 @@ obj/item/clothing/head/helmet/bluetaghelm
armor = list(melee = 30, bullet = 10, laser = 20,energy = 10, bomb = 20, bio = 0, rad = 0)
// Offer about the same protection as a hardhat.
flags_inv = HIDEEARS|HIDEEYES
+
+//LightToggle
+
+/obj/item/clothing/head/helmet/update_icon()
+
+ var/state = "[initial(icon_state)]"
+ if(helmetCam)
+ state += "-cam" //"helmet-cam"
+ if(F)
+ if(F.on)
+ state += "-flight-on" //"helmet-flight-on" // "helmet-cam-flight-on"
+ else
+ state += "-flight" //etc.
+
+ icon_state = state
+
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_head(0)
+
+ return
+
+/obj/item/clothing/head/helmet/ui_action_click()
+ toggle_helmlight()
+
+/obj/item/clothing/head/helmet/attackby(var/obj/item/A as obj, mob/user as mob, params)
+ if(istype(A, /obj/item/device/flashlight/seclite))
+ var/obj/item/device/flashlight/seclite/S = A
+ if(can_flashlight)
+ if(!F)
+ user.drop_item()
+ user << "You click [S] into place on [src]."
+ if(S.on)
+ SetLuminosity(0)
+ F = S
+ A.loc = src
+ update_icon()
+ update_helmlight(user)
+ verbs += /obj/item/clothing/head/helmet/proc/toggle_helmlight
+ return
+
+ if(istype(A, /obj/item/weapon/screwdriver))
+ if(F)
+ for(var/obj/item/device/flashlight/seclite/S in src)
+ user << "You unscrew the seclite from [src]."
+ F = null
+ S.loc = get_turf(user)
+ update_helmlight(user)
+ S.update_brightness(user)
+ update_icon()
+ usr.update_inv_head(0)
+ verbs -= /obj/item/clothing/head/helmet/proc/toggle_helmlight
+ return
+
+
+ if(istype(A, /obj/item/weapon/camera_assembly))
+ if(!canAttachCam)
+ user << "You can't attach [A] to [src]!"
+ return
+ if(helmetCam)
+ user << "[src] already has a mounted camera."
+ return
+ user.drop_item()
+ helmetCam = new /obj/machinery/camera/portable(src)
+ helmetCam.assembly = A
+ A.loc = helmetCam
+ helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])"
+ helmetCam.network = list("SS13")
+ update_icon()
+ user.visible_message("[user] attaches [A] to [src]","You attach [A] to [src]")
+ return
+
+ if(istype(A, /obj/item/weapon/crowbar))
+ if(!helmetCam)
+ ..()
+ return
+ user.visible_message("[user] removes [helmetCam] from [src]","You remove [helmetCam] from [src]")
+ helmetCam.assembly.loc = get_turf(src)
+ helmetCam.assembly = null
+ qdel(helmetCam)
+ helmetCam = null
+ update_icon()
+ return
+
+ ..()
+ return
+
+/obj/item/clothing/head/helmet/proc/toggle_helmlight()
+ set name = "Toggle Helmetlight"
+ set category = "Object"
+ set desc = "Click to toggle your helmet's attached flashlight."
+
+ if(!F)
+ return
+
+ var/mob/living/carbon/human/user = usr
+ if(!isturf(user.loc))
+ user << "You cannot turn the light on while in this [user.loc]."
+ F.on = !F.on
+ user << "You toggle the helmetlight [F.on ? "on":"off"]."
+
+ playsound(user, 'sound/weapons/empty.ogg', 100, 1)
+ update_helmlight(user)
+ return
+
+/obj/item/clothing/head/helmet/proc/update_helmlight(var/mob/user = null)
+ if(F)
+ action_button_name = "Toggle Helmetlight"
+ if(F.on)
+ if(loc == user)
+ user.AddLuminosity(F.brightness_on)
+ else if(isturf(loc))
+ SetLuminosity(F.brightness_on)
+ else
+ if(loc == user)
+ user.AddLuminosity(-F.brightness_on)
+ else if(isturf(loc))
+ SetLuminosity(0)
+ update_icon()
+ else
+ action_button_name = null
+ if(loc == user)
+ user.AddLuminosity(-5)
+ else if(isturf(loc))
+ SetLuminosity(0)
+ return
+
+/obj/item/clothing/head/helmet/pickup(mob/user)
+ if(F)
+ if(F.on)
+ user.AddLuminosity(F.brightness_on)
+ SetLuminosity(0)
+
+
+/obj/item/clothing/head/helmet/equipped(mob/user)
+ if(helmetCam)
+ spawn(10) //Gives time for the game to set a name (lol rhyme) to roundstart officers.
+ helmetCam.c_tag = "Helmet-Mounted Camera ([user.name])([rand(1,999)])"
+
+/obj/item/clothing/head/helmet/dropped(mob/user)
+ if(F)
+ if(F.on)
+ user.AddLuminosity(-F.brightness_on)
+ SetLuminosity(F.brightness_on)
+
+ if(helmetCam)
+ helmetCam.c_tag = "Helmet-Mounted Camera (No User)([rand(1,999)])"
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index c76fbd9c198..610f50c5642 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -11,6 +11,7 @@
action_button_name = "Toggle Helmet Light"
flags = HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP
+
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
if(!isturf(user.loc))
user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
@@ -57,6 +58,7 @@
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
+
/obj/item/clothing/suit/space/hardsuit/atmos
name = "atmospherics hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding."
@@ -79,6 +81,7 @@
heat_protection = HEAD //Uncomment to enable firesuit protection
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
+
/obj/item/clothing/suit/space/hardsuit/elite
icon_state = "hardsuit-white"
name = "advanced hardsuit"
@@ -100,6 +103,7 @@
armor = list(melee = 40, bullet = 5, laser = 10, energy = 5, bomb = 50, bio = 100, rad = 50)
brightness_on = 7
+
/obj/item/clothing/suit/space/hardsuit/mining
icon_state = "hardsuit-mining"
name = "mining hardsuit"
@@ -208,6 +212,7 @@
item_state = "s_helmet"
item_color = "owl"
+
/obj/item/clothing/suit/space/hardsuit/syndi/owl
name = "owl hardsuit"
desc = "A dual-mode advanced hardsuit designed for any crime-fighting situation. It is in travel mode."
@@ -231,6 +236,7 @@
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
unacidable = 1
+
/obj/item/clothing/suit/space/hardsuit/wizard
icon_state = "hardsuit-wiz"
name = "gem-encrusted hardsuit"
@@ -258,6 +264,7 @@
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES
armor = list(melee = 10, bullet = 5, laser = 10, energy = 5, bomb = 10, bio = 100, rad = 50)
+
/obj/item/clothing/suit/space/hardsuit/medical
icon_state = "hardsuit-medical"
name = "medical hardsuit"
@@ -278,6 +285,7 @@
item_color = "sec"
armor = list(melee = 30, bullet = 15, laser = 30,energy = 10, bomb = 10, bio = 100, rad = 50)
+
/obj/item/clothing/suit/space/hardsuit/security
icon_state = "hardsuit-sec"
name = "security hardsuit"
@@ -294,6 +302,7 @@
item_color = "hos"
armor = list(melee = 45, bullet = 25, laser = 30,energy = 10, bomb = 25, bio = 100, rad = 50)
+
/obj/item/clothing/suit/space/hardsuit/security/hos
icon_state = "hardsuit-hos"
name = "head of security's hardsuit"
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 177b23d1572..e9b2ab62b90 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -49,7 +49,7 @@
name = "Secbot"
result = /obj/machinery/bot/secbot
reqs = list(/obj/item/device/assembly/signaler = 1,
- /obj/item/clothing/head/helmet = 1,
+ /obj/item/clothing/head/helmet/sec = 1,
/obj/item/weapon/melee/baton = 1,
/obj/item/device/assembly/prox_sensor = 1,
/obj/item/robot_parts/r_arm = 1)
diff --git a/html/changelogs/Gun_Hog-RR-Steelpoint-PR-8439.yml b/html/changelogs/Gun_Hog-RR-Steelpoint-PR-8439.yml
new file mode 100644
index 00000000000..049a26b1027
--- /dev/null
+++ b/html/changelogs/Gun_Hog-RR-Steelpoint-PR-8439.yml
@@ -0,0 +1,11 @@
+
+# Your name.
+author: Steelpoint, RemieRichards, and Gun Hog
+
+
+delete-after: True
+
+
+changes:
+ - rscadd: "Nanotrasen Security has authorized modifications to the standard issue helmets for officers. These helmets are now issued with a mounted camera, automatically synced to your assigned station's camera network. In addition, the helmets also include mounting points for the Seclite model of flashlights, found in your station's security vendors."
+ - rscadd: "Nanotrasen Security helmets are designed for easy repairs in the field. Officers may remove their Seclite attachment with any screwdriver, and the camera's assembly may be pried off with a crowbar. The assembly is also compatible with analyzer upgrades for scanning through the station's structure, and EMP shielding is possible by applying a sheet of plasma.
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index b8eedb8f334..9c6a3ea0254 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 276aaa7e525..c4d3174916f 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ