From 67fbd4b686a579fc8f6d2c19c93d0f7ea9d8cb0a Mon Sep 17 00:00:00 2001 From: Igor Spichkin Date: Mon, 16 Oct 2023 05:39:29 +0300 Subject: [PATCH] opt(radiation): speed up radiation traveling --- code/__defines/radiation.dm | 5 +++ code/controllers/subsystems/radiation.dm | 23 ++++++++++++-- code/modules/radiation/radiation.dm | 36 ++++++++++------------ code/modules/radiation/radiation_source.dm | 4 +-- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/code/__defines/radiation.dm b/code/__defines/radiation.dm index 80503965573..86a43a57f8b 100644 --- a/code/__defines/radiation.dm +++ b/code/__defines/radiation.dm @@ -1,3 +1,8 @@ +#define MAX_RADIATION_DIST (world.view * 2) +#define RADIATION_DISTANCE_MULT(DST) (log(2, max(2, DST + 2))) +#define RADIATION_MIN_IONIZATION (10 ELECTRONVOLT) +#define RADIATION_CALC_OBJ_RESIST(rad_info, obj) ((obj.atom_flags & ATOM_FLAG_OPEN_CONTAINER) ? 0 : obj.rad_resist[rad_info.radiation_type]) + #define RADIATION_ALPHA_PARTICLE "alpha_particle" #define RADIATION_BETA_PARTICLE "beta_particle" #define RADIATION_HAWKING "hawking" diff --git a/code/controllers/subsystems/radiation.dm b/code/controllers/subsystems/radiation.dm index 7ab47b9eeaa..3cacc0c539b 100644 --- a/code/controllers/subsystems/radiation.dm +++ b/code/controllers/subsystems/radiation.dm @@ -1,3 +1,5 @@ +GLOBAL_DATUM_INIT(rad_instance, /datum/radiation, new(1, RADIATION_ALPHA_PARTICLE)) + SUBSYSTEM_DEF(radiation) name = "Radiation" wait = 2 SECONDS @@ -40,16 +42,31 @@ SUBSYSTEM_DEF(radiation) log_debug("NULLSPACE ALERT: [A.name] | loc: `[A.loc]` | ckey: `[A.ckey]`") continue - var/list/sources = get_sources_in_range(T) for(var/datum/radiation_source/source in sources) if(source.info.activity <= 0 || source.info.energy <= 0) qdel(source) - if(!source.info.is_ionizing()) + var/turf/source_turf = get_turf(source.holder) + + if(source_turf.z != T.z) + continue // Radiation is not multi-z + + var/E = source.info.energy / RADIATION_DISTANCE_MULT(get_dist(T, source_turf)) + + if(isobj(source.holder)) + var/obj/current_obj = source.holder + E = max(E - RADIATION_CALC_OBJ_RESIST(source.info, current_obj), 0) + + if(E < RADIATION_MIN_IONIZATION) continue if(source.flat) - A.rad_act(source, get_turf(A)) + if(source.respect_maint) + var/area/AR = T.loc + if(AR.area_flags & AREA_FLAG_RAD_SHIELDED) + continue // In shielded area + + A.rad_act(source, T) else A.rad_act(source, source.holder) if (MC_TICK_CHECK) diff --git a/code/modules/radiation/radiation.dm b/code/modules/radiation/radiation.dm index 01094e2670b..58131f7e330 100644 --- a/code/modules/radiation/radiation.dm +++ b/code/modules/radiation/radiation.dm @@ -39,15 +39,17 @@ specific_activity = activity -/datum/radiation/proc/copy() - var/datum/radiation/R = new(activity, radiation_type, energy) +/datum/radiation/proc/copy(datum/radiation/target) + target.activity = activity + target.radiation_type = radiation_type + target.energy = energy + target.specific_activity = specific_activity + target.quality_factor = quality_factor - R.specific_activity = specific_activity - - return R + return target /datum/radiation/proc/is_ionizing() - return energy >= (10 ELECTRONVOLT) + return energy >= RADIATION_MIN_IONIZATION /datum/radiation/proc/travel(atom/source, atom/target) var/atom/current_point = source @@ -58,11 +60,15 @@ if(isobj(current_point)) var/obj/current_obj = current_point - energy = max(energy - current_obj.calc_rad_resistance(src), 0) + energy = max(energy - RADIATION_CALC_OBJ_RESIST(src, current_obj), 0) current_point = current_point.loc var/dst = get_dist(get_turf(source), get_turf(target)) - energy /= log(2, max(2, dst + 2)) + + if (dst > MAX_RADIATION_DIST) + return FALSE + + energy /= RADIATION_DISTANCE_MULT(dst) if(!is_ionizing()) return FALSE @@ -74,7 +80,7 @@ continue var/obj/current_obj = current_point - energy = max(energy - current_obj.calc_rad_resistance(src), 0) + energy = max(energy - RADIATION_CALC_OBJ_RESIST(src, current_obj), 0) if(!is_ionizing()) return FALSE @@ -98,7 +104,7 @@ target_parent = target_parent.loc continue - energy = max(energy - target_parent.calc_rad_resistance(src), 0) + energy = max(energy - RADIATION_CALC_OBJ_RESIST(src, target_parent), 0) if(!is_ionizing()) return FALSE @@ -118,7 +124,7 @@ if(source_turf != current_turf) for(var/obj/O in current_turf) if(O.density) - energy = max(energy - O.calc_rad_resistance(src), 0) + energy = max(energy - RADIATION_CALC_OBJ_RESIST(src, O), 0) break current_point = get_step_towards(current_turf, target) @@ -148,14 +154,6 @@ return Clamp(resist, 0.0, 1.0) -/obj/proc/calc_rad_resistance(datum/radiation/info) - var/resist = rad_resist[info.radiation_type] - - if(atom_flags & ATOM_FLAG_OPEN_CONTAINER) - return 0 - - return resist - /// This is used when radiation is exposed from the outside. /// /// When something is exposing radiation inside of the mob - use `radiation` variable directly. diff --git a/code/modules/radiation/radiation_source.dm b/code/modules/radiation/radiation_source.dm index d258e40e918..15ee2e56cc3 100644 --- a/code/modules/radiation/radiation_source.dm +++ b/code/modules/radiation/radiation_source.dm @@ -30,10 +30,10 @@ else info.energy = new_energy if(!flat) - range = world.view * 2 + range = MAX_RADIATION_DIST /datum/radiation_source/proc/travel(atom/target) - var/datum/radiation/R = info.copy() + var/datum/radiation/R = info.copy(GLOB.rad_instance) var/atom/source = flat ? get_turf(target) : holder R.travel(source, target)