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
@@ -199,23 +199,7 @@
deactivate(user)
else
to_chat(user, "<span class='notice'>You activate [src].</span>")
var/start = user.filters.len
var/X
var/Y
var/rsq
var/i
var/f
for(i in 1 to 7)
do
X = 60 * rand() - 30
Y = 60 * rand() - 30
rsq = X * X + Y * Y
while(rsq < 100 || rsq > 900)
user.filters += filter(type = "wave", x = X, y = Y, size = rand() * 2.5 + 0.5, offset = rand())
for(i in 1 to 7)
f = user.filters[start+i]
animate(f, offset = f:offset, time = 0, loop = 3, flags = ANIMATION_PARALLEL)
animate(offset = f:offset - 1, time = rand() * 20 + 10)
apply_wibbly_filters(user)
if(do_after(user, 50, target = user) && user.cell.use(activationCost))
playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6)
to_chat(user, "<span class='notice'>You are now disguised as a Nanotrasen engineering cyborg.</span>")
@@ -223,10 +207,7 @@
else
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
do_sparks(3, FALSE, user)
for(i in 1 to min(7, user.filters.len)) // removing filters that are animating does nothing, we gotta stop the animations first
f = user.filters[start + i]
animate(f)
user.filters = null
remove_wibbly_filters(user)
/obj/item/borg_chameleon/process()
if(S)
@@ -0,0 +1,216 @@
#define RAD_LEVEL_NORMAL 9
#define RAD_LEVEL_MODERATE 100
#define RAD_LEVEL_HIGH 400
#define RAD_LEVEL_VERY_HIGH 800
#define RAD_LEVEL_CRITICAL 1500
/obj/item/geiger_counter //DISCLAIMER: I know nothing about how real-life Geiger counters work. This will not be realistic. ~Xhuis
name = "\improper Geiger counter"
desc = "A handheld device used for detecting and measuring radiation pulses."
icon = 'icons/obj/device.dmi'
icon_state = "geiger_off"
item_state = "multitool"
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
flags = NOBLUDGEON
materials = list(MAT_METAL = 150, MAT_GLASS = 150)
var/grace = RAD_GEIGER_GRACE_PERIOD
var/datum/looping_sound/geiger/soundloop
var/scanning = FALSE
var/radiation_count = 0
var/current_tick_amount = 0
var/last_tick_amount = 0
var/fail_to_receive = 0
var/current_warning = 1
/obj/item/geiger_counter/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
soundloop = new(list(src), FALSE)
/obj/item/geiger_counter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/geiger_counter/process()
update_icon()
update_sound()
if(!scanning)
current_tick_amount = 0
return
radiation_count -= radiation_count / RAD_GEIGER_MEASURE_SMOOTHING
radiation_count += current_tick_amount / RAD_GEIGER_MEASURE_SMOOTHING
if(current_tick_amount)
grace = RAD_GEIGER_GRACE_PERIOD
last_tick_amount = current_tick_amount
else if(!emagged)
grace--
if(grace <= 0)
radiation_count = 0
current_tick_amount = 0
/obj/item/geiger_counter/examine(mob/user)
. = ..()
if(!scanning)
return
. += "<span class='info'>Alt-click it to clear stored radiation levels.</span>"
if(emagged)
. += "<span class='warning'>The display seems to be incomprehensible.</span>"
return
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
. += "<span class='notice'>Ambient radiation level count reports that all is well.</span>"
if(RAD_LEVEL_NORMAL + 1 to RAD_LEVEL_MODERATE)
. += "<span class='alert'>Ambient radiation levels slightly above average.</span>"
if(RAD_LEVEL_MODERATE + 1 to RAD_LEVEL_HIGH)
. += "<span class='warning'>Ambient radiation levels above average.</span>"
if(RAD_LEVEL_HIGH + 1 to RAD_LEVEL_VERY_HIGH)
. += "<span class='danger'>Ambient radiation levels highly above average.</span>"
if(RAD_LEVEL_VERY_HIGH + 1 to RAD_LEVEL_CRITICAL)
. += "<span class='suicide'>Ambient radiation levels nearing critical level.</span>"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
. += "<span class='boldannounce'>Ambient radiation levels above critical level!</span>"
. += "<span class='notice'>The last radiation amount detected was [last_tick_amount]</span>"
/obj/item/geiger_counter/update_icon()
if(!scanning)
icon_state = "geiger_off"
else if(emagged)
icon_state = "geiger_on_emag"
else
switch(radiation_count)
if(-INFINITY to RAD_LEVEL_NORMAL)
icon_state = "geiger_on_1"
if(RAD_LEVEL_NORMAL + 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 RAD_LEVEL_CRITICAL)
icon_state = "geiger_on_4"
if(RAD_LEVEL_CRITICAL + 1 to INFINITY)
icon_state = "geiger_on_5"
/obj/item/geiger_counter/proc/update_sound()
var/datum/looping_sound/geiger/loop = soundloop
if(!scanning)
loop.stop()
return
if(!radiation_count)
loop.stop()
return
loop.last_radiation = radiation_count
loop.start()
/obj/item/geiger_counter/rad_act(amount)
. = ..()
if(amount <= RAD_BACKGROUND_RADIATION || !scanning)
return
current_tick_amount += amount
update_icon()
/obj/item/geiger_counter/attack_self(mob/user)
scanning = !scanning
update_icon()
to_chat(user, "<span class='notice'>[bicon(src)] You switch [scanning ? "on" : "off"] [src].</span>")
/obj/item/geiger_counter/afterattack(atom/target, mob/user)
. = ..()
if(user.a_intent == INTENT_HELP)
if(!emagged)
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='notice'>You scan [target]'s radiation levels with [src]...</span>")
addtimer(CALLBACK(src, .proc/scan, target, user), 20, TIMER_UNIQUE) // Let's not have spamming GetAllContents
else
user.visible_message("<span class='notice'>[user] scans [target] with [src].</span>", "<span class='danger'>You project [src]'s stored radiation into [target]!</span>")
target.rad_act(radiation_count)
radiation_count = 0
return TRUE
/obj/item/geiger_counter/proc/scan(atom/A, mob/user)
var/rad_strength = get_rad_contamination(A)
if(isliving(A))
var/mob/living/M = A
if(!M.radiation)
to_chat(user, "<span class='notice'>[bicon(src)] Radiation levels within normal boundaries.</span>")
else
to_chat(user, "<span class='boldannounce'>[bicon(src)] Subject is irradiated. Radiation levels: [M.radiation].</span>")
if(rad_strength)
to_chat(user, "<span class='boldannounce'>[bicon(src)] Target contains radioactive contamination. Radioactive strength: [rad_strength]</span>")
else
to_chat(user, "<span class='notice'>[bicon(src)] Target is free of radioactive contamination.</span>")
/obj/item/geiger_counter/attackby(obj/item/I, mob/user, params)
if(I.tool_behaviour == TOOL_SCREWDRIVER && emagged)
if(scanning)
to_chat(user, "<span class='warning'>Turn off [src] before you perform this action!</span>")
return FALSE
user.visible_message("<span class='notice'>[user] unscrews [src]'s maintenance panel and begins fiddling with its innards...</span>", "<span class='notice'>You begin resetting [src]...</span>")
if(!I.use_tool(src, user, 40, volume = 50))
return FALSE
user.visible_message("<span class='notice'>[user] refastens [src]'s maintenance panel!</span>", "<span class='notice'>You reset [src] to its factory settings!</span>")
emagged = FALSE
radiation_count = 0
update_icon()
return TRUE
else
return ..()
/obj/item/geiger_counter/AltClick(mob/living/user)
if(!istype(user) || !!user.Adjacent(src))
return ..()
if(!scanning)
to_chat(usr, "<span class='warning'>[src] must be on to reset its radiation level!</span>")
return
radiation_count = 0
to_chat(usr, "<span class='notice'>You flush [src]'s radiation counts, resetting it to normal.</span>")
update_icon()
/obj/item/geiger_counter/emag_act(mob/user)
if(emagged)
return
if(scanning)
to_chat(user, "<span class='warning'>Turn off [src] before you perform this action!</span>")
return
to_chat(user, "<span class='warning'>You override [src]'s radiation storing protocols. It will now generate small doses of radiation, and stored rads are now projected into creatures you scan.</span>")
emagged = TRUE
/obj/item/geiger_counter/cyborg
var/mob/listeningTo
/obj/item/geiger_counter/cyborg/equipped(mob/user)
. = ..()
if(listeningTo == user)
return
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
RegisterSignal(user, COMSIG_ATOM_RAD_ACT, .proc/redirect_rad_act)
listeningTo = user
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped()
. = ..()
if(listeningTo)
UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
#undef RAD_LEVEL_NORMAL
#undef RAD_LEVEL_MODERATE
#undef RAD_LEVEL_HIGH
#undef RAD_LEVEL_VERY_HIGH
#undef RAD_LEVEL_CRITICAL
@@ -10,7 +10,6 @@
var/icon_base = "defib"
var/cooldown = FALSE
var/charge_time = 100
var/emagged = FALSE
/obj/item/handheld_defibrillator/emag_act(mob/user)
if(!emagged)
@@ -52,7 +52,6 @@
origin_tech = "magnets=3;engineering=4"
force = 8
var/emagged = FALSE
var/max_uses = 20
var/uses = 10
// How much to increase per each glass?
@@ -8,7 +8,6 @@
flags = CONDUCT
var/spamcheck = 0
var/emagged = 0
var/insults = 0
var/span = ""
var/list/insultmsg = list("FUCK EVERYONE!", "I'M A TATER!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!")
@@ -5,7 +5,6 @@
item_state = "signaler"
var/code = "Beacon"
origin_tech = "bluespace=1"
var/emagged = 0
var/syndicate = 0
var/area_bypass = FALSE
var/cc_beacon = FALSE //set if allowed to teleport to even if on zlevel2
+23 -50
View File
@@ -12,39 +12,28 @@ REAGENT SCANNER
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
icon = 'icons/obj/device.dmi'
icon_state = "t-ray0"
var/on = 0
var/on = FALSE
slot_flags = SLOT_BELT
w_class = 2
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
materials = list(MAT_METAL=150)
origin_tech = "magnets=1;engineering=1"
var/scan_range = 1
var/pulse_duration = 10
/obj/item/t_scanner/longer_pulse
pulse_duration = 50
/obj/item/t_scanner/extended_range
scan_range = 3
/obj/item/t_scanner/extended_range/longer_pulse
scan_range = 3
pulse_duration = 50
/obj/item/t_scanner/Destroy()
if(on)
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/t_scanner/attack_self(mob/user)
/obj/item/t_scanner/proc/toggle_on()
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
icon_state = copytext_char(icon_state, 1, -1) + "[on]"
if(on)
START_PROCESSING(SSobj, src)
else
STOP_PROCESSING(SSobj, src)
/obj/item/t_scanner/attack_self(mob/user)
toggle_on()
/obj/item/t_scanner/process()
if(!on)
@@ -53,41 +42,25 @@ REAGENT SCANNER
scan()
/obj/item/t_scanner/proc/scan()
t_ray_scan(loc)
for(var/turf/T in range(scan_range, src.loc) )
if(!T.intact)
/proc/t_ray_scan(mob/viewer, flick_time = 8, distance = 3)
if(!ismob(viewer) || !viewer.client)
return
var/list/t_ray_images = list()
for(var/obj/O in orange(distance, viewer))
if(O.level != 1)
continue
for(var/obj/O in T.contents)
if(O.level != 1)
continue
if(O.invisibility == 101)
O.invisibility = 0
O.alpha = 128
spawn(pulse_duration)
if(O)
var/turf/U = O.loc
if(U && U.intact)
O.invisibility = 101
O.alpha = 255
for(var/mob/living/M in T.contents)
var/oldalpha = M.alpha
if(M.alpha < 255 && istype(M))
M.alpha = 255
spawn(10)
if(M)
M.alpha = oldalpha
var/mob/living/M = locate() in T
if(M && M.invisibility == 2)
M.invisibility = 0
spawn(2)
if(M)
M.invisibility = INVISIBILITY_LEVEL_TWO
if(O.invisibility == INVISIBILITY_MAXIMUM)
var/image/I = new(loc = get_turf(O))
var/mutable_appearance/MA = new(O)
MA.alpha = 128
MA.dir = O.dir
I.appearance = MA
t_ray_images += I
if(length(t_ray_images))
flick_overlay(t_ray_images, list(viewer.client), flick_time)
/proc/chemscan(mob/living/user, mob/living/M)
@@ -102,7 +102,7 @@ effective or pretty fucking useless.
if(M)
if(intensity >= 5)
M.apply_effect(round(intensity/1.5), PARALYZE)
M.apply_effect(intensity*10, IRRADIATE)
M.rad_act(intensity * 10)
else
to_chat(user, "<span class='warning'>The radioactive microlaser is still recharging.</span>")
@@ -8,7 +8,6 @@
flags = CONDUCT
var/spamcheck = 0
var/emagged = 0
/obj/item/hailer/attack_self(mob/living/carbon/user as mob)
if(spamcheck)
@@ -70,7 +70,7 @@
if(used)
return
if(istype(M,/mob/living))
M.apply_effect(rand(20 / (damage_coeff ** 2), 50 / (damage_coeff ** 2)), IRRADIATE, 0, 1)
M.apply_effect(rand(20 / (damage_coeff ** 2), 50 / (damage_coeff ** 2)), IRRADIATE)
var/mob/living/carbon/human/H
if(istype(M, /mob/living/carbon/human))
H = M
@@ -36,19 +36,19 @@
icon = 'icons/obj/grenade.dmi'
icon_state = "gluon"
item_state = "flashbang"
var/range = 4
var/rad_damage = 60
var/freeze_range = 4
var/rad_damage = 350
var/stamina_damage = 30
/obj/item/grenade/gluon/prime()
update_mob()
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
for(var/turf/T in view(range, loc))
radiation_pulse(src, rad_damage)
for(var/turf/T in view(freeze_range, loc))
if(isfloorturf(T))
var/turf/simulated/F = T
F.MakeSlippery(TURF_WET_PERMAFROST)
for(var/mob/living/carbon/L in T)
L.adjustStaminaLoss(stamina_damage)
L.apply_effect(rad_damage, IRRADIATE)
L.adjust_bodytemperature(-230)
qdel(src)
@@ -315,7 +315,7 @@
/obj/item/storage/backpack/satchel_flat/hide(var/intact)
if(intact)
invisibility = 101
invisibility = INVISIBILITY_MAXIMUM
anchored = 1 //otherwise you can start pulling, cover it, and drag around an invisible backpack.
icon_state = "[initial(icon_state)]2"
else
@@ -58,6 +58,7 @@
/obj/item/stack/cable_coil,
/obj/item/t_scanner,
/obj/item/analyzer,
/obj/item/geiger_counter,
/obj/item/extinguisher/mini,
/obj/item/holosign_creator)
@@ -135,7 +136,8 @@
/obj/item/sensor_device,
/obj/item/wrench/medical,
/obj/item/handheld_defibrillator,
/obj/item/reagent_containers/applicator
/obj/item/reagent_containers/applicator,
/obj/item/geiger_counter
)
/obj/item/storage/belt/medical/surgery
@@ -21,7 +21,6 @@
var/l_set = 0
var/l_setshort = 0
var/l_hacking = 0
var/emagged = 0
var/open = 0
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL