mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-01-14 03:12:30 +00:00
108 lines
3.7 KiB
Plaintext
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
|