diff --git a/_maps/map_files/stations/boxstation.dmm b/_maps/map_files/stations/boxstation.dmm
index a0ecf52a0ab..50f6f616a00 100644
--- a/_maps/map_files/stations/boxstation.dmm
+++ b/_maps/map_files/stations/boxstation.dmm
@@ -28304,10 +28304,10 @@
pixel_x = -8;
pixel_y = 4
},
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
/obj/item/multitool{
pixel_x = 3
},
@@ -28937,10 +28937,10 @@
pixel_x = -8;
pixel_y = 4
},
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
/obj/item/multitool{
pixel_x = 3
},
diff --git a/_maps/map_files/stations/cerestation.dmm b/_maps/map_files/stations/cerestation.dmm
index 53d30bf966a..0208324f3d9 100644
--- a/_maps/map_files/stations/cerestation.dmm
+++ b/_maps/map_files/stations/cerestation.dmm
@@ -89155,13 +89155,13 @@
},
/obj/item/multitool,
/obj/item/multitool,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
-/obj/item/flash/synthetic,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
+/obj/item/flash,
/turf/simulated/floor/plasteel{
dir = 1;
icon_state = "darkpurple"
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 6a96e40bc1b..e52f5fd5e66 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -13,32 +13,40 @@
materials = list(MAT_METAL = 300, MAT_GLASS = 300)
origin_tech = "magnets=2;combat=1"
- var/times_used = 0 //Number of times it's been used.
- var/broken = FALSE //Is the flash burnt out?
- var/last_used = 0 //last world.time it was used.
- var/battery_panel = FALSE //whether the flash can be modified with a cell or not
- var/overcharged = FALSE //if overcharged the flash will set people on fire then immediately burn out (does so even if it doesn't blind them).
- var/can_overcharge = TRUE //set this to FALSE if you don't want your flash to be overcharge capable
- ///This tracks the world.time until the flash can be used again
- var/cooldown
- ///This is the duration of the cooldown
- var/cooldown_duration = 5 SECONDS
- var/use_sound = 'sound/weapons/flash.ogg'
+ /// Is the flash burnt out?
+ var/broken = FALSE
+ /// Whether the flash can be modified with a cell or not
+ var/battery_panel = FALSE
+ /// If overcharged the flash will set people on fire then immediately burn out (does so even if it doesn't blind them).
+ var/overcharged = FALSE
+ /// Set this to FALSE if you don't want your flash to be overcharge capable
+ var/can_overcharge = TRUE
+ /// How many times have we used the flash recently
+ var/times_used = 0
+ /// What is the max amount we can use this flash before it burns out
+ var/max_uses = 5
+ /// A reference to the timer used to recharge. If we use it while it's on cooldown, we reset the cooling
+ var/flash_timer
+ /// How long do we have between flashes
+ var/time_between_flashes = 5 SECONDS
-/obj/item/flash/proc/clown_check(mob/user)
- if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
- flash_carbon(user, user, 30 SECONDS, 0)
- return FALSE
- return TRUE
+ var/use_sound = 'sound/weapons/flash.ogg'
+ COOLDOWN_DECLARE(flash_cooldown)
/obj/item/flash/attackby(obj/item/I, mob/user, params)
- if(can_overcharge)
- if(battery_panel && !overcharged)
- if(istype(I, /obj/item/stock_parts/cell))
- to_chat(user, "You jam [I] into the battery compartment on [src].")
- qdel(I)
- overcharged = TRUE
- add_overlay("overcharge")
+ if(!can_overcharge || !istype(I, /obj/item/stock_parts/cell))
+ return
+
+ if(battery_panel && !overcharged)
+ to_chat(user, "You jam [I] into the battery compartment on [src].")
+ qdel(I)
+ overcharged = TRUE
+ update_icon(UPDATE_OVERLAYS)
+
+/obj/item/flash/update_overlays()
+ . = ..()
+ if(overcharged)
+ add_overlay("overcharge")
/obj/item/flash/screwdriver_act(mob/living/user, obj/item/I)
if(!can_overcharge)
@@ -51,54 +59,52 @@
battery_panel = !battery_panel
return TRUE
-/obj/item/flash/random/New()
- ..()
- if(prob(25))
- broken = TRUE
- icon_state = "[initial(icon_state)]burnt"
-
/obj/item/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
broken = TRUE
icon_state = "[initial(icon_state)]burnt"
visible_message("[src] burns out!")
-
-/obj/item/flash/proc/flash_recharge(mob/user)
- if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break!
- burn_out()
- return FALSE
-
- var/deciseconds_passed = world.time - last_used
- for(var/seconds = deciseconds_passed/10, seconds>=10, seconds-=10) //get 1 charge every 10 seconds
- times_used--
-
- last_used = world.time
- times_used = max(0, times_used) //sanity
-
-
/obj/item/flash/proc/try_use_flash(mob/user)
if(broken)
return FALSE
- if(cooldown >= world.time && user)
+ if(!COOLDOWN_FINISHED(src, flash_cooldown) && user)
to_chat(user, "Your [name] is still too hot to use again!")
return FALSE
- cooldown = world.time + cooldown_duration
- flash_recharge(user)
- playsound(loc, use_sound, 100, 1)
+ . = TRUE
+ COOLDOWN_START(src, flash_cooldown, time_between_flashes)
+ if(!flash_timer)
+ flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE)
+ else
+ // The flash can't cool down if you overheat it again!
+ deltimer(flash_timer)
+ flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE)
+
+ playsound(loc, use_sound, 100, TRUE)
+
flick("[initial(icon_state)]2", src)
set_light(2, 1, COLOR_WHITE)
- addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2)
- times_used++
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2 DECISECONDS)
- if(user && !clown_check(user))
+ times_used++
+ if(times_used == (max_uses - 1))
+ to_chat(user, "[src] is getting dangerously hot! Don't use it for a few seconds or it will burn out!")
+ else if(times_used == max_uses)
+ burn_out()
+
+ if(user && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
+ flash_carbon(user, user, 30 SECONDS, 0)
return FALSE
- return TRUE
+/obj/item/flash/proc/flash_recharge(mob/user)
+ times_used = max(0, times_used - 1)
+ if(times_used)
+ flash_timer = addtimer(CALLBACK(src, PROC_REF(flash_recharge)), 10 SECONDS, TIMER_STOPPABLE)
+ else
+ flash_timer = null
-
-/obj/item/flash/proc/flash_carbon(mob/living/carbon/M, mob/user = null, power = 10 SECONDS, targeted = 1)
+/obj/item/flash/proc/flash_carbon(mob/living/carbon/M, mob/user, power = 10 SECONDS, targeted = TRUE)
if(user)
add_attack_logs(user, M, "Flashed with [src]")
if(targeted)
@@ -151,7 +157,6 @@
user.create_attack_log("[key_name(user)] EMPd a camera with a flash")
add_attack_logs(user, C, "EMPd with [src]", ATKLOG_ALL)
-
/obj/item/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
if(!try_use_flash(user))
return FALSE
@@ -164,15 +169,13 @@
user.create_attack_log("[key_name(user)] EMPd a camera with a flash")
add_attack_logs(user, C, "EMPd with [src]", ATKLOG_ALL)
-
/obj/item/flash/emp_act(severity)
if(!try_use_flash())
return FALSE
for(var/mob/living/carbon/M in viewers(3, null))
flash_carbon(M, null, 20 SECONDS, 0)
burn_out()
- ..()
-
+ return ..()
/obj/item/flash/proc/revolution_conversion(mob/M, mob/user)
if(!ishuman(M) || !user.mind?.has_antag_datum(/datum/antagonist/rev/head))
@@ -247,7 +250,7 @@
if(charge_tick < 10)
return FALSE
charge_tick = 0
- flash_cur_charges = min(flash_cur_charges+1, flash_max_charges)
+ flash_cur_charges = min(flash_cur_charges + 1, flash_max_charges)
return TRUE
/obj/item/flash/cameraflash/try_use_flash(mob/user = null)
@@ -261,15 +264,15 @@
/obj/item/flash/memorizer
name = "memorizer"
- desc = "If you see this, you're not likely to remember it any time soon."
+ desc = "If you see this, you're not likely to remember it any time soon." // Why doesn't this at least delete your notes smh
icon_state = "memorizer"
item_state = "nullrod"
/obj/item/flash/armimplant
name = "photon projector"
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocols fix the flashbulb if it ever burns out."
- cooldown_duration = 2 SECONDS
- var/obj/item/organ/internal/cyberimp/arm/implant = null
+ time_between_flashes = 2 SECONDS
+ var/obj/item/organ/internal/cyberimp/arm/implant
/obj/item/flash/armimplant/burn_out()
if(implant?.owner)
@@ -280,5 +283,8 @@
implant = null
return ..()
-/// just a regular flash now
-/obj/item/flash/synthetic
+/obj/item/flash/random/Initialize(mapload)
+ . = ..()
+ if(prob(25))
+ broken = TRUE
+ icon_state = "[initial(icon_state)]burnt"
diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm
index 19fc6461988..214f12af72d 100644
--- a/code/modules/research/designs/mechfabricator_designs.dm
+++ b/code/modules/research/designs/mechfabricator_designs.dm
@@ -1255,14 +1255,14 @@
category = list("Misc")
/datum/design/synthetic_flash
- name = "Synthetic Flash"
- desc = "A synthetic flash used mostly in borg construction."
- id = "sflash"
+ name = "Flash"
+ desc = "A flash used mostly in borg construction."
+ id = "sflash" // Keeping this ID as is because we might have something tracking it
req_tech = list("magnets" = 3, "combat" = 2)
build_type = MECHFAB
materials = list(MAT_METAL = 750, MAT_GLASS = 750)
construction_time = 10 SECONDS
- build_path = /obj/item/flash/synthetic
+ build_path = /obj/item/flash
category = list("Misc")
/datum/design/voice_standard