Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //----------------------------------------------
- //Raycast explosion system
- //----------------------------------------------
- var/datum/explosions/controller/the_controller = new
- #define IDLE 0
- #define STARTING 1
- #define MERGE 2
- #define PROCESSING 3
- #define INPROCESSING 4
- /datum/explosions
- controller
- var/list/datum/explosions/explosion/explosions = list()
- //var/list/datum/explosions/explosion_data/data_by_turf = list()
- var/list/list/datum/explosions/explosion_data/data_by_step = list()
- var/explosion_step = 0
- var/state = IDLE
- var/atom/movable/ray
- New()
- ray = new
- ray.invisibility = 101
- ..()
- start()
- proc
- AddExplosion(datum/explosions/explosion/exp)
- if (exp)
- sleep(0)
- explosions += exp
- state = STARTING //Activate
- AddData(datum/explosions/explosion_data/expdata, datum/explosions/explosion/exp)
- var/dist = get_dist(expdata.object, exp.ground_zero)
- var/step = explosion_step + round(dist)
- data_by_step[step] += expdata
- start()
- //----------------------------------------------------
- // Asynchonous machine. Explosion can be added intime.
- //----------------------------------------------------
- spawn while (1)
- if (state == STARTING)
- for (var/datum/explosions/explosion/exp in explosions)
- exp.calculate_explosion()
- state = MERGE
- if (state == MERGE)
- merge()
- state = PROCESSING
- if (state == PROCESSING)
- state = INPROCESSING
- start_processing()
- start_processing()
- spawn while (data_by_step[explosion_step+1])
- explosion_step++
- recalculate()
- for (var/datum/explosions/explosion_data/expdata in data_by_step[explosion_step])
- expdata.object.ex_act(expdata.power)
- data_by_step[explosion_step] -= expdata
- explosion_step = 0
- state = IDLE
- recalculate()
- for (var/list/datum/explosions/explosion_data/expdata in data_by_step)
- for (var/datum/explosions/explosion_data/check in expdata)
- if (get_turf(check.object) == check.location) continue
- check.power = check.explosion.cast_ray(get_turf(check.object)) //Find new power for moved object
- data_by_step[data_by_step.Find(expdata)] -= check //Delete old
- AddData(check, check.explosion) //Add old in new place
- merge()
- for (var/list/datum/explosions/explosion_data/expdata in data_by_step)
- for (var/datum/explosions/explosion_data/first in expdata)
- for (var/datum/explosions/explosion_data/second in expdata)
- if (first == second) continue
- if (first.object != second.object) continue
- if (first.power > second.power)
- first.power = second.power
- expdata -= second
- del(second)
- explosion
- var/turf/ground_zero
- var/radius = 0
- New(turf/loc, radius)
- if (loc && radius > 0)
- src.ground_zero = loc
- src.radius = radius
- the_controller.AddExplosion(src)
- return 1
- del(src)
- CRASH("/datum/explosions/explosion has crashed at NEW")
- proc
- cast_ray(turf/target)
- spawn(-1)
- if (!target) return 0
- var/atom/ray = the_controller.ray
- var/remain_radius = radius
- the_controller.ray.loc = ground_zero
- do
- var/taken_radius = 0
- for (var/atom/A in get_turf(ray))
- if (A == ray) continue
- if (A.vars["explosion_resistance"]) taken_radius += A:explosion_resistance
- step_towards(ray, target)
- remain_radius -= taken_radius
- while (get_turf(ray) != target && remain_radius > 0)
- the_controller.ray.loc = null
- return get_severity(remain_radius)
- cast_ray_trace(turf/target)
- spawn(-1)
- if (!target) return 0
- var/atom/ray = the_controller.ray
- var/remain_radius = radius
- var/list/datum/explosions/explosion_data/data = list()
- the_controller.ray.loc = ground_zero
- do
- for (var/atom/A in get_turf(ray))
- if (A == ray) continue
- var/datum/explosions/explosion_data/new_data = new
- new_data.object = A
- new_data.location = get_turf(A)
- new_data.power = get_severity(remain_radius)
- new_data.explosion = src
- data += new_data
- step_towards(ray, target)
- var/taken_radius = 0
- for (var/atom/A in get_turf(ray))
- if (A == ray) continue
- if (A.vars["explosion_resistance"]) taken_radius += A:explosion_resistance
- remain_radius -= taken_radius
- while (get_turf(ray) != target && remain_radius > 0)
- the_controller.ray.loc = null
- return data
- calculate_explosion()
- var/list/turf/corners = range(radius+1, ground_zero) - range(radius, ground_zero)
- for (var/turf/corner in corners)
- var/list/datum/explosions/explosion_data/data = cast_ray_trace(corner)
- the_controller.AddData(data, src)
- get_severity(radius)
- var/const/max_dest = 1 - 3/14
- var/const/hev_dest = 1 - 7/14
- var/const/lig_dest = 1 - 14/14
- if (radius >= src.radius * max_dest) return 1
- if (radius >= src.radius * hev_dest) return 2
- if (radius >= src.radius * lig_dest) return 3
- return 0
- explosion_data
- var/atom/object
- var/power = 0
- var/turf/location
- var/datum/explosions/explosion/explosion
- /datum/explosions/debug_panel
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement