Skip to content

Commit 1ca65e6

Browse files
authored
fixes radiation performance (#1117)
1 parent c2899cd commit 1ca65e6

File tree

2 files changed

+61
-31
lines changed

2 files changed

+61
-31
lines changed

code/__HELPERS/radiation.dm

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
pulse_information.threshold = threshold
3232
pulse_information.chance = chance
3333
pulse_information.minimum_exposure_time = minimum_exposure_time
34+
pulse_information.turfs_to_process = RANGE_TURFS(max_range, source)
3435

3536
SSradiation.processing += pulse_information
3637

@@ -42,6 +43,7 @@
4243
var/threshold
4344
var/chance
4445
var/minimum_exposure_time
46+
var/list/turfs_to_process
4547

4648
#define MEDIUM_RADIATION_THRESHOLD_RANGE 0.5
4749
#define EXTREME_RADIATION_CHANCE 30

code/controllers/subsystem/radiation.dm

+59-31
Original file line numberDiff line numberDiff line change
@@ -16,73 +16,101 @@ SUBSYSTEM_DEF(radiation)
1616

1717
/datum/controller/subsystem/radiation/fire(resumed)
1818
while (processing.len)
19-
var/datum/radiation_pulse_information/pulse_information = popleft(processing)
19+
var/datum/radiation_pulse_information/pulse_information = processing[1]
2020

2121
var/datum/weakref/source_ref = pulse_information.source_ref
2222
var/atom/source = source_ref.resolve()
2323
if (isnull(source))
24+
processing.Cut(1, 2)
2425
continue
2526

2627
pulse(source, pulse_information)
2728

2829
if (MC_TICK_CHECK)
2930
return
3031

32+
processing.Cut(1, 2)
33+
3134
/datum/controller/subsystem/radiation/stat_entry(msg)
3235
msg = "[msg] | Pulses: [processing.len]"
3336
return ..()
3437

3538
/datum/controller/subsystem/radiation/proc/pulse(atom/source, datum/radiation_pulse_information/pulse_information)
3639
var/list/cached_rad_insulations = list()
40+
var/list/cached_turfs_to_process = pulse_information.turfs_to_process
41+
var/turfs_iterated = 0
42+
for (var/turf/turf_to_irradiate as anything in cached_turfs_to_process)
43+
turfs_iterated += 1
44+
for (var/atom/movable/target in turf_to_irradiate)
45+
if (!can_irradiate_basic(target))
46+
continue
3747

38-
for (var/atom/movable/target in range(pulse_information.max_range, source))
39-
if (!can_irradiate_basic(target))
40-
continue
48+
var/current_insulation = 1
49+
50+
for (var/turf/turf_in_between in get_line(source, target) - get_turf(source))
51+
var/insulation = cached_rad_insulations[turf_in_between]
52+
if (isnull(insulation))
53+
insulation = turf_in_between.rad_insulation
54+
for (var/atom/on_turf as anything in turf_in_between.contents)
55+
insulation *= on_turf.rad_insulation
56+
cached_rad_insulations[turf_in_between] = insulation
4157

42-
var/current_insulation = 1
58+
current_insulation *= insulation
4359

44-
for (var/turf/turf_in_between in get_line(source, target) - get_turf(source))
45-
var/insulation = cached_rad_insulations[turf_in_between]
46-
if (isnull(insulation))
47-
insulation = turf_in_between.rad_insulation
48-
for (var/atom/on_turf as anything in turf_in_between.contents)
49-
insulation *= on_turf.rad_insulation
50-
cached_rad_insulations[turf_in_between] = insulation
60+
if (current_insulation <= pulse_information.threshold)
61+
break
5162

52-
current_insulation *= insulation
63+
SEND_SIGNAL(target, COMSIG_IN_RANGE_OF_IRRADIATION, pulse_information, current_insulation)
64+
65+
// Check a second time, because of TRAIT_BYPASS_EARLY_IRRADIATED_CHECK
66+
if (HAS_TRAIT(target, TRAIT_IRRADIATED))
67+
continue
5368

5469
if (current_insulation <= pulse_information.threshold)
55-
break
70+
continue
5671

57-
SEND_SIGNAL(target, COMSIG_IN_RANGE_OF_IRRADIATION, pulse_information, current_insulation)
72+
/// Perceived chance of target getting irradiated.
73+
var/perceived_chance
74+
/// Intensity variable which will describe the radiation pulse.
75+
/// It is used by perceived intensity, which diminishes over range. The chance of the target getting irradiated is determined by perceived_intensity.
76+
/// Intensity is calculated so that the chance of getting irradiated at half of the max range is the same as the chance parameter.
77+
var/intensity
78+
/// Diminishes over range. Used by perceived chance, which is the actual chance to get irradiated.
79+
var/perceived_intensity
5880

59-
// Check a second time, because of TRAIT_BYPASS_EARLY_IRRADIATED_CHECK
60-
if (HAS_TRAIT(target, TRAIT_IRRADIATED))
61-
continue
81+
if(pulse_information.chance < 100) // Prevents log(0) runtime if chance is 100%
82+
intensity = -log(1 - pulse_information.chance / 100) * (1 + pulse_information.max_range / 2) ** 2
83+
perceived_intensity = intensity * INVERSE((1 + get_dist_euclidean(source, target)) ** 2) // Diminishes over range.
84+
perceived_intensity *= (current_insulation - pulse_information.threshold) * INVERSE(1 - pulse_information.threshold) // Perceived intensity decreases as objects that absorb radiation block its trajectory.
85+
perceived_chance = 100 * (1 - NUM_E ** -perceived_intensity)
86+
else
87+
perceived_chance = 100
6288

63-
if (current_insulation <= pulse_information.threshold)
64-
continue
89+
var/irradiation_result = SEND_SIGNAL(target, COMSIG_IN_THRESHOLD_OF_IRRADIATION, pulse_information)
90+
if (irradiation_result & CANCEL_IRRADIATION)
91+
continue
6592

66-
var/irradiation_result = SEND_SIGNAL(target, COMSIG_IN_THRESHOLD_OF_IRRADIATION, pulse_information)
67-
if (irradiation_result & CANCEL_IRRADIATION)
68-
continue
93+
if (pulse_information.minimum_exposure_time && !(irradiation_result & SKIP_MINIMUM_EXPOSURE_TIME_CHECK))
94+
target.AddComponent(/datum/component/radiation_countdown, pulse_information.minimum_exposure_time)
95+
continue
6996

70-
if (pulse_information.minimum_exposure_time && !(irradiation_result & SKIP_MINIMUM_EXPOSURE_TIME_CHECK))
71-
target.AddComponent(/datum/component/radiation_countdown, pulse_information.minimum_exposure_time)
72-
continue
97+
if (!prob(perceived_chance))
98+
continue
7399

74-
if (!prob(pulse_information.chance))
75-
continue
100+
if (irradiate_after_basic_checks(target))
101+
target.investigate_log("was irradiated by [source].", INVESTIGATE_RADIATION)
102+
103+
if(MC_TICK_CHECK)
104+
break
76105

77-
if (irradiate_after_basic_checks(target))
78-
target.investigate_log("was irradiated by [source].", INVESTIGATE_RADIATION)
106+
cached_turfs_to_process.Cut(1, turfs_iterated + 1)
79107

80108
/// Will attempt to irradiate the given target, limited through IC means, such as radiation protected clothing.
81109
/datum/controller/subsystem/radiation/proc/irradiate(atom/target)
82110
if (!can_irradiate_basic(target))
83111
return FALSE
84112

85-
irradiate_after_basic_checks()
113+
irradiate_after_basic_checks(target)
86114
return TRUE
87115

88116
/datum/controller/subsystem/radiation/proc/irradiate_after_basic_checks(atom/target)

0 commit comments

Comments
 (0)