Radiation Rework (#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
This commit is contained in:
Migratingcocofruit
2025-03-02 22:34:45 +02:00
committed by GitHub
parent e29a599118
commit ebf7fdbfd2
66 changed files with 945 additions and 384 deletions
+3 -1
View File
@@ -61,8 +61,10 @@
#define COMSIG_ATOM_ACID_ACT "atom_acid_act"
///from base of atom/emag_act(): (/mob/user)
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act"
///from base of atom/rad_act(intensity)
///from base of atom/rad_act(intensity, emission_type)
#define COMSIG_ATOM_RAD_ACT "atom_rad_act"
///from base of turf/irradiate(/datum/radiation_wave)
#define COMSIG_TURF_IRRADIATE
///from base of atom/singularity_pull(): (S, current_size)
#define COMSIG_ATOM_SING_PULL "atom_sing_pull"
///from base of atom/set_light(): (l_range, l_power, l_color)
+30 -10
View File
@@ -38,21 +38,41 @@ Ask ninjanomnom if they're around
#define RAD_MOB_GORILLIZE 1500 // How much stored radiation to check for gorillization
#define RAD_MOB_GORILLIZE_PROB 0.1 // Chance of gorillization per tick when over threshold
#define RAD_NO_INSULATION 1.0 // For things that shouldn't become irradiated for whatever reason
#define RAD_VERY_LIGHT_INSULATION 0.9 // What girders have
// Values here are for how much of the radiation is let through
#define RAD_NO_INSULATION 1.0 // Default value for Gamma and Beta insulation
#define RAD_ONE_PERCENT 0.99 // Used by geiger counters
#define RAD_MOB_INSULATION 0.98 // Default value for mobs
#define RAD_VERY_LIGHT_INSULATION 0.9
#define RAD_LIGHT_INSULATION 0.8
#define RAD_MEDIUM_INSULATION 0.7 // What common walls have
#define RAD_HEAVY_INSULATION 0.6 // What reinforced walls have
#define RAD_EXTREME_INSULATION 0.5 // What rad collectors have
#define RAD_MEDIUM_INSULATION 0.7
#define RAD_HEAVY_INSULATION 0.6
#define RAD_VERY_HEAVY_INSULATION 0.5
#define RAD_EXTREME_INSULATION 0.4
#define RAD_VERY_EXTREME_INSULATION 0.2
#define RAD_GAMMA_WINDOW 0.4 // For directional windows that are activated by gamma radiation
#define RAD_GAMMA_FULL_WINDOW 0.16 // For full tile windows that are activated by gamma radiation
#define RAD_BETA_COLLECTOR 0.2 // Amount of Beta radiation absorbed by collectors
#define RAD_BETA_BLOCKER 0.2 // Amount of Beta radiation blocked by metallic things like walls and airlocks
#define RAD_ALPHA_BLOCKER 0.01 // default value for Alpha insulation
#define RAD_FULL_INSULATION 0 // Unused
// WARNING: The defines below could have disastrous consequences if tweaked incorrectly. See: The great SM purge of Oct.6.2017
// contamination_strength = (strength - RAD_MINIMUM_CONTAMINATION) * RAD_CONTAMINATION_STR_COEFFICIENT
#define RAD_MINIMUM_CONTAMINATION 350 // How strong does a radiation wave have to be to contaminate objects
#define RAD_CONTAMINATION_STR_COEFFICIENT 0.25 // Higher means higher strength scaling contamination strength
#define RAD_DISTANCE_COEFFICIENT 1 // Lower means further rad spread
// Contamination chance in percent. Mostly used by contaminate_adjacent(atom/source, intensity, emission_type)
#define CONTAMINATION_CHANCE_TURF 1 // Chance to contaminate things while on/in a turf
#define CONTAMINATION_CHANCE_OTHER 10 // Chance to contaminate things while in something like a bag
#define RAD_HALF_LIFE 90 // The half-life of contaminated objects
#define RAD_GEIGER_MEASURE_SMOOTHING 5
#define RAD_GEIGER_GRACE_PERIOD 2
/// The portion of a radiation wave that acts on the source tile.
#define RAD_SOURCE_WEIGHT 0.25
/// The point in steps at which radiation waves start to decay
#define RAD_DECAY_POINT 10
/// This multiplies the intensity of the radiation wave each step after reaching the decay point.
#define RAD_DECAY_RATE 0.7943 // 1% after 20 tiles
#define ALPHA_RAD 1
#define BETA_RAD 2
#define GAMMA_RAD 3
+171 -22
View File
@@ -3,52 +3,183 @@
* Components which return COMPONENT_BLOCK_RADIATION prevent further searching into that object's contents. The object itself will get returned still.
* The ignore list makes those objects never return at all
*/
/proc/get_rad_contents(atom/location)
/proc/get_rad_contents(atom/location, emission_type)
var/static/list/ignored_things = typecacheof(list(
/mob/dead,
/mob/camera,
/mob/dead,
/obj/effect,
/obj/docking_port,
/atom/movable/lighting_object,
/obj/item/projectile,
/obj/structure/railing // uhhhh they're highly radiation resistant, or some shit (stops stupid exploits)
/atom/movable/emissive_blocker,
))
var/list/processing_list = list(location)
var/list/window_priority = list()
var/list/collector_priority = list()
var/list/other_priority = list()
. = list()
var/insulation = 1
while(length(processing_list))
var/atom/thing = processing_list[1]
processing_list -= thing
if(!thing || ignored_things[thing.type])
continue
switch(emission_type)
if(ALPHA_RAD)
insulation = thing.rad_insulation_alpha
if(BETA_RAD)
insulation = thing.rad_insulation_beta
if(GAMMA_RAD)
insulation = thing.rad_insulation_gamma
/// 1 means no rad insulation, which means perfectly permeable, so no interaction with it directly, but the contents might be relevant.
if(insulation < 1)
if(istype(thing, /obj/structure/window))
window_priority += thing
else if(istype(thing, /obj/machinery/power/rad_collector))
collector_priority += thing
else
other_priority += thing
if((thing.flags_2 & RAD_PROTECT_CONTENTS_2) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
continue
if(ishuman(thing))
var/mob/living/carbon/human/target_mob = thing
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
continue
processing_list += thing.contents
. = window_priority + collector_priority + other_priority
/proc/get_rad_contamination_adjacent(atom/location, atom/source)
var/static/list/ignored_things = typecacheof(list(
/mob/camera,
/mob/dead,
/obj/effect,
/obj/docking_port,
/atom/movable/lighting_object,
/obj/item/projectile,
/atom/movable/emissive_blocker,
))
var/list/processing_list = list(location)
// 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.
// If the source is a human(like a uranium golem) we just attempt to contaminate all our contents
if(!ishuman(location) || ishuman(source))
processing_list += location.contents
. = list()
for(var/atom/thing in processing_list)
if(thing && source && thing.UID() == source.UID())
continue
if(ignored_things[thing.type])
continue
if((SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING) & COMPONENT_BLOCK_CONTAMINATION) || thing.flags_2 & RAD_NO_CONTAMINATE_2)
continue
if(ishuman(thing) || ishuman(thing.loc))
var/mob/living/carbon/human/target_mob = ishuman(thing) ? thing : thing.loc
var/passed = TRUE
var/zone
var/pocket = FALSE
// Check if we hold the contamination source, have it in our pockets or in our belts or if it's inside us
if(target_mob.UID() == location.UID())
// If it's in our hands check if it can permeate our gloves
if((source && (target_mob.r_hand && target_mob.r_hand.UID() == source.UID()) || (target_mob.l_hand && target_mob.l_hand.UID() == source.UID())))
zone = HANDS
// If it's in our pockets check against our jumpsuit only
else if((target_mob?.l_store && target_mob?.l_store?.UID() == source?.UID()) || (target_mob?.r_store && target_mob?.r_store.UID() == source?.UID()))
zone = LOWER_TORSO
pocket = TRUE
// If it's on our belt check against both our outer layer and jumpsuit
if(location.loc.UID() == target_mob.UID() && istype(location, /obj/item/storage/belt))
zone = LOWER_TORSO
// If on the floor check if it can permeate our shoes
if(istype(location, /turf/))
zone = FEET
// zone being unchanged here means the item is inside the mob
var/list/results = target_mob.rad_contaminate_zone(zone, pocket)
passed = results[1]
results -= results[1]
. |= results
if(!passed)
continue
. += thing
/proc/get_rad_contamination_target(atom/location, atom/source)
var/static/list/ignored_things = typecacheof(list(
/mob/camera,
/mob/dead,
/obj/effect,
/obj/docking_port,
/atom/movable/lighting_object,
/obj/item/projectile,
/atom/movable/emissive_blocker,
))
var/list/processing_list = list(location) + location.contents
. = list()
while(length(processing_list))
var/atom/thing = processing_list[1]
processing_list -= thing
if(thing?.UID() == source?.UID())
continue
if(ignored_things[thing.type])
continue
. += thing
if((thing.flags_2 & RAD_PROTECT_CONTENTS_2) || (SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION))
if((SEND_SIGNAL(thing, COMSIG_ATOM_RAD_CONTAMINATING) & COMPONENT_BLOCK_CONTAMINATION) || thing.flags_2 & RAD_NO_CONTAMINATE_2)
continue
/// If it's a human check for rad protection on all areas
if(ishuman(thing))
var/mob/living/carbon/human/H = thing
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
var/mob/living/carbon/human/target_mob = thing
var/zone = 0
var/list/contaminate = list()
var/list/results = list()
var/passed = TRUE
for(var/i in 0 to 9)
zone = (1<<i)
results = target_mob.rad_contaminate_zone(zone)
passed = results[1] || passed
results -= results[1]
contaminate |= results
. |= contaminate
if(!passed)
continue
processing_list += thing.contents
for(var/atom/human_content in target_mob.contents)
if(!istype(human_content, /obj/item/clothing))
. |= human_content
. += thing
/proc/radiation_pulse(atom/source, intensity, range_modifier, log = FALSE, can_contaminate = TRUE, source_radius = 0)
if(!SSradiation.can_fire)
/proc/radiation_pulse(atom/source, intensity, emission_type = ALPHA_RAD, log = FALSE)
if(!SSradiation.can_fire || intensity < RAD_BACKGROUND_RADIATION)
return
for(var/dir in GLOB.cardinal)
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate, source_radius)
var/datum/radiation_wave/wave = new /datum/radiation_wave(source, intensity, emission_type)
var/list/things = get_rad_contents(source) //copypasta because I don't want to put special code in waves to handle their origin
for(var/k in 1 to length(things))
var/atom/thing = things[k]
if(!thing)
continue
thing.rad_act(intensity)
var/turf/start_turf = source
// Find the turf where we are
while(!istype(start_turf, /turf))
start_turf = start_turf.loc
var/list/things = get_rad_contents(start_turf, emission_type) // Radiate the waves origin frist
// Adjust the weights so the source tile doesn't get all the rads
wave.weight_sum = RAD_SOURCE_WEIGHT
wave.weights = list(wave.weight_sum)
for(var/atom/thing in things)
if(thing.UID() == source.UID())
// Don't block our own radiation
source.base_rad_act(source ,intensity, emission_type)
else
wave.weight_sum = wave.weight_sum * thing.base_rad_act(source ,intensity * wave.weight_sum, emission_type)
// Add the rest of the weight back
wave.weight_sum += (1 - RAD_SOURCE_WEIGHT)
// We can do this because we are on one tile so we have one weight
wave.weights[1] = wave.weight_sum
var/static/last_huge_pulse = 0
if(intensity > 3000 && world.time > last_huge_pulse + 200)
if(intensity > 12000 && world.time > last_huge_pulse + 200)
last_huge_pulse = world.time
log = TRUE
if(log)
var/turf/_source_T = isturf(source) ? source : get_turf(source)
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ")
log_game("Radiation pulse with intensity: [intensity] in [loc_name(_source_T)] ")
return TRUE
/proc/get_rad_contamination(atom/location)
@@ -58,6 +189,24 @@
if(!thing)
continue
var/datum/component/radioactive/radiation = thing.GetComponent(/datum/component/radioactive)
if(radiation && rad_strength < radiation.strength)
rad_strength = radiation.strength
if(radiation && rad_strength < (radiation.alpha_strength + radiation.beta_strength + radiation.gamma_strength))
rad_strength = (radiation.alpha_strength + radiation.beta_strength + radiation.gamma_strength)
return rad_strength
/// Contaminate things that share our immediate location(periodic)
/proc/contaminate_adjacent(atom/source, intensity, emission_type)
// If the source is a turf it is it's location
var/atom/location = isturf(source) ? source : source.loc
// Are we on a turf or in something else
var/is_source_on_turf = isturf(location)
var/contamination_chance = is_source_on_turf ? CONTAMINATION_CHANCE_TURF : CONTAMINATION_CHANCE_OTHER
var/list/contamination_contents = get_rad_contamination_adjacent(location, source)
for(var/atom/thing in contamination_contents)
if(prob(contamination_chance))
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)
/// Contaminate the contents of a target(single instance)
/proc/contaminate_target(atom/target, atom/source, intensity, emission_type)
var/list/contamination_contents = get_rad_contamination_target(target, source)
for(var/atom/thing in contamination_contents)
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)
+2
View File
@@ -1403,6 +1403,8 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
var/obj/structure/window/W = O
if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
return FALSE
if(istype(O, /obj/machinery/power/rad_collector))
return FALSE
return TRUE
//datum may be null, but it does need to be a typed var
+16 -4
View File
@@ -26,7 +26,7 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
warned_atoms[ref] = TRUE
var/atom/master = contamination.parent
SSblackbox.record_feedback("tally", "contaminated", 1, master.type)
var/msg = "has become contaminated with enough radiation to contaminate other objects. || Source: [contamination.source] || Strength: [contamination.strength]"
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]"
master.investigate_log(msg, "radiation")
/datum/controller/subsystem/processing/radiation/fire(resumed)
@@ -41,13 +41,25 @@ PROCESSING_SUBSYSTEM_DEF(radiation)
else
return 0
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache(datum/component/radioactive/thing)
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache_contaminated(datum/component/radioactive/thing)
var/atom/owner = thing.parent
var/turf/place = get_turf(owner)
if(turf_rad_cache[place])
turf_rad_cache[place] += thing.strength
turf_rad_cache[place][1] += thing.alpha_strength
turf_rad_cache[place][2] += thing.beta_strength
turf_rad_cache[place][3] += thing.gamma_strength
else
turf_rad_cache[place] = thing.strength
turf_rad_cache[place] = list(thing.alpha_strength, thing.beta_strength, thing.gamma_strength)
/datum/controller/subsystem/processing/radiation/proc/update_rad_cache_inherent(datum/component/inherent_radioactivity/thing)
var/atom/owner = thing.parent
var/turf/place = get_turf(owner)
if(turf_rad_cache[place])
turf_rad_cache[place][1] += thing.radioactivity_alpha
turf_rad_cache[place][2] += thing.radioactivity_beta
turf_rad_cache[place][3] += thing.radioactivity_gamma
else
turf_rad_cache[place] = list(thing.radioactivity_alpha, thing.radioactivity_beta, thing.radioactivity_gamma)
/datum/controller/subsystem/processing/radiation/proc/refresh_rad_cache()
@@ -0,0 +1,72 @@
/datum/component/inherent_radioactivity
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
var/radioactivity_alpha
var/radioactivity_beta
var/radioactivity_gamma
/// Contamination cooldown in seconds
var/contaminate_cd
var/contained = FALSE
COOLDOWN_DECLARE(contaminate_cooldown)
/datum/component/inherent_radioactivity/Initialize(_radioactivity_alpha = 0, _radioactivity_beta = 0, _radioactivity_gamma = 0, _contaminate_cd = 1.5)
radioactivity_alpha = _radioactivity_alpha
radioactivity_beta = _radioactivity_beta
radioactivity_gamma = _radioactivity_gamma
contaminate_cd = _contaminate_cd
RegisterSignal(parent, list(COMSIG_MOVABLE_IMPACT, COMSIG_ATOM_HITBY), PROC_REF(impact_contaminate))
RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(try_contaminate_hand))
if(isitem(parent))
RegisterSignal(parent, list(COMSIG_ATTACK, COMSIG_ATTACK_OBJ), PROC_REF(impact_contaminate))
START_PROCESSING(SSradiation, src)
/datum/component/inherent_radioactivity/proc/impact_contaminate(atom/source, atom/target)
SIGNAL_HANDLER
if(contaminate_cd <= 0 || COOLDOWN_FINISHED(src, contaminate_cooldown))
if(radioactivity_alpha)
target.contaminate_atom(source, radioactivity_alpha, ALPHA_RAD)
if(radioactivity_beta)
target.contaminate_atom(source, radioactivity_beta, BETA_RAD)
if(radioactivity_gamma)
target.contaminate_atom(source, radioactivity_gamma, GAMMA_RAD)
if(contaminate_cd > 0)
COOLDOWN_START(src, contaminate_cooldown, contaminate_cd SECONDS)
/datum/component/inherent_radioactivity/proc/try_contaminate_hand(atom/source, atom/target)
SIGNAL_HANDLER
if(contaminate_cd <= 0 || COOLDOWN_FINISHED(src, contaminate_cooldown))
if(radioactivity_alpha)
target.contaminate_atom(source, radioactivity_alpha, ALPHA_RAD, HANDS)
if(radioactivity_beta)
target.contaminate_atom(source, radioactivity_beta, BETA_RAD, HANDS)
if(radioactivity_gamma)
target.contaminate_atom(source, radioactivity_gamma, GAMMA_RAD, HANDS)
if(contaminate_cd > 0)
COOLDOWN_START(src, contaminate_cooldown, contaminate_cd SECONDS)
/datum/component/inherent_radioactivity/InheritComponent(datum/component/C, i_am_original, _radioactivity_alpha = 0, _radioactivity_beta = 0, _radioactivity_gamma = 0, _contaminate_cd = 1.5)
if(!i_am_original)
return
if(C)
var/datum/component/inherent_radioactivity/other = C
radioactivity_alpha = other.radioactivity_alpha
radioactivity_beta = other.radioactivity_beta
radioactivity_gamma = other.radioactivity_gamma
contaminate_cd = other.contaminate_cd
else
radioactivity_alpha = _radioactivity_alpha
radioactivity_beta = _radioactivity_beta
radioactivity_gamma = _radioactivity_gamma
contaminate_cd = _contaminate_cd
/datum/component/inherent_radioactivity/process()
if(radioactivity_alpha > 0)
contaminate_adjacent(parent, radioactivity_alpha, ALPHA_RAD)
radiation_pulse(parent, 2 * radioactivity_alpha, ALPHA_RAD)
if(radioactivity_beta > 0)
contaminate_adjacent(parent, radioactivity_beta, BETA_RAD)
radiation_pulse(parent, 2 * radioactivity_beta, BETA_RAD)
if(radioactivity_gamma > 0)
contaminate_adjacent(parent, radioactivity_gamma, GAMMA_RAD)
radiation_pulse(parent, 2 * radioactivity_gamma, GAMMA_RAD)
SSradiation.update_rad_cache_inherent(src)
+79 -22
View File
@@ -2,6 +2,9 @@
#define RAD_AMOUNT_MEDIUM 200
#define RAD_AMOUNT_HIGH 500
#define RAD_AMOUNT_EXTREME 1000
#define GLOW_ALPHA "#225dff5d"
#define GLOW_BETA "#39ff1430"
#define GLOW_GAMMA "#c125ff6b"
/datum/component/radioactive
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
@@ -9,27 +12,31 @@
var/source
///the half-life measured in ticks
var/hl3_release_date
var/strength
var/can_contaminate
var/alpha_strength
var/beta_strength
var/gamma_strength
/datum/component/radioactive/Initialize(_strength = 0, _source, _half_life = RAD_HALF_LIFE, _can_contaminate = TRUE)
/datum/component/radioactive/Initialize(_strength, _source, emission_type, _half_life = RAD_HALF_LIFE)
if(!istype(parent, /atom))
return COMPONENT_INCOMPATIBLE
strength = _strength
switch(emission_type)
if(ALPHA_RAD)
alpha_strength = _strength
if(BETA_RAD)
beta_strength = _strength
if(GAMMA_RAD)
gamma_strength = _strength
source = _source
hl3_release_date = _half_life
can_contaminate = _can_contaminate
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(rad_examine))
RegisterSignal(parent, COMSIG_ADMIN_DECONTAMINATE, PROC_REF(admin_decontaminate))
if(isitem(parent))
RegisterSignal(parent, COMSIG_ATTACK, PROC_REF(rad_attack))
RegisterSignal(parent, COMSIG_ATTACK_OBJ, PROC_REF(rad_attack))
if(strength > RAD_MINIMUM_CONTAMINATION)
SSradiation.warn(src)
//Let's make er glow
//This relies on parent not being a turf or something. IF YOU CHANGE THAT, CHANGE THIS
var/atom/movable/master = parent
master.add_filter("rad_glow", 2, list("type" = "outline", "color" = "#39ff1430", "size" = 2))
master.add_filter("rad_glow", 2, list("type" = "outline", "color" = get_glow_color(), "size" = 2))
addtimer(CALLBACK(src, PROC_REF(glow_loop), master), rand(1, 19)) //Things should look uneven
LAZYADD(SSradiation.all_radiations, src)
START_PROCESSING(SSradiation, src)
@@ -41,15 +48,40 @@
master.remove_filter("rad_glow")
return ..()
/datum/component/radioactive/proc/get_glow_color()
var/list/glow_alpha = rgb2num(GLOW_ALPHA)
var/list/glow_beta = rgb2num(GLOW_BETA)
var/list/glow_gamma = rgb2num(GLOW_GAMMA)
var/list/rad_color = list()
var/alpha_part = alpha_strength / (alpha_strength + beta_strength + gamma_strength)
var/beta_part = beta_strength / (alpha_strength + beta_strength + gamma_strength)
var/gamma_part = 1 - (alpha_part + beta_part)
var/max_ratio = 0
for(var/i in 1 to 4)
rad_color += glow_alpha[i] * alpha_part + glow_beta[i] * beta_part + glow_gamma[i] * gamma_part
// Find the ratio between the color value closest to 256 and 256.
if(i < 4 && max_ratio < (rad_color[i] / 256))
max_ratio = rad_color[i] / 256
return rgb(rad_color[1] / max_ratio, rad_color[2] / max_ratio, rad_color[3] / max_ratio, rad_color[4])
/datum/component/radioactive/process()
if(!prob(50))
return
radiation_pulse(parent, strength, RAD_DISTANCE_COEFFICIENT * 2, FALSE, can_contaminate)
if(alpha_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, alpha_strength, ALPHA_RAD)
if(beta_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, beta_strength, BETA_RAD)
if(gamma_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, gamma_strength, GAMMA_RAD)
if(!hl3_release_date)
return
strength -= strength / hl3_release_date
SSradiation.update_rad_cache(src)
if(strength <= RAD_BACKGROUND_RADIATION)
alpha_strength -= alpha_strength / hl3_release_date
beta_strength -= beta_strength / hl3_release_date
gamma_strength -= gamma_strength / hl3_release_date
SSradiation.update_rad_cache_contaminated(src)
if(alpha_strength + beta_strength + gamma_strength <= RAD_BACKGROUND_RADIATION)
qdel(src)
return PROCESS_KILL
@@ -59,16 +91,30 @@
animate(filter, alpha = 110, time = 15, loop = -1)
animate(alpha = 40, time = 25)
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, _strength, _source, _half_life, _can_contaminate)
/datum/component/radioactive/InheritComponent(datum/component/C, i_am_original, _strength, _source, emission_type, _half_life = RAD_HALF_LIFE)
if(!i_am_original)
return
if(!hl3_release_date) // Permanently radioactive things don't get to grow stronger
return
if(C)
var/datum/component/radioactive/other = C
strength = max(strength, other.strength)
alpha_strength = max(alpha_strength, other.alpha_strength)
beta_strength = max(beta_strength, other.beta_strength)
gamma_strength = max(gamma_strength, other.gamma_strength)
hl3_release_date = other.hl3_release_date
else
strength = max(strength, _strength)
switch(emission_type)
if(ALPHA_RAD)
alpha_strength = max(alpha_strength, _strength)
if(BETA_RAD)
beta_strength = max(beta_strength, _strength)
if(GAMMA_RAD)
gamma_strength = max(gamma_strength, _strength)
hl3_release_date = _half_life
var/atom/movable/master = parent
var/filter = master.get_filter("rad_glow")
animate(filter, color = get_glow_color())
/datum/component/radioactive/proc/rad_examine(datum/source, mob/user, list/out)
SIGNAL_HANDLER
@@ -78,7 +124,7 @@
var/list/fragments = list()
if(get_dist(master, user) <= 1)
fragments += "The air around [master] feels warm"
switch(strength)
switch(alpha_strength + beta_strength + gamma_strength)
if(0 to RAD_AMOUNT_LOW)
if(length(fragments))
fragments += "."
@@ -94,12 +140,20 @@
/datum/component/radioactive/proc/rad_attack(datum/source, atom/movable/target, mob/living/user)
SIGNAL_HANDLER
radiation_pulse(parent, strength / 20)
target.rad_act(strength / 2)
if(alpha_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, alpha_strength / 20, ALPHA_RAD)
target.base_rad_act(parent ,alpha_strength / 2, ALPHA_RAD)
if(beta_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, beta_strength / 20, BETA_RAD)
target.base_rad_act(parent, beta_strength / 2, BETA_RAD)
if(gamma_strength > RAD_BACKGROUND_RADIATION)
radiation_pulse(parent, gamma_strength / 20, GAMMA_RAD)
target.base_rad_act(parent, gamma_strength / 2, GAMMA_RAD)
if(!hl3_release_date)
return
strength -= strength / hl3_release_date
alpha_strength -= alpha_strength / hl3_release_date
beta_strength -= beta_strength / hl3_release_date
gamma_strength -= gamma_strength / hl3_release_date
/datum/component/radioactive/proc/admin_decontaminate()
SIGNAL_HANDLER
@@ -116,3 +170,6 @@
#undef RAD_AMOUNT_MEDIUM
#undef RAD_AMOUNT_HIGH
#undef RAD_AMOUNT_EXTREME
#undef GLOW_ALPHA
#undef GLOW_BETA
#undef GLOW_GAMMA
+1 -9
View File
@@ -12,8 +12,6 @@
RegisterSignal(target, COMSIG_ATOM_RAD_PROBE, PROC_REF(rad_probe_react))
if(contamination_proof) // Can this object be contaminated?
RegisterSignal(target, COMSIG_ATOM_RAD_CONTAMINATING, PROC_REF(rad_contaminating))
if(_amount != 1) // If it's 1 it won't have any impact on radiation passing through anyway
RegisterSignal(target, COMSIG_ATOM_RAD_WAVE_PASSING, PROC_REF(rad_pass))
amount = _amount
@@ -22,13 +20,7 @@
return COMPONENT_BLOCK_RADIATION
/datum/element/rad_insulation/proc/rad_contaminating(datum/source, strength)
/datum/element/rad_insulation/proc/rad_contaminating(datum/source)
SIGNAL_HANDLER
return COMPONENT_BLOCK_CONTAMINATION
/datum/element/rad_insulation/proc/rad_pass(datum/source, datum/radiation_wave/wave, width)
SIGNAL_HANDLER
wave.intensity = wave.intensity * (1 - ((1 - amount) / width)) // The further out the rad wave goes the less it's affected by insulation (larger width)
return COMPONENT_RAD_WAVE_HANDLED
+69 -108
View File
@@ -1,41 +1,31 @@
#define WRAP_INDEX(index, length)((index - 1) % length + 1)
/datum/radiation_wave
/// The thing that spawned this radiation wave
var/source
/// The center of the wave
/// The top left corner of the wave, from which we begin iteration on a step
var/turf/master_turf
/// How far we've moved
var/steps = 0
/// How strong it was originaly
/// The strength at the origin. Multiplied by the weight of a tile to determine the strength of radiation there.
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 distance from the source point the wave can cover without losing any strength.
var/source_radius
/// 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
/// Weights of the current tiles in the step going clockwise from the top left corner. Starts as one tile with a weight of 1
var/list/weights = list(1)
/// Sum of all weights
var/weight_sum = 1
/// The type of particle emitted
var/emission_type = ALPHA_RAD
/datum/radiation_wave/New(atom/_source, dir, _intensity = 0, _range_modifier = RAD_DISTANCE_COEFFICIENT, _can_contaminate = TRUE, _source_radius = 0)
source = "[_source] \[[_source.UID()]\]"
/datum/radiation_wave/New(atom/_source, _intensity = 0, _emission_type = ALPHA_RAD)
source = _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
source_radius = _source_radius
emission_type = _emission_type
START_PROCESSING(SSradiation, src)
/datum/radiation_wave/Destroy()
@@ -43,99 +33,70 @@
STOP_PROCESSING(SSradiation, src)
..()
/// Deals with wave propagation. Radiation waves always expand in a 90 degree cone
/datum/radiation_wave/process()
master_turf = get_step(master_turf, move_dir)
// If the wave is too weak to do anything
if(weight_sum * intensity < RAD_BACKGROUND_RADIATION)
qdel(src)
return
/// We start iteration from the top left corner of the current wave step
master_turf = get_step(master_turf, NORTHWEST)
if(!master_turf)
qdel(src)
return
steps++
var/list/atoms = get_rad_atoms()
var/list/new_weights = list()
var/turf/current_turf = master_turf
weight_sum = 0
var/weight_left
var/weight_center
var/weight_right
var/index
var/offset
var/walk_dir = EAST
var/ratio = steps > 1 ? (steps - 1) / steps : (1 / 8)
var/weight_length = length(weights)
// Iterate around the periphery of a square for each step
for(var/i in 0 to (8 * steps - 1))
// our index along the edge we are on, each corner starts a new edge.
index = (i % (2 * steps)) + 1
// Get weights for rear, right rear and left rear tiles if they were part of the previous step, where rear means towards the center and left and right are along the edge we are on
weight_left = index > 2 ? weights[WRAP_INDEX((index + offset - 2), weight_length)] : 0
weight_center = index > 1 ? weights[WRAP_INDEX((index + offset - 1), weight_length)] : 0
weight_right = index < (2 * steps) ? weights[WRAP_INDEX((index + offset), weight_length)] : 0
// The weight of the current tile the average of the weights of the tiles we checked for earlier
// And is reduced by irradiating things and getting blocked
if(weight_left + weight_center + weight_right)
new_weights += radiate(source, current_turf, (ratio) * (weight_left + weight_center + weight_right) / ((1 + (index > 1 && index < (2 * steps + 1) && steps > 1) + (index > 2 && index < (2 * steps)))), emission_type)
else
new_weights += 0
weight_sum += new_weights[i + 1]
// Advance to next turf
current_turf = get_step(current_turf, walk_dir)
// If we reached a corner turn to the right
if(index == (2 * steps))
walk_dir = turn(walk_dir, -90)
offset += 2 * (steps - 1)
var/strength
if(steps > source_radius + 1)
strength = INVERSE_SQUARE(intensity, max(range_modifier * (steps - source_radius), 1), 1)
weights = new_weights
// With the spread each step being linear waves can spread very far. This limits the distance for performace reasons
if(steps > RAD_DECAY_POINT)
intensity *= RAD_DECAY_RATE
/// Calls rad act on each relevant atom in the turf and returns the resulting weight for that tile after reduction by insulation
/datum/radiation_wave/proc/radiate(atom/source, turf/current_turf, weight, emission_type)
var/list/turf_atoms = list()
if(length(current_turf.contents))
turf_atoms = get_rad_contents(current_turf, emission_type)
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 length(atoms))
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)
turf_atoms = list(current_turf)
for(var/k in turf_atoms)
var/atom/thing = k
if(QDELETED(thing))
continue
thing.rad_act(strength)
weight = weight * thing.base_rad_act(source ,weight * intensity, emission_type)
// return the resulting weight if the radiation on the tile would end up greater than background
return (((weight * intensity) > RAD_BACKGROUND_RADIATION) ? weight : 0)
// 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/bio_chip,
/obj/singularity,
))
if(!can_contaminate || !can_contam || blacklisted[thing.type])
continue
if(thing.flags_2 & RAD_NO_CONTAMINATE_2 || 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)
#undef WRAP_INDEX
@@ -55,7 +55,7 @@
return
if(prob(max(0, 100 - ARMOUR_VALUE_TO_PERCENTAGE(resist))))
L.rad_act(400)
L.base_rad_act(L ,400 , BETA_RAD)
if(HAS_TRAIT(H, TRAIT_GENELESS))
return
randmuti(H) // Applies bad mutation
+35 -7
View File
@@ -60,8 +60,12 @@
var/list/atom_colours //used to store the different colors on an atom
//its inherent color, the colored paint applied on it, special color effect etc...
/// Radiation insulation types
var/rad_insulation = RAD_NO_INSULATION
/// Radiation insulation for alpha emissions
var/rad_insulation_alpha = RAD_ALPHA_BLOCKER
/// Radiation insulation for beta emissions
var/rad_insulation_beta = RAD_NO_INSULATION
/// Radiation insulation for gamma emissions
var/rad_insulation_gamma = RAD_NO_INSULATION
/// Last name used to calculate a color for the chatmessage overlays. Used for caching.
var/chat_color_name
@@ -608,10 +612,32 @@
/**
* Respond to a radioactive wave hitting this atom
*
* Default behaviour is to send [COMSIG_ATOM_RAD_ACT] and return
* This should only be called through the atom/base_rad_act proc
*/
/atom/proc/rad_act(amount)
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, amount)
/atom/proc/rad_act(atom/source, amount, emission_type)
return
/**
* Sends a COMSIG_ATOM_RAD_ACT signal, calls the atoms rad_act with the amount of radiation it should have absorbed and returns the rad insulation of the atom that isappropriate for emission_type
*/
/atom/proc/base_rad_act(atom/source, amount, emission_type)
switch(emission_type)
if(ALPHA_RAD)
. = rad_insulation_alpha
if(BETA_RAD)
. = rad_insulation_beta
if(GAMMA_RAD)
. = rad_insulation_gamma
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, amount, emission_type)
if(amount >= RAD_BACKGROUND_RADIATION)
rad_act(source, amount * (1 - .), emission_type)
/// Attempt to contaminate a single atom
/atom/proc/contaminate_atom(atom/source, intensity, emission_type)
if(flags_2 & RAD_NO_CONTAMINATE_2 || (SEND_SIGNAL(src, COMSIG_ATOM_RAD_CONTAMINATING) & COMPONENT_BLOCK_CONTAMINATION))
return
AddComponent(/datum/component/radioactive, intensity, source, emission_type)
/atom/proc/fart_act(mob/living/M)
return FALSE
@@ -1002,8 +1028,10 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
/atom/proc/clean_radiation(clean_factor = 2)
var/datum/component/radioactive/healthy_green_glow = GetComponent(/datum/component/radioactive)
if(!QDELETED(healthy_green_glow))
healthy_green_glow.strength = max(0, (healthy_green_glow.strength - (RAD_BACKGROUND_RADIATION * clean_factor)))
if(healthy_green_glow.strength <= RAD_BACKGROUND_RADIATION)
healthy_green_glow.alpha_strength = max(0, (healthy_green_glow.alpha_strength - (RAD_BACKGROUND_RADIATION * clean_factor)))
healthy_green_glow.beta_strength = max(0, (healthy_green_glow.beta_strength - (RAD_BACKGROUND_RADIATION * clean_factor)))
healthy_green_glow.gamma_strength = max(0, (healthy_green_glow.gamma_strength - (RAD_BACKGROUND_RADIATION * clean_factor)))
if((healthy_green_glow.alpha_strength + healthy_green_glow.beta_strength + healthy_green_glow.gamma_strength) <= RAD_BACKGROUND_RADIATION)
healthy_green_glow.RemoveComponent()
/obj/effect/decal/cleanable/blood/clean_blood(radiation_clean = FALSE)
+1 -1
View File
@@ -265,7 +265,7 @@
return TRUE
/datum/mutation/disability/radioactive/on_life(mob/living/carbon/human/H)
radiation_pulse(H, 20)
radiation_pulse(H, 80, ALPHA_RAD)
/datum/mutation/disability/radioactive/on_draw_underlays(mob/M, g)
return "rads_s"
+10 -4
View File
@@ -18,10 +18,13 @@ GLOBAL_VAR(bomb_set)
icon_state = "nuclearbomb1"
density = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
flags_2 = NO_MALF_EFFECT_2 | CRITICAL_ATOM_2
flags_2 = NO_MALF_EFFECT_2 | CRITICAL_ATOM_2 | RAD_NO_CONTAMINATE_2 | RAD_PROTECT_CONTENTS_2
anchored = TRUE
power_state = NO_POWER_USE
interact_offline = TRUE
rad_insulation_alpha = RAD_FULL_INSULATION
rad_insulation_beta = RAD_FULL_INSULATION
rad_insulation_gamma = RAD_FULL_INSULATION
/// Are our bolts *supposed* to be in the floor, may not actually cause anchoring if the bolts are cut
var/extended = TRUE
@@ -80,7 +83,8 @@ GLOBAL_VAR(bomb_set)
GLOB.poi_list |= src
GLOB.nuke_list |= src
core = new /obj/item/nuke_core/plutonium(src)
STOP_PROCESSING(SSobj, core) //Let us not irradiate the vault by default.
var/datum/component/inherent_radioactivity/radioactivity = core.GetComponent(/datum/component/inherent_radioactivity)
STOP_PROCESSING(SSradiation, radioactivity)//Let us not irradiate the vault by default.
update_icon(UPDATE_OVERLAYS)
radio = new(src)
radio.listening = FALSE
@@ -201,7 +205,8 @@ GLOBAL_VAR(bomb_set)
"<span class='notice'>You repair [src]'s inner core plate. The radiation is contained.</span>")
removal_stage = NUKE_CORE_PANEL_UNWELDED
if(core)
STOP_PROCESSING(SSobj, core)
var/datum/component/inherent_radioactivity/radioactivity = core.GetComponent(/datum/component/inherent_radioactivity)
STOP_PROCESSING(SSradiation, radioactivity)
update_icon(UPDATE_OVERLAYS)
return ITEM_INTERACT_COMPLETE
if(istype(used, /obj/item/stack/sheet/metal) && removal_stage == NUKE_CORE_PANEL_EXPOSED)
@@ -271,7 +276,8 @@ GLOBAL_VAR(bomb_set)
removal_stage = NUKE_CORE_FULLY_EXPOSED
new /obj/item/stack/sheet/mineral/titanium(loc, 5)
if(core)
START_PROCESSING(SSobj, core)
var/datum/component/inherent_radioactivity/radioactivity = core.GetComponent(/datum/component/inherent_radioactivity)
START_PROCESSING(SSradiation, radioactivity)
if(removal_stage == NUKE_UNWRENCHED)
user.visible_message("<span class='notice'>[user] begins lifting [src] off of the anchors.</span>", "<span class='notice'>You begin lifting the device off the anchors...</span>")
if(!I.use_tool(src, user, 8 SECONDS, volume = I.tool_volume) || removal_stage != NUKE_UNWRENCHED)
+2 -1
View File
@@ -61,7 +61,8 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
assemblytype = /obj/structure/door_assembly
siemens_strength = 1
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_MEDIUM_INSULATION
smoothing_groups = list(SMOOTH_GROUP_AIRLOCK)
cares_about_temperature = TRUE
var/security_level = 0 //How much are wires secured
+6 -8
View File
@@ -160,16 +160,14 @@
paintable = FALSE
var/last_event = 0
/obj/machinery/door/airlock/uranium/process()
if(world.time > last_event + 20)
if(prob(50))
radiate()
last_event = world.time
..()
/obj/machinery/door/airlock/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 150, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/obj/machinery/door/airlock/uranium/proc/radiate()
radiation_pulse(get_turf(src), 150)
/obj/machinery/door/airlock/uranium/attack_hand(mob/user)
. = ..()
/obj/machinery/door/airlock/uranium/glass
opacity = FALSE
+1
View File
@@ -213,6 +213,7 @@
return attack_hand(user)
/obj/machinery/door/attack_hand(mob/user)
. = ..()
return try_to_activate_door(user)
/obj/machinery/door/attack_tk(mob/user)
+8 -4
View File
@@ -18,18 +18,22 @@
desc = "Lead-lined shutters with a radiation hazard symbol. Whilst this won't stop you getting irradiated, especially by a supermatter crystal, it will stop radiation travelling as far."
icon = 'icons/obj/doors/shutters_radiation.dmi'
icon_state = "closed"
rad_insulation = RAD_EXTREME_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_VERY_EXTREME_INSULATION
/obj/machinery/door/poddoor/shutters/radiation/preopen
icon_state = "open"
density = FALSE
opacity = FALSE
rad_insulation = RAD_NO_INSULATION
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_NO_INSULATION
/obj/machinery/door/poddoor/shutters/radiation/open()
. = ..()
rad_insulation = RAD_NO_INSULATION
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_NO_INSULATION
/obj/machinery/door/poddoor/shutters/radiation/close()
. = ..()
rad_insulation = RAD_EXTREME_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_VERY_EXTREME_INSULATION
+1 -1
View File
@@ -204,7 +204,7 @@
flick("grinder-b0",src)
playsound(loc, 'sound/effects/alert.ogg', 50, 0)
sleep(5)
H.rad_act(rand(150, 200))
H.base_rad_act(src ,rand(150, 200), GAMMA_RAD)
if(prob(5))
if(prob(75))
randmutb(H) // Applies bad mutation
@@ -434,11 +434,11 @@
fuel_per_cycle_idle = 10
fuel_per_cycle_active = 150
power_per_cycle = 250
var/rad_per_cycle = 30
var/rad_per_cycle = 120
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/process()
if(..())
radiation_pulse(get_turf(src), rad_per_cycle)
radiation_pulse(get_turf(src), rad_per_cycle, BETA_RAD)
/obj/item/mecha_parts/mecha_equipment/thrusters
name = "exosuit ion thrusters"
@@ -36,6 +36,9 @@
/obj/effect/decal/cleanable/glass/plasma
icon_state = "plasmatiny"
/obj/effect/decal/cleanable/glass/plastitanium
icon_state = "plastitaniumtiny"
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
+3 -1
View File
@@ -282,7 +282,9 @@ GLOBAL_LIST_INIT(meteors_gore, list(/obj/effect/meteor/meaty = 5, /obj/effect/me
..()
explosion(loc, 0, 0, 4, 3, 0)
new /obj/effect/decal/cleanable/greenglow(get_turf(src))
radiation_pulse(src, 5000, 7)
radiation_pulse(src, 20000, 7, ALPHA_RAD)
for(var/turf/target_turf in range(loc, 3))
contaminate_target(target_turf, src, 2000, ALPHA_RAD)
//Hot take on this one. This often hits walls. It really has to breach into somewhere important to matter. This at leats makes the area slightly dangerous for a bit
/obj/effect/meteor/bananium
+1 -1
View File
@@ -75,7 +75,7 @@
var/radiation_amount
/obj/effect/mine/dnascramble/mineEffect(mob/living/victim)
victim.rad_act(radiation_amount)
victim.base_rad_act(src, radiation_amount, BETA_RAD)
if(!victim.dna || HAS_TRAIT(victim, TRAIT_GENELESS))
return
randmutb(victim)
@@ -15,14 +15,23 @@
slot_flags = ITEM_SLOT_BELT
flags = NOBLUDGEON
materials = list(MAT_METAL = 210, MAT_GLASS = 150)
rad_insulation_alpha = RAD_ONE_PERCENT
rad_insulation_beta = RAD_ONE_PERCENT
rad_insulation_gamma = RAD_ONE_PERCENT
var/grace = RAD_GEIGER_GRACE_PERIOD
var/datum/looping_sound/geiger/soundloop
var/scanning = FALSE
var/radiation_count = 0
var/current_tick_amount = 0
var/last_tick_amount = 0
var/radiation_count_alpha = 0
var/radiation_count_beta = 0
var/radiation_count_gamma = 0
var/current_tick_amount_alpha = 0
var/current_tick_amount_beta = 0
var/current_tick_amount_gamma = 0
var/last_tick_amount_alpha = 0
var/last_tick_amount_beta = 0
var/last_tick_amount_gamma = 0
var/fail_to_receive = 0
var/current_warning = 1
@@ -40,19 +49,33 @@
/obj/item/geiger_counter/process()
if(scanning)
radiation_count -= radiation_count / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count += current_tick_amount / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_alpha -= radiation_count_alpha / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_alpha += current_tick_amount_alpha / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_beta -= radiation_count_beta / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_beta += current_tick_amount_beta / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_gamma -= radiation_count_gamma / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count_gamma += current_tick_amount_gamma / RAD_GEIGER_MEASURE_SMOOTHING
if(current_tick_amount)
if(current_tick_amount_alpha)
grace = RAD_GEIGER_GRACE_PERIOD
last_tick_amount = current_tick_amount
last_tick_amount_alpha = current_tick_amount_alpha
if(current_tick_amount_beta)
grace = RAD_GEIGER_GRACE_PERIOD
last_tick_amount_beta = current_tick_amount_beta
if(current_tick_amount_gamma)
grace = RAD_GEIGER_GRACE_PERIOD
last_tick_amount_gamma = current_tick_amount_gamma
else if(!emagged)
grace--
if(grace <= 0)
radiation_count = 0
radiation_count_alpha = 0
radiation_count_beta = 0
radiation_count_gamma = 0
current_tick_amount = 0
current_tick_amount_alpha = 0
current_tick_amount_beta = 0
current_tick_amount_gamma = 0
update_icon(UPDATE_ICON_STATE)
update_sound()
@@ -65,6 +88,7 @@
if(emagged)
. += "<span class='warning'>The display seems to be incomprehensible.</span>"
return
var/radiation_count = max(radiation_count_alpha, radiation_count_beta, radiation_count_gamma)
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
. += "<span class='notice'>Ambient radiation level count reports that all is well.</span>"
@@ -79,7 +103,9 @@
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
. += "<span class='boldannounceic'>Ambient radiation levels above critical level!</span>"
. += "<span class='notice'>The last radiation amount detected was [last_tick_amount]</span>"
. += "<span class='notice'>The alpha radiation amount detected was [last_tick_amount_alpha]</span>"
. += "<span class='notice'>The beta radiation amount detected was [last_tick_amount_beta]</span>"
. += "<span class='notice'>The gamma radiation amount detected was [last_tick_amount_gamma]</span>"
/obj/item/geiger_counter/update_icon_state()
if(!scanning)
@@ -87,6 +113,7 @@
else if(emagged)
icon_state = "geiger_on_emag"
else
var/radiation_count = max(radiation_count_alpha + radiation_count_beta + radiation_count_gamma)
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
@@ -103,17 +130,24 @@
/obj/item/geiger_counter/proc/update_sound()
var/datum/looping_sound/geiger/loop = soundloop
var/radiation_count = max(radiation_count_alpha, radiation_count_beta, radiation_count_gamma)
if(!scanning || !radiation_count)
loop.stop()
return
loop.last_radiation = radiation_count
loop.start()
/obj/item/geiger_counter/rad_act(amount)
. = ..()
/obj/item/geiger_counter/rad_act(atom/source, amount, emission_type)
amount *= 100
if(amount <= RAD_BACKGROUND_RADIATION || !scanning)
return
current_tick_amount += amount
switch(emission_type)
if(ALPHA_RAD)
current_tick_amount_alpha += amount
if(BETA_RAD)
current_tick_amount_beta += amount
if(GAMMA_RAD)
current_tick_amount_gamma += amount
update_icon(UPDATE_ICON_STATE)
/obj/item/geiger_counter/attack_self__legacy__attackchain(mob/user)
@@ -129,8 +163,12 @@
addtimer(CALLBACK(src, PROC_REF(scan), target, user), 20, TIMER_UNIQUE) // Let's not have spamming GetAllContents
else
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='danger'>You project [src]'s stored radiation into [target]!</span>")
target.rad_act(radiation_count)
radiation_count = 0
target.base_rad_act(src, radiation_count_alpha, ALPHA_RAD)
target.base_rad_act(src, radiation_count_beta, BETA_RAD)
target.base_rad_act(src, radiation_count_gamma, GAMMA_RAD)
radiation_count_alpha = 0
radiation_count_beta = 0
radiation_count_gamma = 0
return TRUE
/obj/item/geiger_counter/proc/scan(atom/A, mob/user)
@@ -158,7 +196,9 @@
return FALSE
user.visible_message("<span class='notice'>[user] refastens [src]'s maintenance panel!</span>", "<span class='notice'>You reset [src] to its factory settings!</span>")
emagged = FALSE
radiation_count = 0
radiation_count_alpha = 0
radiation_count_beta = 0
radiation_count_gamma = 0
update_icon(UPDATE_ICON_STATE)
return TRUE
else
@@ -170,7 +210,9 @@
if(!scanning)
to_chat(user, "<span class='warning'>[src] must be on to reset its radiation level!</span>")
return
radiation_count = 0
radiation_count_alpha = 0
radiation_count_beta = 0
radiation_count_gamma = 0
to_chat(user, "<span class='notice'>You flush [src]'s radiation counts, resetting it to normal.</span>")
update_icon(UPDATE_ICON_STATE)
@@ -198,8 +240,8 @@
RegisterSignal(user, COMSIG_ATOM_RAD_ACT, PROC_REF(redirect_rad_act))
listeningTo = user
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount, emission_type)
base_rad_act(source, amount, emission_type)
/obj/item/geiger_counter/cyborg/dropped()
. = ..()
@@ -279,7 +279,9 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list(
recipes = GLOB.titaniumglass_recipes
GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
new /datum/stack_recipe/window("plastitanium window", /obj/structure/window/full/plastitanium, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE)
new /datum/stack_recipe("plastitanium shard", /obj/item/shard/plastitanium, time = 0 SECONDS),
new /datum/stack_recipe/window("directional plastitanium window", /obj/structure/window/plastitanium, 1, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE),
new /datum/stack_recipe/window("fulltile plastitanium window", /obj/structure/window/full/plastitanium, 2, time = 0 SECONDS, on_floor = TRUE, window_checks = TRUE),
))
//////////////////////////////
@@ -295,6 +297,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100)
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/plastitaniumglass
created_window = /obj/structure/window/plastitanium
full_window = /obj/structure/window/full/plastitanium
table_type = /obj/structure/table/glass/reinforced/plastitanium
+25 -17
View File
@@ -11,16 +11,19 @@
icon_state = "plutonium_core"
item_state = "plutoniumcore"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
flags_2 = RAD_NO_CONTAMINATE_2 //Don't have the item itself become irradiated when it makes radiation.
flags_2 = RAD_NO_CONTAMINATE_2 //This is made from radioactive material so cannot really be contaminated
var/cooldown = 0
var/pulseicon = "plutonium_core_pulse"
// Is this made from radioactive material or not.
var/radioactive_material = TRUE
/obj/item/nuke_core/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
if(radioactive_material)
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 0, 400, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/obj/item/nuke_core/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/nuke_core/attackby__legacy__attackchain(obj/item/nuke_core_container/container, mob/user)
@@ -29,12 +32,6 @@
else
return ..()
/obj/item/nuke_core/process()
if(cooldown < world.time - 6 SECONDS)
cooldown = world.time
flick(pulseicon, src)
radiation_pulse(src, 400, 2)
/obj/item/nuke_core/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is rubbing [src] against [user.p_themselves()]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return TOXLOSS
@@ -104,7 +101,11 @@
/obj/item/nuke_core_container/proc/seal()
if(!QDELETED(core))
STOP_PROCESSING(SSobj, core)
var/datum/component/inherent_radioactivity/radioactivity = core.GetComponent(/datum/component/inherent_radioactivity)
var/datum/component/radioactive/box_contamination = GetComponent(/datum/component/radioactive)
STOP_PROCESSING(SSradiation, radioactivity)
if(box_contamination)
box_contamination.RemoveComponent()
icon_state = "core_container_sealed"
playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE)
if(ismob(loc))
@@ -123,7 +124,8 @@
/obj/item/nuke_core_container/proc/crack_open()
visible_message("<span class='boldnotice'>[src] bursts open!</span>")
if(core)
START_PROCESSING(SSobj, core)
var/datum/component/inherent_radioactivity/radioactivity = core.GetComponent(/datum/component/inherent_radioactivity)
START_PROCESSING(SSradiation, radioactivity)
icon_state = "core_container_cracked_loaded"
else
icon_state = "core_container_cracked_empty"
@@ -164,6 +166,7 @@
pulseicon = "supermatter_sliver_pulse"
w_class = WEIGHT_CLASS_BULKY //can't put it into bags
layer = ABOVE_MOB_LAYER + 0.02
radioactive_material = FALSE
/obj/item/nuke_core/supermatter_sliver/Initialize(mapload)
. = ..()
@@ -201,16 +204,17 @@
else
if(issilicon(user))
to_chat(user, "<span class='userdanger'>You try to touch [src] with one of your modules. Error!</span>")
radiation_pulse(user, 500, 2)
radiation_pulse(user, 2000, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
user.dust()
qdel(src)
return
to_chat(user, "<span class='danger'>As it touches [src], both [src] and [I] burst into dust!</span>")
radiation_pulse(user, 100)
radiation_pulse(user, 400, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
qdel(I)
qdel(src)
return ..()
/obj/item/nuke_core/supermatter_sliver/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!isliving(hit_atom))
@@ -230,7 +234,7 @@
"<span class='userdanger'>You're hit by [src] and everything suddenly goes silent.\n[src] flashes into dust, and soon as you can register this, you do as well.</span>",
"<span class='hear'>Everything suddenly goes silent.</span>")
victim.dust()
radiation_pulse(src, 500, 2)
radiation_pulse(src, 2000, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
qdel(src)
@@ -243,7 +247,7 @@
user.visible_message("<span class='danger'>[user] reaches out and tries to pick up [src]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!</span>",
"<span class='userdanger'>You reach for [src] with your hands. That was dumb.</span>",
"<span class='hear'>Everything suddenly goes silent.</span>")
radiation_pulse(user, 500, 2)
radiation_pulse(user, 2000, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
user.dust()
@@ -268,9 +272,13 @@
to_chat(user, "<span class='warning'>Container is sealing...</span>")
addtimer(CALLBACK(src, PROC_REF(seal)), 10 SECONDS)
/obj/item/nuke_core_container/supermatter/seal()
if(!QDELETED(sliver))
STOP_PROCESSING(SSobj, sliver)
var/datum/component/radioactive/contamination = GetComponent(/datum/component/radioactive)
if(contamination)
contamination.RemoveComponent()
icon_state = "supermatter_container_sealed"
playsound(src, 'sound/items/deconstruct.ogg', 60, TRUE)
if(ismob(loc))
@@ -305,7 +313,7 @@
user.visible_message("<span class='danger'>[user] reaches out and tries to pick up [sliver]. [user.p_their()] body starts to glow and bursts into flames before flashing into dust!</span>",
"<span class='userdanger'>You reach for [sliver] with your hands. That was dumb.</span>",
"<span class='italics'>Everything suddenly goes silent.</span>")
radiation_pulse(user, 500, 2)
radiation_pulse(user, 2000, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
message_admins("[sliver] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].")
investigate_log("has consumed [key_name(user)].", "supermatter")
@@ -400,6 +408,6 @@
user.dust()
icon_state = "supermatter_tongs"
item_state = "supermatter_tongs"
radiation_pulse(src, 500, 2)
radiation_pulse(src, 2000, GAMMA_RAD)
playsound(src, 'sound/effects/supermatter.ogg', 50, TRUE)
QDEL_NULL(sliver)
@@ -37,13 +37,13 @@
icon_state = "gluon"
item_state = "grenade"
var/freeze_range = 4
var/rad_damage = 350
var/rad_damage = 1400
var/stamina_damage = 30
/obj/item/grenade/gluon/prime()
update_mob()
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
radiation_pulse(src, rad_damage)
radiation_pulse(src, rad_damage, BETA_RAD)
for(var/turf/simulated/floor/T in view(freeze_range, loc))
T.MakeSlippery(TURF_WET_ICE)
for(var/mob/living/carbon/L in T)
+10
View File
@@ -95,3 +95,13 @@
materials = list(MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
icon_prefix = "plasma"
welded_type = /obj/item/stack/sheet/plasmaglass
/obj/item/shard/plastitanium
name = "plastitanium shard"
desc = "A shard of plastitanium glass. Considerably tougher then normal glass shards. Apparently not tough enough to be a window."
force = 6
throwforce = 11
icon_state = "plastitaniumlarge"
materials = list(MAT_TITANIUM = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_PLASMA = MINERAL_MATERIAL_AMOUNT * 0.5, MAT_GLASS = MINERAL_MATERIAL_AMOUNT)
icon_prefix = "plastitanium"
welded_type = /obj/item/stack/sheet/plastitaniumglass
+2 -1
View File
@@ -116,7 +116,8 @@
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50)
damage_deflection = 0
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_MEDIUM_INSULATION
rad_insulation_gamma = RAD_LIGHT_INSULATION
var/initial_state
var/state_open = FALSE
var/is_operating = FALSE
@@ -44,7 +44,7 @@
if(prob(50))
empulse(src, 4, 10)
else
radiation_pulse(get_turf(src), 500, 2)
radiation_pulse(get_turf(src), 2000, BETA_RAD)
/obj/structure/fusionreactor/wrench_act(mob/user, obj/item/I)
. = TRUE
+7 -18
View File
@@ -14,7 +14,8 @@
icon_state = "wall-0"
base_icon_state = "wall"
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_LIGHT_INSULATION
layer = TURF_LAYER
var/mineral = /obj/item/stack/sheet/metal
@@ -63,6 +64,7 @@
toggle(user)
/obj/structure/falsewall/attack_hand(mob/user)
. = ..()
toggle(user)
/obj/structure/falsewall/proc/toggle(mob/user)
@@ -217,23 +219,10 @@
smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_URANIUM_WALLS)
canSmoothWith = list(SMOOTH_GROUP_URANIUM_WALLS)
/obj/structure/falsewall/uranium/attackby__legacy__attackchain(obj/item/W as obj, mob/user as mob, params)
radiate()
..()
/obj/structure/falsewall/uranium/attack_hand(mob/user as mob)
radiate()
..()
/obj/structure/falsewall/uranium/proc/radiate()
if(!active)
if(world.time > last_event + 1.5 SECONDS)
active = TRUE
radiation_pulse(src, 150)
for(var/turf/simulated/wall/mineral/uranium/T in orange(1, src))
T.radiate()
last_event = world.time
active = FALSE
/obj/structure/falsewall/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 50, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/*
* Other misc falsewall types
*/
+1 -1
View File
@@ -6,7 +6,7 @@
density = TRUE
layer = BELOW_OBJ_LAYER
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_insulation_beta = RAD_HEAVY_INSULATION
cares_about_temperature = TRUE
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
+1
View File
@@ -14,6 +14,7 @@
max_integrity = 50
integrity_failure = 20
cares_about_temperature = TRUE
rad_insulation_beta = RAD_BETA_BLOCKER
var/rods_type = /obj/item/stack/rods
var/rods_amount = 2
var/rods_broken = 1
+2 -2
View File
@@ -70,7 +70,7 @@
/obj/structure/holosign/barrier/engineering
icon_state = "holosign_engi"
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_LIGHT_INSULATION
rad_insulation_beta = RAD_LIGHT_INSULATION
/obj/structure/holosign/barrier/atmos
name = "holo firelock"
@@ -81,7 +81,7 @@
anchored = TRUE
alpha = 150
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_LIGHT_INSULATION
rad_insulation_beta = RAD_LIGHT_INSULATION
/obj/structure/holosign/barrier/atmos/Initialize(mapload)
. = ..()
@@ -10,7 +10,8 @@
max_integrity = 200
armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 10, RAD = 100, FIRE = 50, ACID = 50)
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_LIGHT_INSULATION
var/initial_state
var/state_open = FALSE
var/is_operating = FALSE
@@ -144,13 +145,12 @@
icon_state = "silver"
sheetType = /obj/item/stack/sheet/mineral/silver
max_integrity = 300
rad_insulation = RAD_HEAVY_INSULATION
/obj/structure/mineral_door/gold
name = "gold door"
icon_state = "gold"
sheetType = /obj/item/stack/sheet/mineral/gold
rad_insulation = RAD_HEAVY_INSULATION
rad_insulation_gamma = RAD_MEDIUM_INSULATION
/obj/structure/mineral_door/uranium
name = "uranium door"
@@ -167,7 +167,7 @@
/obj/structure/mineral_door/transparent
opacity = FALSE
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_insulation_beta = RAD_MEDIUM_INSULATION
/obj/structure/mineral_door/transparent/operate_update()
density = !density
@@ -205,7 +205,6 @@
icon_state = "diamond"
sheetType = /obj/item/stack/sheet/mineral/diamond
max_integrity = 1000
rad_insulation = RAD_EXTREME_INSULATION
/obj/structure/mineral_door/wood
name = "wood door"
@@ -216,7 +215,7 @@
hardness = 1
resistance_flags = FLAMMABLE
max_integrity = 200
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_insulation_beta = RAD_VERY_LIGHT_INSULATION
/obj/structure/mineral_door/wood/Initialize(mapload)
. = ..()
+4 -19
View File
@@ -71,25 +71,10 @@
desc = "This statue has a sickening green colour."
icon_state = "eng"
/obj/structure/statue/uranium/attackby__legacy__attackchain(obj/item/W, mob/user, params)
radiate()
return ..()
/obj/structure/statue/uranium/Bumped(atom/user)
radiate()
..()
/obj/structure/statue/uranium/attack_hand(mob/user)
radiate()
..()
/obj/structure/statue/uranium/proc/radiate()
if(!active)
if(world.time > last_event + 1.5 SECONDS)
active = TRUE
radiation_pulse(src, 30)
last_event = world.time
active = FALSE
/obj/statue/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 150, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/obj/structure/statue/plasma
max_integrity = 200
+50 -12
View File
@@ -14,7 +14,7 @@
max_integrity = 25
resistance_flags = ACID_PROOF
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 80, ACID = 100)
rad_insulation = RAD_VERY_LIGHT_INSULATION
rad_insulation_beta = RAD_MEDIUM_INSULATION
cares_about_temperature = TRUE
var/ini_dir = null
var/state = WINDOW_OUT_OF_FRAME
@@ -40,6 +40,13 @@
var/env_smash_level = ENVIRONMENT_SMASH_STRUCTURES
/// How well this window resists superconductivity.
var/superconductivity = WINDOW_HEAT_TRANSFER_COEFFICIENT
/// How much we get activated by gamma radiation
var/rad_conversion_amount = 0
/obj/structure/window/rad_act(atom/source, amount, emission_type)
if(emission_type == GAMMA_RAD && amount * rad_conversion_amount > RAD_BACKGROUND_RADIATION)
AddComponent(/datum/component/radioactive, amount * rad_conversion_amount, src, BETA_RAD, 60)
/obj/structure/window/examine(mob/user)
. = ..()
@@ -518,7 +525,7 @@
reinf = TRUE
heat_resistance = 1300
armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 25, RAD = 100, FIRE = 80, ACID = 100)
rad_insulation = RAD_NO_INSULATION
rad_insulation_beta = RAD_NO_INSULATION
max_integrity = 50
explosion_block = 1
glass_type = /obj/item/stack/sheet/rglass
@@ -631,7 +638,7 @@
/obj/structure/window/plasmabasic
name = "plasma window"
desc = "A window made out of a plasma-silicate alloy. It looks insanely tough to break and burn through. Lacks protection from radiation."
desc = "A window made out of a plasma-silicate alloy. It looks insanely tough to break and burn through. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon_state = "plasmawindow"
glass_decal = /obj/effect/decal/cleanable/glass/plasma
shardtype = /obj/item/shard/plasma
@@ -640,12 +647,14 @@
max_integrity = 150
explosion_block = 1
armor = list(MELEE = 75, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 45, RAD = 100, FIRE = 99, ACID = 100)
rad_insulation = RAD_NO_INSULATION
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_WINDOW
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_conversion_amount = 2
/obj/structure/window/plasmareinforced
name = "reinforced plasma window"
desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof. Lacks protection from radiation."
desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon_state = "plasmarwindow"
glass_decal = /obj/effect/decal/cleanable/glass/plasma
shardtype = /obj/item/shard/plasma
@@ -655,10 +664,31 @@
max_integrity = 500
explosion_block = 2
armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, RAD = 100, FIRE = 99, ACID = 100)
rad_insulation = RAD_NO_INSULATION
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_WINDOW
damage_deflection = 21
env_smash_level = ENVIRONMENT_SMASH_WALLS // these windows are a fair bit tougher
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_conversion_amount = 1.5
/obj/structure/window/plastitanium
name = "plastitanium window"
desc = "An evil looking window of plasma and titanium. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon_state = "plastitaniumwindow"
glass_decal = /obj/effect/decal/cleanable/glass/plastitanium
shardtype = /obj/item/shard/plasma
glass_type = /obj/item/stack/sheet/plastitaniumglass
reinf = TRUE
heat_resistance = 32000
max_integrity = 600
explosion_block = 2
armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, RAD = 100, FIRE = 99, ACID = 100)
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_WINDOW
damage_deflection = 21
env_smash_level = ENVIRONMENT_SMASH_WALLS // these windows are a fair bit tougher
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_conversion_amount = 2.25
/obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
@@ -683,7 +713,7 @@
/obj/structure/window/full/plasmabasic
name = "plasma window"
desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through. Has very light protection from radiation."
desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon = 'icons/obj/smooth_structures/windows/plasma_window.dmi'
icon_state = "plasma_window-0"
base_icon_state = "plasma_window"
@@ -697,10 +727,13 @@
edge_overlay_file = 'icons/obj/smooth_structures/windows/window_edges.dmi'
env_smash_level = ENVIRONMENT_SMASH_WALLS // these windows are a fair bit tougher
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_FULL_WINDOW
rad_conversion_amount = 2.6
/obj/structure/window/full/plasmareinforced
name = "reinforced plasma window"
desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof. Offers superior protection from radiation."
desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon = 'icons/obj/smooth_structures/windows/rplasma_window.dmi'
icon_state = "rplasma_window-0"
base_icon_state = "rplasma_window"
@@ -712,10 +745,12 @@
max_integrity = 1000
explosion_block = 2
armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, RAD = 100, FIRE = 99, ACID = 100)
rad_insulation = RAD_HEAVY_INSULATION
edge_overlay_file = 'icons/obj/smooth_structures/windows/reinforced_window_edges.dmi'
env_smash_level = ENVIRONMENT_SMASH_RWALLS // these ones are insanely tough
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_FULL_WINDOW
rad_conversion_amount = 2.2
/obj/structure/window/full/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
@@ -730,7 +765,7 @@
reinf = TRUE
heat_resistance = 1600
armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 25, RAD = 100, FIRE = 80, ACID = 100)
rad_insulation = RAD_HEAVY_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
explosion_block = 1
glass_type = /obj/item/stack/sheet/rglass
edge_overlay_file = 'icons/obj/smooth_structures/windows/reinforced_window_edges.dmi'
@@ -775,7 +810,7 @@
/obj/structure/window/full/plastitanium
name = "plastitanium window"
desc = "An evil looking window of plasma and titanium."
desc = "An evil looking window of plasma and titanium. When hit with Gamma particles it will become charged and start emitting Beta particles"
icon = 'icons/obj/smooth_structures/windows/plastitanium_window.dmi'
icon_state = "plastitanium_window-0"
base_icon_state = "plastitanium_window"
@@ -783,13 +818,16 @@
reinf = TRUE
heat_resistance = 32000
armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, RAD = 100, FIRE = 99, ACID = 100)
rad_insulation = RAD_HEAVY_INSULATION
rad_insulation_beta = RAD
explosion_block = 3
glass_type = /obj/item/stack/sheet/plastitaniumglass
smoothing_groups = list(SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_WINDOW_FULLTILE_PLASTITANIUM, SMOOTH_GROUP_PLASTITANIUM_WALLS)
canSmoothWith = list(SMOOTH_GROUP_WINDOW_FULLTILE_PLASTITANIUM, SMOOTH_GROUP_SYNDICATE_WALLS, SMOOTH_GROUP_PLASTITANIUM_WALLS)
env_smash_level = ENVIRONMENT_SMASH_RWALLS //used in shuttles, same reason as above
superconductivity = ZERO_HEAT_TRANSFER_COEFFICIENT
rad_insulation_beta = RAD_NO_INSULATION
rad_insulation_gamma = RAD_GAMMA_FULL_WINDOW
rad_conversion_amount = 3
/obj/structure/window/reinforced/clockwork
name = "brass window"
+1 -1
View File
@@ -24,7 +24,7 @@ GLOBAL_LIST_INIT(icons_to_ignore_at_floor_init, list("damaged1","damaged2","dama
var/current_overlay = null
var/floor_tile = null //tile that this floor drops
var/keep_dir = TRUE //When false, resets dir to default on changeturf()
rad_insulation_alpha = RAD_NO_INSULATION
var/footstep = FOOTSTEP_FLOOR
var/barefootstep = FOOTSTEP_HARD_BAREFOOT
var/clawfootstep = FOOTSTEP_HARD_CLAW
@@ -247,6 +247,11 @@
var/last_event = 0
var/active = FALSE
/turf/simulated/floor/mineral/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 100, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/turf/simulated/floor/mineral/uranium/Entered(mob/AM)
.=..()
if(!.)
@@ -268,7 +273,7 @@
if(!active)
if(world.time > last_event + 15)
active = TRUE
radiation_pulse(src, 10)
radiation_pulse(src, 40, ALPHA_RAD)
for(var/turf/simulated/floor/mineral/uranium/T in orange(1, src))
T.radiate()
last_event = world.time
+1 -1
View File
@@ -14,7 +14,7 @@
density = TRUE
blocks_air = TRUE
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
layer = EDGED_TURF_LAYER
temperature = TCMB
color = COLOR_ROCK
+2 -1
View File
@@ -25,7 +25,8 @@
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
flags_ricochet = RICOCHET_HARD
rad_insulation = RAD_MEDIUM_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_MEDIUM_INSULATION
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
+4 -23
View File
@@ -73,29 +73,10 @@
smoothing_groups = list(SMOOTH_GROUP_SIMULATED_TURFS, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_URANIUM_WALLS)
canSmoothWith = list(SMOOTH_GROUP_URANIUM_WALLS)
/turf/simulated/wall/mineral/uranium/proc/radiate()
if(!active)
if(world.time > last_event + 1.5 SECONDS)
active = TRUE
radiation_pulse(src, 40)
for(var/turf/simulated/wall/mineral/uranium/T in orange(1, src))
T.radiate()
last_event = world.time
active = FALSE
/turf/simulated/wall/mineral/uranium/attack_hand(mob/user as mob)
radiate()
..()
/turf/simulated/wall/mineral/uranium/attack_by(obj/item/attacking, mob/user, params)
if(..())
return FINISH_ATTACK
radiate()
/turf/simulated/wall/mineral/uranium/Bumped(AM as mob|obj)
radiate()
..()
/turf/simulated/wall/mineral/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 50, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/turf/simulated/wall/mineral/plasma
name = "plasma wall"
@@ -8,7 +8,8 @@
opacity = TRUE
density = TRUE
explosion_block = 2
rad_insulation = RAD_HEAVY_INSULATION
rad_insulation_beta = RAD_BETA_BLOCKER
rad_insulation_gamma = RAD_VERY_EXTREME_INSULATION
damage_cap = 600
hardness = 10
sheet_type = /obj/item/stack/sheet/plasteel
+1
View File
@@ -153,6 +153,7 @@
..()
/turf/attack_hand(mob/user as mob)
. = ..()
user.Move_Pulled(src)
/turf/attack_robot(mob/user)
@@ -430,7 +430,7 @@
var/flashmod = max(cos(look_angle - angle_to_bore), 0)
someone.flash_eyes(min(round(output_level/ EYE_DAMAGE_THRESHOLD), 3) * flashmod, TRUE, TRUE)
if(output_level > RAD_THRESHOLD) // Starts causing weak, quickly dissipating radiation pulses around the bore when power is high enough
radiation_pulse(get_front_turf(), (output_level / RAD_THRESHOLD) * 50, RAD_DISTANCE_COEFFICIENT)
radiation_pulse(get_front_turf(), (output_level / RAD_THRESHOLD) * 200, GAMMA_RAD)
charge -= output_level
+1 -1
View File
@@ -6,7 +6,7 @@
invisibility = INVISIBILITY_ABSTRACT
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
explosion_block = 50
rad_insulation = RAD_FULL_INSULATION
rad_insulation_beta = RAD_FULL_INSULATION
opacity = TRUE
density = TRUE
blocks_air = TRUE
+1 -4
View File
@@ -98,10 +98,7 @@
if(msg && ishuman(wearer))
wearer.show_message("<b><span class='robot'>[msg]</span></b>", 1)
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(amount)
. = ..()
if(amount <= RAD_BACKGROUND_RADIATION)
return
/obj/item/clothing/head/helmet/space/hardsuit/rad_act(atom/source, amount, emission_type)
current_tick_amount += amount
/obj/item/clothing/head/helmet/space/hardsuit/process()
+6
View File
@@ -140,6 +140,9 @@
"Drask" = 'icons/mob/clothing/species/drask/head/utility.dmi',
"Kidan" = 'icons/mob/clothing/species/kidan/head/utility.dmi'
)
rad_insulation_alpha = RAD_FULL_INSULATION
rad_insulation_beta = RAD_FULL_INSULATION
rad_insulation_gamma = RAD_FULL_INSULATION
/obj/item/clothing/suit/radiation
name = "radiation suit"
@@ -170,3 +173,6 @@
"Drask" = 'icons/mob/clothing/species/drask/suits/utility.dmi',
"Kidan" = 'icons/mob/clothing/species/kidan/suits/utility.dmi'
)
rad_insulation_alpha = RAD_FULL_INSULATION
rad_insulation_beta = RAD_FULL_INSULATION
rad_insulation_gamma = RAD_FULL_INSULATION
+4 -7
View File
@@ -419,14 +419,11 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "coin_uranium_heads"
materials = list(MAT_URANIUM = 400)
credits = 160
COOLDOWN_DECLARE(radiation_cooldown)
/obj/item/coin/uranium/attack_self__legacy__attackchain(mob/user)
..()
if(!COOLDOWN_FINISHED(src, radiation_cooldown))
return
radiation_pulse(src, 50)
COOLDOWN_START(src, radiation_cooldown, 1.5 SECONDS)
/obj/item/coin/uranium/Initialize(mapload)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = AddComponent(/datum/component/inherent_radioactivity, 50, 0, 0, 1.5)
START_PROCESSING(SSradiation, radioactivity)
/obj/item/coin/clown
cmineral = "bananium"
@@ -1406,3 +1406,12 @@ so that different stomachs can handle things in different ways VB*/
M.update_revive()
add_attack_logs(M, M, "Revived with Lazarus Reagent")
SSblackbox.record_feedback("tally", "players_revived", 1, "lazarus_reagent")
/mob/living/carbon/is_inside_mob(atom/thing)
if(!(..()))
return FALSE
if(head && head.UID() == thing.UID())
return FALSE
if(wear_suit && wear_suit.UID() == thing.UID())
return FALSE
return TRUE
@@ -837,3 +837,47 @@ emp_act
/mob/living/carbon/human/canBeHandcuffed()
return has_left_hand() || has_right_hand()
/// Returns a list. The first element is whether we penetrated all clothing for the zone, the rest are the clothes that got contaminated
/mob/living/carbon/human/proc/rad_contaminate_zone(zone_flag, pocket = FALSE)
// This is for items inside of the mob
if(!zone_flag)
return list(TRUE)
var/list/garments = list()
var/list/contaminate = list()
var/passed = TRUE
// items in our pocket are treated uniquely as they are outside of the mob but also under most of its clothing
if(pocket)
garments = list(w_uniform)
else
// the suit is worn on top of all other stuff so it needs to be checked first
if(wear_suit)
garments = list(wear_suit)
for(var/obj/item/clothing/garment in contents)
if(garment.body_parts_covered & zone_flag)
garments |= garment
// If we have a suit push it to the start of the list
if(wear_suit)
garments -= wear_suit
garments = list(wear_suit) + garments
while(length(garments) && passed)
var/obj/item/clothing/garment = garments[1]
garments -= garment
passed = prob((garment.permeability_coefficient * 100) - 1) && !(garment.flags_2 & RAD_PROTECT_CONTENTS_2)
if(garment.flags_2 & RAD_NO_CONTAMINATE_2)
continue
contaminate += garment
return list(passed) + contaminate
/// Tries to contaminate a human
/mob/living/carbon/human/contaminate_atom(atom/source, intensity, emission_type, zone = null)
if(!zone)
zone = hit_zone_to_clothes_zone(ran_zone())
var/list/to_contaminate = rad_contaminate_zone(zone)
if(to_contaminate[1])
to_contaminate += src
to_contaminate -= to_contaminate[1]
for(var/atom/thing in to_contaminate)
thing.AddComponent(/datum/component/radioactive, intensity, source, emission_type)
@@ -1502,7 +1502,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && drop_item_to_ground(hand))
step_towards(hand, src)
to_chat(src, "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>")
rad_act(current_size * 3)
base_rad_act(S, current_size * 3, GAMMA_RAD)
/mob/living/carbon/human/narsie_act()
if(iswizard(src) || IS_CULTIST(src)) // Wizards are immune to the magic. Cultists also don't get transformed.
@@ -2132,3 +2132,35 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
hallucination_to_make = string_path
new hallucination_to_make(get_turf(src), src)
/// Checks if an item is inside the body of the mob
/mob/living/carbon/human/is_inside_mob(atom/thing)
if(!(..()))
return FALSE
if(w_uniform && w_uniform.UID() == thing.UID())
return FALSE
if(shoes && shoes.UID() == thing.UID())
return FALSE
if(belt && belt.UID() == thing.UID())
return FALSE
if(gloves && gloves.UID() == thing.UID())
return FALSE
if(neck && neck.UID() == thing.UID())
return FALSE
if(glasses && glasses.UID() == thing.UID())
return FALSE
if(l_ear && l_ear.UID() == thing.UID())
return FALSE
if(r_ear && r_ear.UID() == thing.UID())
return FALSE
if(wear_id && wear_id.UID() == thing.UID())
return FALSE
if(wear_pda && wear_pda.UID() == thing.UID())
return FALSE
if(r_store && r_store.UID() == thing.UID())
return FALSE
if(l_store && l_store.UID() == thing.UID())
return FALSE
if(s_store && s_store.UID() == thing.UID())
return FALSE
return TRUE
@@ -342,9 +342,15 @@
prefix = "Uranium"
special_names = list("Oxide", "Rod", "Meltdown")
/datum/species/golem/uranium/handle_life(mob/living/carbon/human/H)
radiation_pulse(H, 20)
..()
/datum/species/golem/uranium/on_species_gain(mob/living/carbon/human/H)
. = ..()
var/datum/component/inherent_radioactivity/radioactivity = H.AddComponent(/datum/component/inherent_radioactivity, 40, 0, 0)
START_PROCESSING(SSradiation, radioactivity)
/datum/species/golem/uranium/on_species_loss(mob/living/carbon/human/H)
. = ..()
var/datum/component/inherent_radioactivity/rads = H.GetComponent(/datum/component/inherent_radioactivity)
rads.RemoveComponent()
//Ventcrawler
/datum/species/golem/plastic
+21 -4
View File
@@ -1040,9 +1040,13 @@
..()
update_z(new_turf?.z)
/mob/living/rad_act(amount)
. = ..()
/mob/living/rad_act(atom/source, amount, emission_type)
// Mobs block very little Beta and Gamma radiation, but we still want the rads to affect them.
if(emission_type > ALPHA_RAD)
amount /= (1 - RAD_MOB_INSULATION)
// Alpha sources outside the body don't do much
else if(!is_inside_mob(source))
amount /= 100
if(!amount || (amount < RAD_MOB_SKIN_PROTECTION) || HAS_TRAIT(src, TRAIT_RADIMMUNE))
return
@@ -1054,9 +1058,22 @@
if(amount > RAD_BURN_THRESHOLD)
apply_damage(RAD_BURN_CURVE(amount), BURN, null, blocked)
apply_effect((amount * RAD_MOB_COEFFICIENT) / max(1, (radiation ** 2) * RAD_OVERDOSE_REDUCTION), IRRADIATE, ARMOUR_VALUE_TO_PERCENTAGE(blocked))
/mob/living/proc/is_inside_mob(atom/thing)
if(!(thing in contents))
return FALSE
if(l_hand && l_hand.UID() == thing.UID())
return FALSE
if(r_hand && r_hand.UID() == thing.UID())
return FALSE
if(back && back.UID() == thing.UID())
return FALSE
if(wear_mask && wear_mask.UID() == thing.UID())
return FALSE
return TRUE
/mob/living/proc/fakefireextinguish()
return
+6 -5
View File
@@ -1417,14 +1417,15 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
*/
/mob/proc/show_rads(range)
for(var/turf/place in range(range, src))
var/rads = SSradiation.get_turf_radiation(place)
if(rads < RAD_BACKGROUND_RADIATION)
var/list/rads = SSradiation.get_turf_radiation(place)
if(!rads || (rads[1] + rads[2] + rads[3]) < RAD_BACKGROUND_RADIATION)
continue
var/strength = round(rads / 1000, 0.1)
var/alpha_strength = round(rads[1] / 1000, 0.1)
var/beta_strength = round(rads[2] / 1000, 0.1)
var/gamma_strength = round(rads[3] / 1000, 0.1)
var/image/pic = image(loc = place)
var/mutable_appearance/MA = new()
MA.maptext = MAPTEXT("[strength]k")
MA.maptext = MAPTEXT("Α [alpha_strength]k\nΒ [beta_strength]k\nΓ [gamma_strength]k")
MA.color = "#04e604"
MA.layer = RAD_TEXT_LAYER
MA.plane = GAME_PLANE
+24
View File
@@ -244,6 +244,30 @@
return zone
/// Convert the impact zone of a projectile to a clothing zone we can do a contamination check on
/proc/hit_zone_to_clothes_zone(zone)
switch(zone)
if("head")
return HEAD
if("chest")
return UPPER_TORSO
if("l_hand")
return HANDS
if("r_hand")
return HANDS
if("l_arm")
return ARMS
if("r_arm")
return ARMS
if("l_leg")
return LEGS
if("r_leg")
return LEGS
if("l_foot")
return FEET
if("r_foot")
return FEET
/proc/above_neck(zone)
var/list/zones = list("head", "mouth", "eyes")
if(zones.Find(zone))
+2
View File
@@ -9,6 +9,8 @@
throwforce = 10
var/datum/mind/mind
blocks_emissive = EMISSIVE_BLOCK_GENERIC
rad_insulation_beta = RAD_MOB_INSULATION
rad_insulation_gamma = RAD_MOB_INSULATION
/// Is this mob alive, unconscious or dead?
var/stat = CONSCIOUS // TODO: Move to /mob/living
@@ -1,12 +1,12 @@
// stored_energy += (pulse_strength - RAD_COLLECTOR_EFFICIENCY) * RAD_COLLECTOR_COEFFICIENT
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
#define RAD_COLLECTOR_COEFFICIENT 100
// stored_energy += (pulse_strength - RAD_COLLECTOR_THRESHOLD) * RAD_COLLECTOR_COEFFICIENT
#define RAD_COLLECTOR_THRESHOLD 80 // This gets subtracted from the value of absorbed radiation
#define RAD_COLLECTOR_COEFFICIENT 400
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this * 100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
#define RAD_COLLECTOR_OUTPUT min(stored_energy, (stored_energy * RAD_COLLECTOR_STORED_OUT) + 1000) //Produces at least 1000 watts if it has more than that stored
/obj/machinery/power/rad_collector
name = "radiation collector array"
desc = "A device which uses Hawking Radiation and plasma to produce power."
desc = "A device which converts raditation to useable electical energy using plasma. It absorbs Beta particles extremely well, and Gamma particles to a lesser extent"
icon = 'icons/obj/singularity.dmi'
icon_state = "ca"
anchored = FALSE
@@ -14,13 +14,24 @@
req_access = list(ACCESS_ENGINE_EQUIP)
max_integrity = 350
integrity_failure = 80
rad_insulation = RAD_EXTREME_INSULATION
rad_insulation_beta = RAD_BETA_COLLECTOR
rad_insulation_gamma = RAD_LIGHT_INSULATION
var/obj/item/tank/internals/plasma/loaded_tank = null
var/stored_energy = 0
var/active = FALSE
var/locked = FALSE
var/drainratio = 1
var/powerproduction_drain = 0.001
var/power_threshold = RAD_COLLECTOR_THRESHOLD
var/power_coefficient = RAD_COLLECTOR_COEFFICIENT
/// A record of the absorbed strength of each beta wave that hit the collector. This keeps record up to rad_time old, and only the maximum absorption for each time point.
var/beta_waves = list()
/// A record of the absorbed strength of each gamma wave that hit the collector. This keeps record up to rad_time old, and only the maximum absorption for each time point.
var/gamma_waves = list()
/// Amount of time across which the maximum wave is checked
var/rad_time = 5 SECONDS
/// The current time count for clearing old data from the lists
var/rad_time_counter = 0
/obj/machinery/power/rad_collector/process()
if(!loaded_tank)
@@ -36,6 +47,20 @@
var/power_produced = RAD_COLLECTOR_OUTPUT
produce_direct_power(power_produced)
stored_energy -= power_produced
if(world.time > rad_time_counter)
rad_time_counter = world.time + rad_time
for(var/listing in gamma_waves)
if(world.time > text2num(listing) + rad_time)
gamma_waves -= listing
// We put the listing in oldest to newest so as soon as we hit something new enough we can keep the rest
else
break
for(var/listing in beta_waves)
if(world.time > text2num(listing) + rad_time)
beta_waves -= listing
// We put the listing in oldest to newest so as soon as we hit something new enough we can keep the rest
else
break
/obj/machinery/power/rad_collector/attack_hand(mob/user)
@@ -109,7 +134,21 @@
// Therefore, its units are joules per SSmachines.wait * 0.1 seconds.
// So joules = stored_energy * SSmachines.wait * 0.1
var/joules = stored_energy * SSmachines.wait * 0.1
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayJoules(joules)]</b>, and is processing <b>[DisplayPower(RAD_COLLECTOR_OUTPUT)]</b>.</span>"
var/max_beta = 0
var/max_gamma = 0
// Find the maximum beta and gamma absorptions we have logged
for(var/listing in beta_waves)
if(max_beta < beta_waves[listing])
max_beta = beta_waves[listing]
for(var/listing in gamma_waves)
if(max_gamma < gamma_waves[listing])
max_gamma = gamma_waves[listing]
var/beta_delta = max_beta - RAD_COLLECTOR_THRESHOLD
var/gamma_delta = max_gamma - RAD_COLLECTOR_THRESHOLD
. += "<span class='notice'>[src]'s display states that it has stored <b>[DisplayJoules(joules)]</b>, and is processing <b>[DisplayPower(RAD_COLLECTOR_OUTPUT)]</b></span>"
. +="<span class='notice'>Strongest Beta absorption over the last [rad_time /(1 SECONDS)] seconds: <b>[max_beta]</b>, <b>[abs(beta_delta)]</b> [beta_delta >= 0 ? "above" : "below"] threshold</span>"
. +="<span class='notice'>Strongest Gamma absorption over the last [rad_time /(1 SECONDS)] seconds: <b>[max_gamma]</b>, <b>[abs(gamma_delta)]</b> [gamma_delta >= 0 ? "above" : "below"] threshold</span>"
else
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>.\"</span>"
@@ -132,10 +171,21 @@
else
update_icons()
/obj/machinery/power/rad_collector/rad_act(amount)
. = ..()
if(loaded_tank && active && amount > RAD_COLLECTOR_EFFICIENCY)
stored_energy += (amount - RAD_COLLECTOR_EFFICIENCY) * RAD_COLLECTOR_COEFFICIENT
/// Converts absorbed Beta or Gamma radiation into electrical energy
/obj/machinery/power/rad_collector/rad_act(atom/source, amount, emission_type)
// Log the absorption at current time. If we already have one logged and the new value is bigger overwrite it.
if(emission_type == BETA_RAD)
if(!beta_waves["[world.time]"])
beta_waves += list("[world.time]" = amount)
else if(beta_waves["[world.time]"] < amount)
beta_waves["[world.time]"] = amount
if(emission_type == GAMMA_RAD)
if(!gamma_waves["[world.time]"])
gamma_waves += list("[world.time]" = amount)
else if(gamma_waves["[world.time]"] < amount)
gamma_waves["[world.time]"] = amount
if(emission_type != ALPHA_RAD && loaded_tank && active && amount > power_threshold)
stored_energy += (amount - power_threshold) * power_coefficient
/obj/machinery/power/rad_collector/proc/update_icons()
@@ -158,7 +208,7 @@
flick("ca_deactive", src)
update_icons()
#undef RAD_COLLECTOR_EFFICIENCY
#undef RAD_COLLECTOR_THRESHOLD
#undef RAD_COLLECTOR_COEFFICIENT
#undef RAD_COLLECTOR_STORED_OUT
#undef RAD_COLLECTOR_OUTPUT
@@ -39,7 +39,7 @@
/obj/effect/accelerated_particle/proc/try_irradiate(src, atom/A)
if(isliving(A))
var/mob/living/L = A
L.rad_act(energy * 6)
L.base_rad_act(src, energy * 6, GAMMA_RAD)
else if(istype(A, /obj/machinery/the_singularitygen))
var/obj/machinery/the_singularitygen/S = A
S.energy += energy
@@ -151,7 +151,7 @@ GLOBAL_VAR_INIT(global_singulo_id, 1)
// it might mean we are stuck in a corner somewere. So move around to try to expand.
move()
if(current_size >= STAGE_TWO)
radiation_pulse(src, (energy * 4.5) + 1000, RAD_DISTANCE_COEFFICIENT, source_radius = consume_range + 1)
radiation_pulse(src, (energy * 90) + 8000, GAMMA_RAD)
if(prob(event_chance))//Chance for it to run a special event TODO:Come up with one or two more that fit
event()
eat()
@@ -377,7 +377,7 @@
var/hallucination_amount = (max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1))))) SECONDS
H.AdjustHallucinate(hallucination_amount)
var/rads = DETONATION_RADS * sqrt(1 / (get_dist(L, src) + 1))
L.rad_act(rads)
L.base_rad_act(src, rads, GAMMA_RAD)
var/turf/T = get_turf(src)
var/super_matter_charge_sound = sound('sound/magic/charge.ogg')
@@ -568,8 +568,8 @@
var/crush_ratio = combined_gas / MOLE_CRUNCH_THRESHOLD
gas_coefficient = 1 + (crush_ratio ** 2 * (crush_ratio <= 1) + (crush_ratio > 1) * 2 * crush_ratio / (crush_ratio + 1)) * (plasmacomp * PLASMA_CRUNCH + o2comp * O2_CRUNCH + co2comp * CO2_CRUNCH + n2comp * N2_CRUNCH + n2ocomp * N2O_CRUNCH)
if(prob(50))
radiation_pulse(src, power * (gas_coefficient + max(0, ((power_transmission_bonus / 10)))))
radiation_pulse(src, 6 * power * (gas_coefficient + max(0, ((power_transmission_bonus / 10)))), GAMMA_RAD)
//Power * 0.55 * a value between 1 and 0.8
var/device_energy = power * REACTION_POWER_MODIFIER
@@ -597,7 +597,7 @@
l.AdjustHallucinate(hallucination_amount, 0, 200 SECONDS)
for(var/mob/living/l in range(src, round((power / 100) ** 0.25)))
var/rads = (power / 10) * sqrt( 1 / max(get_dist(l, src), 1) )
l.rad_act(rads)
l.base_rad_act(src, rads, GAMMA_RAD)
//Transitions between one function and another, one we use for the fast inital startup, the other is used to prevent errors with fusion temperatures.
//Use of the second function improves the power gain imparted by using co2
@@ -832,7 +832,7 @@
Consume(used)
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
radiation_pulse(src, 150, 4)
radiation_pulse(src, 600, GAMMA_RAD)
/obj/machinery/atmospherics/supermatter_crystal/Bumped(atom/movable/AM)
@@ -887,7 +887,7 @@
matter_power += 200
//Some poor sod got eaten, go ahead and irradiate people nearby.
radiation_pulse(src, 3000, 2, TRUE)
radiation_pulse(src, 12000, GAMMA_RAD, TRUE)
for(var/mob/living/L in range(10))
investigate_log("has irradiated [key_name(L)] after consuming [AM].", "supermatter")
if(L in view())
@@ -333,12 +333,12 @@
/obj/machinery/power/port_gen/pacman/super/use_fuel()
//produces a tiny amount of radiation when in use
if(prob(2 * power_output))
radiation_pulse(get_turf(src), 50)
radiation_pulse(get_turf(src), 200, ALPHA_RAD)
..()
/obj/machinery/power/port_gen/pacman/super/explode()
//a nice burst of radiation
radiation_pulse(get_turf(src), 500, 2)
radiation_pulse(get_turf(src), 2000, ALPHA_RAD)
explosion(loc, 3, 3, 5, 3)
qdel(src)
+2 -2
View File
@@ -343,9 +343,9 @@ GLOBAL_LIST_EMPTY(gravity_generators)
/obj/machinery/gravity_generator/main/proc/pulse_radiation()
radiation_pulse(src, 600, 2)
radiation_pulse(src, 2400, BETA_RAD)
for(var/mob/living/L in view(7, src)) //Windows kinda make it a non threat, no matter how much I amp it up, so let us cheat a little
radiation_pulse(get_turf(L), 600, 2)
radiation_pulse(get_turf(L), 2400, BETA_RAD)
/**
* Shake everyone on the area list and play an alarm to let them know that gravity was enagaged/disenagaged.
@@ -83,7 +83,7 @@
tap.radio.autosay("Bluespace harvester has released a spike of radiation!", tap, "Engineering")
/datum/engi_event/bluespace_tap_event/radiation/on_start()
radiation_pulse(tap, 3000, 7)
radiation_pulse(tap, 12000, BETA_RAD)
// electrical arc
/datum/engi_event/bluespace_tap_event/electric_arc
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

+1
View File
@@ -469,6 +469,7 @@
#include "code\datums\components\forces_doors_open.dm"
#include "code\datums\components\fullauto.dm"
#include "code\datums\components\ghost_direct_control.dm"
#include "code\datums\components\inherent_radioactivity.dm"
#include "code\datums\components\jetpack_component.dm"
#include "code\datums\components\label.dm"
#include "code\datums\components\largeobjecttransparency.dm"