diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index e128530958d..4c39d2e8414 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1220,3 +1220,21 @@ B --><-- A for(var/atom/location = A.loc, location, location = location.loc) if(location == src) return 1 + + +/proc/get_closest_atom(type, list, source) + var/closest_atom + var/closest_distance + for(var/A in list) + if(!istype(A, type)) + continue + var/distance = get_dist(source, A) + if(!closest_distance) + closest_distance = distance + closest_atom = A + else + if(closest_distance > distance) + closest_distance = distance + closest_atom = A + return closest_atom + diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 49ad34f033a..2470949b883 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -412,4 +412,16 @@ Class Procs: if (hclient.client.mob && hclient.client.mob.machine == src) hclient.client.mob.unset_machine() /obj/machinery/proc/can_be_overridden() - . = 1 \ No newline at end of file + . = 1 + + +/obj/machinery/tesla_act(var/power) + ..() + if(prob(85)) + emp_act(2) + else if(prob(50)) + ex_act(3) + else if(prob(90)) + ex_act(2) + else + ex_act(1) diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index d11aed5a694..f34f92ce559 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -28,44 +28,44 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, grav_pull = 0 contained = 0 density = 1 - + var/list/orbiting_balls = list() var/produced_power - var/energy_to_raise = 100 - var/energy_to_lower = -10 + var/energy_to_raise = 32 + var/energy_to_lower = -20 /obj/singularity/energy_ball/Destroy() - if (orbiting && istype(orbiting, /obj/singularity/energy_ball)) + if(orbiting && istype(orbiting, /obj/singularity/energy_ball)) var/obj/singularity/energy_ball/EB = orbiting EB.orbiting_balls -= src orbiting = null - + for(var/ball in orbiting_balls) var/obj/singularity/energy_ball/EB = ball qdel(EB) - + return ..() /obj/singularity/energy_ball/process() - if(orbiting) + if(!orbiting) handle_energy() - + move_the_basket_ball(2 + orbiting_balls.len * 2) - + playsound(src.loc, 'sound/magic/lightningbolt.ogg', 100, 1, extrarange = 15) - + pixel_x = 0 pixel_y = 0 - + dir = tesla_zap(src, 7, TESLA_DEFAULT_POWER) - + pixel_x = -32 pixel_y = -32 for (var/ball in orbiting_balls) tesla_zap(ball, rand(1, Clamp(orbiting_balls.len, 3, 7)), TESLA_MINI_POWER) else energy = 0 // ensure we dont have miniballs of miniballs - + return /obj/singularity/energy_ball/examine(mob/user) @@ -85,28 +85,28 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, /obj/singularity/energy_ball/proc/handle_energy() if(energy >= energy_to_raise) - energy_to_lower = energy_to_raise - 10 + energy_to_lower = energy_to_raise - 20 energy_to_raise += energy_to_raise playsound(src.loc, 'sound/magic/lightning_chargeup.ogg', 100, 1, extrarange = 15) spawn(100) var/obj/singularity/energy_ball/EB = new(loc) - + EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7) var/icon/I = icon(icon,icon_state,dir) - - var/orbitsize = (I.Width() + I.Height()) * pick(0.5, 0.6, 0.7) + + var/orbitsize = (I.Width() + I.Height()) * pick(0.4, 0.5, 0.6, 0.7, 0.8) orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) - + EB.orbit(src, orbitsize, pick(FALSE, TRUE), rand(10, 25), pick(3, 4, 5, 6, 36)) - + else if(energy < energy_to_lower && orbiting_balls.len) energy_to_raise = energy_to_raise * 0.5 - energy_to_lower = (energy_to_raise * 0.5) - 10 - + energy_to_lower = (energy_to_raise * 0.5) - 20 + var/Orchiectomy_target = pick(orbiting_balls) qdel(Orchiectomy_target) - + else if(orbiting_balls.len) energy -= orbiting_balls.len @@ -120,9 +120,9 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, if (istype(target)) target.orbiting_balls += src poi_list -= src - + . = ..() - + if (istype(target)) target.orbiting_balls -= src @@ -132,106 +132,105 @@ var/list/blacklisted_tesla_types = list(/obj/machinery/atmospherics, C.dust() return -/proc/get_closest_atom(list, source, typetocheck) - var/closest_atom - var/closest_distance - for(var/A in list) - if (typetocheck && !istype(A, typetocheck)) - continue - var/distance = get_dist(source, A) - if(!closest_atom || closest_distance > distance) - closest_distance = distance - closest_atom = A - return closest_atom - /proc/tesla_zap(var/atom/source, zap_range = 3, power) . = source.dir if(power < 1000) return - var/list/tesla_coils = list() - var/list/grounding_rods = list() - var/list/potential_machine_zaps = list() - var/list/potential_mob_zaps = list() - var/list/potential_structure_zaps = list() + + var/closest_dist = 0 var/closest_atom - for(var/atom/A in oview(source, zap_range)) + 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 + + for(var/A in oview(source, zap_range)) if(istype(A, /obj/machinery/power/tesla_coil)) + var/dist = get_dist(source, A) var/obj/machinery/power/tesla_coil/C = A - if(!C.being_shocked) - tesla_coils += C + if((dist < closest_dist || !closest_tesla_coil) && !C.being_shocked) + closest_dist = dist + + //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 + + + else if(closest_tesla_coil) + continue //no need checking these other things else if(istype(A, /obj/machinery/power/grounding_rod)) - var/obj/machinery/power/grounding_rod/R = A - grounding_rods += R - + var/dist = get_dist(source, A) + if(dist < closest_dist || !closest_grounding_rod) + closest_grounding_rod = A + closest_atom = A + closest_dist = dist + + else if(closest_grounding_rod || is_type_in_list(A, blacklisted_tesla_types)) + continue + + else if(istype(A, /mob/living)) + var/dist = get_dist(source, A) + var/mob/living/L = A + if((dist < closest_dist || !closest_mob) && L.stat != DEAD) + closest_mob = L + closest_atom = A + closest_dist = dist + + else if(closest_mob) + continue + else if(istype(A, /obj/machinery)) var/obj/machinery/M = A - if(!is_type_in_list(M, blacklisted_tesla_types) && !M.being_shocked) - potential_machine_zaps += M - + var/dist = get_dist(source, A) + if((dist < closest_dist || !closest_machine) && !M.being_shocked) + closest_machine = M + closest_atom = A + closest_dist = dist + + else if(closest_mob) + continue + else if(istype(A, /obj/structure)) - var/obj/structure/M = A - if(!is_type_in_list(M, blacklisted_tesla_types) && !M.being_shocked) - potential_structure_zaps += M - - else if(istype(A, /mob/living)) - var/mob/living/L = A - if(!is_type_in_list(L, blacklisted_tesla_types) && L.stat != DEAD) - potential_mob_zaps += L + var/obj/structure/S = A + var/dist = get_dist(source, A) + if((dist < closest_dist || !closest_tesla_coil) && !S.being_shocked) + closest_structure = S + closest_atom = A + closest_dist = dist - closest_atom = get_closest_atom(tesla_coils, source) - if(closest_atom) - var/obj/machinery/power/tesla_coil/C = closest_atom - source.Beam(C, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5) - C.tesla_act(power) - if(!closest_atom) - closest_atom = get_closest_atom(grounding_rods, source) - if(closest_atom) - var/obj/machinery/power/grounding_rod/R = closest_atom - source.Beam(R, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5) - R.tesla_act(power) - - if(!closest_atom) - closest_atom = get_closest_atom(potential_mob_zaps, source) - if(closest_atom) - var/mob/living/L = closest_atom - var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) - source.Beam(L, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5) - L.electrocute_act(shock_damage, source, 1, tesla_shock = 1) - if(istype(L, /mob/living/silicon)) - var/mob/living/silicon/S = L - S.emp_act(2) - tesla_zap(S, 7, power / 1.5) // metallic folks bounce it further - else - tesla_zap(L, 5, power / 1.5) - - if(!closest_atom) - closest_atom = get_closest_atom(potential_machine_zaps, source) - if(closest_atom) - var/obj/machinery/M = closest_atom - source.Beam(M, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi',time=5) - M.tesla_act(power) - if(prob(85)) - M.emp_act(2) - else - if(prob(50)) - M.ex_act(3) - else - if(prob(90)) - M.ex_act(2) - else - M.ex_act(1) - - if(!closest_atom) - closest_atom = get_closest_atom(/obj/structure, potential_structure_zaps, source) - if(closest_atom) - var/obj/structure/S = closest_atom - source.Beam(S, icon_state="lightning[rand(1,12)]", icon='icons/effects/effects.dmi', time=5) - S.tesla_act(power) - + //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)]", icon='icons/effects/effects.dmi', time=5) var/zapdir = get_dir(source, closest_atom) - if (zapdir) - . = zapdir + if(zapdir) + . = closest_atom + + //per type stuff: + if(closest_tesla_coil) + closest_tesla_coil.tesla_act(power) + + else if(closest_grounding_rod) + closest_grounding_rod.tesla_act(power) + + else if(closest_mob) + var/shock_damage = Clamp(round(power/400), 10, 90) + rand(-5, 5) + closest_mob.electrocute_act(shock_damage, source, 1, tesla_shock = 1) + if(istype(closest_mob, /mob/living/silicon)) + var/mob/living/silicon/S = closest_mob + S.emp_act(2) + tesla_zap(S, 7, power / 1.5) // metallic folks bounce it further + else + tesla_zap(closest_mob, 5, power / 1.5) + + else if(closest_machine) + closest_machine.tesla_act(power) + + else if(closest_structure) + closest_structure.tesla_act(power) + diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 3b8886f3571..26807a8dfe0 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -91,22 +91,28 @@ return message_admins("[key_name_admin(Proj.firer)] triggered a fueltank explosion.") log_game("[key_name(Proj.firer)] triggered a fueltank explosion.") - explosion(src.loc,-1,0,2, flame_range = 2) + boom() - -/obj/structure/reagent_dispensers/fueltank/blob_act() +/obj/structure/reagent_dispensers/fueltank/proc/boom() explosion(src.loc,0,1,5,7,10, flame_range = 5) - - -/obj/structure/reagent_dispensers/fueltank/ex_act() - explosion(src.loc,-1,0,2, flame_range = 2) if(src) qdel(src) +/obj/structure/reagent_dispensers/fueltank/blob_act() + boom() + + +/obj/structure/reagent_dispensers/fueltank/ex_act() + boom() + + /obj/structure/reagent_dispensers/fueltank/fire_act() - blob_act() //saving a few lines of copypasta + boom() +/obj/structure/reagent_dispensers/fueltank/tesla_act() + ..() //extend the zap + boom() /obj/structure/reagent_dispensers/peppertank name = "Pepper Spray Refiller"