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
This commit is contained in:
rastaf.zero@gmail.com
2011-01-27 16:40:36 +00:00
parent 1b82a7690e
commit 427313e0ad
18 changed files with 320 additions and 462 deletions
+18 -1
View File
@@ -79,4 +79,21 @@
M.virus.spread_type = CONTACT_GENERAL
src.contract_disease(M.virus)
M.virus.spread_type = s_spread_type
return
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 <B>You feel a powerful shock course through your body!</B>", \
"\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
@@ -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)
+10 -2
View File
@@ -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
+40 -106
View File
@@ -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 <B>You feel a powerful shock course through your body!</B>", "\red You hear a heavy electrical crack")
//user << "\red <B>You feel a powerful shock course through your body!</B>"
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()
..()
..()
/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
+5 -66
View File
@@ -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 <B>ADMIN: </B>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 <B>You feel a powerful shock course through your body!</B>"
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)
+25
View File
@@ -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
+7 -5
View File
@@ -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
+84 -1
View File
@@ -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