Skip to content

Commit ebf7fdb

Browse files
Radiation Rework (ParadiseSS13#28320)
* initial changes * Rad wave is working. now to implement the rest * Makes the waves square * Makes wave square * multiplies the strength in all instances of radiation_pulse by 4 because each pulse makes one wave instead of 4 now * Undef thing and apply suggestion * Make radiation_pulse() not radiate the radiation source and implements contamination * Adds contamination to uranium walls and meteors * Fixes stuff * Handle some contamination on attack still need to take care of meteors * Fixed the meteor stuff * Introduce emission types * moves contaminate_touch to an atom proc and renames it to contaminate_atom * deduplicates some contamination code * Move inherent radioactivity to a component and signals from the atom vars and behaviour * fix some things with the new component * Update inherent_radioactivity.dm * implement contaminating things that hit things that are inherently radioactive * window things * adds emission type to the rad_act call * Changes radiation insulation values on a bunch of stuff * fixes radioactive component radiating the wrong type * more adjustments * refactros rad_act * adjustments to collector power production * Adds plastitaniumglass windows and makes further adjustments * Adds sprites to the shards and plastitanium directional window * Update misc_cleanables.dm * removes alpha rad insulation from floor turfs * Fixes a bug with the starting tile of radiation waves * More adjustments * Adjusting singularity rad production * reduces window half life a bit to make power smoother and buffs full window rad conversion * Strengthens gamma and beta radiation effect on mobs. * Makes radsuit block radiation completely * Fixes Geiger Counters * Fixes contamination not irradiating the contaminated thing * Fixes inherent radioactivity not processing. Also makes it stop processing when a nuke core is contained * Fixes ghost contamination * Adds info to the collector * Handles alpha radiation better on humans and changes some instances of rad_act to base_rad_act * oops * adjustments and fixes to alpha rad handling on mobs * Make collector info more compact * Core no longer radiates and contaminates from within the nuke until the plates are removed * Contamination no longer counts as being inside a mob(it is supposed to be surface level) * Adds inherent radioactivity to a bunch of uranium things. makes it all process. * Nerf full windows * Adjustments to collector and fulltile window radiation absorption * Reduces passive contamination, especially while on the floor * Adds different rad types to the geiger counter and fixes a runtime * Makes full tile windows strong again and disallows building them on top of collectors * adds emissive blockers to the rad blacklist and gives windows and collectors priority when irradiating for increased consistency * Gives each contamination type it's own color. * Gives each contamination type it's own color. And makes the rad hud display them separately * Changes how much the radiation wave affects the source tile, adds decay for performance reasons and adjusts collector parameters as well as SM and singulo rad production * improves performance at very high rad amounts * Fixes supermatter sliver box not containing radiation * Restores supermatter sliver to old behaviour(not inherently radioactive) * Slight nerf to fulltile windows and removes an unnecessary multiplication from rad wave processing * Removes redundant line from window rad act * Fixes radiation waves ignoring walls * fixes it better * more adjustments to collector stats * Adjustment to collector gamma absorption * increases grille beta blocking * Review changes
1 parent e29a599 commit ebf7fdb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+946
-385
lines changed

code/__DEFINES/dcs/atom_signals.dm

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@
6161
#define COMSIG_ATOM_ACID_ACT "atom_acid_act"
6262
///from base of atom/emag_act(): (/mob/user)
6363
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act"
64-
///from base of atom/rad_act(intensity)
64+
///from base of atom/rad_act(intensity, emission_type)
6565
#define COMSIG_ATOM_RAD_ACT "atom_rad_act"
66+
///from base of turf/irradiate(/datum/radiation_wave)
67+
#define COMSIG_TURF_IRRADIATE
6668
///from base of atom/singularity_pull(): (S, current_size)
6769
#define COMSIG_ATOM_SING_PULL "atom_sing_pull"
6870
///from base of atom/set_light(): (l_range, l_power, l_color)

code/__DEFINES/radiation_defines.dm

+30-10
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,41 @@ Ask ninjanomnom if they're around
3838
#define RAD_MOB_GORILLIZE 1500 // How much stored radiation to check for gorillization
3939
#define RAD_MOB_GORILLIZE_PROB 0.1 // Chance of gorillization per tick when over threshold
4040

41-
#define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason
42-
#define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have
41+
// Values here are for how much of the radiation is let through
42+
#define RAD_NO_INSULATION 1.0 // Default value for Gamma and Beta insulation
43+
#define RAD_ONE_PERCENT 0.99 // Used by geiger counters
44+
#define RAD_MOB_INSULATION 0.98 // Default value for mobs
45+
#define RAD_VERY_LIGHT_INSULATION 0.9
4346
#define RAD_LIGHT_INSULATION 0.8
44-
#define RAD_MEDIUM_INSULATION 0.7 // What common walls have
45-
#define RAD_HEAVY_INSULATION 0.6 // What reinforced walls have
46-
#define RAD_EXTREME_INSULATION 0.5 // What rad collectors have
47+
#define RAD_MEDIUM_INSULATION 0.7
48+
#define RAD_HEAVY_INSULATION 0.6
49+
#define RAD_VERY_HEAVY_INSULATION 0.5
50+
#define RAD_EXTREME_INSULATION 0.4
51+
#define RAD_VERY_EXTREME_INSULATION 0.2
52+
#define RAD_GAMMA_WINDOW 0.4 // For directional windows that are activated by gamma radiation
53+
#define RAD_GAMMA_FULL_WINDOW 0.16 // For full tile windows that are activated by gamma radiation
54+
#define RAD_BETA_COLLECTOR 0.2 // Amount of Beta radiation absorbed by collectors
55+
#define RAD_BETA_BLOCKER 0.2 // Amount of Beta radiation blocked by metallic things like walls and airlocks
56+
#define RAD_ALPHA_BLOCKER 0.01 // default value for Alpha insulation
4757
#define RAD_FULL_INSULATION 0 // Unused
4858

49-
// WARNING: The defines below could have disastrous consequences if tweaked incorrectly. See: The great SM purge of Oct.6.2017
50-
// contamination_strength = (strength - RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
51-
#define RAD_MINIMUM_CONTAMINATION 350 // How strong does a radiation wave have to be to contaminate objects
52-
#define RAD_CONTAMINATION_STR_COEFFICIENT 0.25 // Higher means higher strength scaling contamination strength
53-
#define RAD_DISTANCE_COEFFICIENT 1 // Lower means further rad spread
59+
// Contamination chance in percent. Mostly used by contaminate_adjacent(atom/source, intensity, emission_type)
60+
#define CONTAMINATION_CHANCE_TURF 1 // Chance to contaminate things while on/in a turf
61+
#define CONTAMINATION_CHANCE_OTHER 10 // Chance to contaminate things while in something like a bag
5462

5563
#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
5664

5765
#define RAD_GEIGER_MEASURE_SMOOTHING 5
5866
#define RAD_GEIGER_GRACE_PERIOD 2
67+
68+
/// The portion of a radiation wave that acts on the source tile.
69+
#define RAD_SOURCE_WEIGHT 0.25
70+
71+
/// The point in steps at which radiation waves start to decay
72+
#define RAD_DECAY_POINT 10
73+
/// This multiplies the intensity of the radiation wave each step after reaching the decay point.
74+
#define RAD_DECAY_RATE 0.7943 // 1% after 20 tiles
75+
76+
#define ALPHA_RAD 1
77+
#define BETA_RAD 2
78+
#define GAMMA_RAD 3

code/__HELPERS/radiation_helpers.dm

+170-21
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,183 @@
33
* Components which return COMPONENT_BLOCK_RADIATION prevent further searching into that object's contents. The object itself will get returned still.
44
* The ignore list makes those objects never return at all
55
*/
6-
/proc/get_rad_contents(atom/location)
6+
/proc/get_rad_contents(atom/location, emission_type)
77
var/static/list/ignored_things = typecacheof(list(
8-
/mob/dead,
98
/mob/camera,
9+
/mob/dead,
1010
/obj/effect,
1111
/obj/docking_port,
1212
/atom/movable/lighting_object,
1313
/obj/item/projectile,
14-
/obj/structure/railing // uhhhh they're highly radiation resistant, or some shit (stops stupid exploits)
14+
/atom/movable/emissive_blocker,
1515
))
1616
var/list/processing_list = list(location)
17+
var/list/window_priority = list()
18+
var/list/collector_priority = list()
19+
var/list/other_priority = list()
1720
. = list()
21+
var/insulation = 1
1822
while(length(processing_list))
1923
var/atom/thing = processing_list[1]
2024
processing_list -= thing
21-
if(ignored_things[thing.type])
25+
if(!thing || ignored_things[thing.type])
2226
continue
23-
. += thing
27+
switch(emission_type)
28+
if(ALPHA_RAD)
29+
insulation = thing.rad_insulation_alpha
30+
if(BETA_RAD)
31+
insulation = thing.rad_insulation_beta
32+
if(GAMMA_RAD)
33+
insulation = thing.rad_insulation_gamma
34+
/// 1 means no rad insulation, which means perfectly permeable, so no interaction with it directly, but the contents might be relevant.
35+
if(insulation < 1)
36+
if(istype(thing, /obj/structure/window))
37+
window_priority += thing
38+
else if(istype(thing, /obj/machinery/power/rad_collector))
39+
collector_priority += thing
40+
else
41+
other_priority += thing
2442
if((thing.flags_2 & RAD_PROTECT_CONTENTS_2) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
2543
continue
2644
if(ishuman(thing))
27-
var/mob/living/carbon/human/H = thing
28-
if(H.get_rad_protection() >= 0.99) // I would do exactly equal to 1, but you will never hit anything between 1 and .975, and byond seems to output 0.99999
45+
var/mob/living/carbon/human/target_mob = thing
46+
if(target_mob.get_rad_protection() >= 0.99) // I would do exactly equal to 1, but you will never hit anything between 1 and .975, and byond seems to output 0.99999
2947
continue
3048
processing_list += thing.contents
49+
. = window_priority + collector_priority + other_priority
3150

32-
/proc/radiation_pulse(atom/source, intensity, range_modifier, log = FALSE, can_contaminate = TRUE, source_radius = 0)
33-
if(!SSradiation.can_fire)
34-
return
35-
for(var/dir in GLOB.cardinal)
36-
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate, source_radius)
51+
/proc/get_rad_contamination_adjacent(atom/location, atom/source)
52+
var/static/list/ignored_things = typecacheof(list(
53+
/mob/camera,
54+
/mob/dead,
55+
/obj/effect,
56+
/obj/docking_port,
57+
/atom/movable/lighting_object,
58+
/obj/item/projectile,
59+
/atom/movable/emissive_blocker,
60+
))
61+
var/list/processing_list = list(location)
62+
// We want to select which clothes and items we contaminate depending on where on the human we are. We assume we are in some form of storage or on the floor otherwise.
63+
// If the source is a human(like a uranium golem) we just attempt to contaminate all our contents
64+
if(!ishuman(location) || ishuman(source))
65+
processing_list += location.contents
66+
. = list()
67+
for(var/atom/thing in processing_list)
68+
if(thing && source && thing.UID() == source.UID())
69+
continue
70+
if(ignored_things[thing.type])
71+
continue
72+
if((SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING) & COMPONENT_BLOCK_CONTAMINATION) || thing.flags_2 & RAD_NO_CONTAMINATE_2)
73+
continue
74+
if(ishuman(thing) || ishuman(thing.loc))
75+
var/mob/living/carbon/human/target_mob = ishuman(thing) ? thing : thing.loc
76+
var/passed = TRUE
77+
var/zone
78+
var/pocket = FALSE
79+
// Check if we hold the contamination source, have it in our pockets or in our belts or if it's inside us
80+
if(target_mob.UID() == location.UID())
81+
// If it's in our hands check if it can permeate our gloves
82+
if((source && (target_mob.r_hand && target_mob.r_hand.UID() == source.UID()) || (target_mob.l_hand && target_mob.l_hand.UID() == source.UID())))
83+
zone = HANDS
3784

