From 427313e0ad75990a687c96a4d562a51962e014ef Mon Sep 17 00:00:00 2001 From: "rastaf.zero@gmail.com" Date: Thu, 27 Jan 2011 16:40:36 +0000 Subject: [PATCH] Shocking overhaul. Fixed bugs are: - shocking by autolathe, vendomats and airlocks works if powernet has power OR if APC has charged battery; - autolathe able to shock without cable underneath; - improvements from Barhandar and Errorage are included; - making stungloves may electrocute you; - handmade stungloves partially loses insulating; Eliminated 4-seconds lag caused by all apcs changing state to "fully charged" after first few minutes of game. Fixed message "The airlock's motors resist your efforts to pry it open." Latest innovations in nanotechnologies! Matchbox now fits in pocket! Fixed burn_skin(), so containment field now hurt people properly. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@919 316c924e-a436-60f5-8080-3fe189b3f50e --- code/defines/obj/weapon.dm | 2 + code/game/machinery/autolathe.dm | 37 +++-- code/game/machinery/computer/computer.dm | 45 ------ code/game/machinery/doors/airlock.dm | 108 ++----------- code/game/machinery/machinery.dm | 77 +++++++++ code/game/machinery/main.dm | 30 ---- code/game/machinery/vending.dm | 71 +-------- code/game/objects/grille.dm | 27 +--- code/game/objects/items/apc_frame.dm | 7 +- code/modules/mob/living/carbon/carbon.dm | 19 ++- code/modules/mob/living/carbon/human/human.dm | 6 + code/modules/mob/mob.dm | 12 +- code/modules/power/apc.dm | 146 +++++------------- code/modules/power/cable.dm | 71 +-------- code/modules/power/cell.dm | 25 +++ code/modules/power/lighting.dm | 12 +- code/modules/power/power.dm | 85 +++++++++- tgstation.dme | 2 +- 18 files changed, 320 insertions(+), 462 deletions(-) create mode 100644 code/game/machinery/machinery.dm delete mode 100644 code/game/machinery/main.dm diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 114b2258084..ed41cca28a4 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -26,6 +26,7 @@ icon_state = "match_unlit" var/lit = 0 var/smoketime = 5 + w_class = 1.0 /obj/item/weapon/matchbox name = "Matchbox" @@ -33,6 +34,7 @@ icon = 'cigarettes.dmi' icon_state = "matchbox" var/matchcount = 10 + w_class = 1.0 /obj/item/weapon/rcd name = "rapid-construction-device (RCD)" diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index e8611fe3d09..dba9959e060 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -121,9 +121,9 @@ if(..()) return if (src.shocked) - src.shock(user) + src.shock(user,50) if (src.opened) - wires_win(user) + wires_win(user,50) return if (src.disabled) user << "\red You press the button, but nothing happens." @@ -178,11 +178,11 @@ spawn(100) src.hacked = !src.hacked if(src.disable_wire == href_list["wire"]) src.disabled = !src.disabled - src.shock(usr) + src.shock(usr,50) spawn(100) src.disabled = !src.disabled if(src.shock_wire == href_list["wire"]) src.shocked = !src.shocked - src.shock(usr) + src.shock(usr,50) spawn(100) src.shocked = !src.shocked if(href_list["act"] == "wire") if (!istype(usr.equipped(), /obj/item/weapon/wirecutters)) @@ -192,10 +192,10 @@ src.hacked = !src.hacked if(src.disable_wire == href_list["wire"]) src.disabled = !src.disabled - src.shock(usr) + src.shock(usr,50) if(src.shock_wire == href_list["wire"]) src.shocked = !src.shocked - src.shock(usr) + src.shock(usr,50) else usr << "\red The autolathe is busy. Please wait for completion of previous operation." src.updateUsrDialog() @@ -263,16 +263,15 @@ var/global/list/autolathe_recipes_hidden = list( \ src.disable_wire = pick(w) w -= src.disable_wire -/obj/machinery/autolathe/proc/get_connection() - var/turf/T = src.loc - if(!istype(T, /turf/simulated/floor)) - return - - for(var/obj/cable/C in T) - if(C.d1 == 0) - return C.netnum - - return 0 - -/obj/machinery/autolathe/proc/shock(M as mob) - return src.electrocute(M, 50, get_connection()) \ No newline at end of file +/obj/machinery/autolathe/proc/shock(mob/user, prb) + if(stat & (BROKEN|NOPOWER)) // unpowered, no shock + return 0 + if(!prob(prb)) + return 0 + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() + if (electrocute_mob(user, get_area(src), src)) + return 1 + else + return 0 \ No newline at end of file diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 89893774502..fdfd5369dbf 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -6,51 +6,6 @@ ID Computer Pod/Blast Doors computer */ -/obj/machinery/Topic(href, href_list) - ..() - if(stat & (NOPOWER|BROKEN)) - return 1 - if(usr.restrained() || usr.lying || usr.stat) - return 1 - if ( ! (istype(usr, /mob/living/carbon/human) || \ - istype(usr, /mob/living/silicon) || \ - istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) - usr << "\red You don't have the dexterity to do this!" - return 1 - if ((!in_range(src, usr) || !istype(src.loc, /turf)) && !istype(usr, /mob/living/silicon)) - return 1 - src.add_fingerprint(usr) - return 0 - -/obj/machinery/attack_ai(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/attack_paw(mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/attack_hand(mob/user as mob) - if(stat & (NOPOWER|BROKEN|MAINT)) - return 1 - if(user.lying || user.stat) - return 1 - if ( ! (istype(usr, /mob/living/carbon/human) || \ - istype(usr, /mob/living/silicon) || \ - istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) - usr << "\red You don't have the dexterity to do this!" - return 1 - if ((get_dist(src, user) > 1 || !istype(src.loc, /turf)) && !istype(user, /mob/living/silicon)) - return 1 - if (ishuman(user)) - if(user.brainloss >= 60) - for(var/mob/M in viewers(src, null)) - M << "\red [user] stares cluelessly at [src] and drools." - return 1 - else if(prob(user.brainloss)) - user << "\red You momentarily forget how to use [src]." - return 1 - - src.add_fingerprint(user) - return 0 /obj/machinery/computer/meteorhit(var/obj/O as obj) for(var/x in src.verbs) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 0b639961a94..6b1bbfb5108 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -147,7 +147,7 @@ About the new airlock wires panel: spawn (10) src.justzap = 0 return - else if (src.justzap) + else /*if (src.justzap)*/ return ..(user) @@ -173,8 +173,8 @@ About the new airlock wires panel: else if(src.arePowerSystemsOn()) //only can raise bolts if power's on src.locked = 0 + usr << "You hear a click from inside the door." src.updateUsrDialog() - usr << "You hear a click from inside the door." update_icon() if (AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) @@ -347,108 +347,22 @@ About the new airlock wires panel: if (src.secondsBackupPowerLost > 0) src.secondsBackupPowerLost = 0 -//borrowed from the grille's get_connection -/obj/machinery/door/airlock/proc/get_connection() - var/netnumber = 0 - if(stat & NOPOWER) return 0 - var/turf/TU = src.loc - if (!TU) return 0 - var/area/A = TU.loc - if (!A) return 0 - for(var/area/RA in A.related) - for(var/obj/machinery/power/apc/APC in RA) - var/obj/machinery/power/terminal/T = APC.terminal - netnumber = T.netnum - return netnumber - return 0 - // shock user with probability prb (if all connections & power are working) // returns 1 if shocked, 0 otherwise // The preceding comment was borrowed from the grille's shock script /obj/machinery/door/airlock/proc/shock(mob/user, prb) - - + if((stat & (NOPOWER)) || !src.arePowerSystemsOn()) // unpowered, no shock + return 0 if(!prob(prb)) return 0 //you lucked out, no shock for you - - var/net = get_connection() // find the powernet of the connected cable - - if(!net) // cable is unpowered - return 0 - - - if (src.airlockelectrocute(user, prb, net)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() //sparks always. + if (electrocute_mob(user, get_area(src), src)) return 1 else return 0 -/obj/machinery/door/airlock/proc/airlockelectrocute(mob/user, prb, netnum) - //You're probably getting shocked deal w/ it - - if (prob(min(100,max(0,100-prb)))) - return 0 - - if(!netnum) // unconnected cable is unpowered - return 0 - - if(!((src.arePowerSystemsOn() && !(stat & NOPOWER)))) - return - - var/prot = 1 - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - - prot = G.siemens_coefficient - else if (istype(user, /mob/living/silicon)) - return 0 - - var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(5, 1, src) - s.start() - - if(prot == 0) // elec insulted gloves protect completely - return 0 - - //ok you're getting shocked now - var/datum/powernet/PN // find the powernet - if(powernets && powernets.len >= netnum) - PN = powernets[netnum] - - var/shock_damage = 0 - if(PN.avail > 750000) //someone juiced up the grid enough, people going to die! - shock_damage = min(rand(70,145),rand(70,145))*prot - else if(PN.avail > 100000) - shock_damage = min(rand(35,110),rand(35,110))*prot - else if(PN.avail > 75000) - shock_damage = min(rand(30,100),rand(30,100))*prot - else if(PN.avail > 50000) - shock_damage = min(rand(25,90),rand(25,90))*prot - else if(PN.avail > 25000) - shock_damage = min(rand(20,80),rand(20,80))*prot - else if(PN.avail > 10000) - shock_damage = min(rand(20,65),rand(20,65))*prot - else - shock_damage = min(rand(20,45),rand(20,45))*prot - -// message_admins("\blue ADMIN: DEBUG: shock_damage = [shock_damage] PN.avail = [PN.avail] user = [user] netnum = [netnum]") - - user.burn_skin(shock_damage) - user.fireloss += shock_damage - user.updatehealth() - user << "\red You feel a powerful shock course through your body!" - sleep(1) - - if(user.stunned < shock_damage) user.stunned = shock_damage - if(user.weakened < 20*prot) user.weakened = 20*prot - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red [user.name] was shocked by the [src.name]!", 3, "\red You hear a heavy electrical crack", 2) - return 1 - /obj/machinery/door/airlock/update_icon() if(overlays) overlays = null @@ -878,7 +792,6 @@ About the new airlock wires panel: /obj/machinery/door/airlock/attackby(C as obj, mob/user as mob) //world << text("airlock attackby src [] obj [] mob []", src, C, user) - var/turf/T = get_turf(user) if (!istype(usr, /mob/living/silicon)) if (src.isElectrified()) if(src.shock(user, 75)) @@ -913,8 +826,7 @@ About the new airlock wires panel: if ((src.density) && ( src.welded ) && !( src.operating ) && src.p_open && (!src.arePowerSystemsOn() || (stat & NOPOWER)) && !src.locked) playsound(src.loc, 'Crowbar.ogg', 100, 1) user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics into the airlock assembly.") - sleep(40) - if(get_turf(user) == T) + if(do_after(user,40)) user << "\blue You removed the airlock electronics!" switch(src.doortype) if(0) new/obj/door_assembly/door_assembly_0( src.loc ) @@ -936,7 +848,7 @@ About the new airlock wires panel: del(src) return - else if (src.arePowerSystemsOn() || !(stat & NOPOWER)) + else if (src.arePowerSystemsOn() && !(stat & NOPOWER)) user << "\blue The airlock's motors resist your efforts to pry it open." else if (src.locked) user << "\blue The airlock's bolts prevent it from being pried open." diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm new file mode 100644 index 00000000000..d493a5bdbb6 --- /dev/null +++ b/code/game/machinery/machinery.dm @@ -0,0 +1,77 @@ +/obj/machinery/New() + ..() + machines.Add(src) + +/obj/machinery/Del() + machines.Remove(src) + ..() + +/obj/machinery/proc/process() + return + +/obj/machinery/ex_act(severity) + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(50)) + del(src) + return + if(3.0) + if (prob(25)) + del(src) + return + else + return + +/obj/machinery/blob_act() + if(prob(50)) + del(src) + + +/obj/machinery/Topic(href, href_list) + ..() + if(stat & (NOPOWER|BROKEN)) + return 1 + if(usr.restrained() || usr.lying || usr.stat) + return 1 + if ( ! (istype(usr, /mob/living/carbon/human) || \ + istype(usr, /mob/living/silicon) || \ + istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) + usr << "\red You don't have the dexterity to do this!" + return 1 + if ((!in_range(src, usr) || !istype(src.loc, /turf)) && !istype(usr, /mob/living/silicon)) + return 1 + src.add_fingerprint(usr) + return 0 + +/obj/machinery/attack_ai(mob/user as mob) + return src.attack_hand(user) + +/obj/machinery/attack_paw(mob/user as mob) + return src.attack_hand(user) + +/obj/machinery/attack_hand(mob/user as mob) + if(stat & (NOPOWER|BROKEN|MAINT)) + return 1 + if(user.lying || user.stat) + return 1 + if ( ! (istype(usr, /mob/living/carbon/human) || \ + istype(usr, /mob/living/silicon) || \ + istype(usr, /mob/living/carbon/monkey) && ticker && ticker.mode.name == "monkey") ) + usr << "\red You don't have the dexterity to do this!" + return 1 + if ((get_dist(src, user) > 1 || !istype(src.loc, /turf)) && !istype(user, /mob/living/silicon)) + return 1 + if (ishuman(user)) + if(user.brainloss >= 60) + for(var/mob/M in viewers(src, null)) + M << "\red [user] stares cluelessly at [src] and drools." + return 1 + else if(prob(user.brainloss)) + user << "\red You momentarily forget how to use [src]." + return 1 + + src.add_fingerprint(user) + return 0 \ No newline at end of file diff --git a/code/game/machinery/main.dm b/code/game/machinery/main.dm deleted file mode 100644 index 8f593641219..00000000000 --- a/code/game/machinery/main.dm +++ /dev/null @@ -1,30 +0,0 @@ -/obj/machinery/New() - ..() - machines.Add(src) - -/obj/machinery/Del() - machines.Remove(src) - ..() - -/obj/machinery/proc/process() - return - -/obj/machinery/ex_act(severity) - switch(severity) - if(1.0) - del(src) - return - if(2.0) - if (prob(50)) - del(src) - return - if(3.0) - if (prob(25)) - del(src) - return - else - return - -/obj/machinery/blob_act() - if(prob(50)) - del(src) \ No newline at end of file diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 7cb5dcd886d..42f53caf117 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -378,75 +378,16 @@ src.shoot_inventory = !src.shoot_inventory -//"Borrowed" airlock shocking code. /obj/machinery/vending/proc/shock(mob/user, prb) - - - if(!prob(prb)) - return 0 - if(stat & (BROKEN|NOPOWER)) // unpowered, no shock return 0 - - if (src.electrocute(user, 1)) + if(!prob(prb)) + return 0 + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() + if (electrocute_mob(user, get_area(src), src)) return 1 else return 0 -/obj/machinery/vending/electrocute(mob/user, netnum) - - if(!netnum) // unconnected cable is unpowered - return 0 - - var/prot = 1 - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - - prot = G.siemens_coefficient - else if (istype(user, /mob/living/silicon)) - return 0 - - if(prot == 0) // elec insulted gloves protect completely - return 0 - - //ok you're getting shocked now - var/datum/powernet/PN // find the powernet - if(powernets && powernets.len >= netnum) - PN = powernets[netnum] - - var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(5, 1, src) - s.start() - - var/shock_damage = 0 - if(PN.avail > 750000) //someone juiced up the grid enough, people going to die! - shock_damage = min(rand(70,145),rand(70,145))*prot - else if(PN.avail > 100000) - shock_damage = min(rand(35,110),rand(35,110))*prot - else if(PN.avail > 75000) - shock_damage = min(rand(30,100),rand(30,100))*prot - else if(PN.avail > 50000) - shock_damage = min(rand(25,90),rand(25,90))*prot - else if(PN.avail > 25000) - shock_damage = min(rand(20,80),rand(20,80))*prot - else if(PN.avail > 10000) - shock_damage = min(rand(20,65),rand(20,65))*prot - else - shock_damage = min(rand(20,45),rand(20,45))*prot - - user.burn_skin(shock_damage) - user.fireloss += shock_damage - user.updatehealth() - user << "\red You feel a powerful shock course through your body!" - sleep(1) - - if(user.stunned < shock_damage) user.stunned = shock_damage - if(user.weakened < 20*prot) user.weakened = 20*prot - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red [user.name] was shocked by the [src.name]!", 3, "\red You hear a heavy electrical crack", 2) - return 1 diff --git a/code/game/objects/grille.dm b/code/game/objects/grille.dm index 0a1422b39e2..b1259ca3bef 100644 --- a/code/game/objects/grille.dm +++ b/code/game/objects/grille.dm @@ -1,16 +1,3 @@ -//returns the netnum of a stub cable at this grille loc, or 0 if none - -/obj/grille/proc/get_connection() - var/turf/T = src.loc - if(!istype(T, /turf/simulated/floor)) - return - - for(var/obj/cable/C in T) - if(C.d1 == 0) - return C.netnum - - return 0 - /obj/grille/ex_act(severity) switch(severity) @@ -152,9 +139,11 @@ if(!prob(prb)) return 0 - var/net = get_connection() // find the powernet of the connected cable - - if(!net) // cable is unpowered - return 0 - - return src.electrocute(user, prb, net) + var/turf/T = get_turf(src) + if (electrocute_mob(user, T.get_cable_node(), src)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() + return 1 + else + return 0 \ No newline at end of file diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 4441bf49c5c..a9793c46f90 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -16,10 +16,9 @@ if (!istype(loc, /turf/simulated/floor)) usr << "\red APC cannot be placed on this spot." return - for(var/area/RA in A.related) - for(var/obj/machinery/power/apc/FINDME in RA) - usr << "\red This area already has APC." - return //only one APC per area + if (A.get_apc()) + usr << "\red This area already has APC." + return //only one APC per area if (A.requires_power == 0) usr << "\red APC cannot be placed in this area." return diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 25aabbd5365..0bb0c06a0b6 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -79,4 +79,21 @@ M.virus.spread_type = CONTACT_GENERAL src.contract_disease(M.virus) M.virus.spread_type = s_spread_type - return \ No newline at end of file + return + +/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0) + shock_damage *= siemens_coeff + if (shock_damage<1) + return 0 + src.burn_skin(shock_damage) + //src.fireloss += shock_damage //burn_skin will do this for us + src.updatehealth() + src.visible_message( + "\red [src] was shocked by the [source]!", \ + "\red You feel a powerful shock course through your body!", \ + "\red You hear a heavy electrical crack." \ + ) + if(src.stunned < shock_damage) src.stunned = shock_damage + if(src.weakened < 20*siemens_coeff) src.weakened = 20*siemens_coeff + + return shock_damage \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e8be1fb2c5e..39984f49f81 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -2643,3 +2643,9 @@ id = pda.id if (istype(id)) return id + +/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0) + if(src.gloves) + var/obj/item/clothing/gloves/G = src.gloves + siemens_coeff = G.siemens_coefficient + return ..(shock_damage,source,siemens_coeff) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index d9b1c19cf92..ad1f43bec39 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1904,7 +1904,10 @@ //sort of a legacy burn method for /electrocute, /shock, and the e_chair /mob/proc/burn_skin(burn_amount) - if(istype(src, /mob/living/carbon/human) && (!src.mutations & 2)) + if(istype(src, /mob/living/carbon/human)) + //world << "DEBUG: burn_skin(), mutations=[mutations]" + if (src.mutations & 2) //fireproof + return 0 var/mob/living/carbon/human/H = src //make this damage method divide the damage to be done among all the body parts, then burn each body part for that much damage. will have better effect then just randomly picking a body part var/divided_damage = (burn_amount)/(H.organs.len) var/datum/organ/external/affecting = null @@ -1920,7 +1923,9 @@ H.UpdateDamageIcon() H.updatehealth() return 1 - else if(istype(src, /mob/living/carbon/monkey) && (!src.mutations & 2)) + else if(istype(src, /mob/living/carbon/monkey)) + if (src.mutations & 2) //fireproof + return 0 var/mob/living/carbon/monkey/M = src M.fireloss += burn_amount M.updatehealth() @@ -2194,3 +2199,6 @@ note dizziness decrements automatically in the mob's Life() proc. boom.icon_state = "loss_malf" else boom.icon_state = "loss_general" + +/mob/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0) + return 0 //only carbon liveforms has this proc \ No newline at end of file diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 9765e46eaf7..6bcc111a2ae 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -171,10 +171,11 @@ // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/proc/updateicon() + src.overlays = null if(opened) var/basestate = "apc[ cell ? "2" : "1" ]" // if opened, show cell if it's inserted if (opened==1) - if (stat & MAINT) + if (stat & (MAINT|BROKEN)) icon_state = "apcmaint" //disassembled APC cannot hold cell else icon_state = basestate @@ -183,31 +184,18 @@ icon_state = "[basestate]-b-nocover" else /* if (emagged)*/ icon_state = "[basestate]-nocover" - src.overlays = null // also delete all overlays - return - else if(emagged || malfhack) - icon_state = "apcemag" - src.overlays = null - return - else if(wiresexposed) - icon_state = "apcewires" - src.overlays = null - return else if (stat & BROKEN) icon_state = "apc-b" - src.overlays = null - return + else if(emagged || malfhack) + icon_state = "apcemag" + else if(wiresexposed) + icon_state = "apcewires" else icon_state = "apc0" - // if closed, update overlays for channel status - - src.overlays = null if (!(stat & (BROKEN|MAINT))) overlays += image('power.dmi', "apcox-[locked]") // 0=blue 1=red overlays += image('power.dmi', "apco3-[charging]") // 0=red, 1=yellow/black 2=green - - if(operating) overlays += image('power.dmi', "apco0-[equipment]") // 0=red, 1=green, 2=blue overlays += image('power.dmi', "apco1-[lighting]") @@ -338,7 +326,10 @@ if(do_after(user, 20) && C.amount >= 10) var/turf/T = get_turf_loc(src) var/obj/cable/N = T.get_cable_node() - if (N && N.electrocute(usr, 50, N.netnum)) + if (prob(80) && electrocute_mob(usr, N, N)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() return C.use(10) user.visible_message(\ @@ -353,7 +344,10 @@ user << "You begin to cut cables..." playsound(src.loc, 'Deconstruct.ogg', 50, 1) if(do_after(user, 50)) - if (terminal.electrocute(usr, 50, terminal.netnum)) + if (prob(80) && electrocute_mob(usr, terminal.powernet, terminal)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() return new /obj/item/weapon/cable_coil(loc,10) user.visible_message(\ @@ -394,18 +388,18 @@ if (opened==2) opened = 1 user.visible_message(\ - "\red [user.name] has replace the damaged APC frontal panel with new one.",\ + "\red [user.name] has replaced the damaged APC frontal panel with new one.",\ "You replace the damaged APC frontal panel with new one.") del(W) updateicon() else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack)) if (has_electronics) - user << "You cannot repair this heavy damaged APC until broken electronics still inside." + user << "You cannot repair this heavy damaged APC until broken electronics stills inside." return user << "You begin to replace the damaged APC frame..." if(do_after(user, 50)) user.visible_message(\ - "\red [user.name] has replace the damaged APC frame with new one.",\ + "\red [user.name] has replaced the damaged APC frame with new one.",\ "You replace the damaged APC frame with new one.") del(W) stat &= ~BROKEN @@ -428,6 +422,10 @@ else if (istype(user, /mob/living/silicon)) return src.attack_hand(user) + if (wiresexposed && \ + (istype(W, /obj/item/device/multitool) || \ + istype(W, /obj/item/weapon/wirecutters))) + return src.attack_hand(user) user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ "\red You hit the [src.name] with your [W.name]!", \ "You hear bang") @@ -438,13 +436,7 @@ add_fingerprint(user) if(opened && (!istype(user, /mob/living/silicon))) if(cell) - cell.loc = usr - cell.layer = 20 - if (user.hand ) - user.l_hand = cell - else - user.r_hand = cell - + usr.put_in_hand(cell) cell.add_fingerprint(user) cell.updateicon() @@ -633,85 +625,13 @@ var/wireFlag = APCIndexToFlag[wireIndex] return ((src.apcwires & wireFlag) == 0) -/obj/machinery/power/apc/proc/get_connection() - if(stat & (BROKEN|MAINT)) return 0 - return 1 - -/obj/machinery/power/apc/proc/shock(mob/user, prb) - if(!prob(prb)) - return 0 - var/is_powered = get_connection() // find the powernet of the connected cable - return src.apcelectrocute(user, is_powered) - -/obj/machinery/power/apc/proc/apcelectrocute(mob/user, is_powered) - - if(!is_powered) // unconnected cable is unpowered - return 0 - - var/prot = 1 - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - prot = G.siemens_coefficient - else if (istype(user, /mob/living/silicon)) - return 0 - - if(prot == 0) // elec insulted gloves protect completely - return 0 - - var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(3, 1, src) - s.start() - - var/shock_damage = 0 - if (cell.charge >=2500) - shock_damage = min(rand(70,145),rand(70,145))*prot - cell.use(2000) - else if(cell.charge >=1750) - shock_damage = min(rand(35,110),rand(35,110))*prot - cell.use(1600) - else if(cell.charge >=1500) - shock_damage = min(rand(30,100),rand(30,100))*prot - cell.use(1000) - else if(cell.charge >=750) - shock_damage = min(rand(25,90),rand(25,90))*prot - cell.use(500) - else if(cell.charge >=250) - shock_damage = min(rand(20,80),rand(20,80))*prot - cell.use(125) - else if(cell.charge >=100) - shock_damage = min(rand(20,65),rand(20,65))*prot - cell.use(50) - else - return 0 - - user.burn_skin(shock_damage) - user.fireloss += shock_damage - user.updatehealth() - user.visible_message("\red [user.name] was shocked by the [src.name]!", "\red You feel a powerful shock course through your body!", "\red You hear a heavy electrical crack") - //user << "\red You feel a powerful shock course through your body!" - sleep(1) - - if(user.stunned < shock_damage) user.stunned = shock_damage - if(user.weakened < 20*prot) user.weakened = 20*prot - -/* - * for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red [user.name] was shocked by the [src.name]!", 3, "\red You hear a heavy electrical crack", 2) -*/ - return 1 - - /obj/machinery/power/apc/proc/cut(var/wireColor) var/wireFlag = APCWireColorToFlag[wireColor] var/wireIndex = APCWireColorToIndex[wireColor] apcwires &= ~wireFlag switch(wireIndex) if(APC_WIRE_MAIN_POWER1) - src.shock(usr, 50) //this doesn't work for some reason, give me a while I'll figure it out + src.shock(usr, 50) src.shorted = 1 src.updateDialog() if(APC_WIRE_MAIN_POWER2) @@ -1066,9 +986,11 @@ // update icon & area power if anything changed - if(last_lt != lighting || last_eq != equipment || last_en != environ || last_ch != charging) + if(last_lt != lighting || last_eq != equipment || last_en != environ) updateicon() update() + else if (last_ch != charging) + updateicon() //src.updateDialog() src.updateDialog() @@ -1137,7 +1059,7 @@ // overload all the lights in this APC area /obj/machinery/power/apc/proc/overload_lighting() - if(!get_connection() || !operating || shorted) + if(/* !get_connection() || */ !operating || shorted) return if( cell && cell.charge>=20) cell.use(20); @@ -1153,4 +1075,16 @@ area.power_equip = 0 area.power_environ = 0 area.power_change() - ..() \ No newline at end of file + ..() + + +/obj/machinery/power/apc/proc/shock(mob/user, prb) + if(!prob(prb)) + return 0 + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() + if (electrocute_mob(user, src, src)) + return 1 + else + return 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index af7787c2dd3..87eaa3c5fdc 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -116,7 +116,7 @@ var/obj/item/weapon/cable_coil/coil = W coil.cable_join(src, user) - //note do shock in cable_join + //TODO: shock in cable_join else if(istype(W, /obj/item/device/multitool)) @@ -139,76 +139,15 @@ // shock the user with probability prb /obj/cable/proc/shock(mob/user, prb) - if(!netnum) // unconnected cable is unpowered - return 0 - - return src.electrocute(user, prb, netnum) - - -/atom/proc/electrocute(mob/user, prb, netnum) - if(!prob(prb)) return 0 - - if(!netnum) // unconnected cable is unpowered - return 0 - - var/datum/powernet/PN - if(powernets && powernets.len >= netnum) - PN = powernets[netnum] - - if(PN && (PN.avail > 0)) // is it powered? - var/prot = 1 - - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - - prot = G.siemens_coefficient - else if (istype(user, /mob/living/silicon)) - return 0 - - if(prot == 0) // elec insulted gloves protect completely - return 0 - + if (electrocute_mob(user, powernets[src.netnum], src)) var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(3, 1, src) + s.set_up(5, 1, src) s.start() - - var/shock_damage = 0 - if(PN.avail > 750000) //someone juiced up the grid enough, people going to die! - shock_damage = min(rand(70,145),rand(70,145))*prot - else if(PN.avail > 100000) - shock_damage = min(rand(35,110),rand(35,110))*prot - else if(PN.avail > 75000) - shock_damage = min(rand(30,100),rand(30,100))*prot - else if(PN.avail > 50000) - shock_damage = min(rand(25,90),rand(25,90))*prot - else if(PN.avail > 25000) - shock_damage = min(rand(20,80),rand(20,80))*prot - else if(PN.avail > 10000) - shock_damage = min(rand(20,65),rand(20,65))*prot - else - shock_damage = min(rand(20,45),rand(20,45))*prot - -// message_admins("\blue ADMIN: DEBUG: shock_damage = [shock_damage] PN.avail = [PN.avail] user = [user] netnum = [netnum]") - - user.burn_skin(shock_damage) - user.fireloss += shock_damage - user.updatehealth() - user << "\red You feel a powerful shock course through your body!" - sleep(1) - - if(user.stunned < shock_damage) user.stunned = shock_damage - if(user.weakened < 20*prot) user.weakened = 20*prot - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red [user.name] was shocked by the [src.name]!", 3, "\red You hear a heavy electrical crack", 2) return 1 - return 0 - + else + return 0 /obj/cable/ex_act(severity) switch(severity) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 0591a2707a2..814e9e2acc9 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -57,9 +57,15 @@ /obj/item/weapon/cell/attackby(obj/item/W, mob/user) var/obj/item/clothing/gloves/G = W if(istype(G)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(3, 1, src) + s.start() + if (prob(80) && electrocute_mob(user, src, src)) + return 1 if(charge < 1000) return + G.siemens_coefficient = min(G.siemens_coefficient,0.7) G.elecgen = 1 G.uses = min(5, round(charge / 1000)) use(G.uses*1000) @@ -131,3 +137,22 @@ /obj/item/weapon/cell/blob_act() if(prob(75)) explode() + +/obj/item/weapon/cell/proc/get_electrocute_damage() + switch (charge) + if (9000 to INFINITY) + return min(rand(90,150),rand(90,150)) + if (2500 to 9000-1) + return min(rand(70,145),rand(70,145)) + if (1750 to 2500-1) + return min(rand(35,110),rand(35,110)) + if (1500 to 1750-1) + return min(rand(30,100),rand(30,100)) + if (750 to 1500-1) + return min(rand(25,90),rand(25,90)) + if (250 to 750-1) + return min(rand(20,80),rand(20,80)) + if (100 to 250-1) + return min(rand(20,65),rand(20,65)) + else + return 0 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 10caa158e88..5623de11cdf 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -170,8 +170,9 @@ continue M.show_message("[user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) if(on && (W.flags & CONDUCT)) - if(!user.mutations & 2) - src.electrocute(user, 50, null, 20000) + //if(!user.mutations & 2) + if (prob(50)) + electrocute_mob(user, get_area(src), src) broken() else @@ -179,13 +180,14 @@ // attempt to stick weapon into light socket else if(status == LIGHT_EMPTY) - user << "You stick \the [W.name] into the light socket!" + user << "You stick \the [W] into the light socket!" if(has_power() && (W.flags & CONDUCT)) var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread s.set_up(3, 1, src) s.start() - if(!user.mutations & 2) - src.electrocute(user, 75, null, 20000) + //if(!user.mutations & 2) + if (prob(75)) + electrocute_mob(user, get_area(src), src) // returns whether this light has power diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 6820f5e4bbb..993fd675f2f 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -356,6 +356,25 @@ for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network S.restore() // and restore some of the power that was used +/datum/powernet/proc/get_electrocute_damage() + switch(avail) + if (750000 to INFINITY) + return min(rand(70,145),rand(70,145)) + if (100000 to 750000-1) + return min(rand(35,110),rand(35,110)) + if (75000 to 100000-1) + return min(rand(30,100),rand(30,100)) + if (50000 to 75000-1) + return min(rand(25,90),rand(25,90)) + if (25000 to 50000-1) + return min(rand(20,80),rand(20,80)) + if (10000 to 25000-1) + return min(rand(20,65),rand(20,65)) + if (100 to 10000-1) + return min(rand(10,20),rand(10,20)) + else + return 0 + /obj/machinery/power/proc/connect_to_network() var/turf/T = src.loc var/obj/cable/C = T.get_cable_node() @@ -363,7 +382,6 @@ return makepowernets() //TODO: find fast way - /obj/machinery/power/proc/disconnect_from_network() //TODO: dunno how to do that return @@ -375,3 +393,68 @@ if(C.d1 == 0) return C return null + +/area/proc/get_apc() + for(var/area/RA in src.related) + var/obj/machinery/power/apc/FINDME = locate() in RA + if (FINDME) + return FINDME + + +//Determines how strong could be shock, deals damage to mob, uses power. +//M is a mob who touched wire/whatever +//power_source is a source of electricity, can be powercell, area, apc, cable, powernet or null +//source is an object caused electrocuting (airlock, grille, etc) +//No animations will be performed by this proc. +/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source) + var/area/source_area + if (istype(power_source,/area)) + source_area = power_source + power_source = source_area.get_apc() + if (istype(power_source,/obj/cable)) + var/obj/cable/tmp = power_source + power_source = powernets[tmp.netnum] + + var/datum/powernet/PN + var/obj/item/weapon/cell/cell + + if (istype(power_source,/datum/powernet)) + PN = power_source + else if (istype(power_source,/obj/item/weapon/cell)) + cell = power_source + else if (istype(power_source,/obj/machinery/power/apc)) + var/obj/machinery/power/apc/apc = power_source + cell = apc.cell + if (apc.terminal) + PN = apc.terminal.powernet + else if (!power_source) + return 0 + else + log_admin("ERROR: /proc/electrocute_mob([M], [power_source], [source]): wrong power_source") + return 0 + if (!cell && !PN) + return 0 + var/PN_damage = 0 + var/cell_damage = 0 + if (PN) + PN_damage = PN.get_electrocute_damage() + if (cell) + cell_damage = cell.get_electrocute_damage() + var/shock_damage = 0 + if (PN_damage>=cell_damage) + power_source = PN + shock_damage = PN_damage + else + power_source = cell + shock_damage = cell_damage + var/drained_hp = M.electrocute_act(shock_damage, source) //zzzzzzap! + var/drained_energy = drained_hp*20 + + if (source_area) + source_area.use_power(drained_energy/CELLRATE) + else if (istype(power_source,/datum/powernet)) + var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" + PN.newload+=drained_power + else if (istype(power_source, /obj/item/weapon/cell)) + cell.use(drained_energy) + return drained_energy \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 446c238e8d2..dccc2965738 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -353,7 +353,7 @@ #include "code\game\machinery\hydroponics.dm" #include "code\game\machinery\igniter.dm" #include "code\game\machinery\lightswitch.dm" -#include "code\game\machinery\main.dm" +#include "code\game\machinery\machinery.dm" #include "code\game\machinery\microwave.dm" #include "code\game\machinery\morgue.dm" #include "code\game\machinery\navbeacon.dm"