mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-24 20:47:10 +01:00
Radiation Refactor (#15331)
* First Commit * visible radiation and engine goggles * correction * t-ray fix * further adjustments and fixups * gieger addition and cleaning fixup * yet more fixes * styling fixes * fixes * human glowing fix * do the merge conflict avoidance dance * Update supermatter.dm * supermatter rads * mapping in * radiation doors * yeah yeah line endings * clean up * styling issues * showers
This commit is contained in:
@@ -97,7 +97,7 @@ By design, d1 is the smallest direction and d2 is the highest
|
||||
/obj/structure/cable/hide(i)
|
||||
|
||||
if(level == 1 && isturf(loc))
|
||||
invisibility = i ? 101 : 0
|
||||
invisibility = i ? INVISIBILITY_MAXIMUM : 0
|
||||
updateicon()
|
||||
|
||||
/obj/structure/cable/proc/updateicon()
|
||||
|
||||
@@ -367,8 +367,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
|
||||
|
||||
|
||||
/obj/machinery/gravity_generator/main/proc/pulse_radiation()
|
||||
for(var/mob/living/L in view(7, src))
|
||||
L.apply_effect(20, IRRADIATE)
|
||||
radiation_pulse(src, 200)
|
||||
|
||||
// Shake everyone on the z level to let them know that gravity was enagaged/disenagaged.
|
||||
/obj/machinery/gravity_generator/main/proc/shake_everyone()
|
||||
|
||||
@@ -401,19 +401,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
|
||||
if(prob(2 * power_output))
|
||||
radiation_pulse(get_turf(src), 50)
|
||||
..()
|
||||
|
||||
/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_pulse(get_turf(src), 500, 2)
|
||||
explosion(src.loc, 3, 3, 5, 3)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
// 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
|
||||
#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
|
||||
|
||||
GLOBAL_LIST_EMPTY(rad_collectors)
|
||||
|
||||
/obj/machinery/power/rad_collector
|
||||
name = "Radiation Collector Array"
|
||||
name = "\improper radiation collector array"
|
||||
desc = "A device which uses Hawking Radiation and plasma to produce power."
|
||||
icon = 'icons/obj/singularity.dmi'
|
||||
icon_state = "ca"
|
||||
anchored = 0
|
||||
density = 1
|
||||
anchored = FALSE
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_ENGINE_EQUIP)
|
||||
// use_power = NO_POWER_USE
|
||||
max_integrity = 350
|
||||
integrity_failure = 80
|
||||
var/obj/item/tank/plasma/P = null
|
||||
var/last_power = 0
|
||||
var/active = 0
|
||||
var/locked = 0
|
||||
rad_insulation = RAD_EXTREME_INSULATION
|
||||
var/obj/item/tank/plasma/loaded_tank = null
|
||||
var/stored_energy = 0
|
||||
var/active = FALSE
|
||||
var/locked = FALSE
|
||||
var/drainratio = 1
|
||||
var/powerproduction_drain = 0.001
|
||||
|
||||
/obj/machinery/power/rad_collector/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -26,114 +33,118 @@ GLOBAL_LIST_EMPTY(rad_collectors)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/process()
|
||||
if(P)
|
||||
if(P.air_contents.toxins <= 0)
|
||||
investigate_log("<font color='red'>out of fuel</font>.","singulo")
|
||||
P.air_contents.toxins = 0
|
||||
eject()
|
||||
else
|
||||
P.air_contents.toxins -= 0.001*drainratio
|
||||
return
|
||||
if(!loaded_tank)
|
||||
return
|
||||
if(!loaded_tank.air_contents.toxins)
|
||||
investigate_log("<font color='red'>out of fuel</font>.", "singulo")
|
||||
playsound(src, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
eject()
|
||||
else
|
||||
var/gasdrained = min(powerproduction_drain * drainratio, loaded_tank.air_contents.toxins)
|
||||
loaded_tank.air_contents.toxins -= gasdrained
|
||||
|
||||
var/power_produced = RAD_COLLECTOR_OUTPUT
|
||||
add_avail(power_produced)
|
||||
stored_energy -= power_produced
|
||||
|
||||
|
||||
/obj/machinery/power/rad_collector/attack_hand(mob/user as mob)
|
||||
/obj/machinery/power/rad_collector/attack_hand(mob/user)
|
||||
if(anchored)
|
||||
if(!src.locked)
|
||||
if(!locked)
|
||||
toggle_power()
|
||||
user.visible_message("[user.name] turns the [src.name] [active? "on":"off"].", \
|
||||
"You turn the [src.name] [active? "on":"off"].")
|
||||
investigate_log("turned [active?"<font color='green'>on</font>":"<font color='red'>off</font>"] by [user.key]. [P?"Fuel: [round(P.air_contents.toxins/0.29)]%":"<font color='red'>It is empty</font>"].","singulo")
|
||||
return
|
||||
user.visible_message("[user.name] turns the [name] [active ? "on" : "off"].", "You turn the [name] [active ? "on" : "off"].")
|
||||
investigate_log("turned [active ? "<font color='green'>on</font>" : "<font color='red'>off</font>"] by [user.key]. [loaded_tank ? "Fuel: [round(loaded_tank.air_contents.toxins / 0.29)]%" : "<font color='red'>It is empty</font>"].", "singulo")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The controls are locked!</span>")
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/multitool))
|
||||
to_chat(user, "<span class='notice'>The [W.name] detects that [last_power]W were recently produced.</span>")
|
||||
return 1
|
||||
else if(istype(W, /obj/item/analyzer) && P)
|
||||
atmosanalyzer_scan(P.air_contents, user)
|
||||
else if(istype(W, /obj/item/tank/plasma))
|
||||
if(!src.anchored)
|
||||
to_chat(user, "<span class='warning'>The [src] needs to be secured to the floor first.</span>")
|
||||
return 1
|
||||
if(src.P)
|
||||
/obj/machinery/power/rad_collector/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/analyzer) && loaded_tank)
|
||||
atmosanalyzer_scan(loaded_tank.air_contents, user)
|
||||
else if(istype(I, /obj/item/tank/plasma))
|
||||
if(!anchored)
|
||||
to_chat(user, "<span class='warning'>[src] needs to be secured to the floor first.</span>")
|
||||
return TRUE
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='warning'>There's already a plasma tank loaded.</span>")
|
||||
return 1
|
||||
user.drop_item()
|
||||
src.P = W
|
||||
W.loc = src
|
||||
update_icons()
|
||||
else if(istype(W, /obj/item/crowbar))
|
||||
if(P && !src.locked)
|
||||
return TRUE
|
||||
if(user.drop_item())
|
||||
loaded_tank = I
|
||||
I.forceMove(src)
|
||||
update_icons()
|
||||
else if(iscrowbar(I))
|
||||
if(loaded_tank && !locked)
|
||||
eject()
|
||||
return 1
|
||||
else if(istype(W, /obj/item/wrench))
|
||||
if(P)
|
||||
return TRUE
|
||||
else if(iswrench(I))
|
||||
if(loaded_tank)
|
||||
to_chat(user, "<span class='notice'>Remove the plasma tank first.</span>")
|
||||
return 1
|
||||
playsound(src.loc, W.usesound, 75, 1)
|
||||
src.anchored = !src.anchored
|
||||
user.visible_message("[user.name] [anchored? "secures":"unsecures"] the [src.name].", \
|
||||
"You [anchored? "secure":"undo"] the external bolts.", \
|
||||
"You hear a ratchet")
|
||||
return TRUE
|
||||
playsound(loc, I.usesound, 75, TRUE)
|
||||
anchored = !anchored
|
||||
user.visible_message("[user.name] [anchored ? "secures" : "unsecures"] the [name].", "You [anchored ? "secure" : "undo"] the external bolts.", "You hear a ratchet")
|
||||
if(anchored)
|
||||
connect_to_network()
|
||||
else
|
||||
disconnect_from_network()
|
||||
else if(istype(W, /obj/item/card/id)||istype(W, /obj/item/pda))
|
||||
if(src.allowed(user))
|
||||
else if(istype(I, /obj/item/card/id) || istype(I, /obj/item/pda))
|
||||
if(allowed(user))
|
||||
if(active)
|
||||
src.locked = !src.locked
|
||||
to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]")
|
||||
locked = !locked
|
||||
to_chat(user, "The controls are now [locked ? "locked." : "unlocked."]")
|
||||
else
|
||||
src.locked = 0 //just in case it somehow gets locked
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when the [src] is active</span>")
|
||||
locked = FALSE //just in case it somehow gets locked
|
||||
to_chat(user, "<span class='warning'>The controls can only be locked when [src] is active</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied!</span>")
|
||||
return 1
|
||||
return TRUE
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/rad_collector/examine(mob/user)
|
||||
. = ..()
|
||||
if(active)
|
||||
// stored_energy is converted directly to watts every SSmachines.wait * 0.1 seconds.
|
||||
// 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>"
|
||||
else
|
||||
. += "<span class='notice'><b>[src]'s display displays the words:</b> \"Power production mode. Please insert <b>Plasma</b>.\"</span>"
|
||||
|
||||
/obj/machinery/power/rad_collector/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT))
|
||||
eject()
|
||||
stat |= BROKEN
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/eject()
|
||||
locked = 0
|
||||
var/obj/item/tank/plasma/Z = src.P
|
||||
locked = FALSE
|
||||
var/obj/item/tank/plasma/Z = loaded_tank
|
||||
if(!Z)
|
||||
return
|
||||
Z.loc = get_turf(src)
|
||||
Z.forceMove(drop_location())
|
||||
Z.layer = initial(Z.layer)
|
||||
Z.plane = initial(Z.plane)
|
||||
src.P = null
|
||||
loaded_tank = null
|
||||
if(active)
|
||||
toggle_power()
|
||||
else
|
||||
update_icons()
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/receive_pulse(var/pulse_strength)
|
||||
if(P && active)
|
||||
var/power_produced = 0
|
||||
power_produced = P.air_contents.toxins*pulse_strength*20
|
||||
add_avail(power_produced)
|
||||
last_power = power_produced
|
||||
return
|
||||
return
|
||||
/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
|
||||
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/update_icons()
|
||||
overlays.Cut()
|
||||
if(P)
|
||||
overlays += image('icons/obj/singularity.dmi', "ptank")
|
||||
cut_overlays()
|
||||
if(loaded_tank)
|
||||
add_overlay("ptank")
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(active)
|
||||
overlays += image('icons/obj/singularity.dmi', "on")
|
||||
add_overlay("on")
|
||||
|
||||
|
||||
/obj/machinery/power/rad_collector/proc/toggle_power()
|
||||
@@ -145,4 +156,8 @@ GLOBAL_LIST_EMPTY(rad_collectors)
|
||||
icon_state = "ca"
|
||||
flick("ca_deactive", src)
|
||||
update_icons()
|
||||
return
|
||||
|
||||
#undef RAD_COLLECTOR_EFFICIENCY
|
||||
#undef RAD_COLLECTOR_COEFFICIENT
|
||||
#undef RAD_COLLECTOR_STORED_OUT
|
||||
#undef RAD_COLLECTOR_OUTPUT
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
/obj/effect/accelerated_particle/proc/try_irradiate(src, atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
L.apply_effect((energy * 6), IRRADIATE, 0)
|
||||
L.rad_act(energy * 6)
|
||||
else if(istype(A, /obj/machinery/the_singularitygen))
|
||||
var/obj/machinery/the_singularitygen/S = A
|
||||
S.energy += energy
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
// it might mean we are stuck in a corner somewere. So move around to try to expand.
|
||||
move()
|
||||
if(current_size >= STAGE_TWO)
|
||||
pulse()
|
||||
radiation_pulse(src, min(5000, (energy * 4.5) + 1000), RAD_DISTANCE_COEFFICIENT * 0.5)
|
||||
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,15 +377,13 @@
|
||||
|
||||
|
||||
/obj/singularity/proc/event()
|
||||
var/numb = pick(1,2,3,4,5,6)
|
||||
var/numb = rand(1, 4)
|
||||
switch(numb)
|
||||
if(1)//EMP
|
||||
if(1) //EMP
|
||||
emp_area()
|
||||
if(2,3)//tox damage all carbon mobs in area
|
||||
toxmob()
|
||||
if(4)//Stun mobs who lack optic scanners
|
||||
if(2) //Stun mobs who lack optic scanners
|
||||
mezzer()
|
||||
if(5,6) //Sets all nearby mobs on fire
|
||||
if(3, 4) //Sets all nearby mobs on fire
|
||||
if(current_size < STAGE_SIX)
|
||||
return 0
|
||||
combust_mobs()
|
||||
@@ -394,17 +392,6 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/singularity/proc/toxmob()
|
||||
var/toxrange = 10
|
||||
var/radiation = 15
|
||||
var/radiationmin = 3
|
||||
if(energy>200)
|
||||
radiation += round((energy-150)/10,1)
|
||||
radiationmin = round((radiation/5),1)
|
||||
for(var/mob/living/M in view(toxrange, src.loc))
|
||||
M.apply_effect(rand(radiationmin,radiation), IRRADIATE)
|
||||
|
||||
|
||||
/obj/singularity/proc/combust_mobs()
|
||||
for(var/mob/living/carbon/C in urange(20, src, 1))
|
||||
C.visible_message("<span class='warning'>[C]'s skin bursts into flame!</span>", \
|
||||
@@ -438,12 +425,6 @@
|
||||
empulse(src, 8, 10)
|
||||
return
|
||||
|
||||
|
||||
/obj/singularity/proc/pulse()
|
||||
for(var/obj/machinery/power/rad_collector/R in GLOB.rad_collectors)
|
||||
if(R.z == z && get_dist(R, src) <= 15) // Better than using orange() every process
|
||||
R.receive_pulse(energy)
|
||||
|
||||
/obj/singularity/singularity_act()
|
||||
var/gain = (energy/2)
|
||||
var/dist = max((current_size - 2),1)
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
icon_state = "darkmatter"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
|
||||
light_range = 4
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF
|
||||
var/base_icon_state = "darkmatter"
|
||||
@@ -291,7 +292,7 @@
|
||||
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(L, src) + 1))
|
||||
L.apply_effect(rads, IRRADIATE)
|
||||
L.rad_act(rads)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
@@ -463,9 +464,8 @@
|
||||
power = max((removed.temperature * temp_factor / T0C) * gasmix_power_ratio + power, 0)
|
||||
|
||||
if(prob(50))
|
||||
for(var/obj/machinery/power/rad_collector/R in GLOB.rad_collectors)
|
||||
if(atoms_share_level(R, src) && get_dist(R, src) <= 15) //Better than using orange() every process
|
||||
R.receive_pulse(power * (1 + power_transmission_bonus / 10))
|
||||
|
||||
radiation_pulse(src, power * max(0, (1 + (power_transmission_bonus / 10))))
|
||||
|
||||
//Power * 0.55 * a value between 1 and 0.8
|
||||
var/device_energy = power * REACTION_POWER_MODIFIER
|
||||
@@ -500,7 +500,7 @@
|
||||
l.hallucination = clamp(l.hallucination, 0, 200)
|
||||
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.apply_effect(rads, IRRADIATE)
|
||||
l.rad_act(rads)
|
||||
|
||||
//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
|
||||
@@ -676,7 +676,7 @@
|
||||
Consume(I)
|
||||
playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, TRUE)
|
||||
|
||||
user.apply_effect(150, IRRADIATE)
|
||||
radiation_pulse(src, 150, 4)
|
||||
|
||||
/obj/machinery/power/supermatter_crystal/Bumped(atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
@@ -716,9 +716,8 @@
|
||||
matter_power += 200
|
||||
|
||||
//Some poor sod got eaten, go ahead and irradiate people nearby.
|
||||
radiation_pulse(src, 3000, 2, TRUE)
|
||||
for(var/mob/living/L in range(10))
|
||||
var/rads = 500 * sqrt( 1 / (get_dist(L, src) + 1))
|
||||
L.apply_effect(rads, IRRADIATE)
|
||||
investigate_log("has irradiated [key_name(L)] after consuming [AM].", "supermatter")
|
||||
if(L in view())
|
||||
L.show_message("<span class='danger'>As [src] slowly stops resonating, you find your skin covered in new radiation burns.</span>", 1,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/obj/machinery/power/terminal/hide(i)
|
||||
if(i)
|
||||
invisibility = 101
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
icon_state = "term-f"
|
||||
else
|
||||
invisibility = 0
|
||||
|
||||
Reference in New Issue
Block a user