38-
var/list/things = get_rad_contents(source) //copypasta because I don't want to put special code in waves to handle their origin
39-
for(var/k in 1 to length(things))
40-
var/atom/thing = things[k]
41-
if(!thing)
85+
// If it's in our pockets check against our jumpsuit only
86+
else if((target_mob?.l_store && target_mob?.l_store?.UID() == source?.UID()) || (target_mob?.r_store && target_mob?.r_store.UID() == source?.UID()))
87+
zone = LOWER_TORSO
88+
pocket = TRUE
89+
90+
// If it's on our belt check against both our outer layer and jumpsuit
91+
if(location.loc.UID() == target_mob.UID() && istype(location, /obj/item/storage/belt))
92+
zone = LOWER_TORSO
93+
94+
// If on the floor check if it can permeate our shoes
95+
if(istype(location, /turf/))
96+
zone = FEET
97+
98+
// zone being unchanged here means the item is inside the mob
99+
var/list/results = target_mob.rad_contaminate_zone(zone, pocket)
100+
passed = results[1]
101+
results -= results[1]
102+
. |= results
103+
if(!passed)
104+
continue
105+
. += thing
106+
107+
/proc/get_rad_contamination_target(atom/location, atom/source)
108+
var/static/list/ignored_things = typecacheof(list(
109+
/mob/camera,
110+
/mob/dead,
111+
/obj/effect,
112+
/obj/docking_port,
113+
/atom/movable/lighting_object,
114+
/obj/item/projectile,
115+
/atom/movable/emissive_blocker,
116+
))
117+
var/list/processing_list = list(location) + location.contents
118+
. = list()
119+
while(length(processing_list))
120+
var/atom/thing = processing_list[1]
121+
processing_list -= thing
122+
if(thing?.UID() == source?.UID())
123+
continue
124+
if(ignored_things[thing.type])
125+
continue
126+
if((SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING) & COMPONENT_BLOCK_CONTAMINATION) || thing.flags_2 & RAD_NO_CONTAMINATE_2)
42127
continue
43-
thing.rad_act(intensity)
128+
/// If it's a human check for rad protection on all areas
129+
if(ishuman(thing))
130+
var/mob/living/carbon/human/target_mob = thing
131+
var/zone = 0
132+
var/list/contaminate = list()
133+
var/list/results = list()
134+
var/passed = TRUE
135+
for(var/i in 0 to 9)
136+
zone = (1<<i)
137+
results = target_mob.rad_contaminate_zone(zone)
138+
passed = results[1] || passed
139+
results -= results[1]
140+
contaminate |= results
141+
. |= contaminate
142+
if(!passed)
143+
continue
144+
for(var/atom/human_content in target_mob.contents)
145+
if(!istype(human_content, /obj/item/clothing))
146+
. |= human_content
147+
. += thing
148+
149+
150+
/proc/radiation_pulse(atom/source, intensity, emission_type = ALPHA_RAD, log = FALSE)
151+
if(!SSradiation.can_fire || intensity < RAD_BACKGROUND_RADIATION)
152+
return
153+
var/datum/radiation_wave/wave = new /datum/radiation_wave(source, intensity, emission_type)
154+
155+
var/turf/start_turf = source
156+
157+
// Find the turf where we are
158+
while(!istype(start_turf, /turf))
159+
start_turf = start_turf.loc
160+
161+
var/list/things = get_rad_contents(start_turf, emission_type) // Radiate the waves origin frist
162+
// Adjust the weights so the source tile doesn't get all the rads
163+
wave.weight_sum = RAD_SOURCE_WEIGHT
164+
wave.weights = list(wave.weight_sum)
165+
for(var/atom/thing in things)
166+
if(thing.UID() == source.UID())
167+
// Don't block our own radiation
168+
source.base_rad_act(source ,intensity, emission_type)
169+
else
170+
wave.weight_sum = wave.weight_sum * thing.base_rad_act(source ,intensity * wave.weight_sum, emission_type)
171+
// Add the rest of the weight back
172+
wave.weight_sum += (1 - RAD_SOURCE_WEIGHT)
173+
// We can do this because we are on one tile so we have one weight
174+
wave.weights[1] = wave.weight_sum
44175

