diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm
index 9d34bc14d2..9facaf5d70 100644
--- a/code/__DEFINES/flags.dm
+++ b/code/__DEFINES/flags.dm
@@ -20,27 +20,41 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define DF_ISPROCESSING (1<<2)
//FLAGS BITMASK
-
-#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
-#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this.
-#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.)
-#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff
-#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay
-#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving
-#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows
+///This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
+#define HEAR_1 (1<<3)
+///Projectiels will check ricochet on things impacted that have this.
+#define CHECK_RICOCHET_1 (1<<4)
+///Conducts electricity (metal etc.).
+#define CONDUCT_1 (1<<5)
+///For machines and structures that should not break into parts, eg, holodeck stuff.
+#define NODECONSTRUCT_1 (1<<7)
+///Atom queued to SSoverlay.
+#define OVERLAY_QUEUED_1 (1<<8)
+///Item has priority to check when entering or leaving.
+#define ON_BORDER_1 (1<<9)
+///Prevent clicking things below it on the same turf eg. doors/ fulltile windows.
+#define PREVENT_CLICK_UNDER_1 (1<<11)
#define HOLOGRAM_1 (1<<12)
-#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity
-#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object
-#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff.
-#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) /// should not get harmed if this gets caught by an explosion?
-#define BLOCK_FACE_ATOM_1 (1<<17) /// Early returns mob.face_atom()
+///Prevents mobs from getting chainshocked by teslas and the supermatter.
+#define SHOCKED_1 (1<<13)
+///Whether /atom/Initialize() has already run for the object.
+#define INITIALIZED_1 (1<<14)
+///was this spawned by an admin? used for stat tracking stuff.
+#define ADMIN_SPAWNED_1 (1<<15)
+/// should not get harmed if this gets caught by an explosion?
+#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16)
+/// Early returns mob.face_atom()
+#define BLOCK_FACE_ATOM_1 (1<<17)
//turf-only flags
#define NOJAUNT_1 (1<<0)
#define UNUSED_RESERVATION_TURF_1 (1<<1)
-#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas.
-#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf
-#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf
+///If a turf can be made dirty at roundstart. This is also used in areas.
+#define CAN_BE_DIRTY_1 (1<<2)
+///Blocks lava rivers being generated on the turf.
+#define NO_LAVA_GEN_1 (1<<6)
+///Blocks ruins spawning on the turf.
+#define NO_RUINS_1 (1<<10)
/*
These defines are used specifically with the atom/pass_flags bitmask
@@ -76,14 +90,15 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define GOLIATH_WEAKNESS (1<<9) //CIT CHANGE
//tesla_zap
-#define TESLA_MACHINE_EXPLOSIVE (1<<0)
-#define TESLA_ALLOW_DUPLICATES (1<<1)
-#define TESLA_OBJ_DAMAGE (1<<2)
-#define TESLA_MOB_DAMAGE (1<<3)
-#define TESLA_MOB_STUN (1<<4)
+#define ZAP_MACHINE_EXPLOSIVE (1<<0)
+#define ZAP_ALLOW_DUPLICATES (1<<1)
+#define ZAP_OBJ_DAMAGE (1<<2)
+#define ZAP_MOB_DAMAGE (1<<3)
+#define ZAP_MOB_STUN (1<<4)
-#define TESLA_DEFAULT_FLAGS ALL
-#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN
+#define ZAP_DEFAULT_FLAGS ALL
+#define ZAP_FUSION_FLAGS ZAP_OBJ_DAMAGE | ZAP_MOB_DAMAGE | ZAP_MOB_STUN
+#define ZAP_SUPERMATTER_FLAGS NONE
//EMP protection
#define EMP_PROTECT_SELF (1<<0)
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 91a4a6f2c3..a63a59c75f 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -88,6 +88,7 @@
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
#define TRAIT_PUSHIMMUNE "push_immunity"
#define TRAIT_SHOCKIMMUNE "shock_immunity"
+#define TRAIT_TESLA_SHOCKIMMUNE "tesla_shock_immunity"
#define TRAIT_STABLEHEART "stable_heart"
#define TRAIT_STABLELIVER "stable_liver"
#define TRAIT_RESISTHEAT "resist_heat"
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 52eff15492..1aab96f85e 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -132,9 +132,11 @@ GLOBAL_LIST_INIT(bitfields, list(
"NO_RUINS_1" = NO_RUINS_1,
"PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1,
"HOLOGRAM_1" = HOLOGRAM_1,
- "TESLA_IGNORE_1" = TESLA_IGNORE_1,
+ "SHOCKED_1" = SHOCKED_1,
"INITIALIZED_1" = INITIALIZED_1,
"ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1,
+ "BLOCK_FACE_ATOM_1" = BLOCK_FACE_ATOM_1,
+ "PREVENT_CONTENTS_EXPLOSION_1" = PREVENT_CONTENTS_EXPLOSION_1
),
"clothing_flags" = list(
"LAVAPROTECT" = LAVAPROTECT,
@@ -148,12 +150,12 @@ GLOBAL_LIST_INIT(bitfields, list(
"IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS,
"SCAN_REAGENTS" = SCAN_REAGENTS
),
- "tesla_flags" = list(
- "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
- "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE,
- "TESLA_MOB_STUN" = TESLA_MOB_STUN,
- "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES,
- "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE,
+ "zap_flags" = list(
+ "ZAP_MOB_DAMAGE" = ZAP_MOB_DAMAGE,
+ "ZAP_OBJ_DAMAGE" = ZAP_OBJ_DAMAGE,
+ "ZAP_MOB_STUN" = ZAP_MOB_STUN,
+ "ZAP_ALLOW_DUPLICATES" = ZAP_ALLOW_DUPLICATES,
+ "ZAP_MACHINE_EXPLOSIVE" = ZAP_MACHINE_EXPLOSIVE,
),
"smooth" = list(
"SMOOTH_TRUE" = SMOOTH_TRUE,
diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm
index dd8b9f0d94..1b100bebaf 100644
--- a/code/_globalvars/traits.dm
+++ b/code/_globalvars/traits.dm
@@ -29,6 +29,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_SLEEPIMMUNE" = TRAIT_SLEEPIMMUNE,
"TRAIT_PUSHIMMUNE" = TRAIT_PUSHIMMUNE,
"TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE,
+ "TRAIT_TESLA_SHOCKIMMUNE" = TRAIT_TESLA_SHOCKIMMUNE,
"TRAIT_STABLEHEART" = TRAIT_STABLEHEART,
"TRAIT_STABLELIVER" = TRAIT_STABLELIVER,
"TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT,
diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm
index a7a61802d3..216d82b4c8 100644
--- a/code/datums/diseases/_MobProcs.dm
+++ b/code/datums/diseases/_MobProcs.dm
@@ -145,4 +145,10 @@
return !is_mouth_covered()
/mob/living/carbon/CanSpreadAirborneDisease()
- return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25)))
\ No newline at end of file
+ return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25)))
+
+/mob/living/proc/set_shocked()
+ flags_1 |= SHOCKED_1
+
+/mob/living/proc/reset_shocked()
+ flags_1 &= ~ SHOCKED_1
\ No newline at end of file
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index a63f63f4a4..1ff27bafa9 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -581,6 +581,14 @@
SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode)
return FALSE
+/**
+ * Respond to a electric bolt action on our item
+ *
+ * Default behaviour is to return, we define here to allow for cleaner code later on
+ */
+/atom/proc/zap_act(power, zap_flags, shocked_targets)
+ return
+
/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user)
if(GetComponent(/datum/component/storage))
return component_storage_contents_dump_act(src_object, user)
diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm
index dca50be5b9..af75315ded 100644
--- a/code/game/gamemodes/gangs/dominator.dm
+++ b/code/game/gamemodes/gangs/dominator.dm
@@ -48,9 +48,6 @@
/obj/machinery/dominator/hulk_damage()
return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED
-/obj/machinery/dominator/tesla_act()
- qdel(src)
-
/obj/machinery/dominator/update_icon()
cut_overlays()
if(stat & BROKEN)
diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm
index 470c26ed0f..e2f26d6617 100644
--- a/code/game/machinery/_machinery.dm
+++ b/code/game/machinery/_machinery.dm
@@ -522,11 +522,11 @@ Class Procs:
/obj/machinery/proc/can_be_overridden()
. = 1
-/obj/machinery/tesla_act(power, tesla_flags, shocked_objects)
- ..()
- if(prob(85) && (tesla_flags & TESLA_MACHINE_EXPLOSIVE))
+/obj/machinery/zap_act(power, zap_flags, shocked_objects)
+ . = ..()
+ if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE))
explosion(src, 1, 2, 4, flame_range = 2, adminlog = FALSE, smoke = FALSE)
- if(tesla_flags & TESLA_OBJ_DAMAGE)
+ else if(zap_flags & ZAP_OBJ_DAMAGE)
take_damage(power/2000, BURN, "energy")
if(prob(40))
emp_act(EMP_LIGHT)
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 3ac3347222..7cc76da312 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -433,7 +433,7 @@
H.visible_message("The defibrillator safely discharges the excessive charge into the floor!")
return
var/mob/living/M = H.pulledby
- if(M.electrocute_act(30, src))
+ if(M.electrocute_act(30, H))
M.visible_message("[M] is electrocuted by [M.p_their()] contact with [H]!")
M.emote("scream")
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index 8dac972d04..87afd8e421 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -232,15 +232,16 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
cut_overlay(GLOB.fire_overlay, TRUE)
SSfire_burning.processing -= src
-/obj/proc/tesla_act(power, tesla_flags, shocked_targets)
+/obj/zap_act(power, zap_flags, shocked_targets)
+ if(QDELETED(src))
+ return 0
obj_flags |= BEING_SHOCKED
- var/power_bounced = power / 2
- tesla_zap(src, 3, power_bounced, tesla_flags, shocked_targets)
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
+ return power / 2
//The surgeon general warns that being buckled to certain objects receiving powerful shocks is greatly hazardous to your health
-//Only tesla coils and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later.
-/obj/proc/tesla_buckle_check(var/strength)
+//Only tesla coils, vehicles, and grounding rods currently call this because mobs are already targeted over all other objects, but this might be useful for more things later.
+/obj/proc/zap_buckle_check(var/strength)
if(has_buckled_mobs())
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 54e08db210..20151a0bdb 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -267,7 +267,7 @@
var/obj/structure/cable/C = T.get_cable_node()
if(C)
playsound(src, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
- tesla_zap(src, 3, C.newavail() * 0.01, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
+ tesla_zap(src, 3, C.newavail() * 0.01, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN | ZAP_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot.
C.add_delayedload(C.newavail() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock.
return ..()
diff --git a/code/modules/antagonists/abductor/equipment/glands/electric.dm b/code/modules/antagonists/abductor/equipment/glands/electric.dm
index 82ee77d192..7e52f6fcb6 100644
--- a/code/modules/antagonists/abductor/equipment/glands/electric.dm
+++ b/code/modules/antagonists/abductor/equipment/glands/electric.dm
@@ -23,5 +23,5 @@
addtimer(CALLBACK(src, .proc/zap), rand(30, 100))
/obj/item/organ/heart/gland/electric/proc/zap()
- tesla_zap(owner, 4, 8000, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN)
+ tesla_zap(owner, 4, 8000, ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN)
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, TRUE)
\ No newline at end of file
diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm
index 5717dc557d..6a73dc579b 100644
--- a/code/modules/antagonists/blob/blob/theblob.dm
+++ b/code/modules/antagonists/blob/blob/theblob.dm
@@ -207,8 +207,8 @@
if(prob(100 - severity * 30))
new /obj/effect/temp_visual/emp(get_turf(src))
-/obj/structure/blob/tesla_act(power)
- ..()
+/obj/structure/blob/zap_act(power)
+ . = ..()
if(overmind)
if(overmind.blobstrain.tesla_reaction(src, power))
take_damage(power/400, BURN, "energy")
diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
index 2907a1c285..a11ecaa3df 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm
@@ -451,9 +451,9 @@
return
qdel(src)
-/obj/machinery/nuclearbomb/tesla_act(power, tesla_flags)
+/obj/machinery/nuclearbomb/zap_act(power, zap_flags)
..()
- if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
+ if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
#define NUKERANGE 127
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index d49a8f83c6..a9bc64a932 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -226,7 +226,11 @@
/datum/spellbook_entry/lightningbolt/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) //return 1 on success
. = ..()
- user.flags_1 |= TESLA_IGNORE_1
+ ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
+
+/datum/spellbook_entry/lightningbolt/Refund(mob/living/carbon/human/user, obj/item/spellbook/book)
+ . = ..()
+ REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "lightning_bolt_spell")
/datum/spellbook_entry/infinite_guns
name = "Lesser Summon Guns"
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index d5aa49072d..695d25dbf4 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -649,7 +649,6 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | IMMUTABLE_SLOW
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG helmet"
@@ -665,7 +664,6 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- flags_1 = TESLA_IGNORE_1
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/Initialize()
. = ..()
@@ -676,12 +674,14 @@
if (slot == SLOT_HEAD)
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.add_hud_to(user)
+ ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
/obj/item/clothing/head/helmet/space/hardsuit/ancient/mason/dropped(mob/living/carbon/human/user)
..()
- if (user.head == src)
+ if (HAS_TRAIT_FROM(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit"))
var/datum/atom_hud/DHUD = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
DHUD.remove_hud_from(user)
+ REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "mason_hardsuit")
/obj/item/clothing/suit/space/hardsuit/ancient/proc/on_mob_move()
var/mob/living/carbon/human/H = loc
diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm
index c9b7695779..98fb836c38 100644
--- a/code/modules/clothing/suits/reactive_armour.dm
+++ b/code/modules/clothing/suits/reactive_armour.dm
@@ -164,21 +164,21 @@
desc = "An experimental suit of armor with sensitive detectors hooked up to a huge capacitor grid, with emitters strutting out of it. Zap."
siemens_coefficient = -1
reactivearmor_cooldown_duration = 20
- var/tesla_power = 25000
- var/tesla_range = 20
- var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
+ var/zap_power = 25000
+ var/zap_range = 20
+ var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
var/legacy = FALSE
var/legacy_dmg = 30
/obj/item/clothing/suit/armor/reactive/tesla/dropped(mob/user)
..()
if(istype(user))
- user.flags_1 &= ~TESLA_IGNORE_1
+ REMOVE_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
/obj/item/clothing/suit/armor/reactive/tesla/equipped(mob/user, slot)
..()
if(slot_flags & slotdefine2slotbit(slot)) //Was equipped to a valid slot for this item?
- user.flags_1 |= TESLA_IGNORE_1
+ ADD_TRAIT(user, TRAIT_TESLA_SHOCKIMMUNE, "reactive_tesla_armor")
/obj/item/clothing/suit/armor/reactive/tesla/block_action(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
if(prob(hit_reaction_chance))
@@ -190,7 +190,7 @@
return
owner.visible_message("[src] blocks [attack_text], sending out arcs of lightning!")
if(!legacy)
- tesla_zap(owner, tesla_range, tesla_power, tesla_flags)
+ tesla_zap(owner, zap_range, zap_power, zap_flags)
else
for(var/mob/living/M in view(7, owner))
if(M == owner)
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 3023907831..b422ee5745 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -234,38 +234,44 @@
var/obj/item/organ/O = X
O.emp_act(severity)
+///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects.
/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
- if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
- return FALSE
- if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
- return FALSE
- shock_damage *= siemens_coeff
- if(dna && dna.species)
- shock_damage *= dna.species.siemens_coeff
- if(shock_damage < 1)
- return 0
- if(reagents.has_reagent(/datum/reagent/teslium))
- shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
- if((flags & SHOCK_ILLUSION))
- adjustStaminaLoss(shock_damage)
- else
- take_overall_damage(0,shock_damage)
- visible_message(
- "[src] was shocked by \the [source]!", \
- "You feel a powerful shock coursing through your body!", \
- "You hear a heavy electrical crack." \
- )
- jitteriness += 1000 //High numbers for violent convulsions
+ . = ..()
+ if(!.)
+ return
+ //Propagation through pulling, fireman carry
+ if(!(flags & SHOCK_ILLUSION))
+ var/list/shocking_queue = list()
+ if(iscarbon(pulling) && source != pulling)
+ shocking_queue += pulling
+ if(iscarbon(pulledby) && source != pulledby)
+ shocking_queue += pulledby
+ if(iscarbon(buckled) && source != buckled)
+ shocking_queue += buckled
+ for(var/mob/living/carbon/carried in buckled_mobs)
+ if(source != carried)
+ shocking_queue += carried
+ //Found our victims, now lets shock them all
+ for(var/victim in shocking_queue)
+ var/mob/living/carbon/C = victim
+ C.electrocute_act(shock_damage*0.75, src, 1, flags)
+ //Stun
+ var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)
+ if(should_stun)
+ Stun(40)
+ //Jitter and other fluff.
+ jitteriness += 1000
do_jitter_animation(jitteriness)
stuttering += 2
- if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
- Stun(40)
- spawn(20)
- jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
- if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
- DefaultCombatKnockdown(60)
+ addtimer(CALLBACK(src, .proc/secondary_shock, should_stun), 20)
return shock_damage
+///Called slightly after electrocute act to reduce jittering and apply a secondary stun.
+/mob/living/carbon/proc/secondary_shock(should_stun)
+ jitteriness = max(jitteriness - 990, 10)
+ if(should_stun)
+ DefaultCombatKnockdown(60)
+
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
to_chat(M, "You can't put [p_them()] out with just your bare hands!")
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 856c57687f..5ba0675bc1 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -348,40 +348,34 @@
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
-//Added a safety check in case you want to shock a human mob directly through electrocute_act.
+///Calculates the siemens coeff based on clothing and species, can also restart hearts.
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
- if(flags & SHOCK_TESLA)
- var/total_coeff = 1
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- if(G.siemens_coefficient <= 0)
- total_coeff -= 0.5
+ //Calculates the siemens coeff based on clothing. Completely ignores the arguments
+ if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
+ if(gloves && gloves.siemens_coefficient <= 0)
+ siemens_coeff -= 0.5
if(wear_suit)
- var/obj/item/clothing/suit/S = wear_suit
- if(S.siemens_coefficient <= 0)
- total_coeff -= 0.95
- else if(S.siemens_coefficient == (-1))
- total_coeff -= 1
- siemens_coeff = total_coeff
- if(flags_1 & TESLA_IGNORE_1)
- siemens_coeff = 0
- else if(!(flags & SHOCK_NOGLOVES))
- var/gloves_siemens_coeff = 1
+ if(wear_suit.siemens_coefficient == -1)
+ siemens_coeff -= 1
+ else if(wear_suit.siemens_coefficient <= 0)
+ siemens_coeff -= 0.95
+ siemens_coeff = max(siemens_coeff, 0)
+ else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks
if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- gloves_siemens_coeff = G.siemens_coefficient
- siemens_coeff = gloves_siemens_coeff
- if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
- if(shock_damage * siemens_coeff >= 1 && prob(25))
- var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
- heart.beating = TRUE
- if(stat == CONSCIOUS)
- to_chat(src, "You feel your heart beating again!")
+ siemens_coeff *= gloves.siemens_coefficient
siemens_coeff *= physiology.siemens_coeff
. = ..()
- if(.)
- electrocution_animation(40)
-
+ //Don't go further if the shock was blocked/too weak.
+ if(!.)
+ return
+ //Note we both check that the user is in cardiac arrest and can actually heartattack
+ //If they can't, they're missing their heart and this would runtime
+ if(undergoing_cardiac_arrest() && can_heartattack() && !(flags & SHOCK_ILLUSION))
+ if(shock_damage * siemens_coeff >= 1 && prob(25))
+ var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
+ if(heart.Restart() && stat == CONSCIOUS)
+ to_chat(src, "You feel your heart beating again!")
+ electrocution_animation(40)
/mob/living/carbon/human/emp_act(severity)
. = ..()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 44b41c8cd8..45b8a35c86 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -412,21 +412,26 @@
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
+///As the name suggests, this should be called to apply electric shocks.
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
- if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
+ shock_damage *= siemens_coeff
+ if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
- if(shock_damage > 0)
- if(!(flags & SHOCK_ILLUSION))
- adjustFireLoss(shock_damage)
- visible_message(
- "[src] was shocked by \the [source]!", \
- "You feel a powerful shock coursing through your body!", \
- "You hear a heavy electrical crack." \
- )
- return shock_damage
+ if(shock_damage < 1)
+ return FALSE
+ if(!(flags & SHOCK_ILLUSION))
+ adjustFireLoss(shock_damage)
+ else
+ adjustStaminaLoss(shock_damage)
+ visible_message(
+ "[src] was shocked by \the [source]!", \
+ "You feel a powerful shock coursing through your body!", \
+ "You hear a heavy electrical crack." \
+ )
+ return shock_damage
/mob/living/emp_act(severity)
. = ..()
@@ -509,7 +514,6 @@
/mob/living/proc/getBruteLoss_nonProsthetic()
return getBruteLoss()
-
+
/mob/living/proc/getFireLoss_nonProsthetic()
return getFireLoss()
-
\ No newline at end of file
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 582d72f6c0..1644673ece 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -39,9 +39,9 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
if(prob(20))
set_broken()
-/obj/machinery/gravity_generator/tesla_act(power, tesla_flags)
+/obj/machinery/gravity_generator/zap_act(power, zap_flags)
..()
- if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
+ if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
qdel(src)//like the singulo, tesla deletes it. stops it from exploding over and over
/obj/machinery/gravity_generator/update_icon_state()
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index fd6ecef31f..344d41071d 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -687,9 +687,9 @@
on = TRUE
update()
-/obj/machinery/light/tesla_act(power, tesla_flags)
- if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
- explosion(src,0,0,0,flame_range = 5, adminlog = 0)
+/obj/machinery/light/zap_act(power, zap_flags)
+ if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
+ explosion(src,0,0,0,flame_range = 5, adminlog = FALSE)
qdel(src)
else
return ..()
diff --git a/code/modules/power/rtg.dm b/code/modules/power/rtg.dm
index afbeef30a1..b558031fab 100644
--- a/code/modules/power/rtg.dm
+++ b/code/modules/power/rtg.dm
@@ -97,6 +97,7 @@
/obj/machinery/power/rtg/abductor/fire_act(exposed_temperature, exposed_volume)
overload()
-/obj/machinery/power/rtg/abductor/tesla_act()
- ..() //extend the zap
- overload()
+/obj/machinery/power/rtg/abductor/zap_act(power, zap_flags, shocked_objects)
+ . = ..() //extend the zap
+ if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
+ overload()
diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm
index 64d317b385..eb80548441 100644
--- a/code/modules/power/tesla/coil.dm
+++ b/code/modules/power/tesla/coil.dm
@@ -73,7 +73,7 @@
return ..()
-/obj/machinery/power/tesla_coil/tesla_act(power, tesla_flags, shocked_targets)
+/obj/machinery/power/tesla_coil/zap_act(power, zap_flags, shocked_targets)
if(anchored && !panel_open)
obj_flags |= BEING_SHOCKED
//don't lose arc power when it's not connected to anything
@@ -81,17 +81,17 @@
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("coilhit", src)
- playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
- tesla_zap(src, 5, power_produced, tesla_flags, shocked_targets)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
D.adjust_money(min(power_produced, 1))
if(istype(linked_techweb))
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 1)) // x4 coils = ~240/m point bonus for R&D
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
- tesla_buckle_check(power)
+ zap_buckle_check(power)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
+ return power_produced
else
- ..()
+ . = ..()
/obj/machinery/power/tesla_coil/proc/zap()
if((last_zap + zap_cooldown) > world.time || !powernet)
@@ -102,8 +102,8 @@
var/power = (powernet.avail/2)
add_load(power)
playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
- tesla_zap(src, 10, power/(coeff/2), TESLA_FUSION_FLAGS)
- tesla_buckle_check(power/(coeff/2))
+ tesla_zap(src, 10, power/(coeff/2), ZAP_FUSION_FLAGS)
+ zap_buckle_check(power/(coeff/2))
// Tesla R&D researcher
/obj/machinery/power/tesla_coil/research
@@ -113,23 +113,23 @@
circuit = /obj/item/circuitboard/machine/tesla_coil/research
power_loss = 20 // something something, high voltage + resistance
-/obj/machinery/power/tesla_coil/research/tesla_act(power, tesla_flags, shocked_things)
+/obj/machinery/power/tesla_coil/research/zap_act(power, zap_flags, shocked_targets)
if(anchored && !panel_open)
obj_flags |= BEING_SHOCKED
var/power_produced = powernet ? power / power_loss : power
add_avail(power_produced*input_power_multiplier)
flick("rpcoilhit", src)
- playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5)
- tesla_zap(src, 5, power_produced, tesla_flags, shocked_things)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_ENG)
if(D)
D.adjust_money(min(power_produced, 3))
if(istype(linked_techweb))
linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, min(power_produced, 3)) // x4 coils with a pulse per second or so = ~720/m point bonus for R&D
addtimer(CALLBACK(src, .proc/reset_shocked), 10)
- tesla_buckle_check(power)
+ zap_buckle_check(power)
+ playsound(src.loc, 'sound/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
+ return power_produced
else
- ..()
+ . = ..()
/obj/machinery/power/tesla_coil/research/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20)
. = ..()
@@ -180,9 +180,10 @@
return ..()
-/obj/machinery/power/grounding_rod/tesla_act(var/power)
+/obj/machinery/power/grounding_rod/zap_act(var/power)
if(anchored && !panel_open)
flick("grounding_rodhit", src)
- tesla_buckle_check(power)
+ zap_buckle_check(power)
+ return 0
else
- ..()
+ . = ..()
diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm
index e98fe3c88e..06e5d27f6d 100644
--- a/code/modules/power/tesla/energy_ball.dm
+++ b/code/modules/power/tesla/energy_ball.dm
@@ -1,5 +1,14 @@
#define TESLA_DEFAULT_POWER 1738260
#define TESLA_MINI_POWER 869130
+//Zap constants, speeds up targeting
+#define BIKE (COIL + 1)
+#define COIL (ROD + 1)
+#define ROD (RIDE + 1)
+#define RIDE (LIVING + 1)
+#define LIVING (MACHINERY + 1)
+#define MACHINERY (BLOB + 1)
+#define BLOB (STRUCTURE + 1)
+#define STRUCTURE (1)
/obj/singularity/energy_ball
name = "energy ball"
@@ -32,6 +41,9 @@
/obj/singularity/energy_ball/ex_act(severity, target)
return
+/obj/singularity/energy_ball/consume(severity, target)
+ return
+
/obj/singularity/energy_ball/Destroy()
if(orbiting && istype(orbiting.parent, /obj/singularity/energy_ball))
var/obj/singularity/energy_ball/EB = orbiting.parent
@@ -39,7 +51,7 @@
for(var/ball in orbiting_balls)
var/obj/singularity/energy_ball/EB = ball
- qdel(EB)
+ QDEL_NULL(EB)
. = ..()
@@ -55,12 +67,12 @@
move_the_basket_ball(4 + orbiting_balls.len * 1.5)
- playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 30)
+ playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, TRUE, extrarange = 30)
pixel_x = 0
pixel_y = 0
- tesla_zap(src, 7, TESLA_DEFAULT_POWER, TRUE)
+ tesla_zap(src, 7, TESLA_DEFAULT_POWER)
pixel_x = -32
pixel_y = -32
@@ -73,7 +85,7 @@
/obj/singularity/energy_ball/examine(mob/user)
. = ..()
if(orbiting_balls.len)
- . += "The amount of orbiting mini-balls is [orbiting_balls.len]."
+ . += "There are [orbiting_balls.len] mini-balls orbiting it."
/obj/singularity/energy_ball/proc/move_the_basket_ball(var/move_amount)
@@ -96,7 +108,7 @@
energy_to_lower = energy_to_raise - 20
energy_to_raise = energy_to_raise * 1.25
- playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 30)
+ playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, TRUE, extrarange = 30)
addtimer(CALLBACK(src, .proc/new_mini_ball), 100)
else if(energy < energy_to_lower && orbiting_balls.len)
@@ -132,22 +144,19 @@
/obj/singularity/energy_ball/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
- log_game("[key_name(C)] has been disintegrated by a telekenetic grab on a tesla ball.")
to_chat(C, "That was a shockingly dumb idea.")
- C.visible_message("A bright flare of lightning is seen from [C]'s head, shortly before you hear a sickening sizzling!")
var/obj/item/organ/brain/rip_u = locate(/obj/item/organ/brain) in C.internal_organs
- rip_u.Remove()
+ C.ghostize(0)
qdel(rip_u)
- return
- return ..()
+ C.death()
/obj/singularity/energy_ball/orbit(obj/singularity/energy_ball/target)
if (istype(target))
target.orbiting_balls += src
GLOB.poi_list -= src
target.dissipate_strength = target.orbiting_balls.len
-
. = ..()
+
/obj/singularity/energy_ball/stop_orbit()
if (orbiting && istype(orbiting.parent, /obj/singularity/energy_ball))
var/obj/singularity/energy_ball/orbitingball = orbiting.parent
@@ -171,20 +180,19 @@
var/mob/living/carbon/C = A
C.dust()
-/proc/tesla_zap(atom/source, zap_range = 3, power, tesla_flags = TESLA_DEFAULT_FLAGS, list/shocked_targets)
+/proc/tesla_zap(atom/source, zap_range = 3, power, zap_flags = ZAP_DEFAULT_FLAGS, list/shocked_targets)
+ if(QDELETED(source))
+ return
. = source.dir
if(power < 1000)
return
- var/closest_dist = 0
- var/closest_atom
- var/obj/machinery/power/tesla_coil/closest_tesla_coil
- var/obj/machinery/power/grounding_rod/closest_grounding_rod
- var/mob/living/closest_mob
- var/obj/machinery/closest_machine
- var/obj/structure/closest_structure
- var/obj/structure/blob/closest_blob
- var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure))
+ /*
+ THIS IS SO FUCKING UGLY AND I HATE IT, but I can't make it nice without making it slower, check*N rather then n. So we're stuck with it.
+ */
+ var/atom/closest_atom
+ var/closest_type = 0
+ var/static/things_to_shock = typecacheof(list(/obj/machinery, /mob/living, /obj/structure, /obj/vehicle/ridden))
var/static/blacklisted_tesla_types = typecacheof(list(/obj/machinery/atmospherics,
/obj/machinery/power/emitter,
/obj/machinery/field/generator,
@@ -205,112 +213,133 @@
/obj/machinery/gateway,
/obj/structure/lattice,
/obj/structure/grille,
- /obj/machinery/the_singularitygen/tesla,
/obj/structure/frame/machine))
- for(var/A in typecache_filter_multi_list_exclusion(oview(source, zap_range+2), things_to_shock, blacklisted_tesla_types))
- if(!(tesla_flags & TESLA_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A))
+ //Ok so we are making an assumption here. We assume that view() still calculates from the center out.
+ //This means that if we find an object we can assume it is the closest one of its type. This is somewhat of a speed increase.
+ //This also means we have no need to track distance, as the doview() proc does it all for us.
+
+ //Darkness fucks oview up hard. I've tried dview() but it doesn't seem to work
+ //I hate existance
+ for(var/a in typecache_filter_multi_list_exclusion(oview(zap_range+2, source), things_to_shock, blacklisted_tesla_types))
+ var/atom/A = a
+ if(!(zap_flags & ZAP_ALLOW_DUPLICATES) && LAZYACCESS(shocked_targets, A))
continue
+ if(closest_type >= BIKE)
+ break
- if(istype(A, /obj/machinery/power/tesla_coil))
- var/dist = get_dist(source, A)
- var/obj/machinery/power/tesla_coil/C = A
- if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(C.obj_flags & BEING_SHOCKED))
- closest_dist = dist
-
+ else if(istype(A, /obj/vehicle/ridden/bicycle))//God's not on our side cause he hates idiots.
+ var/obj/vehicle/ridden/bicycle/B = A
+ if(!(B.obj_flags & BEING_SHOCKED) && B.can_buckle)//Gee goof thanks for the boolean
//we use both of these to save on istype and typecasting overhead later on
//while still allowing common code to run before hand
- closest_tesla_coil = C
- closest_atom = C
+ closest_type = BIKE
+ closest_atom = B
-
- else if(closest_tesla_coil)
+ else if(closest_type >= COIL)
continue //no need checking these other things
- else if(istype(A, /obj/machinery/power/grounding_rod))
- var/dist = get_dist(source, A)-2
- if(dist <= zap_range && (dist < closest_dist || !closest_grounding_rod))
- closest_grounding_rod = A
- closest_atom = A
- closest_dist = dist
+ else if(istype(A, /obj/machinery/power/tesla_coil))
+ var/obj/machinery/power/tesla_coil/C = A
+ if(!(C.obj_flags & BEING_SHOCKED))
+ closest_type = COIL
+ closest_atom = C
- else if(closest_grounding_rod)
+ else if(closest_type >= ROD)
+ continue
+
+ else if(istype(A, /obj/machinery/power/grounding_rod))
+ closest_type = ROD
+ closest_atom = A
+
+ else if(closest_type >= RIDE)
+ continue
+
+ else if(istype(A,/obj/vehicle/ridden))
+ var/obj/vehicle/ridden/R = A
+ if(R.can_buckle && !(R.obj_flags & BEING_SHOCKED))
+ closest_type = RIDE
+ closest_atom = A
+
+ else if(closest_type >= LIVING)
continue
else if(isliving(A))
- var/dist = get_dist(source, A)
var/mob/living/L = A
- if(dist <= zap_range && (dist < closest_dist || !closest_mob) && L.stat != DEAD && !(L.flags_1 & TESLA_IGNORE_1))
- closest_mob = L
+ if(L.stat != DEAD && !(HAS_TRAIT(L, TRAIT_TESLA_SHOCKIMMUNE)) && !(L.flags_1 & SHOCKED_1))
+ closest_type = LIVING
closest_atom = A
- closest_dist = dist
- else if(closest_mob)
+ else if(closest_type >= MACHINERY)
continue
else if(ismachinery(A))
var/obj/machinery/M = A
- var/dist = get_dist(source, A)
- if(dist <= zap_range && (dist < closest_dist || !closest_machine) && !(M.obj_flags & BEING_SHOCKED))
- closest_machine = M
+ if(!(M.obj_flags & BEING_SHOCKED))
+ closest_type = MACHINERY
closest_atom = A
- closest_dist = dist
- else if(closest_mob)
+ else if(closest_type >= BLOB)
continue
else if(istype(A, /obj/structure/blob))
var/obj/structure/blob/B = A
- var/dist = get_dist(source, A)
- if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(B.obj_flags & BEING_SHOCKED))
- closest_blob = B
+ if(!(B.obj_flags & BEING_SHOCKED))
+ closest_type = BLOB
closest_atom = A
- closest_dist = dist
- else if(closest_blob)
+ else if(closest_type >= STRUCTURE)
continue
else if(isstructure(A))
var/obj/structure/S = A
- var/dist = get_dist(source, A)
- if(dist <= zap_range && (dist < closest_dist || !closest_tesla_coil) && !(S.obj_flags & BEING_SHOCKED))
- closest_structure = S
+ if(!(S.obj_flags & BEING_SHOCKED))
+ closest_type = STRUCTURE
closest_atom = A
- closest_dist = dist
//Alright, we've done our loop, now lets see if was anything interesting in range
- if(closest_atom)
- //common stuff
- source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY)
- if(!(tesla_flags & TESLA_ALLOW_DUPLICATES))
- LAZYSET(shocked_targets, closest_atom, TRUE)
- var/zapdir = get_dir(source, closest_atom)
- if(zapdir)
- . = zapdir
+ if(!closest_atom)
+ return
+ //common stuff
+ source.Beam(closest_atom, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY)
+ if(!(zap_flags & ZAP_ALLOW_DUPLICATES))
+ LAZYSET(shocked_targets, closest_atom, TRUE)
+ var/zapdir = get_dir(source, closest_atom)
+ if(zapdir)
+ . = zapdir
- //per type stuff:
- if(closest_tesla_coil)
- closest_tesla_coil.tesla_act(power, tesla_flags, shocked_targets)
+ var/next_range = 3
+ if(closest_type == COIL)
+ next_range = 5
- else if(closest_grounding_rod)
- closest_grounding_rod.tesla_act(power, tesla_flags, shocked_targets)
-
- else if(closest_mob)
- var/shock_damage = (tesla_flags & TESLA_MOB_DAMAGE)? (min(round(power/600), 90) + rand(-5, 5)) : 0
- closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((tesla_flags & TESLA_MOB_STUN) ? NONE : SHOCK_NOSTUN))
+ if(closest_type == LIVING)
+ var/mob/living/closest_mob = closest_atom
+ closest_mob.set_shocked()
+ addtimer(CALLBACK(closest_mob, /mob/living/proc/reset_shocked), 10)
+ var/shock_damage = (zap_flags & ZAP_MOB_DAMAGE) ? (min(round(power/600), 90) + rand(-5, 5)) : 0
+ closest_mob.electrocute_act(shock_damage, source, 1, SHOCK_TESLA | ((zap_flags & ZAP_MOB_STUN) ? NONE : SHOCK_NOSTUN))
if(issilicon(closest_mob))
var/mob/living/silicon/S = closest_mob
- if((tesla_flags & TESLA_MOB_STUN) && (tesla_flags & TESLA_MOB_DAMAGE))
+ if((zap_flags & ZAP_MOB_STUN) && (zap_flags & ZAP_MOB_DAMAGE))
S.emp_act(EMP_LIGHT)
- tesla_zap(S, 7, power / 1.5, tesla_flags, shocked_targets) // metallic folks bounce it further
+ next_range = 7 // metallic folks bounce it further
else
- tesla_zap(closest_mob, 5, power / 1.5, tesla_flags, shocked_targets)
+ next_range = 5
+ power /= 1.5
- else if(closest_machine)
- closest_machine.tesla_act(power, tesla_flags, shocked_targets)
+ else
+ power = closest_atom.zap_act(power, zap_flags, shocked_targets)
+ if(prob(20))//I know I know
+ tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets)
+ tesla_zap(closest_atom, next_range, power * 0.5, zap_flags, shocked_targets)
+ else
+ tesla_zap(closest_atom, next_range, power, zap_flags, shocked_targets)
- else if(closest_blob)
- closest_blob.tesla_act(power, tesla_flags, shocked_targets)
-
- else if(closest_structure)
- closest_structure.tesla_act(power, tesla_flags, shocked_targets)
+#undef BIKE
+#undef COIL
+#undef ROD
+#undef RIDE
+#undef LIVING
+#undef MACHINERY
+#undef BLOB
+#undef STRUCTURE
diff --git a/code/modules/power/tesla/generator.dm b/code/modules/power/tesla/generator.dm
index 53d7010806..260f4128bc 100644
--- a/code/modules/power/tesla/generator.dm
+++ b/code/modules/power/tesla/generator.dm
@@ -5,6 +5,6 @@
icon_state = "TheSingGen"
creation_type = /obj/singularity/energy_ball
-/obj/machinery/the_singularitygen/tesla/tesla_act(power, tesla_flags)
- if(tesla_flags & TESLA_MACHINE_EXPLOSIVE)
+/obj/machinery/the_singularitygen/tesla/zap_act(power, zap_flags)
+ if(zap_flags & ZAP_MACHINE_EXPLOSIVE)
energy += power
diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm
index 2439cee429..1afbdeae25 100644
--- a/code/modules/projectiles/projectile/energy/tesla.dm
+++ b/code/modules/projectiles/projectile/energy/tesla.dm
@@ -3,7 +3,7 @@
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser
var/chain
- var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE
+ var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE
var/zap_range = 3
var/power = 10000
@@ -15,7 +15,7 @@
/obj/item/projectile/energy/tesla/on_hit(atom/target)
. = ..()
- tesla_zap(target, zap_range, power, tesla_flags)
+ tesla_zap(target, zap_range, power, zap_flags)
qdel(src)
/obj/item/projectile/energy/tesla/Destroy()
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index ff6340bcdb..dbb1497367 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -437,9 +437,9 @@
speed = 0.3
flag = "magic"
- var/tesla_power = 20000
- var/tesla_range = 15
- var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_MOB_STUN | TESLA_OBJ_DAMAGE
+ var/zap_power = 20000
+ var/zap_range = 15
+ var/zap_flags = ZAP_MOB_DAMAGE | ZAP_MOB_STUN | ZAP_OBJ_DAMAGE
var/chain
var/mob/living/caster
@@ -456,7 +456,7 @@
visible_message("[src] fizzles on contact with [target]!")
qdel(src)
return BULLET_ACT_BLOCK
- tesla_zap(src, tesla_range, tesla_power, tesla_flags)
+ tesla_zap(src, zap_range, zap_power, zap_flags)
qdel(src)
/obj/item/projectile/magic/aoe/lightning/Destroy()
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 67ff61610d..50d94a637e 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -227,6 +227,18 @@
playsound(M, "sparks", 50, 1)
..()
+/datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/L)
+ . = ..()
+ if(!istype(L))
+ return
+ L.physiology.siemens_coeff *= 2
+
+/datum/reagent/teslium/on_mob_end_metabolize(mob/living/carbon/human/L)
+ . = ..()
+ if(!istype(L))
+ return
+ L.physiology.siemens_coeff *= 0.5
+
/datum/reagent/teslium/energized_jelly
name = "Energized Jelly"
description = "Electrically-charged jelly. Boosts jellypeople's nervous system, but only shocks other lifeforms."
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index 8782d65f76..1d06aaacde 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -429,7 +429,7 @@
noexplosion = TRUE
mix_message = "The teslium starts to spark as electricity arcs away from it!"
mix_sound = 'sound/machines/defib_zap.ogg'
- var/tesla_flags = TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN
+ var/zap_flags = ZAP_MOB_DAMAGE | ZAP_OBJ_DAMAGE | ZAP_MOB_STUN
/datum/chemical_reaction/reagent_explosion/teslium_lightning/on_reaction(datum/reagents/holder, multiplier)
var/T1 = multiplier * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison.
@@ -437,15 +437,15 @@
var/T3 = multiplier * 120
sleep(5)
if(multiplier >= 75)
- tesla_zap(holder.my_atom, 7, T1, tesla_flags)
+ tesla_zap(holder.my_atom, 7, T1, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
sleep(15)
if(multiplier >= 40)
- tesla_zap(holder.my_atom, 7, T2, tesla_flags)
+ tesla_zap(holder.my_atom, 7, T2, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
sleep(15)
if(multiplier >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast.
- tesla_zap(holder.my_atom, 7, T3, tesla_flags)
+ tesla_zap(holder.my_atom, 7, T3, zap_flags)
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
..()
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index c8e50667a8..9ef08590a8 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -120,9 +120,10 @@
/obj/structure/reagent_dispensers/fueltank/fire_act(exposed_temperature, exposed_volume)
boom()
-/obj/structure/reagent_dispensers/fueltank/tesla_act()
+/obj/structure/reagent_dispensers/fueltank/zap_act(power, zap_flags, shocked_objects)
..() //extend the zap
- boom()
+ if(ZAP_OBJ_DAMAGE & zap_flags)
+ boom()
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/P)
. = ..()
diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm
index 1a904b1076..8fab4a221d 100644
--- a/code/modules/spells/spell_types/aimed.dm
+++ b/code/modules/spells/spell_types/aimed.dm
@@ -101,7 +101,7 @@
base_icon_state = "lightning"
sound = 'sound/magic/lightningbolt.ogg'
active = FALSE
- projectile_var_overrides = list("tesla_range" = 15, "tesla_power" = 20000, "tesla_flags" = TESLA_MOB_DAMAGE)
+ projectile_var_overrides = list("zap_range" = 15, "zap_power" = 20000, "zap_flags" = ZAP_MOB_DAMAGE)
active_msg = "You energize your hand with arcane lightning!"
deactive_msg = "You let the energy flow out of your hands back into yourself..."
projectile_type = /obj/item/projectile/magic/aoe/lightning
diff --git a/code/modules/surgery/advanced/bioware/nerve_grounding.dm b/code/modules/surgery/advanced/bioware/nerve_grounding.dm
index 99902ff6d6..eb70a838a4 100644
--- a/code/modules/surgery/advanced/bioware/nerve_grounding.dm
+++ b/code/modules/surgery/advanced/bioware/nerve_grounding.dm
@@ -32,13 +32,11 @@
name = "Grounded Nerves"
desc = "Nerves form a safe path for electricity to traverse, protecting the body from electric shocks."
mod_type = BIOWARE_NERVES
- var/prev_coeff
/datum/bioware/grounded_nerves/on_gain()
..()
- prev_coeff = owner.physiology.siemens_coeff
- owner.physiology.siemens_coeff = 0
+ ADD_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves")
/datum/bioware/grounded_nerves/on_lose()
..()
- owner.physiology.siemens_coeff = prev_coeff
+ REMOVE_TRAIT(owner, TRAIT_SHOCKIMMUNE, "grounded_nerves")
diff --git a/code/modules/vehicles/bicycle.dm b/code/modules/vehicles/bicycle.dm
index 84e0fcbefc..3784f4d459 100644
--- a/code/modules/vehicles/bicycle.dm
+++ b/code/modules/vehicles/bicycle.dm
@@ -24,10 +24,12 @@
buckled_mob.stop_sound_channel(CHANNEL_BICYCLE)
. =..()
-/obj/vehicle/ridden/bicycle/tesla_act() // :::^^^)))
+/obj/vehicle/ridden/bicycle/zap_act(zap_str, zap_flags, shocked_targets) // :::^^^)))
+ //This didn't work for 3 years because none ever tested it I hate life
name = "fried bicycle"
desc = "Well spent."
color = rgb(63, 23, 4)
can_buckle = FALSE
+ . = ..()
for(var/m in buckled_mobs)
unbuckle_mob(m,1)
diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm
index 4f3970dd37..f71d9367d3 100644
--- a/code/modules/vehicles/ridden.dm
+++ b/code/modules/vehicles/ridden.dm
@@ -77,3 +77,7 @@
if(!force && occupant_amount() >= max_occupants)
return FALSE
return ..()
+
+/obj/vehicle/ridden/zap_act(zap_str, zap_flags, shocked_targets)
+ zap_buckle_check(zap_str)
+ . = ..()