From 35388d501d115b0e23874b5111f2b1723dad50a7 Mon Sep 17 00:00:00 2001 From: Ren Erthilo Date: Thu, 26 Apr 2012 23:14:02 +0100 Subject: [PATCH] TG: Updates handheld-flashes so that they cannot break on their first use. Their chance of breaking is directly proportional to their frequency of use (ranges from 0% to 5%, used to be a blanket 2%). Their capacitor recharges one charge every 60 seconds. Once their 6 charges are used up, they temporarily stop working whilst their capacitor recharges. This should mean that flashes will last a long time with light use (defence/rev), but not for spamming (shitcurity). Can now job-ban people from entire departments through the jobban panel. Can now job-ban people even if they log out. Job-ban panel now informs you why people were banned from each job. Runtime fixes for some old jobban code that was preventing the above stuff. Committing some fixes Nodrak pointed out. Credits go to Nodrak for a lot of this. Revision: r3285 Author: elly1...@rocketmail.com --- code/game/machinery/rechargestation.dm | 1 + code/game/objects/devices/flash.dm | 281 +++++++++++++------------ code/modules/admin/banjob.dm | 22 +- 3 files changed, 163 insertions(+), 141 deletions(-) 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