mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-23 20:17:15 +01:00
Radiation additions & Component (#18642)
* It begins * Better coding practices * No mapwide radiation glow! * Update radiation_effects.dm * A bit more efficient * Theeese too * moar * caps * lint * Stops self contamiantion * Mregen Fixes this bug with mRegen. Also gives bruteloss the 1% heal chance. * MAR! * TGUI panel * Nuclear png Attribution not required, but being listed for posterity: From uxwing. Icon name is "Radiation Icon SVG Vector" * colorful * Update nuclear.scss * Update damage_procs.dm * Radiation Negative Trait * Update radiation_effects.dm * get rid of this bad documentation Should only EVER be registerwithparent.
This commit is contained in:
@@ -450,6 +450,11 @@
|
||||
#define COMSIG_LIVING_CAN_TRACK "mob_cantrack"
|
||||
#define COMPONENT_CANT_TRACK (1<<0)
|
||||
|
||||
///from base of /mob/living/proc/apply_effect(var/effect = 0,var/effecttype = STUN, var/blocked = 0, var/check_protection = 1, rad_protection)
|
||||
#define COMSIG_LIVING_IRRADIATE_EFFECT "living_irradiate_effect"
|
||||
///Return this if you want to block the effect.
|
||||
#define COMPONENT_BLOCK_IRRADIATION (1<<0)
|
||||
|
||||
// /mob/living/carbon signals
|
||||
|
||||
///from base of mob/living/carbon/soundbang_act(): (list(intensity))
|
||||
@@ -694,6 +699,12 @@
|
||||
#define COMSIG_HUMAN_DNA_FINALIZED "human_dna_finished"
|
||||
///from /proc/domutcheck(): ()
|
||||
#define COMSIG_MOB_DNA_MUTATION "mob_dna_mutation"
|
||||
///from /mob/living/proc/handle_radiation()
|
||||
#define COMSIG_HANDLE_RADIATION "handle_radiation"
|
||||
#define COMPONENT_BLOCK_LIVING_RADIATION (1<<0)
|
||||
///from /mob/living/proc/handle_mutations()
|
||||
#define COMSIG_HANDLE_MUTATIONS "handle_mutations"
|
||||
#define COMPONENT_BLOCK_LIVING_MUTATIONS (1<<0)
|
||||
|
||||
// Organ specific signals
|
||||
|
||||
|
||||
@@ -20,3 +20,6 @@
|
||||
#define TECHNOMANCER_INSTABILITY_MIN_GLOW 10 // When above this number, the entity starts glowing, affecting others.
|
||||
|
||||
#define RADIATION_SPEED_COEFFICIENT 0.1
|
||||
|
||||
///Maximum amount of radiation an entity can have.
|
||||
#define RADIATION_CAP 5000
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
// Please do note that there is absolutely no bearing on what traits are added to what subtype of `/datum`, this is just an easily referenceable list sorted by type.
|
||||
// The only thing that truly matters about traits is the code that is built to handle the traits, and where that code is located. Nothing else.
|
||||
#define WEAKENED_RADIATION_RESISTANCE "Weakened"
|
||||
#define NORMAL_RADIATION_RESISTANCE "Normal"
|
||||
#define RESISTANT_RADIATION_RESISTANCE "Resistant"
|
||||
#define MAJOR_RESISTANT_RADIATION_RESISTANCE "Major Resistance"
|
||||
#define IMMUNITY_RADIATION_RESISTANCE "Immunity"
|
||||
GLOBAL_LIST_INIT(radiation_levels, list(
|
||||
WEAKENED_RADIATION_RESISTANCE = list("safe" = 15, "danger_1" = 50, "danger_2" = 150, "danger_3" = 200, "danger_4" = 750),
|
||||
NORMAL_RADIATION_RESISTANCE = list("safe" = 50, "danger_1" = 100, "danger_2" = 300, "danger_3" = 400, "danger_4" = 1500),
|
||||
RESISTANT_RADIATION_RESISTANCE = list("safe" = 70, "danger_1" = 150, "danger_2" = 450, "danger_3" = 600, "danger_4" = 2250),
|
||||
MAJOR_RESISTANT_RADIATION_RESISTANCE = list("safe" = 150, "danger_1" = 300, "danger_2" = 600, "danger_3" = 1000, "danger_4" = 3000),
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
//Reference to our owner (the person that possesses us)
|
||||
//This can be anything that is our owner that we want to reference. Swap out with mob/living/carbon/human/owner as needed.
|
||||
var/mob/living/owner //easy reference
|
||||
//NOTE: Alternatively, you can do something like "var/mob/living/owner = parent" in procs where needed to avoid having a hard ref to our owner...
|
||||
//It's just a matter of preference at that point.
|
||||
|
||||
//dupe_mode = COMPONENT_DUPE_HIGHLANDER //Default mode. See flags.dm
|
||||
|
||||
@@ -29,10 +31,17 @@
|
||||
owner = parent
|
||||
|
||||
add_verb(owner,/mob/living/proc/example_proc) //We can add verbs to our owner.
|
||||
RegisterSignal(owner, COMSIG_EXAMPLE_SIGNAL, PROC_REF(example_proc)) //To put this easily: Owner is the person we're attached to, COMSIG_EXAMPLE_SIGNAL is the signal we expect them to send out when they want us to use our 'example_proc'
|
||||
|
||||
/datum/component/template/RegisterWithParent()
|
||||
//To put this easily: Owner is the person we're attached to, COMSIG_EXAMPLE_SIGNAL is the signal we expect them to send out when they want us to use our 'example_proc'
|
||||
RegisterSignal(parent, COMSIG_EXAMPLE_SIGNAL, PROC_REF(example_proc))
|
||||
|
||||
//Register this to a signal that is sent out whenever you want this to be called. For example: We want this trait to happen every life() tick, so we register it to the COMSIG_LIVING_LIFE signal that is sent every time life() is called on a /mob.
|
||||
RegisterSignal(owner, COMSIG_LIVING_LIFE, PROC_REF(process))
|
||||
RegisterSignal(parent, COMSIG_LIVING_LIFE, PROC_REF(process))
|
||||
|
||||
/datum/component/template/UnregisterFromParent()
|
||||
//IF we registered a signal, we need to unregister it. This can be a list or done separtely. It's suggested to do it as a list.
|
||||
UnregisterSignal(parent, list(COMSIG_EXAMPLE_SIGNAL, COMSIG_LIVING_LIFE))
|
||||
|
||||
/datum/component/template/process()
|
||||
if (QDELETED(parent))
|
||||
@@ -40,8 +49,6 @@
|
||||
energy = min(100, energy+1) //Add one energy per tick, up to 100
|
||||
|
||||
/datum/component/template/Destroy(force = FALSE)
|
||||
UnregisterSignal(owner, COMSIG_LIVING_LIFE) //IF we registered a signal, we need to unregister it.
|
||||
UnregisterSignal(owner, COMSIG_EXAMPLE_SIGNAL) //MAKE SURE TO UNREGISTER YOUR SIGNALS. SERIOUSLY. OR THE SERVER WILL DIE.
|
||||
owner = null //MAKE SURE TO CLEAR YOUR REFS!
|
||||
. = ..()
|
||||
|
||||
@@ -54,11 +61,26 @@
|
||||
|
||||
|
||||
/datum/component/template/proc/example_proc()
|
||||
if (stat == DEAD)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
if (energy <= 0) //Check a variable on the component.
|
||||
if(energy <= 0) //Check a variable on the component.
|
||||
to_chat(owner, span_danger("You currently have no energy!"))
|
||||
else if (cooldown > world.time) //Check the cooldown variable on the component and compare it.
|
||||
else if(cooldown > world.time) //Check the cooldown variable on the component and compare it.
|
||||
var/time_to_wait = (cooldown - world.time) / (1 SECONDS) //Simple cooldown
|
||||
to_chat(owner, span_warning("You're currently on cooldown! Wait for another [round(time_to_wait,0.1)] seconds!"))
|
||||
return
|
||||
else
|
||||
cooldown = world.time + 5 SECONDS //Set the component on a 5 second cooldown.
|
||||
to_chat(owner, span_warning("You successfully used the example proc!"))
|
||||
|
||||
//Variant of the example proc but under the presumption we don't have a ref to owner.
|
||||
/datum/component/template/proc/example_proc2()
|
||||
var/mob/living/owner = parent
|
||||
if(owner.stat == DEAD)
|
||||
return
|
||||
if(energy <= 0) //Check a variable on the component.
|
||||
to_chat(owner, span_danger("You currently have no energy!"))
|
||||
else if(cooldown > world.time) //Check the cooldown variable on the component and compare it.
|
||||
var/time_to_wait = (cooldown - world.time) / (1 SECONDS) //Simple cooldown
|
||||
to_chat(owner, span_warning("You're currently on cooldown! Wait for another [round(time_to_wait,0.1)] seconds!"))
|
||||
return
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
|
||||
/* Component that handles species effects for mobs/species when they are afflicted with radiation.
|
||||
* Allows for glowing, healing, contamination, and immunity.
|
||||
*/
|
||||
/datum/component/radiation_effects
|
||||
///Below this value, no glow occurs.
|
||||
var/radiation_glow_threshold = 50
|
||||
|
||||
///If we spread radiation or not.
|
||||
var/contamination = FALSE
|
||||
///Strength of our contamination, if we contaminate. Each 1 strength is 100% of the rads we're dissipating.
|
||||
var/contamination_strength = 0.1
|
||||
///What level our radiation has to be above to begin to contaminate our surroundings.
|
||||
var/contamination_threshold = 600
|
||||
|
||||
///If we glow or not.
|
||||
var/glows = TRUE
|
||||
|
||||
///What color we glow.
|
||||
var/radiation_color = "#c3f314"
|
||||
///Intensity modifier of our glow
|
||||
var/intensity_mod = 1
|
||||
///Range modifier of our glow
|
||||
var/range_mod = 1
|
||||
///How much we divide our radiation by to determine how far our glow is.
|
||||
var/range_coefficient = 100
|
||||
///How much we divide our radiation by to determine how intense our glow is.
|
||||
var/intensity_coefficient = 150
|
||||
|
||||
///If we are immune to radiation damage or not.
|
||||
var/radiation_immunity = FALSE
|
||||
|
||||
///If we heal from radiation or not
|
||||
var/radiation_healing = FALSE
|
||||
|
||||
///If we dissipate radiation or keep it.
|
||||
var/radiation_dissipation = TRUE
|
||||
|
||||
/datum/component/radiation_effects/Initialize(glows, radiation_glow_minor_threshold, contamination, contamination_strength, radiation_color, intensity_mod, range_mod, radiation_immunity, radiation_healing, radiation_dissipation)
|
||||
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
if(glows)
|
||||
src.glows = glows
|
||||
if(radiation_glow_threshold)
|
||||
src.radiation_glow_threshold = radiation_glow_threshold
|
||||
if(contamination)
|
||||
src.contamination = contamination
|
||||
if(contamination_strength)
|
||||
src.contamination_strength = contamination_strength
|
||||
if(radiation_color)
|
||||
src.radiation_color = radiation_color
|
||||
if(intensity_mod)
|
||||
src.intensity_mod = intensity_mod
|
||||
if(range_mod)
|
||||
src.range_mod = range_mod
|
||||
if(radiation_immunity)
|
||||
src.radiation_immunity = radiation_immunity
|
||||
if(radiation_healing)
|
||||
src.radiation_healing = radiation_healing
|
||||
if(radiation_dissipation)
|
||||
src.radiation_dissipation = radiation_dissipation
|
||||
|
||||
add_verb(parent, /mob/living/proc/radiation_control_panel)
|
||||
|
||||
/datum/component/radiation_effects/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_HANDLE_RADIATION, PROC_REF(process_component))
|
||||
RegisterSignal(parent, COMSIG_LIVING_LIFE, PROC_REF(process_glow))
|
||||
RegisterSignal(parent, COMSIG_LIVING_IRRADIATE_EFFECT, PROC_REF(handle_irradiate_effect))
|
||||
|
||||
/datum/component/radiation_effects/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_HANDLE_RADIATION, COMSIG_LIVING_LIFE, COMSIG_LIVING_IRRADIATE_EFFECT))
|
||||
|
||||
/datum/component/radiation_effects/proc/process_glow()
|
||||
SIGNAL_HANDLER
|
||||
var/mob/living/living_guy = parent
|
||||
if(!glows)
|
||||
if(living_guy.glow_override) //Toggled glow off while we were still actively glowing.
|
||||
living_guy.glow_override = FALSE
|
||||
living_guy.set_light(0)
|
||||
return
|
||||
if(living_guy.radiation < radiation_glow_threshold)
|
||||
living_guy.glow_override = FALSE
|
||||
living_guy.set_light(0)
|
||||
return
|
||||
|
||||
if(glows)
|
||||
var/light_range = CLAMP((living_guy.radiation/range_coefficient) * range_mod, 1, 7) //Min 1, max 7
|
||||
var/light_power = CLAMP(living_guy.radiation/intensity_coefficient * intensity_mod, 1, 10)
|
||||
|
||||
living_guy.set_light(l_range = light_range, l_power = light_power, l_color = radiation_color, l_on = TRUE)
|
||||
living_guy.glow_override = TRUE
|
||||
|
||||
///Handles the radiation removal, immunity, and healing effects.
|
||||
/datum/component/radiation_effects/proc/process_component()
|
||||
SIGNAL_HANDLER
|
||||
var/mob/living/living_guy = parent
|
||||
if(living_guy.radiation > RADIATION_CAP)
|
||||
living_guy.radiation = CLAMP(living_guy.radiation,0,RADIATION_CAP)
|
||||
living_guy.accumulated_rads = CLAMP(living_guy.accumulated_rads,0,RADIATION_CAP)
|
||||
|
||||
if(QDELETED(parent))
|
||||
return
|
||||
|
||||
//Radiation calculation, done here since contamination uses it
|
||||
var/rad_removal_mod = 1
|
||||
var/rads = living_guy.radiation * 0.04
|
||||
|
||||
if(ishuman(living_guy))
|
||||
var/mob/living/carbon/human/human_guy = parent
|
||||
rad_removal_mod = human_guy.species.rad_removal_mod
|
||||
//End of the calculation.
|
||||
|
||||
if(contamination && living_guy.radiation > contamination_threshold)
|
||||
SSradiation.radiate(living_guy, rads * contamination_strength * rad_removal_mod)
|
||||
|
||||
if(radiation_immunity || radiation_healing)
|
||||
//We have to remove radiation here since we're blocking radiation altogether.
|
||||
var/rads_to_utilize = rads * rad_removal_mod
|
||||
|
||||
//If we heal from radiation, we will dissipate (use up) the amount we heal.
|
||||
if(radiation_healing)
|
||||
living_guy.radiation -= rads_to_utilize
|
||||
living_guy.accumulated_rads -= rads_to_utilize
|
||||
rads_to_utilize = CLAMP(rads_to_utilize, 1, 10) //Only heal up to 10 rads.
|
||||
living_guy.adjust_nutrition(rads_to_utilize)
|
||||
living_guy.adjustBruteLoss(-rads_to_utilize)
|
||||
living_guy.adjustFireLoss(-rads_to_utilize)
|
||||
living_guy.adjustOxyLoss(-rads_to_utilize)
|
||||
living_guy.adjustToxLoss(-rads_to_utilize)
|
||||
living_guy.updatehealth()
|
||||
|
||||
else if(radiation_dissipation)
|
||||
living_guy.radiation -= rads_to_utilize
|
||||
living_guy.accumulated_rads -= rads_to_utilize
|
||||
|
||||
return COMPONENT_BLOCK_LIVING_RADIATION
|
||||
|
||||
/datum/component/radiation_effects/proc/handle_irradiate_effect(var/mob/living/living_guy, var/effect, var/effecttype, var/blocked, var/check_protection, var/rad_protection)
|
||||
SIGNAL_HANDLER
|
||||
///If we're not contaminating, don't worry about this. Proceed like normal.
|
||||
if(!contamination || (contamination && living_guy.radiation < contamination_threshold))
|
||||
//to_chat(world, "Radiation like normal. Current rads = [living_guy.radiation]. Amount of rads being added = [effect].")
|
||||
return
|
||||
|
||||
var/rad_removal_mod = 1
|
||||
if(ishuman(living_guy))
|
||||
var/mob/living/carbon/human/human_guy = parent
|
||||
rad_removal_mod = human_guy.species.rad_removal_mod
|
||||
|
||||
var/radiation_offput = ((living_guy.radiation * 0.04) * contamination_strength * rad_removal_mod)
|
||||
var/radiation_to_apply = (effect - radiation_offput)
|
||||
if(radiation_to_apply > 0)
|
||||
// to_chat(world, "Radiation blocker. Current rads = [living_guy.radiation]. Original = [effect] RTA = [radiation_to_apply] After protection = [radiation_to_apply * rad_protection]. Amount of rads we're offputting = [radiation_offput]")
|
||||
|
||||
//This stops MOST of the radiation we're offputting from hitting us.
|
||||
//If we linger in one place for a prolonged period, the area around us will become irradiated and give us a small bit of radiation back. (only got ~1 rad per tick when we were offputting 60 rads for example)
|
||||
//However, we'll lose our rads faster than we accumulate.
|
||||
living_guy.radiation += max((radiation_to_apply * rad_protection), 0)
|
||||
return COMPONENT_BLOCK_IRRADIATION
|
||||
/datum/component/radiation_effects/promethean
|
||||
radiation_immunity = TRUE
|
||||
|
||||
/datum/component/radiation_effects/shadekin
|
||||
radiation_immunity = TRUE
|
||||
glows = FALSE
|
||||
|
||||
///Heals from radiation. Does not glow.
|
||||
/datum/component/radiation_effects/diona
|
||||
glows = FALSE
|
||||
radiation_healing = TRUE
|
||||
|
||||
///TGUI below here
|
||||
//TGUI Weaver Panel
|
||||
/datum/component/radiation_effects/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "RadiationConfig", "Radiation Config")
|
||||
ui.open()
|
||||
|
||||
|
||||
/mob/living/proc/radiation_control_panel()
|
||||
set name = "Radiation Control Panel"
|
||||
set desc = "Allows you to adjust the settings of various radioactive settings!"
|
||||
set category = "Abilities.Radiation"
|
||||
|
||||
var/datum/component/radiation_effects/rad = get_radiation_component()
|
||||
if(!rad)
|
||||
to_chat(src, span_warning("You don't have the radiation component! This is a bug! Please report this to a maintainer."))
|
||||
return FALSE
|
||||
|
||||
rad.tgui_interact(src)
|
||||
|
||||
/datum/component/radiation_effects/tgui_data(mob/user)
|
||||
var/data = list(
|
||||
"glowing" = glows,
|
||||
"radiation_color" = radiation_color,
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
/datum/component/radiation_effects/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
switch(action)
|
||||
if("toggle_color")
|
||||
var/set_new_color = tgui_color_picker(ui.user, "Select a color you wish your radioactive glow to be!", "Color Selector", radiation_color)
|
||||
if(!set_new_color)
|
||||
return FALSE
|
||||
radiation_color = set_new_color
|
||||
return TRUE
|
||||
if("toggle_glow")
|
||||
glows = !glows
|
||||
to_chat(parent, span_info("You are [glows ? "now" : "no longer"] glowing."))
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/get_radiation_component()
|
||||
var/datum/component/radiation_effects/rad = GetComponent(/datum/component/radiation_effects)
|
||||
if(rad)
|
||||
return rad
|
||||
@@ -17,7 +17,10 @@
|
||||
//Status updates, death etc.
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/handle_mutations_and_radiation()
|
||||
/mob/living/carbon/alien/handle_radiation()
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
|
||||
// rad absorbtion here. This will need to be changed if other baby aliens are added.
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/mob/living/carbon/brain/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_mutations_and_radiation()
|
||||
/mob/living/carbon/brain/handle_radiation()
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
radiation = 100
|
||||
|
||||
@@ -206,6 +206,37 @@
|
||||
to_chat(src, span_danger("Your legs won't respond properly, you fall down!"))
|
||||
Weaken(10)
|
||||
|
||||
/mob/living/carbon/human/handle_mutations()
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(inStasisNow())
|
||||
return
|
||||
|
||||
if(getFireLoss())
|
||||
if((COLD_RESISTANCE in mutations) || (prob(1)))
|
||||
heal_organ_damage(0,1)
|
||||
if(getBruteLoss()) //Fireloss gets this RNG change so may as well give bruteloss it as well.
|
||||
if(prob(1))
|
||||
heal_organ_damage(1,0)
|
||||
|
||||
if((mRegen in mutations))
|
||||
var/heal = rand(0.2,1.3)
|
||||
if(prob(50))
|
||||
for(var/obj/item/organ/external/O in organs) //HAS to be organs and NOT bad_external_organs as a fully healed limb w/ internal damage will NOT be in bad_external_organs
|
||||
for(var/datum/wound/W in O.wounds)
|
||||
if(W.bleeding())
|
||||
W.damage = max(W.damage - heal, 0)
|
||||
if(W.damage <= 0)
|
||||
O.wounds -= W
|
||||
if(W.internal)
|
||||
W.damage = max(W.damage - heal, 0)
|
||||
if(W.damage <= 0)
|
||||
O.wounds -= W
|
||||
else
|
||||
heal_organ_damage(heal,heal)
|
||||
|
||||
|
||||
// RADIATION! Everyone's favorite thing in the world! So let's get some numbers down off the bat.
|
||||
// 50 rads = 1Bq. This means 1 rad = 0.02Bq.
|
||||
// However, unless I am a smoothbrained dumbo, absorbed rads are in Gy. Not Bq.
|
||||
@@ -227,65 +258,20 @@
|
||||
|
||||
// Additionally, RADIATION_SPEED_COEFFICIENT = 0.1
|
||||
|
||||
/mob/living/carbon/human/handle_mutations_and_radiation() //Radiation rework! Now with 'accumulated_rads'
|
||||
/mob/living/carbon/human/handle_radiation() //Radiation rework! Now with 'accumulated_rads'
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(inStasisNow())
|
||||
return
|
||||
|
||||
if(getFireLoss())
|
||||
if((COLD_RESISTANCE in mutations) || (prob(1)))
|
||||
heal_organ_damage(0,1)
|
||||
|
||||
if(stat != DEAD)
|
||||
if((mRegen in mutations))
|
||||
var/heal = rand(0.2,1.3)
|
||||
if(prob(50))
|
||||
for(var/obj/item/organ/external/O in bad_external_organs)
|
||||
for(var/datum/wound/W in O.wounds)
|
||||
if(W.bleeding())
|
||||
W.damage = max(W.damage - heal, 0)
|
||||
if(W.damage <= 0)
|
||||
O.wounds -= W
|
||||
if(W.internal)
|
||||
W.damage = max(W.damage - heal, 0)
|
||||
if(W.damage <= 0)
|
||||
O.wounds -= W
|
||||
else
|
||||
heal_organ_damage(heal,heal)
|
||||
|
||||
radiation = CLAMP(radiation,0,5000) //Max of 100Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
|
||||
accumulated_rads = CLAMP(accumulated_rads,0,5000) //Max of 100Gy as well. You should never get higher than this. You will be dead before you can reach this.
|
||||
radiation = CLAMP(radiation,0,RADIATION_CAP) //Max of 100Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
|
||||
accumulated_rads = CLAMP(accumulated_rads,0,RADIATION_CAP) //Max of 100Gy as well. You should never get higher than this. You will be dead before you can reach this.
|
||||
var/obj/item/organ/internal/I = null //Used for further down below when an organ is picked.
|
||||
if(!radiation)
|
||||
if(species.appearance_flags & RADIATION_GLOWS)
|
||||
glow_override = FALSE
|
||||
set_light(0)
|
||||
if(accumulated_rads)
|
||||
accumulated_rads -= RADIATION_SPEED_COEFFICIENT //Accumulated rads slowly dissipate very slowly. Get to medical to get it treated!
|
||||
else if(((life_tick % 5 == 0) && radiation) || (radiation > 600)) //Radiation is a slow, insidious killer. Unless you get a massive dose, then the onset is sudden!
|
||||
if(species.appearance_flags & RADIATION_GLOWS)
|
||||
glow_override = TRUE
|
||||
set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src))
|
||||
// END DOGSHIT SNOWFLAKE
|
||||
|
||||
var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
|
||||
if(rad_organ && !rad_organ.is_broken())
|
||||
var/rads = radiation/25
|
||||
radiation -= (rads * species.rad_removal_mod)
|
||||
adjust_nutrition(rads * species.rad_removal_mod)
|
||||
adjustBruteLoss(-(rads * species.rad_removal_mod))
|
||||
adjustFireLoss(-(rads * species.rad_removal_mod))
|
||||
adjustOxyLoss(-(rads * species.rad_removal_mod))
|
||||
adjustToxLoss(-(rads * species.rad_removal_mod))
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
var/obj/item/organ/internal/brain/slime/core = locate() in internal_organs
|
||||
if(core)
|
||||
return
|
||||
|
||||
var/obj/item/organ/internal/brain/shadekin/s_brain = locate() in internal_organs
|
||||
if(s_brain)
|
||||
return
|
||||
|
||||
if(reagents.has_reagent(REAGENT_ID_PRUSSIANBLUE)) //Prussian Blue temporarily stops radiation effects.
|
||||
return
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
assisted_langs = list()
|
||||
|
||||
species_component = /datum/component/burninlight/shadow // Until a parent component like xenochimera have is needed, only handles burning in light.
|
||||
species_component = list(/datum/component/burninlight/shadow) // Until a parent component like xenochimera have is needed, only handles burning in light.
|
||||
|
||||
/datum/species/shadow/handle_death(var/mob/living/carbon/human/H)
|
||||
spawn(1)
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
species_component = /datum/component/shadekin
|
||||
species_component = list(/datum/component/shadekin, /datum/component/radiation_effects/shadekin)
|
||||
component_requires_late_recalc = TRUE
|
||||
|
||||
/datum/species/shadekin/handle_death(var/mob/living/carbon/human/H)
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
var/list/env_traits = list()
|
||||
var/pixel_offset_x = 0 // Used for offsetting 64x64 and up icons.
|
||||
var/pixel_offset_y = 0 // Used for offsetting 64x64 and up icons.
|
||||
var/rad_levels = NORMAL_RADIATION_RESISTANCE //For handle_mutations_and_radiation
|
||||
var/rad_levels = NORMAL_RADIATION_RESISTANCE //For handle_radiation
|
||||
var/rad_removal_mod = 1
|
||||
|
||||
var/ambulant_blood = FALSE // Force changeling blood effects
|
||||
@@ -359,7 +359,7 @@
|
||||
var/list/food_preference = list() //RS edit
|
||||
var/food_preference_bonus = 0
|
||||
|
||||
var/datum/component/species_component = null // The component that this species uses. Example: Xenochimera use /datum/component/xenochimera
|
||||
var/list/species_component = list() // The component that this species uses. Example: Xenochimera use /datum/component/xenochimera
|
||||
var/component_requires_late_recalc = FALSE // If TRUE, the component will do special recalculation stuff at the end of update_icons_body()
|
||||
|
||||
// For Lleill and Hanner
|
||||
@@ -804,8 +804,9 @@
|
||||
..()
|
||||
|
||||
/datum/species/proc/apply_components(var/mob/living/carbon/human/H)
|
||||
if(species_component)
|
||||
H.LoadComponent(species_component)
|
||||
if(LAZYLEN(species_component))
|
||||
for(var/component in species_component)
|
||||
H.LoadComponent(component)
|
||||
|
||||
/datum/species/proc/produceCopy(var/list/traits, var/mob/living/carbon/human/H, var/custom_base, var/reset_dna = TRUE) // Traitgenes reset_dna flag required, or genes get reset on resleeve
|
||||
ASSERT(src)
|
||||
|
||||
@@ -35,6 +35,8 @@ var/datum/species/shapeshifter/promethean/prometheans
|
||||
secondary_langs = list(LANGUAGE_PROMETHEAN, LANGUAGE_SOL_COMMON) // For some reason, having this as their species language does not allow it to be chosen.
|
||||
assisted_langs = list(LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX) // Prometheans are weird, let's just assume they can use basically any language.
|
||||
|
||||
species_component = list(/datum/component/radiation_effects/promethean)
|
||||
|
||||
blood_name = "gelatinous ooze"
|
||||
blood_reagents = REAGENT_ID_SLIMEJELLY
|
||||
|
||||
|
||||
@@ -657,13 +657,14 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_mob/protean_blob/handle_mutations_and_radiation()
|
||||
/mob/living/simple_mob/protean_blob/handle_radiation()
|
||||
..()
|
||||
if(!humanform)
|
||||
to_chat(src, span_giant(span_boldwarning("You are currently a blob without a humanform and should be deleted shortly Please report what you were doing when this error occurred to the admins.")))
|
||||
stack_trace("URGENT, SERVER-CRASHING ISSUE: A protean blob does not have a humanform! src = [src] ckey = [ckey]! The blob has been deleted.")
|
||||
qdel(src)
|
||||
return
|
||||
humanform.handle_mutations_and_radiation()
|
||||
humanform.handle_radiation()
|
||||
|
||||
/mob/living/simple_mob/protean_blob/update_icon()
|
||||
..()
|
||||
|
||||
@@ -490,7 +490,7 @@
|
||||
|
||||
reagent_tag = IS_ZADDAT
|
||||
|
||||
species_component = /datum/component/burninlight // Until a parent component like xenochimera have is needed, only handles burning in light.
|
||||
species_component = list(/datum/component/burninlight) // Until a parent component like xenochimera have is needed, only handles burning in light.
|
||||
|
||||
heat_discomfort_strings = list(
|
||||
"Your joints itch.",
|
||||
@@ -564,6 +564,8 @@
|
||||
min_age = 18
|
||||
max_age = 300
|
||||
|
||||
species_component = list(/datum/component/radiation_effects/diona)
|
||||
|
||||
economic_modifier = 10
|
||||
|
||||
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
|
||||
@@ -1548,7 +1550,7 @@
|
||||
tail = "tail" //Spider tail.
|
||||
icobase_tail = 1
|
||||
|
||||
species_component = /datum/component/weaver
|
||||
species_component = list(/datum/component/weaver)
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/tie_hair)
|
||||
@@ -1741,7 +1743,7 @@
|
||||
|
||||
reagent_tag = IS_CHIMERA
|
||||
|
||||
species_component = /datum/component/xenochimera
|
||||
species_component = list(/datum/component/xenochimera)
|
||||
|
||||
/datum/species/xenochimera/handle_environment_special(var/mob/living/carbon/human/H)
|
||||
//Cold/pressure effects when not regenerating
|
||||
|
||||
@@ -677,3 +677,9 @@
|
||||
|
||||
else if(istype(ex_organ, /obj/item/organ/external/chest))
|
||||
ex_organ.encased = FALSE
|
||||
|
||||
/datum/trait/negative/rad_weakness
|
||||
name = "Radiation Weakness"
|
||||
desc = "You are approximately 50% more susceptible to radiation, and it dissipates slower from your body."
|
||||
cost = -2
|
||||
var_changes = list("radiation_mod" = 1.5, "rad_removal_mod" = 0.5, "rad_levels" = WEAKENED_RADIATION_RESISTANCE)
|
||||
|
||||
@@ -1795,3 +1795,17 @@
|
||||
/datum/trait/neutral/strongimmunesystem/apply(datum/species/S, mob/living/carbon/human/H, trait_prefs)
|
||||
..()
|
||||
ADD_TRAIT(H, STRONG_IMMUNITY_TRAIT, ROUNDSTART_TRAIT)
|
||||
|
||||
/datum/trait/neutral/glowing_radiation
|
||||
name = "Radioactive Glow"
|
||||
desc = "You emit a glow when exposed to radiation! This does not prevent you from being harmed by radiation."
|
||||
cost = 0
|
||||
has_preferences = list("glow_color" = list(TRAIT_PREF_TYPE_COLOR, "Glow color", TRAIT_VAREDIT_TARGET_MOB, "#c3f314"))
|
||||
added_component_path = /datum/component/radiation_effects
|
||||
excludes = list(/datum/trait/positive/radioactive_heal)
|
||||
|
||||
/datum/trait/neutral/glowing_radiation/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
|
||||
..()
|
||||
var/datum/component/radiation_effects/G = H.GetComponent(added_component_path)
|
||||
if(trait_prefs)
|
||||
G.radiation_color = trait_prefs["glow_color"]
|
||||
|
||||
@@ -542,3 +542,23 @@
|
||||
|
||||
can_take = ORGANICS
|
||||
var_changes = list("virus_immune" = TRUE)
|
||||
|
||||
/datum/trait/positive/radioactive_heal
|
||||
name = "Radioactive Heal"
|
||||
desc = "You heal when exposed to radiation instead of becoming ill. You can also choose to emit a glow when irradiated."
|
||||
cost = 6
|
||||
is_genetrait = TRUE
|
||||
hidden = FALSE
|
||||
has_preferences = list("glow_color" = list(TRAIT_PREF_TYPE_COLOR, "Glow color", TRAIT_VAREDIT_TARGET_MOB, "#c3f314",),
|
||||
"glow_enabled" = list(TRAIT_PREF_TYPE_BOOLEAN, "Glow enabled on spawn", TRAIT_VAREDIT_TARGET_MOB, FALSE))
|
||||
|
||||
added_component_path = /datum/component/radiation_effects
|
||||
excludes = list(/datum/trait/neutral/glowing_radiation, /datum/trait/positive/rad_resistance, /datum/trait/positive/rad_resistance_extreme, /datum/trait/positive/rad_immune, /datum/trait/negative/rad_weakness)
|
||||
|
||||
/datum/trait/positive/radioactive_heal/apply(var/datum/species/S,var/mob/living/carbon/human/H, var/list/trait_prefs)
|
||||
..()
|
||||
var/datum/component/radiation_effects/G = H.GetComponent(added_component_path)
|
||||
if(trait_prefs)
|
||||
G.radiation_color = trait_prefs["glow_color"]
|
||||
G.glows = trait_prefs["glow_enabled"]
|
||||
G.radiation_healing = TRUE
|
||||
|
||||
@@ -159,13 +159,10 @@
|
||||
if(AGONY)
|
||||
halloss += max((effect * blocked), 0) // Useful for objects that cause "subdual" damage. PAIN!
|
||||
if(IRRADIATE)
|
||||
/*
|
||||
var/rad_protection = check_protection ? getarmor(null, "rad")/100 : 0
|
||||
radiation += max((1-rad_protection)*effect/(blocked+1),0)//Rads auto check armor
|
||||
*/
|
||||
var/rad_protection = getarmor(null, "rad")
|
||||
rad_protection = (100-rad_protection)/100
|
||||
radiation += max((effect * rad_protection), 0)
|
||||
if(!(SEND_SIGNAL(src, COMSIG_LIVING_IRRADIATE_EFFECT, effect, effecttype, blocked, check_protection, rad_protection) & COMPONENT_BLOCK_IRRADIATION))
|
||||
radiation += max((effect * rad_protection), 0)
|
||||
if(STUTTER)
|
||||
if(status_flags & CANSTUN) // stun is usually associated with stutter
|
||||
stuttering = max(stuttering,(effect * blocked))
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
handle_breathing()
|
||||
|
||||
//Mutations and radiation
|
||||
handle_mutations_and_radiation()
|
||||
handle_mutations()
|
||||
handle_radiation()
|
||||
|
||||
|
||||
|
||||
@@ -89,8 +90,15 @@
|
||||
/mob/living/proc/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/proc/handle_mutations_and_radiation()
|
||||
return
|
||||
/mob/living/proc/handle_mutations()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(SEND_SIGNAL(src, COMSIG_HANDLE_MUTATIONS) & COMPONENT_BLOCK_LIVING_MUTATIONS)
|
||||
return COMPONENT_BLOCK_LIVING_MUTATIONS
|
||||
|
||||
/mob/living/proc/handle_radiation()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(SEND_SIGNAL(src, COMSIG_HANDLE_RADIATION) & COMPONENT_BLOCK_LIVING_RADIATION)
|
||||
return COMPONENT_BLOCK_LIVING_RADIATION
|
||||
|
||||
/mob/living/proc/handle_chemicals_in_body()
|
||||
return
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
qdel(src) // Decayed to nothing
|
||||
else
|
||||
rad_power = new_power
|
||||
if(rad_power > 1e15) // Arbitrary cap to prevent going to infinity
|
||||
rad_power = 1e15
|
||||
if(!flat)
|
||||
range = min(round(sqrt(rad_power / CONFIG_GET(number/radiation_lower_limit))), 31) // R = rad_power / dist**2 - Solve for dist
|
||||
return
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 122.88" style="enable-background:new 0 0 122.88 122.88" xml:space="preserve"><style type="text/css">.st0{fill-rule:evenodd;clip-rule:evenodd;}</style><g><path class="st0" d="M86.71,104.87c-16.58,8.49-33.27,8.72-50.08-0.02L54.62,74.2c4.09,2.43,8.89,2.45,14.39,0.01L86.71,104.87 L86.71,104.87z M61.44,0c16.97,0,32.33,6.88,43.44,18c11.12,11.12,18,26.48,18,43.44c0,16.97-6.88,32.33-18,43.44 c-11.12,11.12-26.48,18-43.44,18S29.11,116,18,104.88C6.88,93.77,0,78.41,0,61.44C0,44.47,6.88,29.11,18,18 C29.11,6.88,44.47,0,61.44,0L61.44,0z M101.53,21.35C91.27,11.09,77.1,4.74,61.44,4.74c-15.66,0-29.83,6.35-40.09,16.61 C11.09,31.61,4.74,45.78,4.74,61.44c0,15.66,6.35,29.83,16.61,40.09c10.26,10.26,24.43,16.61,40.09,16.61 c15.66,0,29.83-6.35,40.09-16.61c10.26-10.26,16.61-24.43,16.61-40.09C118.14,45.78,111.79,31.61,101.53,21.35L101.53,21.35z M86.45,17.73c15.64,10.11,24.19,24.45,25.02,43.38l-35.55-0.25c0.06-4.76-2.32-8.92-7.18-12.46L86.45,17.73L86.45,17.73z M61.5,52.41c5.33,0,9.65,4.32,9.65,9.65c0,5.33-4.32,9.65-9.65,9.65c-5.33,0-9.65-4.32-9.65-9.65 C51.85,56.73,56.17,52.41,61.5,52.41L61.5,52.41z M11.53,61.33c0.93-18.6,9.08-33.17,25.06-43.36l17.56,30.91 c-4.15,2.33-6.56,6.47-7.2,12.45H11.53L11.53,61.33z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -9,6 +9,7 @@ import './styles/main.scss';
|
||||
import './styles/themes/abductor.scss';
|
||||
import './styles/themes/cardtable.scss';
|
||||
import './styles/themes/spookyconsole.scss';
|
||||
import './styles/themes/nuclear.scss';
|
||||
import './styles/themes/hackerman.scss';
|
||||
import './styles/themes/crtsoul.scss';
|
||||
import './styles/themes/malfunction.scss';
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { useBackend } from 'tgui/backend';
|
||||
import { Window } from 'tgui/layouts';
|
||||
import {
|
||||
Button,
|
||||
ColorBox,
|
||||
LabeledList,
|
||||
Section,
|
||||
Stack,
|
||||
} from 'tgui-core/components';
|
||||
|
||||
type Data = {
|
||||
radiation_color: string | null;
|
||||
glowing: number;
|
||||
};
|
||||
|
||||
export const RadiationConfig = (props) => {
|
||||
const { act, data } = useBackend<Data>();
|
||||
|
||||
const {
|
||||
radiation_color,
|
||||
glowing,
|
||||
} = data;
|
||||
return (
|
||||
<Window width={220} height={125} theme="nuclear">
|
||||
<Window.Content>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Section fill title="Cosmetic Settings">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Radiation Color">
|
||||
<Stack align="center">
|
||||
<Stack.Item>
|
||||
<Button
|
||||
onClick={() => act('toggle_color')}
|
||||
tooltip="Select a color you wish to glow when irradiated."
|
||||
>
|
||||
Set Color
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<ColorBox color={radiation_color || '#FFFFFF'} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Glow">
|
||||
<Button.Checkbox
|
||||
tooltip="Toggle if you glow when irradiated."
|
||||
checked={glowing}
|
||||
onClick={() => act('toggle_glow')}
|
||||
/>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
.theme-nuclear:root {
|
||||
// Base
|
||||
--color-base: hsl(71, 100%, 13%);
|
||||
--color-primary: hsl(73, 95%, 30%);
|
||||
--color-good: hsl(73, 95%, 46%);
|
||||
--color-average: hsl(64, 99%, 34%);
|
||||
--color-bad: hsl(74, 100%, 25%);
|
||||
--base-gradient-spread: 12;
|
||||
--secondary-lightness-adjustment: 9;
|
||||
|
||||
// Components
|
||||
--button-background-selected: var(--color-good);
|
||||
--button-background-caution: hsl(240, 80%, 35%);
|
||||
--button-background-danger: hsl(282, 61%, 30%);
|
||||
--dimmer-background-opacity: 0.45;
|
||||
--notice-box-background: hsl(64, 90%, 23%);
|
||||
--notice-box-color: var(--color-fixed-white);
|
||||
--progress-bar-background: hsla(0, 97%, 7%, 0.5);
|
||||
|
||||
.Layout__content {
|
||||
background-image: url('../../assets/bg-radiation.svg');
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
--color-base: hsl(0, 100%, 12.5%);
|
||||
--color-primary: hsl(345, 95%, 30%);
|
||||
--color-good: hsl(0, 82%, 52%);
|
||||
--color-average: hsl(0, 77%, 44%);
|
||||
--color-bad: hsl(340, 91%, 32%);
|
||||
--base-gradient-spread: 12;
|
||||
--secondary-lightness-adjustment: 9;
|
||||
|
||||
@@ -666,6 +666,7 @@
|
||||
#include "code\datums\components\traits\gargoyle.dm"
|
||||
#include "code\datums\components\traits\nutrition_size_change.dm"
|
||||
#include "code\datums\components\traits\photosynth.dm"
|
||||
#include "code\datums\components\traits\radiation_effects.dm"
|
||||
#include "code\datums\components\traits\unlucky.dm"
|
||||
#include "code\datums\components\traits\waddle.dm"
|
||||
#include "code\datums\components\traits\weaver.dm"
|
||||
|
||||
Reference in New Issue
Block a user