diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 8ff52bdddda..06f4b2b3190 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -89,6 +89,7 @@
if(istype(O,/obj/item/device/flash))
if(O:broken)
O:broken = 0
+ O:times_used = 0
O:icon_state = "flash"
if(istype(O,/obj/item/weapon/gun/energy/taser/cyborg))
if(O:power_supply.charge < O:power_supply.maxcharge)
diff --git a/code/game/objects/devices/flash.dm b/code/game/objects/devices/flash.dm
index 0d0c9bbcd4f..3485a6c940f 100644
--- a/code/game/objects/devices/flash.dm
+++ b/code/game/objects/devices/flash.dm
@@ -10,170 +10,185 @@
item_state = "electronic"
origin_tech = "magnets=2;combat=1"
- var
- shots_left = 5
- max_shots = 5
- broken = 0
+ var/times_used = 0 //Number of times it's been used.
+ var/broken = 0 //Is the flash burnt out?
+ var/last_used = 0 //last world.time it was used.
- proc
- clown_check(var/mob/user)
- recharge()
+/obj/item/device/flash/proc/clown_check(var/mob/user)
+ if(user && (user.mutations & CLUMSY) && prob(50))
+ user << "\red The Flash slips out of your hand."
+ user.drop_item()
+ return 0
+ return 1
+
+/obj/item/device/flash/proc/flash_recharge()
+ //capacitor recharges over time
+ for(var/i=0, i<3, i++)
+ if(last_used+600 > world.time)
+ break
+ last_used += 600
+ times_used -= 2
+ last_used = world.time
+ times_used = max(0,round(times_used)) //sanity
+/obj/item/device/flash/attack(mob/living/M as mob, mob/user as mob)
+ if(!user || !M) return //sanity
+ M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])")
+
+ log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
+ message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
+ log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey])")
- attack(mob/living/M as mob, mob/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has been flashed (attempt) with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to flash [M.name] ([M.ckey])")
+ if(!clown_check(user)) return
+ if(broken)
+ user.show_message("The [src.name] is broken.", 2)
+ return
- log_admin("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
- message_admins("ATTACK: [user] ([user.ckey]) flashed [M] ([M.ckey]) with [src].")
- log_attack("[user.name] ([user.ckey]) Used the [src.name] to flash [M.name] ([M.ckey])")
+ flash_recharge()
- if(!clown_check(user)) return
- if(broken)
- user.show_message("\red The [src.name] is broken", 2)
- return
-
- if(shots_left <= 0)
- user.show_message("\red *click* *click*", 2)
+ //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
+ //It will never break on the first use.
+ switch(times_used)
+ if(0 to 5)
+ last_used = world.time
+ if(prob(times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
+ broken = 1
+ user << "The bulb has burnt out!"
+ icon_state = "flashburnt"
+ return
+ times_used++
+ else //can only use it 5 times a minute
+ user.show_message("*click* *click*", 2)
for(var/mob/K in viewers(usr))
K << 'empty.ogg'
return
+ playsound(src.loc, 'flash.ogg', 100, 1)
+ var/flashfail = 0
- playsound(src.loc, 'flash.ogg', 100, 1)
- shots_left--
- var/flashfail = 0
+ if(iscarbon(M))
+ var/safety = M:eyecheck()
+ if(safety <= 0)
+ M.Weaken(10)
+ flick("e_flash", M.flash)
- if(iscarbon(M))
- var/safety = M:eyecheck()
- if(safety <= 0)
- M.Weaken(10)
- flick("e_flash", M.flash)
-
- if(ishuman(M) && ishuman(user))
- if(user.mind in ticker.mode.head_revolutionaries)
- var/revsafe = 0
- for(var/datum/organ/external/O in M.organs)
- for(var/obj/item/weapon/implant/loyalty/L in O.implant)
- if(L && L.implanted)
- revsafe = 1
- break
+ if(ishuman(M) && ishuman(user) && M.stat!=DEAD)
+ if(user.mind && user.mind in ticker.mode.head_revolutionaries)
+ var/revsafe = 0
+ for(var/obj/item/weapon/implant/loyalty/L in M)
+ if(L && L.implanted)
+ revsafe = 1
+ break
+ M:update_mind() //give them a mind datum if they don't have one. won't work if they are logged out/ghosted or something.
+ if(M.mind)
if(M.mind.has_been_rev)
revsafe = 2
if(!revsafe)
M.mind.has_been_rev = 1
ticker.mode.add_revolutionary(M.mind)
else if(revsafe == 1)
- user << "\red Something seems to be blocking the flash!"
+ user << "Something seems to be blocking the flash!"
else
- user << "\red This mind seems resistant to the flash!"
- else
- flashfail = 1
-
- else if(issilicon(M))
- M.Weaken(rand(5,10))
-
- if(isrobot(user))
- spawn(0)
- var/atom/movable/overlay/animation = new(user.loc)
- animation.layer = user.layer + 1
- animation.icon_state = "blank"
- animation.icon = 'mob.dmi'
- animation.master = user
- flick("blspell", animation)
- sleep(5)
- del(animation)
-
-
- if(!flashfail)
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\red [] blinds [] with the flash!", user, M))
+ user << "This mind seems resistant to the flash!"
+ user << "This mind is so vacant that it is not susceptible to influence!"
else
- for(var/mob/O in viewers(user, null))
- O.show_message(text("\blue [] fails to blind [] with the flash!", user, M))
+ flashfail = 1
+ else if(issilicon(M))
+ if(!M:flashproof())
+ M.Weaken(rand(5,10))
+ else
+ flashfail++
+ if(isrobot(user))
+ spawn(0)
+ var/atom/movable/overlay/animation = new(user.loc)
+ animation.layer = user.layer + 1
+ animation.icon_state = "blank"
+ animation.icon = 'mob.dmi'
+ animation.master = user
+ flick("blspell", animation)
+ sleep(5)
+ del(animation)
- if (prob(2))
- broken = 1
- user << "\red The bulb has burnt out!"
- icon_state = "flashburnt"
-
- spawn(60)
- recharge()
-
- return
-
-
- attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
- if(!emp)
- if (!clown_check(user)) return
- if(broken)
- if(user)
- user.show_message("\red The [src.name] is broken", 2)
- return
-
- if(shots_left <= 0)
- if(user)
- user.show_message("\red *click* *click*", 2)
- return
-
- playsound(src.loc, 'flash.ogg', 100, 1)
- shots_left--
-
+ if(!flashfail)
flick("flash2", src)
- if(isrobot(user))
- spawn(0)
- var/atom/movable/overlay/animation = new(user.loc)
- animation.layer = user.layer + 1
- animation.icon_state = "blank"
- animation.icon = 'mob.dmi'
- animation.master = user
- flick("blspell", animation)
- sleep(5)
- del(animation)
+ for(var/mob/O in viewers(user, null))
+ O.show_message("[user] blinds [M] with the flash!")
+ else
+ for(var/mob/O in viewers(user, null))
+ O.show_message("[user] fails to blind [M] with the flash!")
+ return
- for(var/mob/living/carbon/M in oviewers(3, null))
- if(prob(50))
- if (locate(/obj/item/weapon/cloaking_device, M))
- for(var/obj/item/weapon/cloaking_device/S in M)
- S.active = 0
- S.icon_state = "shield0"
- var/safety = M:eyecheck()
- if(!safety)
- flick("flash", M.flash)
- if (prob(2))
- broken = 1
- icon_state = "flashburnt"
- if(user)
- user << "\red The bulb has burnt out!"
- return
- spawn(60)
- recharge()
+/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
+ if(!user || !clown_check(user)) return
+ if(broken)
+ user.show_message("The [src.name] is broken", 2)
return
+ flash_recharge()
- emp_act(severity)
- src.attack_self(null,1,1)
- ..()
+ //spamming the flash before it's fully charged (60seconds) increases the chance of it breaking
+ //It will never break on the first use.
+ switch(times_used)
+ if(0 to 5)
+ if(prob(2*times_used)) //if you use it 5 times in a minute it has a 10% chance to break!
+ broken = 1
+ user << "The bulb has burnt out!"
+ icon_state = "flashburnt"
+ return
+ times_used++
+ else //can only use it 5 times a minute
+ user.show_message("*click* *click*", 2)
+ for(var/mob/K in viewers(usr))
+ K << 'empty.ogg'
+ return
+ playsound(src.loc, 'flash.ogg', 100, 1)
+ flick("flash2", src)
+ if(user && isrobot(user))
+ spawn(0)
+ var/atom/movable/overlay/animation = new(user.loc)
+ animation.layer = user.layer + 1
+ animation.icon_state = "blank"
+ animation.icon = 'mob.dmi'
+ animation.master = user
+ flick("blspell", animation)
+ sleep(5)
+ del(animation)
+ for(var/mob/living/carbon/M in oviewers(3, null))
+ if(prob(50))
+ if (locate(/obj/item/weapon/cloaking_device, M))
+ for(var/obj/item/weapon/cloaking_device/S in M)
+ S.active = 0
+ S.icon_state = "shield0"
+ var/safety = M:eyecheck()
+ if(!safety)
+ flick("flash", M.flash)
- clown_check(var/mob/user)
- if((user.mutations & CLUMSY) && prob(50))
- user << "\red The Flash slips out of your hand."
- user.drop_item()
- return 0
- return 1
+ return
-
- recharge()
- if(max_shots > shots_left)
- shots_left++
- if(max_shots > shots_left)
- spawn(60)//more or less 10 seconds
- recharge()
- return
\ No newline at end of file
+/obj/item/device/flash/emp_act(severity)
+ if(broken) return
+ flash_recharge()
+ switch(times_used)
+ if(0 to 5)
+ if(prob(2*times_used))
+ broken = 1
+ icon_state = "flashburnt"
+ return
+ times_used++
+ if(istype(loc, /mob/living/carbon))
+ var/mob/living/carbon/M = loc
+ var/safety = M.eyecheck()
+ if(safety <= 0)
+ M.Weaken(10)
+ flick("e_flash", M.flash)
+ for(var/mob/O in viewers(M, null))
+ O.show_message("[M] is blinded by the flash!")
+ ..()
diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm
index d9cdc9be652..cd6ef81420c 100644
--- a/code/modules/admin/banjob.dm
+++ b/code/modules/admin/banjob.dm
@@ -3,7 +3,7 @@ var
jobban_keylist[0] //to store the keys & ranks
/proc/jobban_fullban(mob/M, rank, reason)
- if (!M || !M.key || !M.client) return
+ if (!M || !M.key) return
jobban_keylist.Add(text("[M.ckey] - [rank] ## [reason]"))
jobban_savebanfile()
@@ -12,19 +12,25 @@ var
jobban_keylist.Add(text("[ckey] - [rank]"))
jobban_savebanfile()
+//returns a reason if M is banned from rank, returns 0 otherwise
/proc/jobban_isbanned(mob/M, rank)
- if(_jobban_isbanned(M, rank)) return 1//for old jobban
- if(M)
+ if(M && rank)
+ if(_jobban_isbanned(M, rank)) return "Reason Unspecified" //for old jobban
if (guest_jobbans(rank))
if(config.guest_jobban && IsGuestKey(M.key))
- return 1
+ return "Guest Job-ban"
if(config.usewhitelist && !check_whitelist(M))
- return 1
+ return "Whitelisted Job"
for (var/s in jobban_keylist)
if( findtext(s,"[M.ckey] - [rank]") )
- return 1
- return 0
+ var/startpos = findtext(s, "## ")+3
+ if(startpos && startpos