Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ported radiation collector arrays from baystation12 #19174

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aurorastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -3151,6 +3151,7 @@
#include "code\modules\power\breaker_box.dm"
#include "code\modules\power\cable.dm"
#include "code\modules\power\cell.dm"
#include "code\modules\power\collector.dm"
#include "code\modules\power\crystal_agitator.dm"
#include "code\modules\power\fractal_reactor.dm"
#include "code\modules\power\generator.dm"
Expand Down
255 changes: 255 additions & 0 deletions code/modules/power/collector.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/// A global list of all radiation collectors.
var/global/list/rad_collectors = list()

/obj/machinery/power/rad_collector
name = "radiation collector array"
desc = "A device which uses radiation and phoron to produce power."
icon = 'icons/obj/machinery/rad_collector.dmi'
icon_state = "ca"
anchored = FALSE
density = TRUE
req_access = list(ACCESS_ENGINE_EQUIP)
/// The tank of phoron currently attached to the radiation collector
var/obj/item/tank/phoron/loaded_tank = null

/// Current health of the collector. Should be replaced with global health ideally.
var/health = 100
/// The maximum safe temperature that the radiation collector can handle
var/max_safe_temp = 1000 + T0C
/// A boolean determining whether the collector has melted or not.
var/melted = FALSE

/// Internal variable storing last power generation amount
var/last_power = 0
/// Internal variable storing last power generation amount. Duplicate variable to account for the SM being processed first
var/last_power_new = 0
/// Whether the radiation collector is active or not.
var/active = FALSE
/// Whether the radiation collector's controls are locked or not.
var/locked = FALSE
/// Determines the ratio of default draining of phoron while radiation collector is active
var/drainratio = 1

/// Internal variable storing last radiation amount measured
var/last_rads
/// Radiation collector will reach max power output at this value, and break at twice this value
var/max_rads = 250
/// Maximum power output for this radiation collector.
var/max_power = 5e5
/// Pulse coefficient, for multiplying power output by radiation input
var/pulse_coeff = 20
/// Internal variable storing last time an alert message was outputted
var/end_time = 0
/// How long to wait between alert messages, if radiation input exceeds safe levels
var/alert_delay = 10 SECONDS

/obj/machinery/power/rad_collector/Initialize()
. = ..()
rad_collectors += src

/obj/machinery/power/rad_collector/Destroy()
rad_collectors -= src
return ..()

/obj/machinery/power/rad_collector/process(seconds_per_tick)
if((stat && BROKEN) || melted)
return
var/turf/T = get_turf(src)
if(T)
var/datum/gas_mixture/our_turfs_air = T.return_air()
if(our_turfs_air.temperature > max_safe_temp)
health -= ((our_turfs_air.temperature - max_safe_temp) / 10) * seconds_per_tick
if(health <= 0)
collector_break()

//so that we don't zero out the meter if the SM is processed first.
last_power = last_power_new
last_power_new = 0
last_rads = SSradiation.get_rads_at_turf(get_turf(src))
if(loaded_tank && active)
if(last_rads > max_rads*2)
collector_break()
if(last_rads)
if(last_rads > max_rads)
if(world.time > end_time)
end_time = world.time + alert_delay
visible_message("[icon2html(src, viewers(get_turf(src)))] \the [src] beeps loudly as the radiation reaches dangerous levels, indicating imminent damage.")
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
receive_pulse(12.5*(last_rads/max_rads)/(0.3+(last_rads/max_rads)) * seconds_per_tick)

if(loaded_tank)
if(loaded_tank.air_contents.gas[GAS_PHORON] == 0)
investigate_log("[SPAN_COLOR("red", "out of fuel")].","singulo")
eject()
else
loaded_tank.air_contents.adjust_gas(GAS_PHORON, (-0.01*drainratio*min(last_rads,max_rads)/max_rads) * seconds_per_tick) //fuel cost increases linearly with incoming radiation


/obj/machinery/power/rad_collector/CanUseTopic(mob/user)
if(!anchored)
return STATUS_CLOSE
return ..()


/obj/machinery/power/rad_collector/attack_hand(mob/user)
if(!CanInteract(user, GLOB.physical_state))
return FALSE
. = TRUE
if((stat & BROKEN) || melted)
to_chat(user, SPAN_WARNING("The [src] is completely destroyed!"))
if(!src.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 ? SPAN_COLOR("green", "on") : SPAN_COLOR("red", "off")] by [user.key]. [loaded_tank ? "Fuel: [round(loaded_tank.air_contents.gas[GAS_PHORON]/0.29)]%" : SPAN_COLOR("red", "It is empty")].","singulo")
else
to_chat(user, SPAN_WARNING("The controls are locked!"))
..()

/obj/machinery/power/rad_collector/attackby(obj/item/attacking_item, mob/user)
if(istype(attacking_item, /obj/item/tank/phoron))
if(!anchored)
to_chat(user, SPAN_WARNING("The [src] needs to be secured to the floor first."))
return TRUE
if(loaded_tank)
to_chat(user, SPAN_WARNING("There's already a phoron tank loaded."))
return TRUE
if(!user.unEquip(attacking_item, src))
return TRUE
loaded_tank = attacking_item
update_icon()
return TRUE

