forked from tgstation/tgstation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathradiation_wave.dm
139 lines (119 loc) · 4.25 KB
/
radiation_wave.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/datum/radiation_wave
/// The thing that spawned this radiation wave
var/source
/// The center of the wave
var/turf/master_turf
/// How far we've moved
var/steps=0
/// How strong it was originaly
var/intensity
/// How much contaminated material it still has
var/remaining_contam
/// Higher than 1 makes it drop off faster, 0.5 makes it drop off half etc
var/range_modifier
/// The direction of movement
var/move_dir
/// The directions to the side of the wave, stored for easy looping
var/list/__dirs
/// Whether or not this radiation wave can create contaminated objects
var/can_contaminate
/datum/radiation_wave/New(atom/_source, dir, _intensity=0, _range_modifier=RAD_DISTANCE_COEFFICIENT, _can_contaminate=TRUE)
source = "[_source] \[[REF(_source)]\]"
master_turf = get_turf(_source)
move_dir = dir
__dirs = list()
__dirs+=turn(dir, 90)
__dirs+=turn(dir, -90)
intensity = _intensity
remaining_contam = intensity
range_modifier = _range_modifier
can_contaminate = _can_contaminate
START_PROCESSING(SSradiation, src)
/datum/radiation_wave/Destroy()
. = QDEL_HINT_IWILLGC
STOP_PROCESSING(SSradiation, src)
..()
/datum/radiation_wave/process()
master_turf = get_step(master_turf, move_dir)
if(!master_turf)
qdel(src)
return
steps++
var/list/atoms = get_rad_atoms()
var/strength
if(steps>1)
strength = INVERSE_SQUARE(intensity, max(range_modifier*steps, 1), 1)
else
strength = intensity
if(strength<RAD_BACKGROUND_RADIATION)
qdel(src)
return
radiate(atoms, strength)
check_obstructions(atoms) // reduce our overall strength if there are radiation insulators
/datum/radiation_wave/proc/get_rad_atoms()
var/list/atoms = list()
var/distance = steps
var/cmove_dir = move_dir
var/cmaster_turf = master_turf
if(cmove_dir == NORTH || cmove_dir == SOUTH)
distance-- //otherwise corners overlap
atoms += get_rad_contents(cmaster_turf)
var/turf/place
for(var/dir in __dirs) //There should be just 2 dirs in here, left and right of the direction of movement
place = cmaster_turf
for(var/i in 1 to distance)
place = get_step(place, dir)
if(!place)
break
atoms += get_rad_contents(place)
return atoms
/datum/radiation_wave/proc/check_obstructions(list/atoms)
var/width = steps
var/cmove_dir = move_dir
if(cmove_dir == NORTH || cmove_dir == SOUTH)
width--
width = 1+(2*width)
for(var/k in 1 to atoms.len)
var/atom/thing = atoms[k]
if(!thing)
continue
if (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_WAVE_PASSING, src, width) & COMPONENT_RAD_WAVE_HANDLED)
continue
if (thing.rad_insulation != RAD_NO_INSULATION)
intensity *= (1-((1-thing.rad_insulation)/width))
/datum/radiation_wave/proc/radiate(list/atoms, strength)
var/can_contam = strength >= RAD_MINIMUM_CONTAMINATION
var/contamination_strength = (strength-RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
contamination_strength = max(contamination_strength, RAD_BACKGROUND_RADIATION)
// It'll never reach 100% chance but the further out it gets the more likely it'll contaminate
var/contamination_chance = 100 - (90 / (1 + steps * 0.1))
for(var/k in atoms)
var/atom/thing = k
if(QDELETED(thing))
continue
thing.rad_act(strength)
// This list should only be for types which don't get contaminated but you want to look in their contents
// If you don't want to look in their contents and you don't want to rad_act them:
// modify the ignored_things list in __HELPERS/radiation.dm instead
var/static/list/blacklisted = typecacheof(list(
/turf,
/obj/structure/cable,
/obj/machinery/atmospherics,
/obj/item/ammo_casing,
/obj/item/implant,
/obj/singularity
))
if(!can_contaminate || !can_contam || blacklisted[thing.type])
continue
if(thing.flags_1 & RAD_NO_CONTAMINATE_1 || SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION)
continue
if(contamination_strength > remaining_contam)
contamination_strength = remaining_contam
if(!prob(contamination_chance))
continue
if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING, strength) & COMPONENT_BLOCK_CONTAMINATION)
continue
remaining_contam -= contamination_strength
if(remaining_contam < RAD_BACKGROUND_RADIATION)
can_contaminate = FALSE
thing.AddComponent(/datum/component/radioactive, contamination_strength, source)