Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //----------------------------------------------
- //Raycast explosion system
- //----------------------------------------------
- var/datum/explosions/controller/the_controller = new
- var/datum/explosions/debug_panel/debug_panel = new
- #define IDLE 0
- #define NEWDATA 1
- #define NEWEXPL 2
- #define EXPLOSION 3
- #define INPROCESS 4
- /list/proc/Append(data)
- var/dimensions = args.len-1
- var/list/curlst = src
- for (var/indx = 2, indx!=dimensions, indx++)
- var/curindx = args[indx]
- if (isnum(curdim))
- if (curlst.len < curindx) curlst.len = curindx
- if (!curlst[curindx])
- curlst[curdindx] = list()
- if (indx==dimensions)
- curlst[curindx] += data
- src = curlst
- /datum/explosions
- controller
- var/list/datum/explosions/explosion/explosions = list()
- var/list/datum/explosions/explosion_data/data_garbage = list()
- var/list/list/datum/explosions/explosion_data/data_sorted = list()
- var/explosion_step = 1
- var/state = IDLE
- New()
- Start()
- proc
- AddData(datum/explosions/explosion_data/data)
- if (!data || data in data_garbage || data in data_sorted) return 0
- data_garbage += data
- state = NEWDATA
- return 1
- AddExplosion(datum/explosions/explosion/exp)
- if (!exp || exp in explosions) return 0
- explosions += exp
- state = NEWEXPL
- return 1
- Start()
- spawn(1) .()
- switch(state)
- if (IDLE)
- explosion_step = 1
- if (NEWDATA)
- SortData()
- state = EXPLOSION
- if (NEWEXPL)
- CalculateExplosions()
- if (EXPLOSION)
- DoExplosions()
- state = INPROCESS
- SortData()
- CalculateExplosions()
- for (var/datum/explosions/explosion/exp in explosions)
- exp.calculate_explosion()
- state = EXPLOSION
- DoExplosions()
- return 0
- 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)
- proc
- cast_ray(turf/target)
- if (!target) return 0
- var/turf/currturf = ground_zero
- var/remain_radius = radius
- do
- var/taken_radius = 0
- var/list/atom/stuff = list()
- var/turf/newturf = get_step_towards(currturf, target)
- stuff += currturf.contents
- stuff += currturf
- for (var/atom/A in stuff)
- if (isturf(A) || isobj(A)) taken_radius += (A:explosion_resistance ? A:explosion_resistance : 0)
- remain_radius -= taken_radius * get_dist_euclidian(currturf, newturf)
- currturf = newturf
- while (currturf != target && remain_radius > 0)
- return get_severity(remain_radius)
- cast_ray_trace(turf/target)
- if (!target) return 0
- var/turf/currturf = ground_zero
- var/remain_radius = radius
- var/list/datum/explosions/explosion_data/data = list()
- do
- var/list/atom/stuff = list()
- var/turf/newturf = get_step_towards(currturf, target)
- stuff += currturf.contents
- stuff += currturf
- for (var/atom/A in stuff)
- var/datum/explosions/explosion_data/new_data = new
- new_data.object = A
- new_data.location = currturf
- new_data.power = get_severity(remain_radius)
- new_data.explosion = src
- data += new_data
- var/taken_radius = 0
- for (var/atom/A in stuff)
- if (isturf(A) || isobj(A)) taken_radius += (A:explosion_resistance ? A:explosion_resistance : 0)
- remain_radius -= taken_radius * get_dist_euclidian(currturf, newturf)
- currturf = newturf
- while (currturf != target && remain_radius > 0)
- return data
- calculate_explosion()
- var/xx1 = min(max(1, ground_zero.x-radius), world.maxx)
- var/yy1 = min(max(1, ground_zero.y-radius), world.maxy)
- var/xx2 = min(max(1, ground_zero.x+radius), world.maxx)
- var/yy2 = min(max(1, ground_zero.y+radius), world.maxy)
- var/z = ground_zero.z
- var/list/turf/corners = block(locate(xx1,yy1,z), locate(xx2,yy2,z))
- var/list/datum/explosions/explosion_data/return_data = list()
- for (var/turf/corner in corners)
- var/list/datum/explosions/explosion_data/data = cast_ray_trace(corner)
- return_data += data
- the_controller.AddData(data)
- return return_data
- get_severity(radius)
- var/const/max_dest = 1 - 1/4
- var/const/hev_dest = 1 - 1/2
- var/const/lig_dest = 1 - 1/1
- 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
- var/step = 0
- proc/get_explosion_step()
- return the_controller.explosion_step + round(get_dist_euclidian(object, explosion.ground_zero))
- /datum/explosions/debug_panel
- var/datum/explosions/explosion/virtual
- /datum/explosions/debug_panel/proc/send()
- var/dat = {"
- Debug:<br>
- /datum/explosions/explosion:<br>
- <a href='?src=\ref[src];action=1'>Create new splosion</a><br>
- <a href='?src=\ref[src];action=2'>cast_ray</a><br>
- <a href='?src=\ref[src];action=4'>calculate_explosion</a><br>
- <a href='?src=\ref[src];action=5'>get_severity</a><br>
- /datum/explosions/controller<br>
- <a href='?src=\ref[src];action=6'>AddExplosion</a><br>
- <a href='?src=\ref[src];action=7'>SortData</a><br>
- <a href='?src=\ref[src];action=8'>Show vars</a><br>
- <a href='?src=\ref[src];action=9'>Show sorted</a><br>
- "}
- usr << browse(dat, "window=debugpanel")
- /datum/explosions/debug_panel/Topic(href, href_list)
- switch (text2num(href_list["action"]))
- if (1)
- var/turf/center = get_turf(usr)
- var/radius = input(usr, "radius") as num
- virtual = new (center, radius)
- the_controller.explosions -= virtual
- the_controller.state = IDLE
- if (2)
- usr << virtual.cast_ray(get_turf(usr))
- if (4)
- var/list/datum/explosions/explosion_data/data = virtual.calculate_explosion()
- the_controller.data_garbage -= data
- for (var/datum/explosions/explosion_data/D in data)
- if (isturf(D.object))
- D.object.color = debug_color(D)
- spawn(20)
- for (var/datum/explosions/explosion_data/D in data)
- if (isturf(D.object))
- D.object.color = null
- if (5)
- usr << virtual.get_severity(input(usr, "radius") as num)
- if (6)
- the_controller.AddExplosion(virtual)
- sleep(5)
- the_controller.state = IDLE
- if (7)
- the_controller.SortData()
- if (8)
- var/dat = {"
- data_garbage: [the_controller.data_garbage.len]<br>
- data_sorted: [the_controller.data_sorted.len]<br>
- "}
- var/res = "\green OK"
- for (var/list/datum/explosions/explosion_data/A in the_controller.data_sorted)
- for (var/datum/explosions/explosion_data/B in A)
- for (var/datum/explosions/explosion_data/C in A)
- if (B == C) continue
- if (B.object == C.object) res = "\red ERROR"
- dat += res
- usr << browse(dat, "window=dms")
- if (9)
- for (var/list/datum/explosions/explosion_data/A in the_controller.data_sorted)
- for (var/datum/explosions/explosion_data/B in A)
- if (isturf(B.object))
- B.object.color = debug_color(B)
- sleep(10)
- spawn(10)
- for (var/list/datum/explosions/explosion_data/A in the_controller.data_sorted)
- for (var/datum/explosions/explosion_data/B in A)
- if (isturf(B.object))
- B.object.color = null
- proc/debug_color(datum/explosions/explosion_data/A)
- return (A.power == 1 ? "#ffff00" : (A.power == 2 ? "#ff9900" : (A.power == 3 ? "#ff0000" : null)))
- /mob/verb/debug_explosions()
- set name = "Show debug panel"
- set category = "Debug"
- debug_panel.send()
- #undef IDLE
Add Comment
Please, Sign In to add comment