45176
var/static/last_huge_pulse = 0
46-
if(intensity > 3000 && world.time > last_huge_pulse + 200)
177+
if(intensity > 12000 && world.time > last_huge_pulse + 200)
47178
last_huge_pulse = world.time
48179
log = TRUE
49180
if(log)
50181
var/turf/_source_T = isturf(source) ? source : get_turf(source)
51-
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ")
182+
log_game("Radiation pulse with intensity: [intensity] in [loc_name(_source_T)] ")
52183
return TRUE
53184

54185
/proc/get_rad_contamination(atom/location)
@@ -58,6 +189,24 @@
58189
if(!thing)
59190
continue
60191
var/datum/component/radioactive/radiation = thing.GetComponent(/datum/component/radioactive)
61-
if(radiation && rad_strength < radiation.strength)
62-
rad_strength = radiation.strength
192+
if(radiation && rad_strength < (radiation.alpha_strength + radiation.beta_strength + radiation.gamma_strength))
193+
rad_strength = (radiation.alpha_strength + radiation.beta_strength + radiation.gamma_strength)
63194
return rad_strength
195+
196+
/// Contaminate things that share our immediate location(periodic)
197+
/proc/contaminate_adjacent(atom/source, intensity, emission_type)
198+
// If the source is a turf it is it's location
199+
var/atom/location = isturf(source) ? source : source.loc
200+
// Are we on a turf or in something else
201+
var/is_source_on_turf = isturf(location)
202+
var/contamination_chance = is_source_on_turf ? CONTAMINATION_CHANCE_TURF : CONTAMINATION_CHANCE_OTHER
203+
var/list/contamination_contents = get_rad_contamination_adjacent(location, source)
204+
for(var/atom/thing in contamination_contents)
205+
if(prob(contamination_chance))
206+
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)
207+
208+
/// Contaminate the contents of a target(single instance)
209+
/proc/contaminate_target(atom/target, atom/source, intensity, emission_type)
210+
var/list/contamination_contents = get_rad_contamination_target(target, source)
211+
for(var/atom/thing in contamination_contents)
212+
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)

