Porting tesla/electrocute code updates. (#12280)

* Porting tesla/electrocute code updates.

* Why is the dominator being insta-deleted by zaps a good idea?

* Yikes.

* ah
This commit is contained in:
Ghom
2020-05-17 16:35:17 -07:00
committed by GitHub
parent fa8351ebd1
commit 12ac08d7c5
35 changed files with 345 additions and 258 deletions
+116 -87
View File
@@ -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.</span>")
to_chat(C, "<span class='userdanger'>That was a shockingly dumb idea.</span>")
C.visible_message("<span class='userdanger'>A bright flare of lightning is seen from [C]'s head, shortly before you hear a sickening sizzling!</span>")
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