Files
Aurora.3/code/game/objects/empulse.dm
Fluffy d8d063edc6 EMP Refactor & Multi Z-level EMPs (#17781)
* sdfasf

* sdfas

* dsf
2023-12-04 19:37:49 +00:00

108 lines
3.7 KiB
Plaintext

// #define EMPDEBUG 10
/**
* Produces an EMP pulse from `epicenter` up to `light_range`
*
* Calls `emp_act()` with a value of `EMP_HEAVY` up to `heavy_range`, with 50% probability between `EMP_HEAVY` and `EMP_LIGHT` at the exact `heavy_range`,
* and with `EMP_LIGHT` up to and including `light_range`
*
*
* * epicenter - A `/turf` where to start the explosion from
* * heavy_range - The range in which `EMP_HEAVY` is applied, as a number
* * light_range - The range, higher or equal than `heavy_range`, where `EMP_LIGHT` is applied, as a number
* * log - Boolean, if you want this call to be logged
* * exclude - A `/list` of objects to exclude, and/or paths to exclude
*
*/
/proc/empulse(turf/epicenter, heavy_range, light_range, log = FALSE, list/exclude = null)
if(!epicenter)
return FALSE
if(!istype(epicenter, /turf))
epicenter = get_turf(epicenter.loc)
//Ensure we got an actual location, no nullspace or error or other shit
if(!(epicenter.x && epicenter.y && epicenter.z))
return FALSE
if(log)
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
if(heavy_range > 1)
var/obj/effect/overlay/pulse = new /obj/effect/overlay(epicenter)
pulse.icon = 'icons/effects/effects.dmi'
pulse.icon_state = "emppulse"
pulse.name = "emp pulse"
pulse.anchored = 1
QDEL_IN(pulse, 2 SECONDS)
if(heavy_range > light_range)
light_range = heavy_range
var/list/connected_z_levels = GetConnectedZlevels(epicenter.z) //Get every zlevel that is part of the current location
for(var/z in connected_z_levels)
//We obtain a virtual epicenter for each connected zlevel
var/virtual_epicenter = locate(epicenter.x, epicenter.y, z)
//We assume each zlevel to be 9 meters tall, and apply the pythagorean theorem to obtain the radius of the sphere at that vertical distance from the epicenter
var/virtual_heavy_range = abs(epicenter.z - z) ? ( sqrt(((heavy_range*heavy_range)-((9*(epicenter.z - z))*(9*(epicenter.z - z))))) ) : heavy_range
var/virtual_light_range = abs(epicenter.z - z) ? ( sqrt(((light_range*light_range)-((9*(epicenter.z - z))*(9*(epicenter.z - z))))) ) : light_range
#ifdef EMPDEBUG
log_and_message_admins("EMPDEBUG: Heavy range for explosion at Z-level [z] is [virtual_heavy_range]")
log_and_message_admins("EMPDEBUG: Light range for explosion at Z-level [z] is [virtual_light_range]")
#endif //EMPDEBUG
if(virtual_light_range < 0 && virtual_heavy_range < 0)
continue
if(virtual_heavy_range > 1)
for(var/mob/M in range(virtual_heavy_range, virtual_epicenter))
sound_to(M, 'sound/effects/EMPulse.ogg')
CHECK_TICK
loop_apply_emp:
for(var/atom/A in spiral_range(max(virtual_light_range, virtual_heavy_range) , virtual_epicenter))
#ifdef EMPDEBUG
var/time = world.timeofday
#endif
if(exclude && length(exclude)) //We have a list with at least one element to exclude
for(var/element in exclude)
if(ispath(element))
if(istype(A, element))
continue loop_apply_emp
else
if(A == element)
continue loop_apply_emp
var/distance = get_dist(epicenter, A)
if(distance < 0)
distance = 0
if(distance < virtual_heavy_range)
A.emp_act(EMP_HEAVY)
else if(distance == virtual_heavy_range)
if(prob(50)) //50% probability it's heavy or light, at the exact heavy range
A.emp_act(EMP_HEAVY)
else
A.emp_act(EMP_LIGHT)
else if(distance <= virtual_light_range)
A.emp_act(EMP_LIGHT)
#ifdef EMPDEBUG
if((world.timeofday - time) >= EMPDEBUG)
log_and_message_admins("EMPDEBUG: [A.name] - [A.type] - took [world.timeofday - time]ds to process emp_act()!")
#endif //EMPDEBUG
CHECK_TICK
return TRUE