mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-11 10:43:20 +00:00
Unified radiation system
This commit is contained in:
43
code/controllers/Processes/radiation.dm
Normal file
43
code/controllers/Processes/radiation.dm
Normal file
@@ -0,0 +1,43 @@
|
||||
/datum/controller/process/radiation
|
||||
var/repository/radiation/linked = null
|
||||
|
||||
/datum/controller/process/radiation/setup()
|
||||
name = "radiation controller"
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
linked = radiation_repository
|
||||
|
||||
/datum/controller/process/radiation/doWork()
|
||||
// set background = 1
|
||||
for(var/turf/T in linked.irradiated_turfs)
|
||||
if(!T)
|
||||
linked.irradiated_turfs.Remove(T)
|
||||
continue
|
||||
linked.irradiated_turfs[T] -= config.radiation_decay_rate
|
||||
if(linked.irradiated_turfs[T] <= config.radiation_lower_limit)
|
||||
linked.irradiated_turfs.Remove(T)
|
||||
SCHECK
|
||||
for(var/mob/living/L in linked.irradiated_mobs)
|
||||
if(!L)
|
||||
linked.irradiated_mobs.Remove(L)
|
||||
continue
|
||||
if(get_turf(L) in linked.irradiated_turfs)
|
||||
L.rad_act(linked.irradiated_turfs[get_turf(L)])
|
||||
if(!L.radiation)
|
||||
linked.irradiated_mobs.Remove(L)
|
||||
SCHECK
|
||||
for(var/thing in linked.sources)
|
||||
if(!thing)
|
||||
linked.sources.Remove(thing)
|
||||
continue
|
||||
var/atom/emitter = thing
|
||||
linked.radiate(emitter, emitter.rad_power)
|
||||
to_process.Cut()
|
||||
SCHECK
|
||||
for(var/thing in linked.resistance_cache)
|
||||
if(!thing)
|
||||
linked.resistance_cache.Remove(thing)
|
||||
continue
|
||||
var/turf/T = thing
|
||||
if((length(T.contents) + 1) != linked.resistance_cache[T])
|
||||
T.calc_rad_resistance()
|
||||
SCHECK
|
||||
@@ -219,6 +219,10 @@ var/list/gamemode_cache = list()
|
||||
|
||||
var/show_human_death_message = 1
|
||||
|
||||
var/radiation_decay_rate = 1 //How much radiation is reduced by each tick
|
||||
var/radiation_resistance_multiplier = 6.5
|
||||
var/radiation_lower_limit = 0.35 //If the radiation level for a turf would be below this, ignore it.
|
||||
|
||||
/datum/configuration/New()
|
||||
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
|
||||
for (var/T in L)
|
||||
|
||||
114
code/datums/repositories/radiation.dm
Normal file
114
code/datums/repositories/radiation.dm
Normal file
@@ -0,0 +1,114 @@
|
||||
//#define RADDBG
|
||||
|
||||
var/repository/radiation/radiation_repository = new()
|
||||
|
||||
var/list/to_process = list()
|
||||
|
||||
/repository/radiation
|
||||
var/list/sources = list() //All the radiation sources we know about
|
||||
var/list/irradiated_turfs = list()
|
||||
var/list/irradiated_mobs = list()
|
||||
var/list/resistance_cache = list()
|
||||
|
||||
/repository/radiation/proc/report_rads(var/turf/T as turf)
|
||||
return irradiated_turfs[T]
|
||||
|
||||
/repository/radiation/proc/radiate(source, power) //Sends out a radiation pulse, taking walls into account
|
||||
if(!(source && power)) //Sanity checking
|
||||
return
|
||||
|
||||
var/range = min(round(sqrt(power / config.radiation_lower_limit)), 31)
|
||||
var/turf/epicentre = get_turf(source)
|
||||
to_process = list()
|
||||
|
||||
range = min(epicentre.x, world.maxx - epicentre.x, epicentre.y, world.maxy - epicentre.y, range)
|
||||
|
||||
to_process = trange(range, epicentre)
|
||||
to_process[epicentre] = power
|
||||
|
||||
for(var/turf/spot in to_process)
|
||||
var/turf/origin = get_turf(epicentre)
|
||||
var/working = power
|
||||
while(origin != spot)
|
||||
origin = get_step_towards(origin, spot) //Raytracing
|
||||
if(!(origin in resistance_cache)) //Only get the resistance if we don't already know it.
|
||||
origin.calc_rad_resistance()
|
||||
working = max((working - (origin.rad_resistance * config.radiation_resistance_multiplier)), 0)
|
||||
if(!working)
|
||||
break
|
||||
if(!to_process[origin])
|
||||
to_process[origin] = working
|
||||
|
||||
else
|
||||
to_process[origin] = max(to_process[origin], working)
|
||||
|
||||
for(var/turf/spot in to_process)
|
||||
irradiated_turfs[spot] = max(((to_process[spot]) * (1 / (get_dist(epicentre, spot) ** 2))), irradiated_turfs[spot]) //Butchered version of the inverse square law. Works for this purpose
|
||||
#ifdef RADDBG
|
||||
var/x = Clamp( irradiated_turfs[spot], 0, 255)
|
||||
spot.color = rgb(5,x,5)
|
||||
#endif
|
||||
|
||||
/repository/radiation/proc/flat_radiate(source, power, range, var/respect_maint=0) //Sets the radiation in a range to a constant value.
|
||||
if(!(source && power && range))
|
||||
return
|
||||
var/turf/epicentre = get_turf(source)
|
||||
range = min(epicentre.x, world.maxx - epicentre.x, epicentre.y, world.maxy - epicentre.y, range)
|
||||
if(!respect_maint)
|
||||
for(var/turf/T in trange(range, epicentre))
|
||||
irradiated_turfs[T] = max(power, irradiated_turfs[T])
|
||||
else
|
||||
for(var/turf/T in trange(range, epicentre))
|
||||
var/area/A = T.loc
|
||||
if(A.flags & RAD_SHIELDED)
|
||||
continue
|
||||
irradiated_turfs[T] = max(power, irradiated_turfs[T])
|
||||
|
||||
/repository/radiation/proc/z_radiate(var/atom/source, power, var/respect_maint=0) //Irradiates a full Z-level. Hacky way of doing it, but not too expensive.
|
||||
if(!(power && source))
|
||||
return
|
||||
var/turf/epicentre = locate(round(world.maxx / 2), round(world.maxy / 2), source.z)
|
||||
flat_radiate(epicentre, power, world.maxx, respect_maint)
|
||||
|
||||
/turf/proc/calc_rad_resistance()
|
||||
rad_resistance = 0
|
||||
for(var/obj/O in src.contents)
|
||||
if(O.rad_resistance) //Override
|
||||
rad_resistance += O.rad_resistance
|
||||
|
||||
else if(O.density) //So doors don't get counted
|
||||
var/material/M = O.get_material()
|
||||
if(!M) continue
|
||||
rad_resistance += M.weight
|
||||
radiation_repository.resistance_cache[src] = (length(contents) + 1)
|
||||
|
||||
/turf/simulated/wall/calc_rad_resistance()
|
||||
radiation_repository.resistance_cache[src] = (length(contents) + 1)
|
||||
rad_resistance = (density ? material.weight : 0)
|
||||
|
||||
/atom
|
||||
var/rad_power = 0
|
||||
var/rad_resistance = 0
|
||||
|
||||
/atom/Destroy()
|
||||
if(rad_power)
|
||||
radiation_repository.sources.Remove(src)
|
||||
. = ..()
|
||||
|
||||
/atom/proc/update_radiation() //For VV'ing something to make it radioactive at runtime
|
||||
if((rad_power) && (!(src in radiation_repository.sources)))
|
||||
radiation_repository.sources.Add(src)
|
||||
else if((!rad_power) && (src in radiation_repository.sources))
|
||||
radiation_repository.sources.Remove(src)
|
||||
|
||||
/atom/proc/rad_act(var/severity) //If people expand the system, this may be useful. Here as a placeholder until then
|
||||
return 1
|
||||
|
||||
/mob/living/rad_act(var/severity)
|
||||
if(severity)
|
||||
src.apply_effect(severity, IRRADIATE, src.getarmor(null, "rad"))
|
||||
for(var/obj/I in src)
|
||||
I.rad_act(severity)
|
||||
|
||||
|
||||
//#undef RADDBG
|
||||
@@ -53,6 +53,9 @@
|
||||
pulledby = null
|
||||
|
||||
/atom/movable/proc/initialize()
|
||||
if(rad_power)
|
||||
radiation_repository.sources.Add(src)
|
||||
|
||||
if(!isnull(gcDestroyed))
|
||||
crash_with("GC: -- [type] had initialize() called after qdel() --")
|
||||
|
||||
|
||||
@@ -271,8 +271,7 @@
|
||||
if(explode)
|
||||
explosion(src.loc, devastation_range = 0, heavy_impact_range = 0, light_impact_range = 4, flash_range = 6, adminlog = 0)
|
||||
new /obj/effect/decal/cleanable/greenglow(get_turf(src))
|
||||
for(var/mob/living/L in view(10, src))
|
||||
L.apply_effect(40, IRRADIATE)
|
||||
radiation_repository.radiate(src, 50)
|
||||
|
||||
// This meteor fries toasters.
|
||||
/obj/effect/meteor/emp
|
||||
|
||||
@@ -263,6 +263,7 @@
|
||||
icon = 'icons/obj/doors/Dooruranium.dmi'
|
||||
mineral = "uranium"
|
||||
var/last_event = 0
|
||||
rad_power = 7.5
|
||||
|
||||
/obj/machinery/door/airlock/process()
|
||||
// Deliberate no call to parent.
|
||||
@@ -277,18 +278,6 @@
|
||||
|
||||
..()
|
||||
|
||||
/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/proc/radiate()
|
||||
for(var/mob/living/L in range (3,src))
|
||||
L.apply_effect(15,IRRADIATE,0)
|
||||
return
|
||||
|
||||
/obj/machinery/door/airlock/phoron
|
||||
name = "Phoron Airlock"
|
||||
desc = "No way this can end badly."
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon = 'icons/obj/doors/rapid_pdoor.dmi'
|
||||
icon_state = null
|
||||
min_force = 20 //minimum amount of force needed to damage the door with a melee weapon
|
||||
|
||||
var/material/implicit_material
|
||||
// Icon states for different shutter types. Simply change this instead of rewriting the update_icon proc.
|
||||
var/icon_state_open = null
|
||||
var/icon_state_opening = null
|
||||
@@ -29,6 +29,13 @@
|
||||
//turning this off prevents awkward zone geometry in places like medbay lobby, for example.
|
||||
block_air_zones = 0
|
||||
|
||||
/obj/machinery/door/blast/initialize()
|
||||
..()
|
||||
implicit_material = get_material_by_name("plasteel")
|
||||
|
||||
/obj/machinery/door/blast/get_material()
|
||||
return implicit_material
|
||||
|
||||
// Proc: Bumped()
|
||||
// Parameters: 1 (AM - Atom that tried to walk through this object)
|
||||
// Description: If we are open returns zero, otherwise returns result of parent function.
|
||||
@@ -46,6 +53,8 @@
|
||||
icon_state = icon_state_closed
|
||||
else
|
||||
icon_state = icon_state_open
|
||||
var/turf/T = get_turf(src)
|
||||
T.calc_rad_resistance()
|
||||
return
|
||||
|
||||
// Proc: force_open()
|
||||
|
||||
@@ -362,6 +362,8 @@
|
||||
icon_state = "door1"
|
||||
else
|
||||
icon_state = "door0"
|
||||
var/turf/T = get_turf(src)
|
||||
T.calc_rad_resistance()
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -1029,7 +1029,7 @@
|
||||
icon_state = "engivend"
|
||||
icon_deny = "engivend-deny"
|
||||
req_access = list(access_engine_equip)
|
||||
products = list(/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/cell/high = 10,
|
||||
products = list(/obj/item/device/geiger = 4,/obj/item/clothing/glasses/meson = 2,/obj/item/device/multitool = 4,/obj/item/weapon/cell/high = 10,
|
||||
/obj/item/weapon/airlock_electronics = 10,/obj/item/weapon/module/power_control = 10,
|
||||
/obj/item/weapon/circuitboard/airalarm = 10,/obj/item/weapon/circuitboard/firealarm = 10,/obj/item/weapon/circuitboard/status_display = 2,
|
||||
/obj/item/weapon/circuitboard/ai_status_display = 2,/obj/item/weapon/circuitboard/newscaster = 2,/obj/item/weapon/circuitboard/holopad = 2,
|
||||
|
||||
@@ -973,11 +973,7 @@
|
||||
|
||||
process(var/obj/item/mecha_parts/mecha_equipment/generator/nuclear/EG)
|
||||
if(..())
|
||||
for(var/mob/living/carbon/M in view(EG.chassis))
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
M.apply_effect((EG.rad_per_cycle*3),IRRADIATE,0)
|
||||
else
|
||||
M.apply_effect(EG.rad_per_cycle, IRRADIATE)
|
||||
radiation_repository.radiate(EG, (EG.rad_per_cycle * 3))
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
53
code/game/objects/items/devices/geiger.dm
Normal file
53
code/game/objects/items/devices/geiger.dm
Normal file
@@ -0,0 +1,53 @@
|
||||
#define RAD_LEVEL_LOW 5 //10 // Around the level at which radiation starts to become harmful
|
||||
#define RAD_LEVEL_MODERATE 15 //15
|
||||
#define RAD_LEVEL_HIGH 50 //50
|
||||
#define RAD_LEVEL_VERY_HIGH 100 //100
|
||||
|
||||
//Geiger counter
|
||||
//Rewritten version of TG's geiger counter
|
||||
//I opted to show exact radiation levels
|
||||
|
||||
/obj/item/device/geiger
|
||||
name = "geiger counter"
|
||||
desc = "A handheld device used for detecting and measuring radiation in an area."
|
||||
icon_state = "geiger_off"
|
||||
item_state = "multitool"
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/scanning = 0
|
||||
var/radiation_count = 0
|
||||
|
||||
/obj/item/device/geiger/New()
|
||||
processing_objects |= src
|
||||
|
||||
/obj/item/device/geiger/process()
|
||||
if(!scanning)
|
||||
return
|
||||
radiation_count = radiation_repository.report_rads(get_turf(src))
|
||||
update_icon()
|
||||
|
||||
/obj/item/device/geiger/examine(mob/user)
|
||||
..(user)
|
||||
to_chat(user, "<span class='warning'>[scanning ? "ambient" : "stored"] radiation level: [radiation_count ? radiation_count : "0"]Bq.</span>")
|
||||
|
||||
/obj/item/device/geiger/attack_self(var/mob/user)
|
||||
scanning = !scanning
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>\icon[src] You switch [scanning ? "on" : "off"] [src].</span>")
|
||||
|
||||
/obj/item/device/geiger/update_icon()
|
||||
if(!scanning)
|
||||
icon_state = "geiger_off"
|
||||
return 1
|
||||
|
||||
switch(radiation_count)
|
||||
if(null) icon_state = "geiger_on_1"
|
||||
if(-INFINITY to RAD_LEVEL_LOW) icon_state = "geiger_on_1"
|
||||
if(RAD_LEVEL_LOW + 1 to RAD_LEVEL_MODERATE) icon_state = "geiger_on_2"
|
||||
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH) icon_state = "geiger_on_3"
|
||||
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH) icon_state = "geiger_on_4"
|
||||
if(RAD_LEVEL_VERY_HIGH + 1 to INFINITY) icon_state = "geiger_on_5"
|
||||
|
||||
#undef RAD_LEVEL_LOW
|
||||
#undef RAD_LEVEL_MODERATE
|
||||
#undef RAD_LEVEL_HIGH
|
||||
#undef RAD_LEVEL_VERY_HIGH
|
||||
@@ -155,6 +155,8 @@
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/device/geiger(src)
|
||||
new /obj/item/device/geiger(src)
|
||||
|
||||
/*
|
||||
* Bombsuit closet
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
if(can_open == WALL_OPENING)
|
||||
return
|
||||
|
||||
calc_rad_resistance()
|
||||
|
||||
if(density)
|
||||
can_open = WALL_OPENING
|
||||
//flick("[material.icon_base]fwall_opening", src)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
else if(material.opacity < 0.5 && opacity)
|
||||
set_light(0)
|
||||
|
||||
calc_rad_resistance()
|
||||
update_connections(1)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
if(!radiate())
|
||||
return PROCESS_KILL
|
||||
|
||||
/turf/simulated/wall/proc/get_material()
|
||||
return material
|
||||
|
||||
/turf/simulated/wall/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(istype(Proj,/obj/item/projectile/beam))
|
||||
burn(2500)
|
||||
@@ -265,8 +268,7 @@
|
||||
if(!total_radiation)
|
||||
return
|
||||
|
||||
for(var/mob/living/L in range(3,src))
|
||||
L.apply_effect(total_radiation, IRRADIATE,0)
|
||||
radiation_repository.radiate(src, total_radiation)
|
||||
return total_radiation
|
||||
|
||||
/turf/simulated/wall/proc/burn(temperature)
|
||||
|
||||
@@ -140,6 +140,12 @@ var/const/enterloopsanity = 100
|
||||
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
var/mob/living/L = A
|
||||
if(istype(L))
|
||||
if(!(L in radiation_repository.irradiated_mobs))
|
||||
if(src in radiation_repository.irradiated_turfs)
|
||||
radiation_repository.irradiated_mobs.Add(L)
|
||||
L.handle_footstep(src)
|
||||
if(!M.lastarea)
|
||||
M.lastarea = get_area(M.loc)
|
||||
if(M.lastarea.has_gravity == 0)
|
||||
@@ -147,9 +153,6 @@ var/const/enterloopsanity = 100
|
||||
else if(!is_space())
|
||||
M.inertia_dir = 0
|
||||
M.make_floating(0)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
L.handle_footstep(src)
|
||||
..()
|
||||
var/objects = 0
|
||||
if(A && (A.flags & PROXMOVE))
|
||||
@@ -255,4 +258,4 @@ var/const/enterloopsanity = 100
|
||||
step(AM, turn(AM.last_move, 180))
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.turf_collision(src, speed)
|
||||
M.turf_collision(src, speed)
|
||||
@@ -186,4 +186,4 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
#undef ASSIGNMENT_JANITOR
|
||||
#undef ASSIGNMENT_MEDICAL
|
||||
#undef ASSIGNMENT_SCIENTIST
|
||||
#undef ASSIGNMENT_SECURITY
|
||||
#undef ASSIGNMENT_SECURITY
|
||||
@@ -30,20 +30,18 @@
|
||||
command_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert")
|
||||
|
||||
/datum/event/radiation_storm/proc/radiate()
|
||||
var/radiation_level = rand(15, 35)
|
||||
for(var/z in using_map.station_levels)
|
||||
radiation_repository.z_radiate(locate(1, 1, z), radiation_level, 1)
|
||||
|
||||
for(var/mob/living/carbon/C in living_mob_list)
|
||||
var/area/A = get_area(C)
|
||||
if(!A)
|
||||
continue
|
||||
if(!(A.z in using_map.station_levels))
|
||||
continue
|
||||
if(A.flags & RAD_SHIELDED)
|
||||
continue
|
||||
|
||||
if(istype(C,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.apply_effect((rand(15,35)),IRRADIATE,0)
|
||||
if(prob(5))
|
||||
H.apply_effect((rand(40,70)),IRRADIATE,0)
|
||||
if (prob(75))
|
||||
randmutb(H) // Applies bad mutation
|
||||
domutcheck(H,null,MUTCHK_FORCED)
|
||||
|
||||
@@ -27,17 +27,14 @@
|
||||
radiate()
|
||||
|
||||
/datum/event/solar_storm/proc/radiate()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T)
|
||||
var/radiation_level = rand(15, 30)
|
||||
for(var/area/A in all_areas)
|
||||
if(!(A.z in using_map.player_levels))
|
||||
continue
|
||||
|
||||
if(!istype(T.loc,/area/space) && !istype(T,/turf/space)) //Make sure you're in a space area or on a space turf
|
||||
continue
|
||||
|
||||
//Todo: Apply some burn damage from the heat of the sun. Until then, enjoy some moderate radiation.
|
||||
L.apply_effect((rand(15,30)),IRRADIATE,blocked = L.getarmor(null, "rad"))
|
||||
|
||||
for(var/turf/T in A)
|
||||
if(!istype(T.loc,/area/space) && !istype(T,/turf/space))
|
||||
continue
|
||||
radiation_repository.irradiated_turfs[T] = radiation_level
|
||||
|
||||
/datum/event/solar_storm/end()
|
||||
command_announcement.Announce("The solar storm has passed the station. It is now safe to resume EVA activities. Please report to medbay if you experience any unusual symptoms. ", "Anomaly Alert")
|
||||
|
||||
@@ -482,7 +482,7 @@ var/list/mining_overlay_cache = list()
|
||||
M.flash_eyes()
|
||||
if(prob(50))
|
||||
M.Stun(5)
|
||||
M.apply_effect(25, IRRADIATE)
|
||||
radiation_repository.flat_radiate(src, 25, 200)
|
||||
if(prob(25))
|
||||
excavate_find(prob(5), finds[1])
|
||||
else if(rand(1,500) == 1)
|
||||
@@ -559,4 +559,4 @@ var/list/mining_overlay_cache = list()
|
||||
if(mineral_name && (mineral_name in ore_data))
|
||||
mineral = ore_data[mineral_name]
|
||||
UpdateMineral()
|
||||
update_icon()
|
||||
update_icon()
|
||||
@@ -94,7 +94,7 @@ emp_act
|
||||
var/obj/item/organ/external/organ = organs_by_name[organ_name]
|
||||
if(organ)
|
||||
var/weight = organ_rel_size[organ_name]
|
||||
armorval += getarmor_organ(organ, type) * weight
|
||||
armorval += (getarmor_organ(organ, type) * weight)
|
||||
total += weight
|
||||
return (armorval/max(total, 1))
|
||||
|
||||
|
||||
@@ -352,6 +352,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += new /obj/item/device/pipe_painter(src)
|
||||
src.modules += new /obj/item/device/floor_painter(src)
|
||||
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
|
||||
src.modules += new /obj/item/device/geiger(src)
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
|
||||
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel()
|
||||
@@ -396,6 +397,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += new /obj/item/device/pipe_painter(src)
|
||||
src.modules += new /obj/item/device/floor_painter(src)
|
||||
src.emag = new /obj/item/weapon/melee/baton/robot/arm(src)
|
||||
src.modules += new /obj/item/device/geiger(src)
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
|
||||
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
|
||||
|
||||
@@ -396,17 +396,13 @@
|
||||
/obj/machinery/power/port_gen/pacman/super/UseFuel()
|
||||
//produces a tiny amount of radiation when in use
|
||||
if (prob(2*power_output))
|
||||
for (var/mob/living/L in range(src, 5))
|
||||
L.apply_effect(1, IRRADIATE) //should amount to ~5 rads per minute at max safe power
|
||||
radiation_repository.radiate(src, 4)
|
||||
..()
|
||||
|
||||
/obj/machinery/power/port_gen/pacman/super/explode()
|
||||
//a nice burst of radiation
|
||||
var/rads = 50 + (sheets + sheet_left)*1.5
|
||||
for (var/mob/living/L in range(src, 10))
|
||||
//should really fall with the square of the distance, but that makes the rads value drop too fast
|
||||
//I dunno, maybe physics works different when you live in 2D -- SM radiation also works like this, apparently
|
||||
L.apply_effect(max(20, round(rads/get_dist(L,src))), IRRADIATE)
|
||||
radiation_repository.radiate(src, (max(20, rads)))
|
||||
|
||||
explosion(src.loc, 3, 3, 5, 3)
|
||||
qdel(src)
|
||||
|
||||
@@ -31,6 +31,11 @@ var/global/list/rad_collectors = list()
|
||||
last_power_new = 0
|
||||
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T in radiation_repository.irradiated_turfs)
|
||||
receive_pulse((radiation_repository.irradiated_turfs[T] * 5)) //Maths is hard
|
||||
|
||||
|
||||
if(P)
|
||||
if(P.air_contents.gas["phoron"] == 0)
|
||||
investigate_log("<font color='red'>out of fuel</font>.","singulo")
|
||||
|
||||
@@ -406,15 +406,13 @@
|
||||
var/toxrange = 10
|
||||
var/toxdamage = 4
|
||||
var/radiation = 15
|
||||
var/radiationmin = 3
|
||||
if (src.energy>200)
|
||||
toxdamage = round(((src.energy-150)/50)*4,1)
|
||||
radiation = round(((src.energy-150)/50)*5,1)
|
||||
radiationmin = round((radiation/5),1)//
|
||||
radiation_repository.radiate(src, radiation) //Always radiate at max, so a decent dose of radiation is applied
|
||||
for(var/mob/living/M in view(toxrange, src.loc))
|
||||
if(M.status_flags & GODMODE)
|
||||
continue
|
||||
M.apply_effect(rand(radiationmin,radiation), IRRADIATE)
|
||||
toxdamage = (toxdamage - (toxdamage*M.getarmor(null, "rad")))
|
||||
M.apply_effect(toxdamage, TOX)
|
||||
return
|
||||
@@ -448,13 +446,13 @@
|
||||
/obj/singularity/proc/smwave()
|
||||
for(var/mob/living/M in view(10, src.loc))
|
||||
if(prob(67))
|
||||
M.apply_effect(rand(energy), IRRADIATE)
|
||||
M << "<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>"
|
||||
M << "<span class=\"notice\">Miraculously, it fails to kill you.</span>"
|
||||
to_chat(M, "<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
|
||||
to_chat(M, "<span class=\"notice\">Miraculously, it fails to kill you.</span>")
|
||||
else
|
||||
M << "<span class=\"danger\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>"
|
||||
M << "<span class=\"danger\">You don't even have a moment to react as you are reduced to ashes by the intense radiation.</span>"
|
||||
M.dust()
|
||||
radiation_repository.radiate(src, rand(energy))
|
||||
return
|
||||
|
||||
/obj/singularity/proc/pulse()
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
#define DAMAGE_RATE_LIMIT 3 //damage rate cap at power = 300, scales linearly with power
|
||||
|
||||
|
||||
//These would be what you would get at point blank, decreases with distance
|
||||
#define DETONATION_RADS 200
|
||||
// Base variants are applied to everyone on the same Z level
|
||||
// Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels)
|
||||
#define DETONATION_RADS 20
|
||||
#define DETONATION_HALLUCINATION_BASE 300
|
||||
#define DETONATION_HALLUCINATION_RANGE 300
|
||||
#define DETONATION_HALLUCINATION 600
|
||||
|
||||
|
||||
@@ -39,6 +42,7 @@
|
||||
anchored = 0
|
||||
light_range = 4
|
||||
|
||||
rad_power = 1 //So it gets added to the repository
|
||||
var/gasefficency = 0.25
|
||||
|
||||
var/base_icon_state = "darkmatter"
|
||||
@@ -95,6 +99,10 @@
|
||||
anchored = 1
|
||||
grav_pulling = 1
|
||||
exploded = 1
|
||||
var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, mecha, or other container shouldn't block it's effects that way.
|
||||
radiation_repository.z_radiate(TS, DETONATION_RADS)
|
||||
radiation_repository.z_radiate(TS, DETONATION_RADS)
|
||||
|
||||
for(var/mob/living/mob in living_mob_list)
|
||||
var/turf/T = get_turf(mob)
|
||||
if(T && (loc.z == T.z))
|
||||
@@ -102,8 +110,6 @@
|
||||
//Hilariously enough, running into a closet should make you get hit the hardest.
|
||||
var/mob/living/carbon/human/H = mob
|
||||
H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
|
||||
var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) )
|
||||
mob.apply_effect(rads, IRRADIATE)
|
||||
spawn(pull_time)
|
||||
explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1)
|
||||
qdel(src)
|
||||
@@ -258,12 +264,15 @@
|
||||
if(eye_shield < 1)
|
||||
l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / max(1,get_dist(l, src)) ) ) )
|
||||
|
||||
/*
|
||||
//adjusted range so that a power of 170 (pretty high) results in 9 tiles, roughly the distance from the core to the engine monitoring room.
|
||||
//note that the rads given at the maximum range is a constant 0.2 - as power increases the maximum range merely increases.
|
||||
for(var/mob/living/l in range(src, round(sqrt(power / 2))))
|
||||
var/radius = max(get_dist(l, src), 1)
|
||||
var/rads = (power / 10) * ( 1 / (radius**2) )
|
||||
l.apply_effect(rads, IRRADIATE)
|
||||
*/
|
||||
rad_power = power * 1.5//Better close those shutters!
|
||||
|
||||
power -= (power/DECAY_FACTOR)**3 //energy losses due to radiation
|
||||
|
||||
@@ -377,8 +386,8 @@
|
||||
"<span class=\"warning\">The unearthly ringing subsides and you notice you have new radiation burns.</span>", 2)
|
||||
else
|
||||
l.show_message("<span class=\"warning\">You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.</span>", 2)
|
||||
var/rads = 500 * sqrt( 1 / (get_dist(l, src) + 1) )
|
||||
l.apply_effect(rads, IRRADIATE)
|
||||
var/rads = 500
|
||||
radiation_repository.radiate(src, rads)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/proc/supermatter_pull()
|
||||
@@ -394,6 +403,7 @@
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/GotoAirflowDest(n) //Supermatter not pushed around by airflow
|
||||
return
|
||||
|
||||
|
||||
@@ -15,16 +15,10 @@
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectAura()
|
||||
if(holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,T))
|
||||
M.apply_effect(radiation_amount,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
radiation_repository.flat_radiate(holder, radiation_amount, src.effectrange)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectPulse()
|
||||
if(holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,T))
|
||||
M.apply_effect(radiation_amount * 25,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
radiation_repository.radiate(holder, ((radiation_amount * 25) * (sqrt(src.effectrange)))) //Need to get feedback on this
|
||||
return 1
|
||||
|
||||
@@ -198,8 +198,7 @@
|
||||
radiation = rand() * 15 + 85
|
||||
if(!rad_shield)
|
||||
//irradiate nearby mobs
|
||||
for(var/mob/living/M in view(7,src))
|
||||
M.apply_effect(radiation / 25, IRRADIATE, 0)
|
||||
radiation_repository.radiate(src, radiation / 25)
|
||||
else
|
||||
t_left_radspike = pick(10,15,25)
|
||||
|
||||
@@ -361,4 +360,4 @@
|
||||
scanned_item = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
return 1 // update UIs attached to this object
|
||||
return 1 // update UIs attached to this object
|
||||
37
html/changelogs/cirra-Radiation.yml
Normal file
37
html/changelogs/cirra-Radiation.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# wip (For works in progress)
|
||||
# tweak
|
||||
# soundadd
|
||||
# sounddel
|
||||
# rscadd (general adding of nice things)
|
||||
# rscdel (general deleting of nice things)
|
||||
# imageadd
|
||||
# imagedel
|
||||
# maptweak
|
||||
# spellcheck (typo fixes)
|
||||
# experiment
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: Cirra
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- rscadd: "Added a unified radiation system. Radiation is lessened by obstacles, and distance."
|
||||
- rscadd: "Added a geiger counter for measuring radiation levels, which can be found in certain vending machines and radiation closets."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 54 KiB |
@@ -150,6 +150,7 @@
|
||||
#include "code\controllers\Processes\nanoui.dm"
|
||||
#include "code\controllers\Processes\obj.dm"
|
||||
#include "code\controllers\Processes\planet.dm"
|
||||
#include "code\controllers\Processes\radiation.dm"
|
||||
#include "code\controllers\Processes\scheduler.dm"
|
||||
#include "code\controllers\Processes\Shuttle.dm"
|
||||
#include "code\controllers\Processes\sun.dm"
|
||||
@@ -212,6 +213,7 @@
|
||||
#include "code\datums\repositories\cameras.dm"
|
||||
#include "code\datums\repositories\crew.dm"
|
||||
#include "code\datums\repositories\decls.dm"
|
||||
#include "code\datums\repositories\radiation.dm"
|
||||
#include "code\datums\repositories\repository.dm"
|
||||
#include "code\datums\supplypacks\atmospherics.dm"
|
||||
#include "code\datums\supplypacks\contraband.dm"
|
||||
@@ -768,6 +770,7 @@
|
||||
#include "code\game\objects\items\devices\flash.dm"
|
||||
#include "code\game\objects\items\devices\flashlight.dm"
|
||||
#include "code\game\objects\items\devices\floor_painter.dm"
|
||||
#include "code\game\objects\items\devices\geiger.dm"
|
||||
#include "code\game\objects\items\devices\hacktool.dm"
|
||||
#include "code\game\objects\items\devices\lightreplacer.dm"
|
||||
#include "code\game\objects\items\devices\locker_painter.dm"
|
||||
|
||||
Reference in New Issue
Block a user