@@ -16,73 +16,101 @@ SUBSYSTEM_DEF(radiation)
16
16
17
17
/ datum / controller/ subsystem/ radiation/ fire(resumed)
18
18
while (processing. len)
19
- var /datum /radiation_pulse_information/pulse_information = popleft( processing)
19
+ var /datum /radiation_pulse_information/pulse_information = processing[ 1 ]
20
20
21
21
var /datum /weakref/source_ref = pulse_information. source_ref
22
22
var /atom /source = source_ref. resolve()
23
23
if (isnull(source))
24
+ processing. Cut(1 , 2 )
24
25
continue
25
26
26
27
pulse (source, pulse_information)
27
28
28
29
if (MC_TICK_CHECK )
29
30
return
30
31
32
+ processing. Cut(1 , 2 )
33
+
31
34
/ datum / controller/ subsystem/ radiation/ stat_entry(msg)
32
35
msg = " [ msg] | Pulses: [ processing. len] "
33
36
return .. ()
34
37
35
38
/ datum / controller/ subsystem/ radiation/ proc / pulse( atom / source, datum / radiation_pulse_information/ pulse_information)
36
39
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
37
47
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
41
57
42
- var / current_insulation = 1
58
+ current_insulation *= insulation
43
59
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
51
62
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
53
68
54
69
if (current_insulation <= pulse_information. threshold)
55
- break
70
+ continue
56
71
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
58
80
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
62
88
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
65
92
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
69
96
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
73
99
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
76
105
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 )
79
107
80
108
// / Will attempt to irradiate the given target, limited through IC means, such as radiation protected clothing.
81
109
/ datum / controller/ subsystem/ radiation/ proc / irradiate( atom / target)
82
110
if (! can_irradiate_basic(target))
83
111
return FALSE
84
112
85
- irradiate_after_basic_checks ()
113
+ irradiate_after_basic_checks (target )
86
114
return TRUE
87
115
88
116
/ datum / controller/ subsystem/ radiation/ proc / irradiate_after_basic_checks( atom / target)
0 commit comments