code/__HELPERS/unsorted.dm

+2
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
14031403
var/obj/structure/window/W = O
14041404
if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
14051405
return FALSE
1406+
if(istype(O, /obj/machinery/power/rad_collector))
1407+
return FALSE
14061408
return TRUE
14071409

14081410
//datum may be null, but it does need to be a typed var

code/controllers/subsystem/SSradiation.dm

+16-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
2626
warned_atoms[ref] = TRUE
2727
var/atom/master = contamination.parent
2828
SSblackbox.record_feedback("tally", "contaminated", 1, master.type)
29-
var/msg = "has become contaminated with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
29+
var/msg = "has become contaminated with enough radiation to emit radiation waves || Source: [contamination.source] || Strength: [contamination.alpha_strength + contamination.beta_strength + contamination.gamma_strength]"
3030
master.investigate_log(msg, "radiation")
3131

3232
/datum/controller/subsystem/processing/radiation/fire(resumed)
@@ -41,13 +41,25 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
4141
else
4242
return 0
4343

44-
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache(datum/component/radioactive/thing)
44+
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache_contaminated(datum/component/radioactive/thing)
4545
var/atom/owner = thing.parent
4646
var/turf/place = get_turf(owner)
4747
if(turf_rad_cache[place])
48-
turf_rad_cache[place] += thing.strength
48+
turf_rad_cache[place][1] += thing.alpha_strength
49+
turf_rad_cache[place][2] += thing.beta_strength
50+
turf_rad_cache[place][3] += thing.gamma_strength
4951
else
50-
turf_rad_cache[place] = thing.strength
52+
turf_rad_cache[place] = list(thing.alpha_strength, thing.beta_strength, thing.gamma_strength)
53+
54+
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache_inherent(datum/component/inherent_radioactivity/thing)
55+
var/atom/owner = thing.parent
56+
var/turf/place = get_turf(owner)
57+
if(turf_rad_cache[place])
58+
turf_rad_cache[place][1] += thing.radioactivity_alpha
59+
turf_rad_cache[place][2] += thing.radioactivity_beta
60+
turf_rad_cache[place][3] += thing.radioactivity_gamma
61+
else
62+
turf_rad_cache[place] = list(thing.radioactivity_alpha, thing.radioactivity_beta, thing.radioactivity_gamma)
5163

5264

5365
/datum/controller/subsystem/processing/radiation/proc/refresh_rad_cache()

0 commit comments

Comments
 (0)