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:
Fox McCloud
2021-01-24 22:03:13 +00:00
committed by GitHub
parent acaefa9591
commit de795c4e31
154 changed files with 1967 additions and 674 deletions
+89 -74
View File
@@ -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
+5 -24
View File
@@ -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)