if(attacking_item.iscrowbar())
if(loaded_tank && !locked)
eject()
return TRUE

if(attacking_item.iswrench())
if(loaded_tank)
to_chat(user, SPAN_NOTICE("Remove the phoron tank first."))
return TRUE
for(var/obj/machinery/power/rad_collector/R in get_turf(src))
if(R != src)
to_chat(user, SPAN_WARNING("You cannot install more than one collector on the same spot."))
return TRUE
playsound(src.loc, 'sound/items/Ratchet.ogg', 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")
if(anchored && !(stat & BROKEN))
connect_to_network()
else
disconnect_from_network()
return TRUE

if(istype(attacking_item, /obj/item/card/id)||istype(attacking_item, /obj/item/modular_computer))
if (allowed(user))
if(active)
locked = !locked
to_chat(user, "The controls are now [locked ? "locked." : "unlocked."]")
else
locked = FALSE //just in case it somehow gets locked while the collector is active
to_chat(user, SPAN_WARNING("The controls can only be locked when the [src] is active"))
else
to_chat(user, SPAN_ALERT("Access denied!"))
return TRUE

return ..()

/// Handles dealing with a breaking radiation collector
/obj/machinery/power/rad_collector/proc/collector_break()
if(loaded_tank && loaded_tank.air_contents)
var/turf/T = get_turf(src)
if(T)
T.assume_air(loaded_tank.air_contents)
audible_message(SPAN_DANGER("\The [loaded_tank] detonates, sending shrapnel flying!"))
explosion(T, -1, -1, 0)
QDEL_NULL(loaded_tank)
disconnect_from_network()
stat |= BROKEN
melted = TRUE
anchored = FALSE
active = FALSE
desc += " This one is destroyed beyond repair."
update_icon()

/obj/machinery/power/rad_collector/get_examine_text(user, distance, is_adjacent, infix, suffix)
. = ..()
if (..(user, 3))
. += "The meter indicates that \the [src] is collecting [last_power] W."

/obj/machinery/power/rad_collector/return_air()
if(loaded_tank)
return loaded_tank.return_air()

/obj/machinery/power/rad_collector/ex_act(severity)
switch(severity)
if(2, 3)
eject()
return ..()

/// Ejects the stored phoron tank
/obj/machinery/power/rad_collector/proc/eject()
locked = 0
var/obj/item/tank/phoron/Z = src.loaded_tank
if (!Z)
return
Z.dropInto(loc)
Z.reset_plane_and_layer()
src.loaded_tank = null
if(active)
toggle_power()
else
update_icon()

/**
* Handles the generation of power for the radiation collector
*
* Arguments:
* - pulse_strength: The strength of the pulse to calculate into power output
*/
/obj/machinery/power/rad_collector/proc/receive_pulse(pulse_strength)
Generalcamo marked this conversation as resolved.
Show resolved Hide resolved
if(loaded_tank && active)
var/power_produced = 0
power_produced = min(100*loaded_tank.air_contents.gas[GAS_PHORON]*pulse_strength*pulse_coeff,max_power)
add_avail(power_produced)
last_power_new = power_produced
return
return


/obj/machinery/power/rad_collector/update_icon()
if(melted)
icon_state = "ca_melt"
else if(active)
icon_state = "ca_on"
else
icon_state = "ca"

ClearOverlays()
underlays.Cut()

if(loaded_tank)
AddOverlays(image(icon, "ptank"))
AddOverlays(emissive_appearance(icon, "ca_filling"))
underlays += image(icon, "ca_filling")
underlays += image(icon, "ca_inside")
if(!operable())
return
if(active)
var/rad_power = round(min(100 * last_rads / max_rads, 100), 20)
AddOverlays(emissive_appearance(icon, "rads_[rad_power]"))
AddOverlays(image(icon, "rads_[rad_power]"))
AddOverlays(emissive_appearance(icon, "on"))
AddOverlays(image(icon, "on"))


/obj/machinery/power/rad_collector/toggle_power()
active = !active
if(active)
flick("ca_active", src)
else
flick("ca_deactive", src)
update_icon()
58 changes: 58 additions & 0 deletions html/changelogs/GeneralCamo - Radiation Collectors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
################################
# 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
# - (fixes bugs)
# wip
# - (work in progress)
# qol
# - (quality of life)
# soundadd
# - (adds a sound)
# sounddel
# - (removes a sound)
# rscadd
# - (adds a feature)
# rscdel
# - (removes a feature)
# imageadd
# - (adds an image or sprite)
# imagedel
# - (removes an image or sprite)
# spellcheck
# - (fixes spelling or grammar)
# experiment
# - (experimental change)
# balance
# - (balance changes)
# code_imp
# - (misc internal code change)
# refactor
# - (refactors code)
# config
# - (makes a change to the config files)
# admin
# - (makes changes to administrator tools)
# server
# - (miscellaneous changes to server)
#################################

# Your name.
author: GeneralCamo

# 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, this gets changed to [] after reading. Just remove the brackets when you add new shit.
# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Added radiation collectors, which use phoron to generate power from radiation."
Binary file added icons/obj/machinery/rad_collector.dmi
Binary file not shown.
Loading