mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-28 18:32:04 +00:00
The NGCR: Nuclear Fission Reactor (#30493)
* coefficient balancing * damage and meltdowns * meltdown stuff * alert stuff * lots of work - whew * some enrichment code * rod encrichmnt * working on enrichment * more fabrication * rod fab * start to the nuke * overload sprites * overload code work * some overload tweaking * small tweak * coolant ejections and QOL things * overheat events + ripley gripper * rebase + venting code * save before rebase * some pre-work for rods * finishing the base rods * fixed my dme * de linting * tiny lint fix * more lint fixes * linting * linting * linting * linting * linting * temp delint * temp delint * undo TM stuff + minor fix * didnt save * some fixes * fixes * fixes and engine repair * fixed broken durability decay * LOTS of things * tgui * lint * linter * linter * minor shit * Update boxstation.dmm * major refactors and fixes * saved this * critical testing tweaks and fixes * fixes and tweaks * smithing start * forgot to save * craftables + grill start * saved * fix * more grill work * Update tgui.bundle.js * linter * linter * fixes * rod fabricator initial * cooking work * push * soundwork * sound work tweak * comments + sounds + toxins gen rework * lots of work * sprite stuff * deconflicting * delinting * bundle rebuild * prettier * feex * fuck you OD * who asked? * update to tgui * another edit to tgui * finish tgui * remove debug metadata button * rod tweaks for tgui * Update code/datums/uplink_items/uplink_traitor.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/game/mecha/equipment/tools/work_tools.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/game/mecha/equipment/tools/work_tools.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/game/objects/items/robot/cyborg_gripper.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/parrot.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/parrot.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/parrot.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/mob/living/simple_animal/parrot.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_misc.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_misc.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_misc.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/reactor.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/reactor.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/reactor.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/smithing/components/misc_components.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update tgui/packages/tgui/interfaces/NuclearRodFabricator.jsx Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Spans * tgui build * rod redo * improve tgui for fabricator * sprites and centrifuge/fab work * tgui update * spritework * cyberiad + hydrogen conversion * kerberos + counter * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * sprite + fab tweak * tgui bundle * lintering * bugfixing * linting * linting * event tweak * add missing gases to fission monitor * issue fixing * sprite/overlay fixes * mapping * stations again * space lattice * tine tweak * linter * no rod alerts * buttons * loose wire * make it so you can interact through rod casings and the uhh big thing in the center, what's that called again * fixes * door fix * many bug fixes + crates * fab ghost touch * water convert + maint sprite + fixes * pack changes + neighbor fix * doors rename * didnt save * hydrogen fix * map tweaks * repair fixes + corium LETHALITY * upped broken rad damage * pipe rename + overload icons * more roundstart moderators * rod tree tweaks * tweaks * pack and enrichment fixes * misc tweaks and fixes * fixes: Density, circuits, coolant offline negation * Apply suggestions from code review Co-authored-by: warriorstar-orion <orion@snowfrost.garden> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * review changes * linter + fix * reviews and fixes * LOTS of tweaks and changes * supermatter kit * spacematter balance * tgui * fixes and tweaks * didnt save this * mapping + smith fix * cargo rods arnt radioactive til opened * Apply suggestions from code review Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * review items * fixes * linters * moving components out of nullspace * examine fix * Update tgui.bundle.js * explosion nerf and minor fix * Apply suggestions from code review Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * reviews * map fix + ripley rad immune * Apply suggestions from code review Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * review * fix chamber examine * tweaks + rod fab disk drop * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * review changes * Update code/modules/power/engines/fission/nuclear_rods.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * fixes * tgui bundle * small rod tweaks * Update code/game/machinery/computer/buildandrepair.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/smithing/components/reactor_components.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/reactor_machines.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/power/engines/fission/reactor_machines.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * reviews * Update code/modules/power/engines/fission/reactor_machines.dm Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com> --------- Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> Signed-off-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Paul <pmerkamp@gmail.com> Co-authored-by: Pooble <90473506+poobsie@users.noreply.github.com> Co-authored-by: warriorstar-orion <orion@snowfrost.garden> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
This commit is contained in:
@@ -79,6 +79,7 @@
|
||||
<BR>
|
||||
<b>Reinforce Station</b><BR>
|
||||
<A href='byond://?src=[UID()];secretsfun=gammashuttle'>Move the Gamma Armory</A>
|
||||
<A href='byond://?src=[UID()];secretsfun=nuclear_overload'>Disable Fission Reactor Safeties</A>
|
||||
<BR>
|
||||
</center>"}
|
||||
|
||||
|
||||
@@ -3341,6 +3341,15 @@
|
||||
log_admin("[key_name(usr)] moved the gamma armory")
|
||||
move_gamma_ship()
|
||||
|
||||
if("nuclear_overload")
|
||||
SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Disable Fission Reactor Safeties")
|
||||
message_admins("[key_name_admin(usr)] disabled reactor safeties")
|
||||
log_admin("[key_name(usr)] disabled reactor safeties")
|
||||
if(GLOB.main_fission_reactor)
|
||||
INVOKE_ASYNC(GLOB.main_fission_reactor, TYPE_PROC_REF(/obj/machinery/atmospherics/fission_reactor/, overload_reactor))
|
||||
else
|
||||
log_admin("An admin attempted to override fission reactor safeties, but no reactor was found!")
|
||||
|
||||
if(usr)
|
||||
log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]")
|
||||
if(ok)
|
||||
|
||||
@@ -105,3 +105,19 @@ USER_CONTEXT_MENU(admin_freeze, R_ADMIN, "\[Admin\] Freeze", atom/movable/M)
|
||||
cut_overlay(freeze_overlay)
|
||||
message_admins(SPAN_NOTICE("[key_name_admin(admin)] [processes ? "unfroze" : "froze"] a supermatter crystal"))
|
||||
log_admin("[key_name(admin)] [processes ? "unfroze" : "froze"] a supermatter crystal")
|
||||
|
||||
/obj/machinery/atmospherics/fission_reactor/admin_Freeze(client/admin)
|
||||
var/obj/effect/overlay/adminoverlay/freeze_overlay = new
|
||||
freeze_overlay.pixel_x = 16
|
||||
if(!admin_intervention)
|
||||
radio.autosay("Alert: Unknown intervention is interfering in reactor core operations. It is not progressing in local timespace.", name, "Engineering")
|
||||
GLOB.frozen_atom_list += src
|
||||
admin_intervention = TRUE
|
||||
add_overlay(freeze_overlay)
|
||||
else
|
||||
radio.autosay("Alert: Unknown intervention has ceased within the reactor core. It has returned to the regular flow of time.", name, "Engineering")
|
||||
GLOB.frozen_atom_list -= src
|
||||
admin_intervention = FALSE
|
||||
cut_overlay(freeze_overlay)
|
||||
message_admins(SPAN_NOTICE("[key_name_admin(admin)] [!admin_intervention ? "unfroze" : "froze"] the NGCR Reactor"))
|
||||
log_admin("[key_name(admin)] [!admin_intervention ? "unfroze" : "froze"] the NGCR Reactor")
|
||||
|
||||
@@ -110,10 +110,9 @@ RESTRICT_TYPE(/obj/machinery/cooking)
|
||||
return
|
||||
var/datum/cooking_surface/surface = surfaces[surface_idx]
|
||||
|
||||
var/list/surface_options = list(
|
||||
RADIAL_ACTION_SET_ALARM = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_setalarm"),
|
||||
RADIAL_ACTION_ON_OFF = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_onoff"),
|
||||
)
|
||||
var/list/surface_options = list(RADIAL_ACTION_SET_ALARM = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_setalarm"))
|
||||
if(surface.allow_toggling)
|
||||
surface_options[RADIAL_ACTION_ON_OFF] = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_onoff")
|
||||
if(surface.allow_temp_change)
|
||||
surface_options[RADIAL_ACTION_SET_TEMPERATURE] = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_settemp")
|
||||
var/option_choice = show_radial_menu(user, src, surface_options, require_near = TRUE)
|
||||
|
||||
@@ -15,6 +15,7 @@ RESTRICT_TYPE(/datum/cooking_surface)
|
||||
var/on = FALSE
|
||||
var/prob_quality_decrease = 0
|
||||
var/allow_temp_change = TRUE
|
||||
var/allow_toggling = TRUE
|
||||
VAR_PRIVATE/burn_callback
|
||||
VAR_PRIVATE/fire_callback
|
||||
VAR_PRIVATE/alarm_callback
|
||||
|
||||
@@ -60,7 +60,8 @@
|
||||
|
||||
/obj/machinery/cooking/grill/examine(mob/user)
|
||||
. = ..()
|
||||
. += SPAN_NOTICE("It contains [round(stored_wood, 0.01)]/[wood_maximum] units of charcoal.")
|
||||
if(wood_maximum != INFINITY)
|
||||
. += SPAN_NOTICE("It contains [round(stored_wood, 0.01)]/[wood_maximum] units of charcoal.")
|
||||
. += SPAN_NOTICE("<b>Ctrl-Click</b> on a surface to set its timer, temperature, and toggle it on or off.")
|
||||
|
||||
/obj/machinery/cooking/grill/process()
|
||||
@@ -207,3 +208,65 @@
|
||||
surface.container = new /obj/item/reagent_containers/cooking/grill_grate(src)
|
||||
stored_wood = 30
|
||||
update_appearance()
|
||||
|
||||
/obj/machinery/cooking/grill/loaded/reactor
|
||||
icon_state = "blank"
|
||||
wood_maximum = INFINITY
|
||||
active_power_consumption = 0
|
||||
idle_power_consumption = 0
|
||||
flags = INDESTRUCTIBLE
|
||||
/// The reactor that the grill is attached to
|
||||
var/obj/machinery/atmospherics/fission_reactor/linked_reactor
|
||||
|
||||
/obj/machinery/cooking/grill/loaded/reactor/Initialize(mapload)
|
||||
. = ..()
|
||||
stored_wood = INFINITY
|
||||
var/datum/cooking_surface/surface = surfaces[1]
|
||||
surface.container.pixel_x = -16
|
||||
surface.container.pixel_y = 0
|
||||
surface.container.transform = matrix().Scale(1.35, 1.35)
|
||||
surface.allow_toggling = FALSE
|
||||
surface = surfaces[2]
|
||||
surface.container.pixel_x = 16
|
||||
surface.container.pixel_y = 0
|
||||
surface.container.transform = matrix().Scale(1.35, 1.35)
|
||||
surface.allow_toggling = FALSE
|
||||
|
||||
/obj/machinery/cooking/grill/loaded/reactor/attack_hand(mob/user, params)
|
||||
var/mob/living/carbon/human/burn_victim = user
|
||||
if(istype(burn_victim) && !burn_victim.gloves)
|
||||
var/which_hand = "l_hand"
|
||||
if(!burn_victim.hand)
|
||||
which_hand = "r_hand"
|
||||
burn_victim.adjustFireLossByPart(5, which_hand)
|
||||
to_chat(burn_victim, SPAN_WARNING("Your hand is burned as you try to remove the grill grate, but its stuck firmly!"))
|
||||
else if(istype(burn_victim))
|
||||
to_chat(burn_victim, SPAN_WARNING("You try to remove the grill grate, but its stuck firmly!"))
|
||||
|
||||
// We dont want most of the normal proc for shutting off.
|
||||
/obj/machinery/cooking/grill/loaded/reactor/ignite()
|
||||
new /obj/effect/fire(loc, T0C + 300, (roll("2d10+15") SECONDS), 1)
|
||||
|
||||
// Chance of spreading
|
||||
var/spread_count = rand(1, 3)
|
||||
if(prob(30))
|
||||
var/list/dirs = GLOB.alldirs.Copy()
|
||||
while(spread_count && length(dirs))
|
||||
var/direction = pick_n_take(dirs)
|
||||
var/turf/T = get_step(src, direction)
|
||||
if(T.density)
|
||||
continue
|
||||
new /obj/effect/fire(T, T0C + 300, (roll("2d10+15") SECONDS), 1)
|
||||
spread_count--
|
||||
|
||||
// we want our icons in a specific spot
|
||||
/obj/machinery/cooking/grill/loaded/reactor/update_surface_icon(surface_idx)
|
||||
var/datum/cooking_surface/surface = surfaces[surface_idx]
|
||||
|
||||
if(!surface.container)
|
||||
return
|
||||
|
||||
add_to_visible(surface.container, surface_idx)
|
||||
|
||||
/obj/machinery/cooking/grill/loaded/reactor/update_overlays()
|
||||
return
|
||||
|
||||
@@ -733,9 +733,28 @@
|
||||
"TOXINS!",
|
||||
"ONI SOMA!",
|
||||
"GOLDEN BLAST",
|
||||
"Is there supposed to be this much plasma in the chamber??",,
|
||||
"Is there supposed to be this much plasma in the chamber??",
|
||||
"Why are there so many borgs?",
|
||||
"Why're your eyes glowing red?"
|
||||
"Why're your eyes glowing red?",
|
||||
"Opening the reactor vent is how it gets gas, right?",
|
||||
"Let's fill the reactor with supermatter rods!",
|
||||
"Think we could weaponize ejected coolant rods?",
|
||||
"WHO KEEPS LEAVING THE FUEL RODS OUT",
|
||||
"Why do we need coolant rods if we use gas?",
|
||||
"Wait, why isn't the reactor integrity going up?",
|
||||
"When did engineering get a pool!?",
|
||||
"Does anyone else taste copper?",
|
||||
"10 sieverts isn't a harmful amount of radiation, is it?",
|
||||
"HELP! THE CHEF IS GRILLING ME ON THE NGCR!",
|
||||
"Replace the spent fuel rods you lazy bums!",
|
||||
"There is a xenomorph nesting on the reactor!",
|
||||
"Why is there a Ripley pulling out the coolant rods?",
|
||||
"Atmospheric Technicians are the NGCR's favorite moderators",
|
||||
"Who let the clown touch the control rods?",
|
||||
"Which of you chucklefucks brought a fuel rod to medbay?",
|
||||
"A coolant rod just flew into the captain!",
|
||||
"The reactor is going supercritical!",
|
||||
"Danger! Reactor core chamber meltdown in progress! Integrity: 79.47%"
|
||||
)
|
||||
unique_pet = TRUE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
103
code/modules/power/engines/fission/datum_nuclear_rods.dm
Normal file
103
code/modules/power/engines/fission/datum_nuclear_rods.dm
Normal file
@@ -0,0 +1,103 @@
|
||||
/datum/nuclear_rod_design
|
||||
var/type_path
|
||||
var/category = "Unknown"
|
||||
var/list/metadata
|
||||
|
||||
/datum/nuclear_rod_design/proc/build_metadata_list(path)
|
||||
metadata = list()
|
||||
type_path = path
|
||||
|
||||
var/obj/item/nuclear_rod/T = path
|
||||
|
||||
metadata["name"] = initial(T.name)
|
||||
metadata["desc"] = initial(T.desc)
|
||||
metadata["icon"] = initial(T.icon)
|
||||
metadata["icon_state"] = initial(T.icon_state)
|
||||
metadata["type_path"] = path
|
||||
|
||||
metadata["max_durability"] = initial(T.max_durability)
|
||||
metadata["degradation_speed"] = initial(T.degradation_speed)
|
||||
metadata["heat_amount"] = initial(T.heat_amount)
|
||||
metadata["heat_amp_mod"] = initial(T.heat_amp_mod)
|
||||
metadata["power_amount"] = initial(T.power_amount)
|
||||
metadata["power_amp_mod"] = initial(T.power_amp_mod)
|
||||
metadata["alpha_rad"] = initial(T.alpha_rad)
|
||||
metadata["beta_rad"] = initial(T.beta_rad)
|
||||
metadata["gamma_rad"] = initial(T.gamma_rad)
|
||||
metadata["minimum_temp_modifier"] = initial(T.minimum_temp_modifier)
|
||||
metadata["upgrade_required"] = initial(T.upgrade_required)
|
||||
|
||||
metadata["required_object"] = initial(T.required_object)
|
||||
|
||||
// Temp object lets us read in materials and adjacent requirements because you can't initial() a list
|
||||
var/obj/item/nuclear_rod/temp_rod = new path()
|
||||
var/list/raw_materials = temp_rod.materials
|
||||
var/list/requirements = temp_rod.adjacent_requirements
|
||||
qdel(temp_rod)
|
||||
|
||||
if(raw_materials && length(raw_materials))
|
||||
var/list/formatted_materials = list()
|
||||
for(var/mat_id in raw_materials)
|
||||
var/display_name = CallMaterialName(mat_id)
|
||||
formatted_materials[display_name] = raw_materials[mat_id]
|
||||
metadata["materials"] = formatted_materials
|
||||
else
|
||||
metadata["materials"] = list()
|
||||
|
||||
if(ispath(path, /obj/item/nuclear_rod/fuel))
|
||||
var/obj/item/nuclear_rod/fuel/F = path
|
||||
metadata["craftable"] = initial(F.craftable)
|
||||
metadata["enrichment_cycles"] = initial(F.enrichment_cycles)
|
||||
metadata["power_enrich_threshold"] = initial(F.power_enrich_threshold)
|
||||
metadata["heat_enrich_threshold"] = initial(F.heat_enrich_threshold)
|
||||
|
||||
// Get enrichment result names
|
||||
if(initial(F.power_enrich_result))
|
||||
var/obj/item/nuclear_rod/power_result = initial(F.power_enrich_result)
|
||||
metadata["power_enrichment"] = initial(power_result.name)
|
||||
metadata["power_enrichment_requirement"] = initial(F.power_enrich_threshold)
|
||||
else
|
||||
metadata["power_enrichment"] = null
|
||||
metadata["power_enrichment_requirement"] = null
|
||||
|
||||
if(initial(F.heat_enrich_result))
|
||||
var/obj/item/nuclear_rod/heat_result = initial(F.heat_enrich_result)
|
||||
metadata["heat_enrichment"] = initial(heat_result.name)
|
||||
metadata["heat_enrichment_requirement"] = initial(F.heat_enrich_threshold)
|
||||
else
|
||||
metadata["heat_enrichment"] = null
|
||||
metadata["heat_enrichment_requirement"] = null
|
||||
else if(ispath(path, /obj/item/nuclear_rod/moderator))
|
||||
var/obj/item/nuclear_rod/moderator/M = path
|
||||
metadata["craftable"] = initial(M.craftable)
|
||||
else if(ispath(path, /obj/item/nuclear_rod/coolant))
|
||||
var/obj/item/nuclear_rod/coolant/C = path
|
||||
metadata["craftable"] = initial(C.craftable)
|
||||
else
|
||||
metadata["craftable"] = FALSE
|
||||
|
||||
if(requirements && length(requirements))
|
||||
var/list/temp_reqs = list()
|
||||
var/list/req_counts = list()
|
||||
|
||||
// Count occurrences of each requirement type
|
||||
for(var/req_path in requirements)
|
||||
var/obj/item/nuclear_rod/req = req_path
|
||||
var/req_name = initial(req.name)
|
||||
if(req_counts[req_name])
|
||||
req_counts[req_name]++
|
||||
else
|
||||
req_counts[req_name] = 1
|
||||
|
||||
// Format the requirements with counts
|
||||
for(var/req_name in req_counts)
|
||||
var/count = req_counts[req_name]
|
||||
temp_reqs += "[count]x [req_name]"
|
||||
|
||||
metadata["neighbor_requirements"] = temp_reqs
|
||||
metadata["adjacent_requirements_display"] = english_list(temp_reqs, and_text = ", ")
|
||||
else
|
||||
metadata["neighbor_requirements"] = list()
|
||||
metadata["adjacent_requirements_display"] = "None"
|
||||
|
||||
return TRUE
|
||||
140
code/modules/power/engines/fission/gas_node.dm
Normal file
140
code/modules/power/engines/fission/gas_node.dm
Normal file
@@ -0,0 +1,140 @@
|
||||
#define MINIMUM_MOLES 3 //! the minimum amount of moles we transfer, regardless of pressure on the other side.
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node
|
||||
name = "reactor gas intake"
|
||||
desc = "A sturdy-looking gas inlet that injects gas into the reactor."
|
||||
icon = 'icons/obj/fission/reactor_machines.dmi'
|
||||
icon_state = "gas_node"
|
||||
layer = GAS_PIPE_VISIBLE_LAYER
|
||||
max_integrity = 2000
|
||||
target_pressure = 100000 // Maximum pressure in KPA
|
||||
flags_2 = NO_MALF_EFFECT_2
|
||||
|
||||
/// Hold which reactor the intake is connected to.
|
||||
var/obj/machinery/atmospherics/fission_reactor/linked_reactor
|
||||
/// Is this vent taking air in or out. TRUE by default.
|
||||
var/intake_vent = TRUE
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/output
|
||||
name = "Reactor Gas Extractor"
|
||||
intake_vent = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/machine/reactor_gas_node(src)
|
||||
component_parts += new /obj/item/stack/sheet/metal(src, 2)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 2)
|
||||
initialize_directions = dir
|
||||
RefreshParts()
|
||||
update_icon()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Needs lateload to prevent reactor not being initialized yet and thus not able to set the link.
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/LateInitialize()
|
||||
. = ..()
|
||||
form_link(TRUE)
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/examine(mob/user)
|
||||
. = ..()
|
||||
. += SPAN_NOTICE("A wrench can be used to alter the direction of the node.")
|
||||
. += SPAN_NOTICE("Gas nodes will only link with reactors when facing a reactor from the side opposite of the inlet pipe.")
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/process_atmos()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
if(!linked_reactor)
|
||||
return FALSE
|
||||
if(linked_reactor.admin_intervention)
|
||||
return FALSE
|
||||
if(linked_reactor.safety_override) // We dont want to cool down an intentional runaway reactor
|
||||
return FALSE
|
||||
var/datum/gas_mixture/network1
|
||||
var/datum/gas_mixture/network2
|
||||
|
||||
if(intake_vent)
|
||||
network1 = linked_reactor.air_contents
|
||||
network2 = air_contents
|
||||
else
|
||||
network1 = air_contents
|
||||
network2 = linked_reactor.air_contents
|
||||
|
||||
if(!network1 || !network2)
|
||||
return FALSE
|
||||
|
||||
// This is basically passive gate code
|
||||
var/output_starting_pressure = network1.return_pressure()
|
||||
var/input_starting_pressure = network2.return_pressure()
|
||||
|
||||
// Calculate necessary moles to transfer using PV = nRT
|
||||
if((network2.total_moles() > 0) && (network2.temperature() > 0))
|
||||
var/pressure_delta = min(target_pressure - output_starting_pressure, (input_starting_pressure - output_starting_pressure) / 2)
|
||||
if(intake_vent)
|
||||
pressure_delta = max(pressure_delta, MINIMUM_MOLES) // Always work at least a little bit when inputting gas
|
||||
var/transfer_moles = pressure_delta * network1.volume / (network2.temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
// Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = network2.remove(transfer_moles)
|
||||
network1.merge(removed)
|
||||
|
||||
parent.update = TRUE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/screwdriver_act(mob/living/user, obj/item/I)
|
||||
default_deconstruction_screwdriver(user, icon_state, icon_state, I)
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/crowbar_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, SPAN_INFORMATION("You begin to pry out the internal piping..."))
|
||||
if(I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume))
|
||||
default_deconstruction_crowbar(user, I)
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/wrench_act(mob/user, obj/item/I)
|
||||
var/list/choices = list("West" = WEST, "East" = EAST, "South" = SOUTH, "North" = NORTH)
|
||||
var/selected = tgui_input_list(user, "Select a direction for the connector.", "Connector Direction", choices)
|
||||
if(!selected)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(!I.use_tool(src, user, 3 SECONDS, volume = I.tool_volume))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(!Adjacent(user))
|
||||
to_chat(user, SPAN_WARNING("You moved away before construction was finished!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
dir = choices[selected]
|
||||
initialize_directions = dir
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
node = target
|
||||
break
|
||||
form_link(FALSE)
|
||||
initialize_atmos_network()
|
||||
update_icon()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/proc/form_link(silent = FALSE)
|
||||
linked_reactor = null
|
||||
var/turf/T = get_step(src, REVERSE_DIR(dir))
|
||||
for(var/obj/machinery/atmospherics/fission_reactor/reactor in T)
|
||||
linked_reactor = reactor
|
||||
for(var/obj/structure/filler/filler in T)
|
||||
if(istype(filler.parent, /obj/machinery/atmospherics/fission_reactor))
|
||||
linked_reactor = filler.parent
|
||||
if(silent)
|
||||
return
|
||||
if(!linked_reactor)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
audible_message(SPAN_INFO("The gas node buzzes as it fails to connect to a reactor."))
|
||||
else
|
||||
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
|
||||
audible_message(SPAN_INFO("The gas node pings as it connects to the reactor."))
|
||||
|
||||
/obj/machinery/atmospherics/unary/reactor_gas_node/multitool_act(mob/living/user, obj/item/I)
|
||||
to_chat(user, SPAN_INFORMATION("You begin to reverse the gas flow direction..."))
|
||||
if(do_after_once(user, 1 SECONDS, TRUE, src, allow_moving = FALSE))
|
||||
intake_vent = !intake_vent
|
||||
if(intake_vent)
|
||||
name = "Reactor Gas Intake"
|
||||
else
|
||||
name = "Reactor Gas Extractor"
|
||||
return ..()
|
||||
|
||||
#undef MINIMUM_MOLES
|
||||
398
code/modules/power/engines/fission/nuclear_misc.dm
Normal file
398
code/modules/power/engines/fission/nuclear_misc.dm
Normal file
@@ -0,0 +1,398 @@
|
||||
// MARK: Reactor Power Output
|
||||
|
||||
/obj/machinery/power/reactor_power
|
||||
name = "reactor output terminal"
|
||||
desc = "A bundle of heavy watt power cables for managing power output from the reactor."
|
||||
icon_state = "term"
|
||||
plane = FLOOR_PLANE
|
||||
layer = WIRE_TERMINAL_LAYER // A bit above wires
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
var/obj/machinery/atmospherics/fission_reactor/linked_reactor
|
||||
|
||||
/obj/machinery/power/reactor_power/Initialize(mapload)
|
||||
. = ..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Needs lateload to prevent reactor not being initialized yet and thus not able to set the link.
|
||||
/obj/machinery/power/reactor_power/LateInitialize()
|
||||
. = ..()
|
||||
linked_reactor = GLOB.main_fission_reactor
|
||||
|
||||
/obj/machinery/power/reactor_power/process()
|
||||
if(linked_reactor && linked_reactor.can_create_power)
|
||||
produce_direct_power(linked_reactor.final_power)
|
||||
|
||||
// MARK: Monitor
|
||||
|
||||
/obj/machinery/computer/fission_monitor
|
||||
name = "NGCR monitoring console"
|
||||
desc = "Used to monitor the Nanotrasen Gas Cooled Fission Reactor."
|
||||
icon_keyboard = "power_key"
|
||||
icon_screen = "smmon_0"
|
||||
circuit = /obj/item/circuitboard/fission_monitor
|
||||
light_color = LIGHT_COLOR_YELLOW
|
||||
/// Last status of the active reactor for caching purposes
|
||||
var/last_status
|
||||
/// Reference to the active reactor
|
||||
var/obj/machinery/atmospherics/fission_reactor/active
|
||||
/// Is this monitor a controller? Affected by visibility from the reactor
|
||||
var/controller = TRUE
|
||||
|
||||
/obj/machinery/computer/fission_monitor/Initialize(mapload)
|
||||
. = ..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/machinery/computer/fission_monitor/LateInitialize()
|
||||
. = ..()
|
||||
active = GLOB.main_fission_reactor
|
||||
determine_control()
|
||||
|
||||
/obj/machinery/computer/fission_monitor/Destroy()
|
||||
active = null
|
||||
return ..()
|
||||
|
||||
// This can normally never happen, but just in case.
|
||||
/obj/machinery/computer/fission_monitor/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
||||
. = ..()
|
||||
determine_control()
|
||||
|
||||
/obj/machinery/computer/fission_monitor/proc/determine_control()
|
||||
if(!active)
|
||||
return
|
||||
if(active in oview(12, src))
|
||||
controller = TRUE
|
||||
else
|
||||
controller = FALSE
|
||||
|
||||
/obj/machinery/computer/fission_monitor/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/fission_monitor/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/fission_monitor/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/fission_monitor/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return FALSE
|
||||
|
||||
if(active)
|
||||
var/new_status = active.get_status()
|
||||
if(last_status != new_status)
|
||||
last_status = new_status
|
||||
icon_screen = "smmon_[last_status]"
|
||||
update_icon()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/fission_monitor/multitool_act(mob/living/user, obj/item/I)
|
||||
if(!I.multitool_check_buffer(user))
|
||||
return
|
||||
var/obj/item/multitool/multitool = I
|
||||
if(istype(multitool.buffer, /obj/machinery/atmospherics/fission_reactor))
|
||||
active = multitool.buffer
|
||||
to_chat(user, SPAN_NOTICE("You load the buffer's linking data to [src]."))
|
||||
|
||||
/obj/machinery/computer/fission_monitor/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ReactorMonitor", name)
|
||||
ui.open()
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/fission_monitor/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
// If we somehow dont have an engine anymore, handle it here.
|
||||
if(!active)
|
||||
return
|
||||
if(active.stat & BROKEN)
|
||||
active = null
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/air = active.air_contents
|
||||
var/power_kilowatts = round((active.final_power / 1000), 1)
|
||||
|
||||
data["venting"] = active.venting
|
||||
data["NGCR_integrity"] = active.get_integrity()
|
||||
data["NGCR_power"] = power_kilowatts
|
||||
data["NGCR_ambienttemp"] = air.temperature()
|
||||
data["NGCR_ambientpressure"] = air.return_pressure()
|
||||
data["NGCR_coefficient"] = active.reactivity_multiplier
|
||||
if(active.control_lockout)
|
||||
data["NGCR_throttle"] = 0
|
||||
else
|
||||
data["NGCR_throttle"] = 100 - active.desired_power
|
||||
data["NGCR_operatingpower"] = 100 - active.operating_power
|
||||
var/list/gasdata = list()
|
||||
var/TM = air.total_moles()
|
||||
if(TM)
|
||||
gasdata.Add(list(list("name" = "Oxygen", "amount" = air.oxygen(), "portion" = round(100 * air.oxygen() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Carbon Dioxide", "amount" = air.carbon_dioxide(), "portion" = round(100 * air.carbon_dioxide() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Nitrogen", "amount" = air.nitrogen(), "portion" = round(100 * air.nitrogen() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Plasma", "amount" = air.toxins(), "portion" = round(100 * air.toxins() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Nitrous Oxide", "amount" = air.sleeping_agent(), "portion" = round(100 * air.sleeping_agent() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Agent B", "amount" = air.agent_b(), "portion" = round(100 * air.agent_b() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Hydrogen", "amount" = air.hydrogen(), "portion" = round(100 * air.hydrogen() / TM, 0.01))))
|
||||
gasdata.Add(list(list("name" = "Water Vapor", "amount" = air.water_vapor(), "portion" = round(100 * air.water_vapor() / TM, 0.01))))
|
||||
else
|
||||
gasdata.Add(list(list("name" = "Oxygen", "amount" = 0, "portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Carbon Dioxide", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Nitrogen", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Plasma", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Nitrous Oxide", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Agent B", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Hydrogen", "amount" = 0,"portion" = 0)))
|
||||
gasdata.Add(list(list("name" = "Water Vapor", "amount" = 0,"portion" = 0)))
|
||||
data["gases"] = gasdata
|
||||
data["controlling"] = controller
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/fission_monitor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
if(action == "set_throttle")
|
||||
if(!controller)
|
||||
visible_message(SPAN_WARNING("Error: Reactor is out of sight from laser guidance control."))
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
return
|
||||
var/temp_number = text2num(params["NGCR_throttle"])
|
||||
active.desired_power = 100 - temp_number
|
||||
|
||||
if(action == "toggle_vent")
|
||||
if(!controller)
|
||||
visible_message(SPAN_WARNING("Error: Reactor is out of sight from laser guidance control."))
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
return
|
||||
if(active.vent_lockout)
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
visible_message(SPAN_WARNING("ERROR: Vent servos unresponsive. Manual closure required."))
|
||||
else
|
||||
active.venting = !active.venting
|
||||
|
||||
// MARK: Slag
|
||||
|
||||
/obj/item/slag
|
||||
name = "corium slag"
|
||||
desc = "A large clump of active nuclear fuel fused with structural reactor metals."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "big_molten"
|
||||
move_resist = MOVE_FORCE_STRONG // Massive chunk of metal slag, shouldnt be moving it without carrying.
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 15
|
||||
throwforce = 10
|
||||
|
||||
/obj/item/slag/Initialize(mapload)
|
||||
. = ..()
|
||||
scatter_atom()
|
||||
var/datum/component/inherent_radioactivity/rad_component = AddComponent(/datum/component/inherent_radioactivity, 5000, 5000, 5000, 2)
|
||||
START_PROCESSING(SSradiation, rad_component)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/item/slag/process()
|
||||
. = ..()
|
||||
radiation_pulse(src, 500, ALPHA_RAD)
|
||||
radiation_pulse(src, 500, BETA_RAD)
|
||||
radiation_pulse(src, 500, GAMMA_RAD)
|
||||
|
||||
// MARK: Starter Grenade
|
||||
|
||||
/obj/item/grenade/nuclear_starter
|
||||
name = "Neutronic Agitator"
|
||||
desc = "A throwable device capable of inducing an artificial startup in rod chambers. Won't do anything for chambers not positioned correctly, or chambers without any rods inserted."
|
||||
|
||||
/obj/item/grenade/nuclear_starter/deconstruct(disassembled)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/nuclear_starter/prime()
|
||||
playsound(src.loc, 'sound/weapons/bsg_explode.ogg', 50, TRUE, -3)
|
||||
var/obj/effect/temp_visual/neutronic/warp = new(loc)
|
||||
warp.pixel_x += 16
|
||||
warp.pixel_y += 16
|
||||
warp.transform = matrix().Scale(0.01, 0.01)
|
||||
animate(warp, time = 0.5 SECONDS, transform = matrix().Scale(1, 1))
|
||||
var/list/chamber_list = list()
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in range(3, loc))
|
||||
chamber_list += chamber
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in chamber_list)
|
||||
if(chamber.chamber_state == CHAMBER_DOWN && chamber.held_rod)
|
||||
chamber.operational = TRUE
|
||||
chamber.update_icon(UPDATE_OVERLAYS)
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in chamber_list)
|
||||
if(chamber.check_status())
|
||||
chamber.requirements_met = TRUE
|
||||
else
|
||||
chamber.requirements_met = FALSE
|
||||
chamber.update_icon(UPDATE_OVERLAYS)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/temp_visual/neutronic
|
||||
icon = 'icons/effects/light_352.dmi'
|
||||
icon_state = "light"
|
||||
plane = GRAVITY_PULSE_PLANE
|
||||
appearance_flags = PIXEL_SCALE|LONG_GLIDE
|
||||
duration = 0.5 SECONDS
|
||||
pixel_x = -176
|
||||
pixel_y = -176
|
||||
|
||||
// MARK: Rad Proof Pool
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool
|
||||
name = "holding pool"
|
||||
icon = 'icons/obj/fission/pool.dmi'
|
||||
icon_state = "pool_round"
|
||||
footstep = FOOTSTEP_WATER
|
||||
barefootstep = FOOTSTEP_WATER
|
||||
clawfootstep = FOOTSTEP_WATER
|
||||
heavyfootstep = FOOTSTEP_WATER
|
||||
/// Holds our pool controller
|
||||
var/obj/machinery/poolcontroller/linkedcontroller
|
||||
/// Holds our effect overlay
|
||||
var/obj/item/effect/pool_overlay/effect
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/Initialize(mapload)
|
||||
. = ..()
|
||||
RegisterSignal(src, COMSIG_ATOM_INITIALIZED_ON, PROC_REF(initialized_on))
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/LateInitialize()
|
||||
. = ..()
|
||||
effect = new(src)
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/crowbar_act(mob/user, obj/item/I)
|
||||
return
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/proc/initialized_on(atom/A)
|
||||
SIGNAL_HANDLER // COMSIG_ATOM_INITIALIZED_ON
|
||||
if(!linkedcontroller)
|
||||
return
|
||||
if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday
|
||||
linkedcontroller.decalinpool += A
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/Entered(atom/movable/AM, atom/OldLoc)
|
||||
. = ..()
|
||||
if(!linkedcontroller)
|
||||
return
|
||||
if(ismob(AM))
|
||||
linkedcontroller.mobinpool += AM
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/Exited(atom/movable/AM, direction)
|
||||
. = ..()
|
||||
if(!linkedcontroller)
|
||||
return
|
||||
if(ismob(AM))
|
||||
linkedcontroller.mobinpool -= AM
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/ChangeTurf(turf/simulated/floor/T, defer_change, keep_icon, ignore_air, copy_existing_baseturf)
|
||||
QDEL_NULL(effect)
|
||||
. = ..()
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/Destroy()
|
||||
QDEL_NULL(effect)
|
||||
. = ..()
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/wall
|
||||
icon_state = "pool_wall_round"
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/wall/ladder
|
||||
icon_state = "ladder_wall_round"
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/wall/filter
|
||||
icon_state = "filter_wall_round"
|
||||
|
||||
/turf/simulated/floor/plasteel/reactor_pool/square
|
||||
icon_state = "pool_sharp_square"
|
||||
|
||||
/obj/structure/railing/pool_lining
|
||||
name = "pool lining"
|
||||
icon = 'icons/obj/fission/pool.dmi'
|
||||
icon_state = "poolborder"
|
||||
flags = ON_BORDER | NODECONSTRUCT | INDESTRUCTIBLE
|
||||
max_integrity = 200
|
||||
|
||||
/obj/structure/railing/pool_lining/ex_act(severity)
|
||||
if(severity == EXPLODE_HEAVY || severity == EXPLODE_DEVASTATE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/effect/pool_overlay
|
||||
name = "holding pool"
|
||||
desc = "water"
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
icon_state = "seadeep"
|
||||
alpha = 75
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/railing/corner/pool_corner
|
||||
name = "pool lining"
|
||||
icon = 'icons/obj/fission/pool.dmi'
|
||||
icon_state = "bordercorner"
|
||||
|
||||
/obj/structure/railing/corner/pool_corner/inner
|
||||
icon_state = "innercorner"
|
||||
|
||||
/obj/machinery/poolcontroller/invisible/nuclear
|
||||
srange = 6
|
||||
deep_water = TRUE
|
||||
|
||||
/obj/machinery/poolcontroller/invisible/nuclear/Initialize(mapload)
|
||||
var/contents_loop = linked_area
|
||||
if(!linked_area)
|
||||
contents_loop = range(srange, src)
|
||||
|
||||
for(var/turf/simulated/floor/plasteel/reactor_pool/T in contents_loop)
|
||||
T.linkedcontroller = src
|
||||
linkedturfs += T
|
||||
return ..()
|
||||
|
||||
/obj/machinery/poolcontroller/invisible/nuclear/Destroy()
|
||||
for(var/turf/simulated/floor/plasteel/reactor_pool/W in linkedturfs)
|
||||
if(W.linkedcontroller == src)
|
||||
W.linkedcontroller = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/poolcontroller/invisible/nuclear/processMob()
|
||||
for(var/mob/M in mobinpool)
|
||||
if(!istype(get_turf(M), /turf/simulated/floor/plasteel/reactor_pool))
|
||||
mobinpool -= M
|
||||
continue
|
||||
|
||||
M.clean_blood(radiation_clean = TRUE)
|
||||
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
L.ExtinguishMob()
|
||||
L.adjust_fire_stacks(-20) //Douse ourselves with water to avoid fire more easily
|
||||
|
||||
if(ishuman(M))
|
||||
handleDrowning(M)
|
||||
|
||||
// MARK: Fab upgrade
|
||||
|
||||
/obj/item/rod_fabricator_upgrade
|
||||
name = "Nuclear Fabricator Upgrade"
|
||||
desc = "A design disk containing a dizzying amount of designs and improvements for nuclear rod fabrication."
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "datadisk5"
|
||||
drop_sound = 'sound/items/handling/disk_drop.ogg'
|
||||
pickup_sound = 'sound/items/handling/disk_pickup.ogg'
|
||||
new_attack_chain = TRUE
|
||||
|
||||
// MARK: Chamber Doors
|
||||
|
||||
/obj/effect/temp_visual/chamber_closing
|
||||
icon = 'icons/obj/fission/reactor_chamber.dmi'
|
||||
icon_state = "doors_closing"
|
||||
duration = 0.7 SECONDS
|
||||
layer = ABOVE_ALL_MOB_LAYER + 0.03
|
||||
|
||||
546
code/modules/power/engines/fission/nuclear_rods.dm
Normal file
546
code/modules/power/engines/fission/nuclear_rods.dm
Normal file
@@ -0,0 +1,546 @@
|
||||
/obj/item/nuclear_rod
|
||||
name = "Nuclear Control Rod"
|
||||
desc = ABSTRACT_TYPE_DESC
|
||||
icon = 'icons/obj/fission/reactor_rods.dmi'
|
||||
icon_state = "fuel_238"
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
force = 15
|
||||
throwforce = 10
|
||||
/// The path of the object required to fabricate this rod. leave null for nothing
|
||||
var/required_object
|
||||
/// How much durability is left before the rod is useless
|
||||
var/durability
|
||||
/// The maximum amount of durability for this rod. Used for percentage calculations
|
||||
var/max_durability = 3000
|
||||
/// How fast does this rod degrade? higher = faster
|
||||
var/degradation_speed = 1
|
||||
/// How much heat does this rod add by default
|
||||
var/heat_amount = 0
|
||||
/// How does this rod affect its neighbors heating
|
||||
var/heat_amp_mod = 1
|
||||
/// Holds the current heat mod after durability loss
|
||||
var/current_heat_mod
|
||||
/// How much power does this rod add by default in watts
|
||||
var/power_amount = 0
|
||||
/// How does this rod affect its neighbors power production
|
||||
var/power_amp_mod = 1
|
||||
/// Holds the current power mod after durability loss
|
||||
var/current_power_mod
|
||||
/// How much Alpha Rad is emitted by this rod
|
||||
var/alpha_rad = 0
|
||||
/// How much Beta Rad is emitted by this rod
|
||||
var/beta_rad = 0
|
||||
/// How much Gamma Rad is emitted by this rod
|
||||
var/gamma_rad = 0
|
||||
/// What items need to be adjacent to this rod for it to function properly
|
||||
var/list/adjacent_requirements = list()
|
||||
/// Modifies the reactor's minimum operating temperature.
|
||||
var/minimum_temp_modifier = 0
|
||||
/// Modified the reactor's overheat threshold
|
||||
var/reactor_overheat_modifier = 0
|
||||
/// holds our component to modify
|
||||
var/datum/component/inherent_radioactivity/rad_component
|
||||
/// Is this rod craftable at all via fabricators, or do they require other means?
|
||||
var/craftable = FALSE
|
||||
/// Does this rod require a science-upgraded fabricator?
|
||||
var/upgrade_required = FALSE
|
||||
|
||||
/obj/item/nuclear_rod/Initialize(mapload)
|
||||
. = ..()
|
||||
durability = max_durability
|
||||
|
||||
/obj/item/nuclear_rod/examine(mob/user)
|
||||
. = ..()
|
||||
if(length(adjacent_requirements))
|
||||
var/list/templist = list()
|
||||
for(var/obj/item/nuclear_rod/requirement as anything in adjacent_requirements)
|
||||
templist += initial(requirement.name)
|
||||
var/requirement_list = english_list(templist, and_text = ", ")
|
||||
. += "This rod has the following neighbor requirements: [requirement_list]"
|
||||
else
|
||||
. += "This rod has no neighbor requirements."
|
||||
|
||||
/obj/item/nuclear_rod/proc/get_durability_mod()
|
||||
var/temp_mod
|
||||
temp_mod = clamp(1.5 * (durability / max_durability) - 0.25, 0.25, 1)
|
||||
return temp_mod
|
||||
|
||||
/obj/item/nuclear_rod/proc/calc_stat_decrease()
|
||||
// Formula: y = (x * A) + (1 - A)
|
||||
var/durability_stat = get_durability_mod()
|
||||
current_power_mod = (power_amp_mod * durability_stat) + (1 - durability_stat)
|
||||
current_heat_mod = (heat_amp_mod * durability_stat) + (1 - durability_stat)
|
||||
|
||||
/obj/item/nuclear_rod/proc/start_rads(power_modifier = 1)
|
||||
var/new_alpha_rad = alpha_rad * power_modifier
|
||||
var/new_beta_rad = beta_rad * power_modifier
|
||||
var/new_gamma_rad = gamma_rad * power_modifier
|
||||
rad_component = AddComponent(/datum/component/inherent_radioactivity, new_alpha_rad, new_beta_rad, new_gamma_rad, 1)
|
||||
START_PROCESSING(SSradiation, rad_component)
|
||||
|
||||
/obj/item/nuclear_rod/proc/stop_rads()
|
||||
if(!rad_component)
|
||||
return
|
||||
rad_component.RemoveComponent()
|
||||
QDEL_NULL(rad_component)
|
||||
|
||||
/obj/item/nuclear_rod/proc/change_rad_intensity(power_modifier = 1)
|
||||
rad_component.radioactivity_alpha = alpha_rad * power_modifier
|
||||
rad_component.radioactivity_beta = beta_rad * power_modifier
|
||||
rad_component.radioactivity_gamma = gamma_rad * power_modifier
|
||||
|
||||
/obj/item/nuclear_rod/proc/check_rad_shield()
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || !loc)
|
||||
stop_rads()
|
||||
return
|
||||
if(istype(T, /turf/simulated/floor/plasteel/reactor_pool))
|
||||
if(!rad_component)
|
||||
return
|
||||
else
|
||||
stop_rads()
|
||||
else if(istype(loc, /obj/machinery/atmospherics/reactor_chamber))
|
||||
stop_rads()
|
||||
else if(!rad_component)
|
||||
start_rads()
|
||||
|
||||
/obj/item/nuclear_rod/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
||||
. = ..()
|
||||
check_rad_shield()
|
||||
|
||||
/obj/item/nuclear_rod/fuel
|
||||
name = "any fuel rod"
|
||||
alpha_rad = 50
|
||||
|
||||
/// the amount of cycles needed to complete enrichment. 30 = ~1 minute
|
||||
var/enrichment_cycles = 25
|
||||
/// the total power amp mod needed to enrich
|
||||
var/power_enrich_threshold = 0
|
||||
/// How far we have progressed from to power enrichment
|
||||
var/power_enrich_progress = 0
|
||||
/// What power enrichment results in
|
||||
var/power_enrich_result
|
||||
/// the total heat amp mod needed to enrich
|
||||
var/heat_enrich_threshold = 0
|
||||
/// How far we have progressed from to power enrichment
|
||||
var/heat_enrich_progress = 0
|
||||
/// What heat enrichment results in
|
||||
var/heat_enrich_result
|
||||
|
||||
/obj/item/nuclear_rod/fuel/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!istype(loc, /obj/structure/closet/crate))
|
||||
check_rad_shield()
|
||||
|
||||
/obj/item/nuclear_rod/fuel/proc/enrich(power_mod, heat_mod)
|
||||
var/successful_enrichment = FALSE
|
||||
if(power_enrich_result)
|
||||
if(power_mod > power_enrich_threshold && power_enrich_progress < enrichment_cycles)
|
||||
power_enrich_progress++
|
||||
successful_enrichment = TRUE
|
||||
if(heat_enrich_result)
|
||||
if(heat_mod > heat_enrich_threshold && heat_enrich_progress < enrichment_cycles)
|
||||
heat_enrich_progress++
|
||||
successful_enrichment = TRUE
|
||||
return successful_enrichment
|
||||
|
||||
// MARK: Fuel Rods
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_238
|
||||
name = "uranium 238 fuel rod"
|
||||
desc = "A standard fuel rod for most NGCR reactors. Has just barely enough Uranium 235 to be useful."
|
||||
heat_amount = 5
|
||||
power_amount = 20 KW
|
||||
heat_amp_mod = 1.8
|
||||
power_amp_mod = 1.1
|
||||
alpha_rad = 200
|
||||
beta_rad = 100
|
||||
heat_enrich_threshold = 10 // all uranium rods surrounding: 1.8 x 1.8 x 1.8 x 1.8
|
||||
power_enrich_threshold = 6.4 // all graphite rods surrounding: 1.6 x 1.6 x 1.6 x 1.6
|
||||
heat_enrich_result = /obj/item/nuclear_rod/fuel/weak_thorium
|
||||
power_enrich_result = /obj/item/nuclear_rod/fuel/weak_plutonium
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/moderator)
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_URANIUM = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/weak_thorium
|
||||
name = "weak thorium fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 238. This rod will last longer than normal, and won't generate as much heat."
|
||||
icon_state = "fuel_weakthor"
|
||||
heat_amount = 5
|
||||
power_amount = 20 KW
|
||||
heat_amp_mod = 1.6
|
||||
power_amp_mod = 1.1
|
||||
max_durability = 5000
|
||||
beta_rad = 100
|
||||
gamma_rad = 100
|
||||
power_enrich_threshold = 8
|
||||
power_enrich_result = /obj/item/nuclear_rod/fuel/uranium_235
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
/obj/item/nuclear_rod/coolant,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/weak_plutonium
|
||||
name = "weak plutonium fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 238. This rod produces twice as much power as standard uranium 238 fuel, but has higher operating requirements."
|
||||
icon_state = "fuel_weakplut"
|
||||
heat_amount = 10
|
||||
power_amount = 40 KW
|
||||
heat_amp_mod = 1.6
|
||||
power_amp_mod = 1.1
|
||||
max_durability = 3500
|
||||
gamma_rad = 100
|
||||
heat_enrich_threshold = 14
|
||||
heat_enrich_result = /obj/item/nuclear_rod/fuel/uranium_235
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
/obj/item/nuclear_rod/coolant,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/uranium_235
|
||||
name = "uranium 235 fuel rod"
|
||||
desc = "An advanced fuel rod for most NGCR reactors, formed from high-density uranium 235 isotopes."
|
||||
icon_state = "fuel_235"
|
||||
heat_amount = 20
|
||||
power_amount = 50 KW
|
||||
heat_amp_mod = 2.2
|
||||
power_amp_mod = 1.3
|
||||
max_durability = 5000
|
||||
alpha_rad = 150
|
||||
beta_rad = 100
|
||||
heat_enrich_threshold = 25
|
||||
power_enrich_threshold = 18
|
||||
heat_enrich_result = /obj/item/nuclear_rod/fuel/thorium_salts
|
||||
power_enrich_result = /obj/item/nuclear_rod/fuel/enriched_plutonium
|
||||
origin_tech = "toxins=2"
|
||||
craftable = TRUE
|
||||
upgrade_required = TRUE
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/coolant/plasma_injector,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
)
|
||||
materials = list(MAT_METAL = 4000, MAT_URANIUM = 4000)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/thorium_salts
|
||||
name = "thorium salts fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 235. While this rod doesn't have any notable power boosts, its amazingly large integrity makes it virtually impossible to deplete in a single shift, if one can manage its heat."
|
||||
icon_state = "fuel_richthor"
|
||||
heat_amount = 40
|
||||
power_amount = 35 KW
|
||||
heat_amp_mod = 2.2
|
||||
power_amp_mod = 1.3
|
||||
max_durability = 15000
|
||||
beta_rad = 250
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
/obj/item/nuclear_rod/fuel/uranium_235,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/enriched_plutonium
|
||||
name = "enriched plutonium fuel rod"
|
||||
desc = "A specialized fuel rod refined from uranium 235. This rod is extremely powerful, boasting high power outputs and moderate durability. However, its heat presents an exceptional danger."
|
||||
icon_state = "fuel_richplut"
|
||||
heat_amount = 60
|
||||
power_amount = 75 KW
|
||||
heat_amp_mod = 4
|
||||
power_amp_mod = 1.6
|
||||
max_durability = 5000
|
||||
beta_rad = 250
|
||||
power_enrich_threshold = 25
|
||||
power_enrich_result = /obj/item/nuclear_rod/fuel/americium
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator,
|
||||
/obj/item/nuclear_rod/fuel/thorium_salts,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/supermatter
|
||||
name = "supermatter fuel rod"
|
||||
desc = "A dangerous fuel rod made entirely of supermatter, contained safely in a specialized housing case. Due to its unusual properties, it completely neutralizes any potential power from nearby rods."
|
||||
icon_state = "fuel_sm"
|
||||
heat_amount = 1200
|
||||
power_amount = 800 KW
|
||||
heat_amp_mod = 8
|
||||
power_amp_mod = 0.1
|
||||
max_durability = INFINITY
|
||||
gamma_rad = 300
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/americium
|
||||
name = "americium fuel rod"
|
||||
desc = "A specialized fuel rod refined from enriched plutonium. A pinnacle of power generation, this rod's power generation is nearly unmatched if one can tame its vicious heat output."
|
||||
icon_state = "fuel_americium"
|
||||
heat_amount = 100
|
||||
power_amount = 200 KW
|
||||
heat_amp_mod = 6
|
||||
power_amp_mod = 1.6
|
||||
max_durability = 4000
|
||||
gamma_rad = 300
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/bananium
|
||||
name = "bananium fuel rod"
|
||||
desc = "The funniest of all fuel rods with no solidified properties. Who knows what you might get out of it!"
|
||||
icon_state = "fuel_clown"
|
||||
gamma_rad = 300
|
||||
craftable = TRUE
|
||||
upgrade_required = TRUE
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_BANANIUM = 2000)
|
||||
|
||||
/obj/item/nuclear_rod/fuel/bananium/Initialize(mapload)
|
||||
max_durability = rand(1000, 10000)
|
||||
power_amp_mod = rand(1, 40) / 10
|
||||
heat_amp_mod = rand(5, 80) / 10
|
||||
power_amount = rand(10 KW, 200 KW)
|
||||
heat_amount = rand(10, 500)
|
||||
return ..()
|
||||
|
||||
/obj/item/nuclear_rod/fuel/meltdown
|
||||
name = "meltdown rod"
|
||||
desc = "A Syndicate-crafted rod capable of generating massive amounts of heat, leading to an eventual meltdown."
|
||||
icon_state = "fuel_syndie"
|
||||
heat_amount = 2000
|
||||
max_durability = INFINITY
|
||||
minimum_temp_modifier = 4000 // BIG hot
|
||||
reactor_overheat_modifier = -400
|
||||
alpha_rad = 250
|
||||
beta_rad = 250
|
||||
gamma_rad = 250
|
||||
|
||||
// MARK: Moderator Rods
|
||||
|
||||
/obj/item/nuclear_rod/moderator
|
||||
name = "any moderator rod"
|
||||
icon_state = "mod_water"
|
||||
|
||||
/obj/item/nuclear_rod/moderator/heavy_water
|
||||
name = "heavy water moderator"
|
||||
desc = "A basic moderation rod filled with a variant of water comprised of deuterium instead of hydrogen atoms."
|
||||
heat_amp_mod = 1.1
|
||||
power_amp_mod = 1.4
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/graphite
|
||||
name = "graphite moderator"
|
||||
desc = "A nuclear moderation rod comprised primarily of layered graphite. A staple of fission reactor operation through the ages."
|
||||
icon_state = "mod_graphite"
|
||||
heat_amp_mod = 1.3
|
||||
power_amp_mod = 1.6
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 4000, MAT_PLASMA = 2000)
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/coolant)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/titanium
|
||||
name = "titanium moderator"
|
||||
desc = "A nuclear moderation rod comprised primarily of cast titanium. For what it lacks in power amplification, it makes up for in versatility and durability."
|
||||
icon_state = "mod_titanium"
|
||||
max_durability = 5000
|
||||
heat_amp_mod = 1.1
|
||||
power_amp_mod = 1.3
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_TITANIUM = 2000)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator
|
||||
name = "plasma agitator"
|
||||
desc = "A specialized moderator rod capable of inducing higher fission rates in fuel rods through a series of micro-burns. It doesn't last long."
|
||||
icon_state = "mod_plasma"
|
||||
max_durability = 2250
|
||||
heat_amount = 20
|
||||
heat_amp_mod = 5
|
||||
power_amp_mod = 3
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/aluminum_reflector
|
||||
name = "liquid aluminum plate reflector"
|
||||
desc = "A specialized moderator rod for amplifying the power output of nearby fuel rods. However, the temperature of the liquid aluminum will force the reactor to run hot."
|
||||
icon_state = "mod_aluminium"
|
||||
max_durability = 6000
|
||||
power_amount = -15 KW
|
||||
heat_amp_mod = 5
|
||||
power_amp_mod = 3
|
||||
minimum_temp_modifier = 400
|
||||
reactor_overheat_modifier = 100
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/coolant/nitrogen_circulator,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/bluespace_agitator
|
||||
name = "bluespace crystal agitator"
|
||||
desc = "An advanced moderator rod that will pull extra neutrons out of bluespace to bombard local fuel rods. The result is a massive increase of power and heat generation. It is exceptionally versatile; however, its power requirements limit its uses."
|
||||
icon_state = "mod_bluespace"
|
||||
max_durability = 4000
|
||||
power_amount = -30 KW
|
||||
heat_amp_mod = 12
|
||||
power_amp_mod = 5
|
||||
upgrade_required = TRUE
|
||||
craftable = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_TITANIUM = 1000, MAT_BLUESPACE = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/diamond_plate
|
||||
name = "diamond reflector plates"
|
||||
desc = "An advanced moderator rod that can reflect nearly all neutrons back to their point of origin. Simple, stable, reliable."
|
||||
icon_state = "mod_diamond"
|
||||
max_durability = 6000
|
||||
heat_amp_mod = 6.5
|
||||
power_amp_mod = 3.3
|
||||
reactor_overheat_modifier = 100
|
||||
craftable = TRUE
|
||||
upgrade_required = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_TITANIUM = 1000, MAT_DIAMOND = 1000)
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/moderator/platinum_plating
|
||||
name = "platinum reflector plating"
|
||||
desc = "An advanced moderator similar to diamond plates, but improved with precious space metals."
|
||||
icon_state = "mod_platinum"
|
||||
max_durability = 8000
|
||||
heat_amp_mod = 8
|
||||
power_amp_mod = 3.9
|
||||
reactor_overheat_modifier = 300
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/fuel/americium)
|
||||
|
||||
/// MARK: Coolant Rods
|
||||
|
||||
/obj/item/nuclear_rod/coolant
|
||||
name = "any coolant rod"
|
||||
icon_state = "coolant_water"
|
||||
|
||||
/obj/item/nuclear_rod/coolant/light_water
|
||||
name = "light water circulator"
|
||||
desc = "A basic coolant rod that circulates distilled water through critical reactor components."
|
||||
heat_amount = -10
|
||||
power_amount = -10 KW
|
||||
reactor_overheat_modifier = 25
|
||||
craftable = TRUE
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/moderator)
|
||||
materials = list(MAT_METAL = 2000, MAT_GLASS = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/co2_regulator
|
||||
name = "carbon dioxide regulator"
|
||||
desc = "A specialized coolant rod filled with carbon dioxide gas, capable of regulating temperature spikes in fuel rods. However, it's very energy inefficient."
|
||||
icon_state = "coolant_carbon"
|
||||
heat_amount = -4
|
||||
heat_amp_mod = 0.6
|
||||
power_amount = -15 KW
|
||||
craftable = TRUE
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/moderator)
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_GLASS = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/plasma_injector
|
||||
name = "plasma injector"
|
||||
desc = "A specialized coolant rod filled with gaseous plasma. By taking advantage of plasma's unique heat-absorbent properties, small amounts injected around fuel rods neutralize excess heat. However, the tank runs out quickly this way."
|
||||
icon_state = "coolant_plasma"
|
||||
max_durability = 1900
|
||||
heat_amp_mod = 0.5
|
||||
power_amp_mod = 1.5
|
||||
craftable = TRUE
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/coolant)
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_GLASS = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/nitrogen_circulator
|
||||
name = "nitrogen circulator"
|
||||
desc = "A specialized coolant rod filled with nitrogen gas. While not as powerful as similar alternatives, this rod is exceptionally stable and will last longer."
|
||||
icon_state = "coolant_nitrogen"
|
||||
max_durability = 3500
|
||||
heat_amount = -10
|
||||
power_amp_mod = 0.9
|
||||
heat_amp_mod = 0.7
|
||||
craftable = TRUE
|
||||
reactor_overheat_modifier = 50
|
||||
power_amount = -5 KW
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_GLASS = 1000)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/molten_salt
|
||||
name = "molten salt circulator"
|
||||
desc = "A specialized coolant rod that circulates molten salts through the core of the reactor. Despite forcing the reactor to run exceptionally hot, this rod provides top-notch cooling potential above its resting temperature."
|
||||
icon_state = "coolant_salt"
|
||||
power_amount = -20 KW
|
||||
heat_amount = -60
|
||||
heat_amp_mod = 0.8
|
||||
max_durability = 8000
|
||||
minimum_temp_modifier = 750
|
||||
reactor_overheat_modifier = 100
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_GLASS = 1000)
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/coolant/nitrogen_circulator,
|
||||
/obj/item/nuclear_rod/moderator,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
/obj/item/nuclear_rod/fuel,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet
|
||||
name = "steam hammerjet"
|
||||
desc = "A specialized coolant rod that injects distilled steam throughout the reactor's critical components. Although it makes the reactor run warm, it's very good at suppressing heat buildup."
|
||||
icon_state = "coolant_steam"
|
||||
power_amount = -10 KW
|
||||
heat_amount = -40
|
||||
heat_amp_mod = 0.4
|
||||
max_durability = 6000
|
||||
minimum_temp_modifier = 450
|
||||
reactor_overheat_modifier = 100
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/coolant/light_water,
|
||||
/obj/item/nuclear_rod/coolant/light_water,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/bluespace_displacer
|
||||
name = "bluespace heat displacer"
|
||||
desc = "An advanced coolant rod capable of pulling heat directly out of neighboring rods and sending it... somewhere."
|
||||
icon_state = "coolant_bluespace"
|
||||
power_amount = -40 KW
|
||||
heat_amount = -100
|
||||
heat_amp_mod = 0.8
|
||||
power_amp_mod = 1.3
|
||||
max_durability = INFINITY
|
||||
reactor_overheat_modifier = 200
|
||||
craftable = TRUE
|
||||
upgrade_required = TRUE
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_BLUESPACE = 1000)
|
||||
adjacent_requirements = list(/obj/item/nuclear_rod/moderator/bluespace_agitator)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/iridium_conductor
|
||||
name = "iridium conductor coolant rod"
|
||||
desc = "A dazzlingly beautiful rod with exceptionally powerful thermal conductivity. A highly sought after piece of equipment for its simplicity and potency."
|
||||
icon_state = "coolant_iridium"
|
||||
heat_amp_mod = 0.1
|
||||
max_durability = 10000
|
||||
reactor_overheat_modifier = 300
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/moderator/aluminum_reflector,
|
||||
/obj/item/nuclear_rod/fuel/uranium_235,
|
||||
)
|
||||
|
||||
/obj/item/nuclear_rod/coolant/condensed_spacematter
|
||||
name = "condensed spacematter coolant rod"
|
||||
desc = "While it's unknown quite what the rod is filled with, there's no questioning its heat-suppressing efficiency. However, it violently disintegrates in contact with anything that isn't its housing."
|
||||
icon_state = "coolant_spacematter"
|
||||
heat_amount = -1500
|
||||
heat_amp_mod = 0.2
|
||||
materials = list(MAT_METAL = 6000, MAT_PLASMA = 4000, MAT_TITANIUM = 2000)
|
||||
craftable = TRUE
|
||||
upgrade_required = TRUE
|
||||
adjacent_requirements = list(
|
||||
/obj/item/nuclear_rod/fuel/enriched_plutonium,
|
||||
/obj/item/nuclear_rod/fuel/thorium_salts,
|
||||
)
|
||||
1110
code/modules/power/engines/fission/reactor.dm
Normal file
1110
code/modules/power/engines/fission/reactor.dm
Normal file
File diff suppressed because it is too large
Load Diff
470
code/modules/power/engines/fission/reactor_machines.dm
Normal file
470
code/modules/power/engines/fission/reactor_machines.dm
Normal file
@@ -0,0 +1,470 @@
|
||||
#define DEFAULT_OPERATION_TIME 10 SECONDS //! The base amount of time needed to craft an item
|
||||
|
||||
/// MARK: Centrifuge
|
||||
/obj/machinery/nuclear_centrifuge
|
||||
name = "Fuel Enrichment Centrifuge"
|
||||
desc = "An advanced device capable of separating and collecting fissile materials from enriched fuel rods."
|
||||
icon = 'icons/obj/fission/reactor_machines.dmi'
|
||||
icon_state = "centrifuge_empty"
|
||||
idle_power_consumption = 200
|
||||
active_power_consumption = 3000
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
resistance_flags = FIRE_PROOF | FREEZE_PROOF
|
||||
armor = list(melee = 25, bullet = 10, laser = 30, energy = 0, bomb = 0, rad = INFINITY, fire = INFINITY, acid = 70)
|
||||
|
||||
/// The time it takes for the machine to process a rod
|
||||
var/work_time
|
||||
/// The averaged amount of all stock parts
|
||||
var/average_component_rating
|
||||
/// The result when we are done operating
|
||||
var/rod_result
|
||||
/// Holds the rod object inserted into the machine
|
||||
var/obj/item/nuclear_rod/held_rod
|
||||
/// the soundloop we will be using while operating
|
||||
var/datum/looping_sound/centrifuge/soundloop
|
||||
|
||||
COOLDOWN_DECLARE(enrichment_timer)
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/Initialize(mapload)
|
||||
. = ..()
|
||||
soundloop = new(list(src), FALSE)
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/nuclear_centrifuge(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
RefreshParts()
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/examine(mob/user)
|
||||
. = ..()
|
||||
if(held_rod)
|
||||
. += SPAN_NOTICE("The current fuel rod may be removed with <b>Alt-Click</b>.")
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/Destroy()
|
||||
QDEL_NULL(soundloop)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/RefreshParts()
|
||||
average_component_rating = 0
|
||||
for(var/obj/item/stock_parts/manipulator/part in component_parts)
|
||||
average_component_rating += part.rating
|
||||
average_component_rating /= 4 // average all 4 components
|
||||
work_time = DEFAULT_OPERATION_TIME / average_component_rating
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
. = ..()
|
||||
if(!istype(used, /obj/item/nuclear_rod/fuel))
|
||||
return CONTINUE_ATTACK
|
||||
if(stat & NOPOWER)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_WARNING("You must close the access panel first!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(power_state == ACTIVE_POWER_USE) // dont start a new cycle when on
|
||||
to_chat(user, SPAN_WARNING("There is already a fuel rod being processed!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
var/obj/item/nuclear_rod/fuel/rod = used
|
||||
var/list/enrichment_to_name = list()
|
||||
var/list/radial_list = list()
|
||||
var/obj/item/nuclear_rod/fuel/rod_enrichment
|
||||
if(rod.power_enrich_progress >= rod.enrichment_cycles && rod.power_enrich_result)
|
||||
rod_enrichment = rod.power_enrich_result
|
||||
enrichment_to_name["[rod_enrichment::name]"] = rod_enrichment
|
||||
radial_list["[rod_enrichment::name]"] = image(icon = rod_enrichment::icon, icon_state = rod_enrichment::icon_state)
|
||||
if(rod.heat_enrich_progress >= rod.enrichment_cycles && rod.heat_enrich_result)
|
||||
rod_enrichment = rod.heat_enrich_result
|
||||
enrichment_to_name["[rod_enrichment::name]"] = rod_enrichment
|
||||
radial_list["[rod_enrichment::name]"] = image(icon = rod_enrichment::icon, icon_state = rod_enrichment::icon_state)
|
||||
if(!length(radial_list))
|
||||
to_chat(user, SPAN_WARNING("This rod has no potential for enrichment!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
var/enrichment_choice = show_radial_menu(user, src, radial_list, src, radius = 30, require_near = TRUE)
|
||||
if(!enrichment_choice)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
rod_result = enrichment_to_name[enrichment_choice]
|
||||
held_rod = rod
|
||||
user.transfer_item_to(rod, src)
|
||||
begin_enrichment()
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/AltClick(mob/user, modifiers)
|
||||
if(!held_rod)
|
||||
return
|
||||
if(power_state == ACTIVE_POWER_USE)
|
||||
to_chat(user, SPAN_WARNING("You cannot remove the fuel rod while the machine is running!"))
|
||||
return
|
||||
held_rod.forceMove(get_turf(src))
|
||||
held_rod = null
|
||||
icon_state = "centrifuge_empty"
|
||||
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/process()
|
||||
if(stat & NOPOWER)
|
||||
if(power_state == ACTIVE_POWER_USE)
|
||||
abort_enrichment()
|
||||
return
|
||||
if(power_state == IDLE_POWER_USE)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, enrichment_timer))
|
||||
return
|
||||
finish_enrichment()
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(held_rod)
|
||||
to_chat(user, SPAN_WARNING("The machine cannot be opened while it contains a fuel rod!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
default_deconstruction_screwdriver(user, "centrifuge_maint", "centrifuge_empty", I)
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/proc/begin_enrichment()
|
||||
power_state = ACTIVE_POWER_USE
|
||||
icon_state = "centrifuge_on"
|
||||
COOLDOWN_START(src, enrichment_timer, work_time)
|
||||
soundloop.start()
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/proc/abort_enrichment()
|
||||
power_state = IDLE_POWER_USE
|
||||
icon_state = "centrifuge_full"
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
soundloop.stop()
|
||||
|
||||
/obj/machinery/nuclear_centrifuge/proc/finish_enrichment()
|
||||
icon_state = "centrifuge_full"
|
||||
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
|
||||
power_state = IDLE_POWER_USE
|
||||
var/new_rod = new rod_result(contents)
|
||||
rod_result = null
|
||||
QDEL_NULL(held_rod)
|
||||
held_rod = new_rod
|
||||
soundloop.stop()
|
||||
|
||||
// MARK: Rod Fabricator
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator
|
||||
name = "Nuclear Fuel Rod Fabricator"
|
||||
desc = "A highly specialized fabricator for crafting nuclear rods."
|
||||
icon = 'icons/obj/fission/reactor_machines.dmi'
|
||||
icon_state = "rod_fab"
|
||||
idle_power_consumption = 50
|
||||
active_power_consumption = 3000
|
||||
density = TRUE
|
||||
resistance_flags = FIRE_PROOF | FREEZE_PROOF
|
||||
armor = list(melee = 25, bullet = 10, laser = 30, energy = 0, bomb = 0, rad = INFINITY, fire = INFINITY, acid = 70)
|
||||
|
||||
/// Our holder for materials
|
||||
var/datum/component/material_container/materials
|
||||
/// How fast do we operate and/or do we get extra rods
|
||||
var/efficiency_coeff = 1
|
||||
/// The list for carrying fuel rods
|
||||
var/list/category_fuel = list()
|
||||
/// The list for carrying moderator rods
|
||||
var/list/category_moderator = list()
|
||||
/// The list for carrying coolant rods
|
||||
var/list/category_coolant = list()
|
||||
/// Is the rod fabricator currently upgraded from science
|
||||
var/upgraded = FALSE
|
||||
/// What is the current item being produced
|
||||
var/schematic
|
||||
/// The time it takes for the machine to process a rod
|
||||
var/work_time
|
||||
|
||||
COOLDOWN_DECLARE(fabrication_timer)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/upgraded
|
||||
upgraded = TRUE
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/Initialize(mapload)
|
||||
. = ..()
|
||||
materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TRANQUILLITE, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC), 0, TRUE, /obj/item/stack, CALLBACK(src, PROC_REF(is_insertion_ready)), CALLBACK(src, PROC_REF(AfterMaterialInsert)))
|
||||
materials.precise_insertion = TRUE
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/nuclear_rod_fabricator(src)
|
||||
component_parts += new /obj/item/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/stock_parts/matter_bin(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
|
||||
RefreshParts()
|
||||
create_designs()
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/RefreshParts()
|
||||
var/temp_coeff = 12
|
||||
var/average_component_rating = 0
|
||||
for(var/obj/item/stock_parts/manipulator/M in component_parts)
|
||||
temp_coeff -= M.rating
|
||||
average_component_rating += M.rating
|
||||
work_time = DEFAULT_OPERATION_TIME / average_component_rating
|
||||
efficiency_coeff = clamp(temp_coeff / 10, 0.05, 1)
|
||||
temp_coeff = 0
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
temp_coeff += M.rating
|
||||
materials.max_amount = temp_coeff * 75000
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/attack_ghost(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/is_insertion_ready(mob/user)
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_WARNING("You can't load [src] while it's opened!"))
|
||||
return FALSE
|
||||
|
||||
if(stat & BROKEN)
|
||||
to_chat(user, SPAN_WARNING("[src] is broken."))
|
||||
return FALSE
|
||||
|
||||
if(stat & NOPOWER)
|
||||
to_chat(user, SPAN_WARNING("[src] has no power."))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
|
||||
var/stack_name
|
||||
if(ispath(type_inserted, /obj/item/stack/ore/bluespace_crystal))
|
||||
stack_name = "bluespace"
|
||||
use_power(MINERAL_MATERIAL_AMOUNT / 10)
|
||||
else
|
||||
var/obj/item/stack/S = type_inserted
|
||||
stack_name = initial(S.name)
|
||||
use_power(min(1000, (amount_inserted / 100)))
|
||||
add_overlay("protolathe_[stack_name]")
|
||||
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, cut_overlay), "protolathe_[stack_name]"), 10)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/check_mat(obj/item/nuclear_rod/being_built, M)
|
||||
var/A = materials.amount(M)
|
||||
if(!A)
|
||||
visible_message(SPAN_WARNING("Something has gone very wrong. Alert a developer."))
|
||||
return
|
||||
else
|
||||
A /= max(1, (being_built.materials[M] * efficiency_coeff))
|
||||
return A
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(istype(used, /obj/item/storage/part_replacer))
|
||||
return ..()
|
||||
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_WARNING("You can't load [src] while the maintenance panel is opened."))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(istype(used, /obj/item/rod_fabricator_upgrade))
|
||||
upgraded = TRUE
|
||||
create_designs()
|
||||
user.drop_item(used)
|
||||
qdel(used)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/crowbar_act(mob/living/user, obj/item/I)
|
||||
if(!panel_open)
|
||||
return
|
||||
. = TRUE
|
||||
materials.retrieve_all()
|
||||
default_deconstruction_crowbar(user, I)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/on_deconstruction()
|
||||
if(upgraded)
|
||||
new /obj/item/rod_fabricator_upgrade(loc)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/create_designs()
|
||||
category_fuel = list()
|
||||
category_moderator = list()
|
||||
category_coolant = list()
|
||||
|
||||
for(var/obj/rod_path as anything in subtypesof(/obj/item/nuclear_rod))
|
||||
if(initial(rod_path.desc) == ABSTRACT_TYPE_DESC)
|
||||
continue
|
||||
|
||||
var/datum/nuclear_rod_design/D = new /datum/nuclear_rod_design()
|
||||
D.build_metadata_list(rod_path)
|
||||
|
||||
if(!D.metadata["craftable"])
|
||||
continue
|
||||
|
||||
if(D.metadata["upgrade_required"] && !upgraded)
|
||||
continue
|
||||
|
||||
if(ispath(rod_path, /obj/item/nuclear_rod/fuel))
|
||||
category_fuel += D
|
||||
else if(ispath(rod_path, /obj/item/nuclear_rod/moderator))
|
||||
category_moderator += D
|
||||
else if(ispath(rod_path, /obj/item/nuclear_rod/coolant))
|
||||
category_coolant += D
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["fuel_rods"] = list()
|
||||
for(var/datum/nuclear_rod_design/D in category_fuel)
|
||||
data["fuel_rods"] += list(D.metadata)
|
||||
|
||||
data["moderator_rods"] = list()
|
||||
for(var/datum/nuclear_rod_design/D in category_moderator)
|
||||
data["moderator_rods"] += list(D.metadata)
|
||||
|
||||
data["coolant_rods"] = list()
|
||||
for(var/datum/nuclear_rod_design/D in category_coolant)
|
||||
data["coolant_rods"] += list(D.metadata)
|
||||
|
||||
// Add available resources from the material container
|
||||
data["resources"] = list()
|
||||
if(materials)
|
||||
// Get all material types that the fabricator supports
|
||||
var/list/supported_materials = list(
|
||||
MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA,
|
||||
MAT_URANIUM, MAT_TITANIUM, MAT_BLUESPACE, MAT_PLASTIC, MAT_BANANIUM, MAT_TRANQUILLITE
|
||||
)
|
||||
for(var/mat_id in supported_materials)
|
||||
var/amount = materials.amount(mat_id)
|
||||
if(amount > 0)
|
||||
var/sheets = round(amount / MINERAL_MATERIAL_AMOUNT)
|
||||
var/display_name = CallMaterialName(mat_id)
|
||||
data["resources"][display_name] = list(
|
||||
"amount" = amount,
|
||||
"sheets" = sheets,
|
||||
"id" = mat_id
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/interact(mob/user)
|
||||
. = ..()
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_WARNING("You can't access [src] while it's opened!"))
|
||||
return
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "NuclearRodFabricator", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
if(..())
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("fabricate_rod")
|
||||
var/rod_type_path = text2path(params["type_path"])
|
||||
if(!rod_type_path)
|
||||
return FALSE
|
||||
|
||||
var/datum/nuclear_rod_design/selected_design
|
||||
for(var/datum/nuclear_rod_design/D in category_fuel + category_moderator + category_coolant)
|
||||
if(D.type_path == rod_type_path)
|
||||
selected_design = D
|
||||
break
|
||||
|
||||
if(!selected_design)
|
||||
return FALSE
|
||||
|
||||
if(power_state == ACTIVE_POWER_USE)
|
||||
to_chat(usr, SPAN_WARNING("A rod is already being fabricated!"))
|
||||
return FALSE
|
||||
|
||||
// Check if we have enough materials
|
||||
var/obj/item/nuclear_rod/temp_rod = new rod_type_path()
|
||||
var/list/required_materials = temp_rod.materials
|
||||
qdel(temp_rod)
|
||||
|
||||
if(!required_materials || !length(required_materials))
|
||||
to_chat(usr, SPAN_WARNING("This rod design has no material requirements defined - please create an issue report!"))
|
||||
return FALSE
|
||||
|
||||
for(var/mat_id in required_materials)
|
||||
var/required_amount = required_materials[mat_id] * efficiency_coeff
|
||||
if(materials.amount(mat_id) < required_amount)
|
||||
to_chat(usr, SPAN_WARNING("Not enough materials! Need [required_amount] units of [mat_id]!"))
|
||||
return FALSE
|
||||
|
||||
// Spend materials
|
||||
var/list/materials_to_use = list()
|
||||
for(var/mat_id in required_materials)
|
||||
materials_to_use[mat_id] = required_materials[mat_id] * efficiency_coeff
|
||||
|
||||
if(!materials.use_amount(materials_to_use))
|
||||
to_chat(usr, SPAN_WARNING("Failed to deduct materials!"))
|
||||
return FALSE
|
||||
|
||||
// Begin Process
|
||||
begin_fabrication(rod_type_path)
|
||||
|
||||
return TRUE
|
||||
|
||||
if("eject_material")
|
||||
var/material_id = params["id"]
|
||||
var/amount = params["amount"]
|
||||
|
||||
if(!material_id || !materials.materials[material_id])
|
||||
return FALSE
|
||||
|
||||
var/desired_sheets = 0
|
||||
if(amount == "custom")
|
||||
var/datum/material/M = materials.materials[material_id]
|
||||
var/max_sheets = round(M.amount / MINERAL_MATERIAL_AMOUNT)
|
||||
if(max_sheets <= 0)
|
||||
to_chat(usr, SPAN_WARNING("Not enough [M.name] to eject!"))
|
||||
return FALSE
|
||||
desired_sheets = tgui_input_number(usr, "How many sheets do you want to eject?", "Ejecting [M.name]", 1, max_sheets, 1)
|
||||
if(isnull(desired_sheets))
|
||||
return FALSE
|
||||
else
|
||||
desired_sheets = text2num(amount)
|
||||
|
||||
desired_sheets = max(0, round(desired_sheets))
|
||||
if(desired_sheets > 0)
|
||||
materials.retrieve_sheets(desired_sheets, material_id, get_turf(src))
|
||||
to_chat(usr, SPAN_NOTICE("[src] ejects [desired_sheets] sheets."))
|
||||
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(power_state == ACTIVE_POWER_USE)
|
||||
to_chat(user, SPAN_WARNING("The machine cannot be opened while it is operating!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
default_deconstruction_screwdriver(user, "rod_fab_maint", "rod_fab", I)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/begin_fabrication(rod_type_path)
|
||||
power_state = ACTIVE_POWER_USE
|
||||
icon_state = "rod_fab_on"
|
||||
COOLDOWN_START(src, fabrication_timer, work_time)
|
||||
schematic = rod_type_path
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/finish_fabrication()
|
||||
power_state = IDLE_POWER_USE
|
||||
icon_state = "rod_fab"
|
||||
var/obj/item/nuclear_rod/new_rod = new schematic(get_turf(src))
|
||||
src.visible_message(SPAN_NOTICE("[src] fabricates \a [new_rod.name]."))
|
||||
playsound(src, 'sound/machines/ping.ogg', 50, TRUE)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/proc/abort_fabrication()
|
||||
power_state = IDLE_POWER_USE
|
||||
icon_state = "rod_fab"
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
|
||||
/obj/machinery/nuclear_rod_fabricator/process()
|
||||
if(stat & NOPOWER)
|
||||
if(power_state == ACTIVE_POWER_USE)
|
||||
abort_fabrication()
|
||||
return
|
||||
if(power_state == IDLE_POWER_USE)
|
||||
return
|
||||
if(!COOLDOWN_FINISHED(src, fabrication_timer))
|
||||
return
|
||||
finish_fabrication()
|
||||
|
||||
#undef DEFAULT_OPERATION_TIME
|
||||
810
code/modules/power/engines/fission/rod_chamber.dm
Normal file
810
code/modules/power/engines/fission/rod_chamber.dm
Normal file
@@ -0,0 +1,810 @@
|
||||
#define CHAMBER_HEAT_DAMAGE 15 //! How much damage reactor chambers do when on.
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber
|
||||
name = "rod housing chamber"
|
||||
desc = "A chamber used to house nuclear rods of various types to facilitate a fission reaction."
|
||||
icon = 'icons/obj/fission/reactor_chamber.dmi'
|
||||
icon_state = "chamber_down"
|
||||
layer = BELOW_OBJ_LAYER
|
||||
pass_flags_self = PASSTAKE
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF | FREEZE_PROOF
|
||||
max_integrity = 400
|
||||
armor = list(melee = 80, bullet = 30, laser = 30, energy = 10, bomb = 40, rad = INFINITY, fire = INFINITY, acid = INFINITY) // Fairly robust
|
||||
idle_power_consumption = 100
|
||||
flags_2 = NO_MALF_EFFECT_2
|
||||
|
||||
/// Each reactor chamber can only be linked to a single reactor, if somehow theres two.
|
||||
var/obj/machinery/atmospherics/fission_reactor/linked_reactor
|
||||
/// Holds the specific rod inserted into the chamber
|
||||
var/obj/item/nuclear_rod/held_rod
|
||||
/// Is the chamber up, down, or open
|
||||
var/chamber_state = 1
|
||||
/// Has the requirements for the rod inside this chamber been met?
|
||||
var/requirements_met = FALSE
|
||||
/// Is the rod chamber actively running and providing its effects
|
||||
var/operational = FALSE
|
||||
/// Holds the list of linked neighbors
|
||||
var/list/neighbors = list()
|
||||
/// Skip this chamber when building links
|
||||
var/skip_link = FALSE
|
||||
/// The total amount of heat produced by this chamber
|
||||
var/heat_total
|
||||
/// The total amount of power produced by this rod
|
||||
var/power_total
|
||||
/// Is the chamber currently in an enrichment process
|
||||
var/enriching = FALSE
|
||||
/// Has the chamber been welded shut. Uh oh!
|
||||
var/welded = FALSE
|
||||
/// Holds the current accumulated power mod value from its neighbors
|
||||
var/power_mod_total = 1
|
||||
/// Holds the current accumulated heat mod value from its neighbors
|
||||
var/heat_mod_total = 1
|
||||
/// A simple binary to prevent open/close spam mucking up the anims
|
||||
var/lockout = FALSE
|
||||
/// Holds our durability bar overlay level. Updates overlays if it changes
|
||||
var/durability_level = 0
|
||||
/// Holds our previous overlay.
|
||||
var/previous_durability_level
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/Initialize(mapload)
|
||||
. = ..()
|
||||
dupe_check()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/circuitboard/machine/reactor_chamber(src)
|
||||
component_parts += new /obj/item/stock_parts/manipulator(src)
|
||||
component_parts += new /obj/item/stack/sheet/mineral/plastitanium(src, 2)
|
||||
component_parts += new /obj/item/stack/sheet/metal(src, 2)
|
||||
component_parts += new /obj/item/stack/cable_coil(src, 5)
|
||||
RefreshParts()
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
RegisterSignal(src, COMSIG_PARENT_EXAMINE, PROC_REF(deep_examine))
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
// Needs to be late so it does not initialize before the reactor or the other neighbors are ready
|
||||
/obj/machinery/atmospherics/reactor_chamber/LateInitialize()
|
||||
. = ..()
|
||||
find_link()
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/uranium
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/uranium/Initialize(mapload)
|
||||
. = ..()
|
||||
held_rod = new /obj/item/nuclear_rod/fuel/uranium_238(src)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/heavy_water
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/heavy_water/Initialize(mapload)
|
||||
. = ..()
|
||||
held_rod = new /obj/item/nuclear_rod/moderator/heavy_water(src)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/examine(mob/user)
|
||||
. = ..()
|
||||
. += SPAN_NOTICE("[src] can be sealed/unsealed from its base with a lit welder using harm intent, but only while the chamber is lowered.")
|
||||
. += SPAN_NOTICE("Alt+click to open and close the shielding while the chamber is raised.")
|
||||
. += SPAN_NOTICE("Click on the chamber while it is closed to raise and lower it.")
|
||||
|
||||
if(isobserver(user))
|
||||
// observers get regular examine + nested multitool info
|
||||
var/list/deep_info = get_deep_examine_info()
|
||||
if(length(deep_info))
|
||||
. += chat_box_examine(deep_info.Join("<br>"))
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/on_deconstruction()
|
||||
desync()
|
||||
if(held_rod) // We shouldnt be able to decon with this in, but just in case
|
||||
if(held_rod.reactor_overheat_modifier)
|
||||
linked_reactor.update_overheat_threshold(-held_rod.reactor_overheat_modifier)
|
||||
held_rod.forceMove(loc)
|
||||
held_rod = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/Destroy()
|
||||
if(held_rod && held_rod.reactor_overheat_modifier)
|
||||
linked_reactor.update_overheat_threshold(-held_rod.reactor_overheat_modifier)
|
||||
QDEL_NULL(held_rod)
|
||||
if(linked_reactor)
|
||||
desync()
|
||||
UnregisterSignal(src, COMSIG_PARENT_EXAMINE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/update_overlays()
|
||||
. = ..()
|
||||
overlays.Cut()
|
||||
if(welded)
|
||||
var/mutable_appearance/weld_overlay = mutable_appearance(layer = BELOW_OBJ_LAYER + 0.03)
|
||||
weld_overlay.icon_state = "welded"
|
||||
. += weld_overlay
|
||||
if(chamber_state == CHAMBER_OPEN)
|
||||
var/mutable_appearance/cover_icon = mutable_appearance(layer = ABOVE_ALL_MOB_LAYER + 0.02)
|
||||
cover_icon.icon = icon
|
||||
cover_icon.icon_state = "door_open"
|
||||
. += cover_icon
|
||||
|
||||
if(!held_rod)
|
||||
return
|
||||
if(chamber_state == CHAMBER_OPEN)
|
||||
var/mutable_appearance/rod_overlay = mutable_appearance(layer = ABOVE_ALL_MOB_LAYER + 0.01)
|
||||
rod_overlay.icon = icon
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
rod_overlay.icon_state = "fuel_overlay"
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/coolant))
|
||||
rod_overlay.icon_state = "coolant_overlay"
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/moderator))
|
||||
rod_overlay.icon_state = "moderator_overlay"
|
||||
. += rod_overlay
|
||||
|
||||
var/mutable_appearance/state_overlay = mutable_appearance(layer = BELOW_OBJ_LAYER + 0.01)
|
||||
state_overlay.icon = icon
|
||||
if(chamber_state == CHAMBER_DOWN)
|
||||
if(enriching)
|
||||
state_overlay.icon_state = "blue"
|
||||
else if(requirements_met)
|
||||
if(operational)
|
||||
state_overlay.icon_state = "green"
|
||||
else
|
||||
state_overlay.icon_state = "orange"
|
||||
else
|
||||
if(operational)
|
||||
state_overlay.icon_state = "orange"
|
||||
else
|
||||
state_overlay.icon_state = "red"
|
||||
|
||||
var/mutable_appearance/display_overlay = mutable_appearance(layer = BELOW_OBJ_LAYER + 0.01)
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
display_overlay.icon_state = "display_fuel"
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/moderator))
|
||||
display_overlay.icon_state = "display_moderator"
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/coolant))
|
||||
display_overlay.icon_state = "display_coolant"
|
||||
. += display_overlay
|
||||
if(chamber_state == CHAMBER_OVERLOAD_IDLE)
|
||||
if(held_rod && istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
state_overlay.icon_state = "orange"
|
||||
else
|
||||
state_overlay.icon_state = "red"
|
||||
if(chamber_state == CHAMBER_OVERLOAD_ACTIVE)
|
||||
state_overlay.icon_state = "overload"
|
||||
. += state_overlay
|
||||
|
||||
var/mutable_appearance/durability_overlay = mutable_appearance(icon, layer = BELOW_OBJ_LAYER + 0.01)
|
||||
durability_overlay.icon_state = "dur_[previous_durability_level]"
|
||||
. += durability_overlay
|
||||
|
||||
/// Check for multiple on a tile and nuke it
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/dupe_check()
|
||||
var/obj/machinery/atmospherics/reactor_chamber/chamber = locate() in range(0, src)
|
||||
if(chamber && chamber != src)
|
||||
visible_message(SPAN_WARNING("[src] has no room to deploy and breaks apart!"))
|
||||
chamber.deconstruct()
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/attack_hand(mob/user)
|
||||
if(!user)
|
||||
return
|
||||
if(linked_reactor && linked_reactor.admin_intervention)
|
||||
to_chat(user, SPAN_WARNING("An unusual force prevents you from moving the chamber!"))
|
||||
return
|
||||
if(stat & NOPOWER)
|
||||
to_chat(user, SPAN_WARNING("The chamber's locks wont disengage without power!"))
|
||||
return
|
||||
|
||||
if(!is_mecha_occupant(user))
|
||||
add_fingerprint(user)
|
||||
|
||||
switch(chamber_state)
|
||||
if(CHAMBER_DOWN, CHAMBER_OVERLOAD_IDLE)
|
||||
if(!Adjacent(user))
|
||||
return
|
||||
if(welded)
|
||||
to_chat(user, SPAN_WARNING("[src] is welded shut. It wont budge!"))
|
||||
return
|
||||
if(!density_check(user))
|
||||
return
|
||||
var/delay = 1 SECONDS
|
||||
if(linked_reactor && !linked_reactor.offline)
|
||||
delay = 8 SECONDS
|
||||
if(!is_mecha_occupant(user)) // Mech users are unaffected
|
||||
burn_handler(user)
|
||||
if(do_after_once(user, delay, target = src, allow_moving = FALSE))
|
||||
if(!Adjacent(user)) // For mecha users
|
||||
return
|
||||
if(density_check(user))
|
||||
raise()
|
||||
return
|
||||
|
||||
if(CHAMBER_UP)
|
||||
if(!density_check(user))
|
||||
return
|
||||
if(do_after_once(user, 2 SECONDS, target = src, allow_moving = FALSE))
|
||||
if(chamber_state != CHAMBER_UP) // So that we cant lower while in the open state
|
||||
return
|
||||
if(density_check(user))
|
||||
lower()
|
||||
return
|
||||
|
||||
if(CHAMBER_OPEN)
|
||||
if(issilicon(user)) // Handled seperately. Dont pull out this way
|
||||
return
|
||||
if(!held_rod)
|
||||
to_chat(user, SPAN_WARNING("There is no rod inside of the chamber to remove!"))
|
||||
return
|
||||
if(user.put_in_hands(held_rod))
|
||||
held_rod.add_fingerprint(user)
|
||||
held_rod = null
|
||||
playsound(loc, 'sound/machines/podopen.ogg', 50, TRUE)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return
|
||||
|
||||
to_chat(user, SPAN_WARNING("Your hands are currently full!"))
|
||||
return
|
||||
if(CHAMBER_OVERLOAD_ACTIVE)
|
||||
to_chat(user, SPAN_ALERT("The chamber lockdowns have been engaged, preventing it from being raised!"))
|
||||
return
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/AltClick(mob/user, modifiers)
|
||||
if(!Adjacent(user) || lockout)
|
||||
return
|
||||
if(linked_reactor && linked_reactor.admin_intervention)
|
||||
to_chat(user, SPAN_WARNING("An unusual force prevents you from manipulating the chamber!"))
|
||||
return
|
||||
if(chamber_state == CHAMBER_UP)
|
||||
if(!lockout)
|
||||
open()
|
||||
return
|
||||
if(chamber_state == CHAMBER_OPEN)
|
||||
if(panel_open == TRUE)
|
||||
to_chat(user, SPAN_WARNING("You must close the maintenance panel before the chamber can be sealed!"))
|
||||
return
|
||||
if(!lockout)
|
||||
close()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/density_check(mob/user)
|
||||
for(var/atom/thing in get_turf(src))
|
||||
if(thing == src)
|
||||
continue
|
||||
if(thing.density)
|
||||
to_chat(user, SPAN_WARNING("The chamber is being blocked from opening!"))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(issilicon(user) && get_dist(src, user) > 1)
|
||||
attack_hand(user)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
if(istype(used, /obj/item/nuclear_rod))
|
||||
if(chamber_state == CHAMBER_OPEN)
|
||||
if(held_rod)
|
||||
to_chat(user, SPAN_WARNING("There is already a rod inside of the chamber!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(panel_open)
|
||||
to_chat(user, SPAN_WARNING("The open maintenance panel prevents the rod from slotting inside!"))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(user.transfer_item_to(used, src, force = TRUE))
|
||||
held_rod = used
|
||||
playsound(loc, 'sound/machines/podclose.ogg', 50, TRUE)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/screwdriver_act(mob/living/user, obj/item/I)
|
||||
if(!I.use_tool(src, user, 0, volume = 0))
|
||||
return
|
||||
. = TRUE
|
||||
if(chamber_state != CHAMBER_OPEN)
|
||||
to_chat(user, SPAN_ALERT("[src] must be raised and opened first!"))
|
||||
return
|
||||
if(linked_reactor && !linked_reactor.offline)
|
||||
to_chat(user, SPAN_ALERT("The safety locks prevent maintenance while the reactor is on!"))
|
||||
return
|
||||
if(held_rod)
|
||||
to_chat(user, SPAN_ALERT("You cannot reach the maintenance panel if there is a rod inside!"))
|
||||
return
|
||||
default_deconstruction_screwdriver(user, "chamber_maint", "chamber_open", I)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/crowbar_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
default_deconstruction_crowbar(user, I)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/welder_act(mob/living/user, obj/item/I)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
if(chamber_state == CHAMBER_OVERLOAD_IDLE || chamber_state == CHAMBER_OVERLOAD_ACTIVE)
|
||||
to_chat(user, SPAN_WARNING("You probably shouldn't try to weld it right now."))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(chamber_state != CHAMBER_DOWN)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
to_chat(user, SPAN_WARNING("You begin [welded ? "unwelding" : "welding"] [src]"))
|
||||
if(!I.use_tool(src, user, (6 SECONDS) * I.toolspeed, volume = I.tool_volume))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(welded)
|
||||
unweld()
|
||||
else
|
||||
weld_shut()
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
if(obj_integrity < max_integrity)
|
||||
to_chat(user, SPAN_WARNING("You begin repairing [src]."))
|
||||
if(!I.use_tool(src, user, (3 SECONDS) * I.toolspeed, volume = I.tool_volume))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
obj_integrity = max_integrity // Lets make sure we can keep these healthy if need be
|
||||
else
|
||||
to_chat(user, SPAN_WARNING("[src] is not in need of repair."))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/multitool_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
show_deep_examine(user)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/get_deep_examine_info()
|
||||
if(chamber_state != CHAMBER_DOWN)
|
||||
return null
|
||||
if(!held_rod)
|
||||
return list(SPAN_WARNING("There is no nuclear rod inside this housing chamber."))
|
||||
if(!linked_reactor)
|
||||
return list(SPAN_WARNING("This chamber is not connected to a reactor."))
|
||||
|
||||
var/operating_rate = linked_reactor.operating_rate()
|
||||
var/durability_mod = held_rod.get_durability_mod()
|
||||
var/list/message = list()
|
||||
message += SPAN_NOTICE("[held_rod] is currently contained within this chamber.")
|
||||
|
||||
message += ""
|
||||
|
||||
if(held_rod.durability == 0)
|
||||
message += SPAN_NOTICE("The rod has been fully depleted and rendered inert.")
|
||||
return message
|
||||
else
|
||||
message += SPAN_NOTICE("Rod integrity is at [(held_rod.durability / held_rod.max_durability) * 100]%.")
|
||||
|
||||
message += ""
|
||||
|
||||
if(power_total && operational)
|
||||
message += SPAN_NOTICE("The chamber is currently producing [(power_total * operating_rate * durability_mod) / 1000] KiloWatts of energy.")
|
||||
message += SPAN_NOTICE("The chamber has a power modifier of [power_mod_total].")
|
||||
else
|
||||
message += SPAN_NOTICE("The chamber is producing no power.")
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
var/obj/item/nuclear_rod/fuel/rod = held_rod
|
||||
if(rod.power_enrich_progress >= rod.enrichment_cycles && rod.power_enrich_result)
|
||||
message += SPAN_NOTICE("[held_rod] has been power enriched")
|
||||
else
|
||||
message += SPAN_NOTICE("[held_rod] has not yet finished a power enrichment process.")
|
||||
|
||||
message += ""
|
||||
|
||||
if(heat_total)
|
||||
message += SPAN_NOTICE("The chamber is currently producing [heat_total * HEAT_MODIFIER * operating_rate * durability_mod] joules of heat.")
|
||||
message += SPAN_NOTICE("The chamber has a heat modifier of [heat_mod_total].")
|
||||
else
|
||||
message += SPAN_NOTICE("The chamber is producing no heat.")
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
var/obj/item/nuclear_rod/fuel/rod = held_rod
|
||||
if(rod.heat_enrich_progress >= rod.enrichment_cycles && rod.heat_enrich_result)
|
||||
message += SPAN_NOTICE("[held_rod] has been heat enriched")
|
||||
else
|
||||
message += SPAN_NOTICE("[held_rod] has not yet finished a heat enrichment process.")
|
||||
|
||||
return message
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/show_deep_examine(mob/user)
|
||||
var/list/info = get_deep_examine_info()
|
||||
if(!info)
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
to_chat(user, chat_box_examine(info.Join("<br>")))
|
||||
return ITEM_INTERACT_COMPLETE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/deep_examine(datum/source, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER // COMSIG_PARENT_EXAMINE
|
||||
show_deep_examine(user)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/raise(playsound = TRUE)
|
||||
chamber_state = CHAMBER_UP
|
||||
icon_state = "chamber_up_anim"
|
||||
lockout = TRUE
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_raise_anim)), 0.7 SECONDS)
|
||||
density = TRUE
|
||||
operational = FALSE
|
||||
enriching = FALSE
|
||||
requirements_met = FALSE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
power_total = 0
|
||||
check_minimum_modifier()
|
||||
if(held_rod && held_rod.reactor_overheat_modifier)
|
||||
linked_reactor.update_overheat_threshold(-held_rod.reactor_overheat_modifier)
|
||||
if(playsound)
|
||||
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
if(linked_reactor.offline)
|
||||
held_rod.start_rads()
|
||||
else
|
||||
held_rod.start_rads(linked_reactor.reactivity_multiplier)
|
||||
|
||||
update_icon()
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in neighbors)
|
||||
if(!chamber.held_rod)
|
||||
continue
|
||||
if(chamber.check_status())
|
||||
chamber.requirements_met = TRUE
|
||||
else
|
||||
chamber.requirements_met = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/finish_raise_anim()
|
||||
lockout = FALSE
|
||||
icon_state = "chamber_up"
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/lower(playsound = TRUE)
|
||||
density = FALSE
|
||||
layer = BELOW_OBJ_LAYER
|
||||
if(playsound)
|
||||
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
|
||||
if(linked_reactor && linked_reactor.safety_override)
|
||||
chamber_state = CHAMBER_OVERLOAD_IDLE
|
||||
icon_state = "chamber_overload"
|
||||
if(linked_reactor.check_overload_ready())
|
||||
linked_reactor.set_overload()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
chamber_state = CHAMBER_DOWN
|
||||
icon_state = "chamber_down_anim"
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_down_anim)), 1.3 SECONDS)
|
||||
|
||||
if(!held_rod)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
held_rod.stop_rads()
|
||||
if(held_rod.reactor_overheat_modifier)
|
||||
linked_reactor.update_overheat_threshold(held_rod.reactor_overheat_modifier)
|
||||
previous_durability_level = clamp(ROUND_UP(((held_rod.durability / held_rod.max_durability) * 5) - 0.8), 0, 5)
|
||||
if(check_status())
|
||||
requirements_met = TRUE
|
||||
else
|
||||
requirements_met = FALSE
|
||||
check_minimum_modifier()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/finish_down_anim()
|
||||
icon_state = "chamber_down"
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/close(playsound = TRUE)
|
||||
chamber_state = CHAMBER_UP
|
||||
new /obj/effect/temp_visual/chamber_closing(loc)
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_closing)), 0.5 SECONDS)
|
||||
lockout = TRUE
|
||||
if(playsound)
|
||||
playsound(loc, 'sound/machines/switch.ogg', 50, TRUE)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/finish_closing()
|
||||
lockout = FALSE
|
||||
icon_state = "chamber_up"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/open(playsound = TRUE)
|
||||
chamber_state = CHAMBER_OPEN
|
||||
icon_state = "chamber_open"
|
||||
var/cover_icon = mutable_appearance(icon, icon_state = "doors_opening", layer = ABOVE_ALL_MOB_LAYER + 0.02)
|
||||
add_overlay(cover_icon)
|
||||
lockout = TRUE
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_opening)), 0.5 SECONDS)
|
||||
if(playsound)
|
||||
playsound(loc, 'sound/machines/switch.ogg', 50, TRUE)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/finish_opening()
|
||||
lockout = FALSE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/set_idle_overload()
|
||||
if(chamber_state == CHAMBER_DOWN)
|
||||
chamber_state = CHAMBER_OVERLOAD_IDLE
|
||||
icon_state = "chamber_overload"
|
||||
if(welded)
|
||||
welded = FALSE
|
||||
operational = FALSE
|
||||
enriching = FALSE
|
||||
requirements_met = FALSE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/set_active_overload()
|
||||
chamber_state = CHAMBER_OVERLOAD_ACTIVE
|
||||
icon_state = "chamber_down"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/// Gets the neighbors of the current chamber, and adds itself to its neighbors. can prompt a cascade of linking
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/get_neighbors()
|
||||
for(var/direction in GLOB.cardinal)
|
||||
var/obj/machinery/atmospherics/reactor_chamber/chamber = locate() in get_step(src, direction)
|
||||
if(!chamber)
|
||||
continue
|
||||
if(chamber.linked_reactor && chamber.linked_reactor != linked_reactor) // If for some god forsaken reason we have two
|
||||
continue
|
||||
if((chamber in neighbors) || (src in chamber.neighbors))
|
||||
continue
|
||||
neighbors += chamber
|
||||
chamber.neighbors += src
|
||||
if(!chamber.linked_reactor)
|
||||
chamber.linked_reactor = linked_reactor
|
||||
linked_reactor.connected_chambers += chamber
|
||||
chamber.get_neighbors()
|
||||
|
||||
/// Removes the chamber from neighbor from its neighbors, and forces them to run status checks
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/desync()
|
||||
if(length(neighbors))
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in neighbors)
|
||||
chamber.neighbors -= src
|
||||
neighbors.Cut()
|
||||
if(linked_reactor)
|
||||
linked_reactor.connected_chambers -= src
|
||||
linked_reactor.clear_reactor_network(restart = TRUE)
|
||||
|
||||
/// Forms the two-way link between the reactor and the chamber, then searches for valid neighbors.
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/form_link(obj/machinery/atmospherics/fission_reactor/reactor)
|
||||
if(linked_reactor || skip_link) // Prevent duplicate linking or unwanted chambers
|
||||
return
|
||||
linked_reactor = reactor
|
||||
linked_reactor.connected_chambers |= src
|
||||
get_neighbors()
|
||||
|
||||
/// Searches for a valid reactor or linked chamber nearby
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/find_link()
|
||||
if(linked_reactor) // We already have a linked reactor
|
||||
return
|
||||
var/turf/nearby_turf
|
||||
for(var/direction in GLOB.cardinal)
|
||||
nearby_turf = get_step(src, direction)
|
||||
var/obj/machinery/atmospherics/fission_reactor/reactor = locate() in nearby_turf
|
||||
if(reactor)
|
||||
form_link(reactor)
|
||||
return TRUE
|
||||
var/obj/structure/filler/filler = locate() in nearby_turf
|
||||
if(filler &&istype(filler.parent, /obj/machinery/atmospherics/fission_reactor))
|
||||
form_link(filler.parent)
|
||||
return TRUE
|
||||
var/obj/machinery/atmospherics/reactor_chamber/chamber = locate() in nearby_turf
|
||||
if(chamber &&chamber.linked_reactor)
|
||||
form_link(chamber.linked_reactor)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/// Validates that all rod requirements are being met
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/check_status()
|
||||
if(!held_rod)
|
||||
return FALSE
|
||||
|
||||
var/list/temp_requirements = list()
|
||||
temp_requirements += held_rod.adjacent_requirements // A temporary modable holder
|
||||
if(!temp_requirements)
|
||||
return TRUE
|
||||
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in neighbors)
|
||||
if(!chamber.operational)
|
||||
continue
|
||||
if(chamber.held_rod.type in temp_requirements)
|
||||
temp_requirements -= chamber.held_rod.type
|
||||
continue
|
||||
for(var/requirement in temp_requirements)
|
||||
if(chamber.held_rod.type in typesof(requirement))
|
||||
temp_requirements -= requirement
|
||||
break
|
||||
|
||||
if(!length(temp_requirements))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/process()
|
||||
if(!linked_reactor)
|
||||
if(find_link())
|
||||
get_neighbors()
|
||||
return
|
||||
if(linked_reactor.admin_intervention)
|
||||
return
|
||||
if(!held_rod)
|
||||
return
|
||||
if(chamber_state != CHAMBER_DOWN) // We should only process reactor info when down
|
||||
return
|
||||
durability_level = clamp(ROUND_UP(((held_rod.durability / held_rod.max_durability) * 5) - 0.8), 0, 5)
|
||||
if(durability_level != previous_durability_level)
|
||||
previous_durability_level = durability_level
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
if(!linked_reactor.offline)
|
||||
held_rod.calc_stat_decrease() // Only need to re-calc durability loss when the chamber is down and reactor is online
|
||||
if(linked_reactor && linked_reactor.safety_override && !linked_reactor.control_lockout) // we only remove control lockout when the others are ready
|
||||
if(chamber_state == CHAMBER_OVERLOAD_IDLE && istype(held_rod, /obj/item/nuclear_rod/fuel))
|
||||
set_active_overload() // For latejoiners
|
||||
if(operational && held_rod.durability <= 0)
|
||||
requirements_met = FALSE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return
|
||||
if(!requirements_met && !operational)
|
||||
if(check_status())
|
||||
requirements_met = TRUE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return
|
||||
if(requirements_met && !operational)
|
||||
if(prob(20))
|
||||
operational = TRUE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return
|
||||
if(!requirements_met && operational) // If it loses requirements, it wont immediately turn off
|
||||
if(istype(held_rod, /obj/item/nuclear_rod/coolant))
|
||||
if(prob(15)) // Higher rates of coolant rod failures once they're already on. Good luck.
|
||||
operational = FALSE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
else if(prob(1))
|
||||
enriching = FALSE
|
||||
operational = FALSE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/process_atmos()
|
||||
if(!held_rod || !linked_reactor || linked_reactor.offline)
|
||||
return
|
||||
if(chamber_state != CHAMBER_OPEN && chamber_state != CHAMBER_UP)
|
||||
return
|
||||
if(linked_reactor.admin_intervention)
|
||||
return
|
||||
|
||||
var/datum/milla_safe/chamber_process/milla = new()
|
||||
milla.invoke_async(src)
|
||||
|
||||
/datum/milla_safe/chamber_process
|
||||
|
||||
/datum/milla_safe/chamber_process/on_run(obj/machinery/atmospherics/reactor_chamber/chamber)
|
||||
var/turf/T = get_turf(chamber)
|
||||
var/datum/gas_mixture/environment = get_turf_air(T)
|
||||
|
||||
if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity.
|
||||
return PROCESS_KILL
|
||||
|
||||
if(!istype(chamber.loc, /turf)) // How in the FUCK did we manage this
|
||||
return // Yeah just stop.
|
||||
|
||||
if(T.density)
|
||||
var/turf/did_it_melt = T.ChangeTurf(T.baseturf)
|
||||
if(!did_it_melt.density) // In case some joker finds way to place these on indestructible walls
|
||||
chamber.visible_message(SPAN_WARNING("[chamber] melts through [T]!"))
|
||||
return
|
||||
|
||||
var/heat_capacity = environment.heat_capacity()
|
||||
var/heat_change = max(chamber.heat_total / heat_capacity) * HEAT_MODIFIER // the hotter the rod, the hotter the air
|
||||
var/temp = environment.temperature()
|
||||
if(chamber.chamber_state == CHAMBER_UP) // Its not fully exposed yet, and heating the reactor
|
||||
heat_change *= 0.25
|
||||
heat_change = max(heat_change, 1) // Always heat up at least a little
|
||||
environment.set_temperature(temp + heat_change)
|
||||
|
||||
/// Calculate how much heat and energy we should be making
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/calculate_stats(operating_rate = 0)
|
||||
power_total = (held_rod.power_amount * operating_rate)
|
||||
heat_total = (held_rod.heat_amount * operating_rate)
|
||||
|
||||
power_mod_total = 1
|
||||
heat_mod_total = 1
|
||||
for(var/obj/machinery/atmospherics/reactor_chamber/chamber in neighbors)
|
||||
if(!chamber.held_rod || chamber.chamber_state == CHAMBER_OPEN)
|
||||
continue
|
||||
if(istype(chamber.held_rod, /obj/item/nuclear_rod/coolant) && !chamber.operational) // Do not apply negative heat gen on coolant when not on.
|
||||
heat_mod_total *= 1
|
||||
else if(held_rod.heat_amount > 0) // Do not multiply negative heat.
|
||||
heat_mod_total *= chamber.held_rod.current_heat_mod // We generate heat even when its not operational
|
||||
if(operational && chamber.chamber_state == CHAMBER_DOWN)
|
||||
if(held_rod.power_amount > 0) // Do not multiply negative power.
|
||||
power_mod_total *= chamber.held_rod.current_power_mod
|
||||
|
||||
power_total *= power_mod_total
|
||||
heat_total *= heat_mod_total
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/eject_rod()
|
||||
raise(FALSE)
|
||||
open(FALSE)
|
||||
var/datum/effect_system/smoke_spread/bad/smoke = new()
|
||||
smoke.set_up(5, FALSE, loc)
|
||||
smoke.start()
|
||||
var/rad_type = pick(ALPHA_RAD, BETA_RAD, GAMMA_RAD)
|
||||
for(var/turf/T in view(2, loc))
|
||||
T.contaminate_atom(src, 300, rad_type)
|
||||
var/distance_traveled = rand(10, 60)
|
||||
var/angle = rand(0, 360)
|
||||
var/turf/end = get_turf_in_angle(angle, loc, distance_traveled)
|
||||
var/obj/effect/immovablerod/nuclear_rod/nuclear_rod = new(loc, end)
|
||||
var/matrix/M = new
|
||||
M.Turn(angle)
|
||||
nuclear_rod.transform = M
|
||||
nuclear_rod.icon = held_rod.icon
|
||||
nuclear_rod.icon_state = held_rod.icon_state
|
||||
nuclear_rod.held_rod = held_rod
|
||||
held_rod.forceMove(src)
|
||||
held_rod = null
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
playsound(src, 'sound/effects/bang.ogg', 70, TRUE)
|
||||
audible_message(SPAN_USERDANGER("POW!"))
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/weld_shut()
|
||||
welded = TRUE
|
||||
playsound(loc, 'sound/items/welder2.ogg', 60, TRUE)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/unweld()
|
||||
welded = FALSE
|
||||
playsound(loc, 'sound/items/welder2.ogg', 60, TRUE)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/burn_handler(mob/user)
|
||||
var/burn_damage = CHAMBER_HEAT_DAMAGE
|
||||
if(linked_reactor.check_overheating()) // Ouch, even hotter!
|
||||
burn_damage *= 2
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.gloves)
|
||||
var/obj/item/clothing/gloves/G = H.gloves
|
||||
if(G.max_heat_protection_temperature)
|
||||
burn_damage *= 0.5
|
||||
else if(HAS_TRAIT(H, TRAIT_RESISTHEAT) || HAS_TRAIT(H, TRAIT_RESISTHEATHANDS))
|
||||
burn_damage *= 0.5
|
||||
var/obj/item/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_hand")
|
||||
if(affecting.receive_damage(0, burn_damage)) // Burn damage to them fingers
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
else if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(issilicon(L)) // More resistant by default
|
||||
burn_damage *= 0.5
|
||||
L.adjustFireLoss(burn_damage)
|
||||
|
||||
/obj/machinery/atmospherics/reactor_chamber/proc/check_minimum_modifier()
|
||||
if(!linked_reactor)
|
||||
return
|
||||
if(!held_rod)
|
||||
return
|
||||
if(!held_rod.minimum_temp_modifier)
|
||||
return
|
||||
if(held_rod.minimum_temp_modifier >= linked_reactor.minimum_operating_temp)
|
||||
linked_reactor.update_minimum_temp()
|
||||
|
||||
/obj/effect/immovablerod/nuclear_rod
|
||||
name = "\improper Nuclear Coolant Rod"
|
||||
desc = "Getting hit by this might make you wish you got radiation sickness instead."
|
||||
notify = FALSE
|
||||
var/obj/held_rod
|
||||
|
||||
/// Lets not break the reactor with this.
|
||||
/obj/effect/immovablerod/nuclear_rod/clong_thing(atom/victim)
|
||||
if(istype(victim, /obj/machinery/atmospherics/fission_reactor))
|
||||
return
|
||||
if(istype(victim, /obj/structure/filler))
|
||||
var/obj/structure/filler/filler = victim
|
||||
if(istype(filler.parent, /obj/machinery/atmospherics/fission_reactor))
|
||||
return
|
||||
if(istype(victim, /obj/machinery/atmospherics/reactor_chamber))
|
||||
return
|
||||
|
||||
if(isobj(victim) && victim.density)
|
||||
victim.ex_act(EXPLODE_HEAVY)
|
||||
else if(ismob(victim))
|
||||
if(ishuman(victim))
|
||||
var/mob/living/carbon/human/H = victim
|
||||
H.visible_message(SPAN_DANGER("[H.name] is penetrated by an ejected coolant rod!"),
|
||||
SPAN_USERDANGER("The rod penetrates you!"),
|
||||
SPAN_DANGER("You hear a CLANG!"))
|
||||
H.adjustBruteLoss(100) // Not as strong as a normal rod
|
||||
if(victim.density || prob(20)) // We want to hit more things than a normal rod though
|
||||
victim.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
/obj/effect/immovablerod/nuclear_rod/Move()
|
||||
. = ..()
|
||||
if(loc == end)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/immovablerod/nuclear_rod/Destroy()
|
||||
held_rod.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
#undef CHAMBER_HEAT_DAMAGE
|
||||
@@ -312,6 +312,16 @@
|
||||
build_path = /obj/item/circuitboard/singulo_monitor
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/nuclear_monitor
|
||||
name = "Console Board (Nuclear Reactor Monitoring)"
|
||||
desc = "Allows for the construction of circuit boards used to build a nuclear reactor monitoring console."
|
||||
id = "nuclear_monitor"
|
||||
req_tech = list("programming" = 2, "powerstorage" = 2)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/fission_monitor
|
||||
category = list("Computer Boards")
|
||||
|
||||
/datum/design/ordercomp
|
||||
name = "Console Board (Supply Ordering Console)"
|
||||
desc = "Allows for the construction of circuit boards used to build a supply ordering console."
|
||||
|
||||
@@ -106,3 +106,64 @@
|
||||
materials = list(MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/grounding_rod
|
||||
category = list("Engineering Machinery")
|
||||
|
||||
/datum/design/centrifuge
|
||||
name = "Machine Design (Nuclear Centrifuge Board)"
|
||||
desc = "The circuit board for a nuclear centrifuge."
|
||||
id = "nuclear_centrifuge"
|
||||
req_tech = list("programming" = 3, "materials" = 5, "magnets" = 5, "plasmatech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GOLD = 1000, MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/nuclear_centrifuge
|
||||
category = list("Power", "Engineering Machinery")
|
||||
|
||||
/datum/design/rod_fabricator
|
||||
name = "Machine Design (Nuclear Rod Fabricator Board)"
|
||||
desc = "The circuit board for a nuclear rod fabricator."
|
||||
id = "nuclear_fabricator"
|
||||
req_tech = list("programming" = 5, "materials" = 5, "magnets" = 4, "plasmatech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GOLD = 1000, MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/nuclear_rod_fabricator
|
||||
category = list("Power", "Engineering Machinery")
|
||||
|
||||
/datum/design/nuclear_gas_node
|
||||
name = "Machine Design (Nuclear Gas Node Board)"
|
||||
desc = "The circuit board for a nuclear gas node."
|
||||
id = "nuclear_gas_node"
|
||||
req_tech = list("programming" = 4, "materials" = 4, "magnets" = 4, "plasmatech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GOLD = 1000, MAT_GLASS = 1000)
|
||||
build_path = /obj/item/circuitboard/machine/reactor_gas_node
|
||||
category = list("Power", "Engineering Machinery")
|
||||
|
||||
/datum/design/rod_fabricator_upgrade
|
||||
name = "Nuclear Rod Fabricator Upgrade"
|
||||
desc = "A design disk containing a dizzying amount of designs and improvements for nuclear rod fabrication."
|
||||
id = "nuclear_fab_upgrade"
|
||||
req_tech = list("programming" = 5, "materials" = 5, "magnets" = 4, "plasmatech" = 3, "toxins" = 3)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 2000, MAT_GLASS = 2000, MAT_URANIUM = 500, MAT_GOLD = 400)
|
||||
build_path = /obj/item/rod_fabricator_upgrade
|
||||
category = list("Power", "Engineering Machinery", "Misc")
|
||||
|
||||
/datum/design/reactor_chamber
|
||||
name = "Machine Design (Reactor Chamber Board)"
|
||||
desc = "A chamber used to house nuclear rods of various types to facilitate a fission reaction."
|
||||
id = "reactor_chamber"
|
||||
req_tech = list("programming" = 4, "materials" = 4, "magnets" = 4, "plasmatech" = 3)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000)
|
||||
build_path = /obj/item/circuitboard/machine/reactor_chamber
|
||||
category = list("Power", "Engineering Machinery", "Misc")
|
||||
|
||||
/datum/design/neutron_grenade
|
||||
name = "Neutron Agitator Grenade"
|
||||
desc = "A throwable device capable of inducing an artificial startup in rod chambers."
|
||||
id = "neutron_grenade"
|
||||
req_tech = list("materials" = 6, "magnets" = 5, "plasmatech" = 5, "toxins" = 5)
|
||||
build_type = PROTOLATHE
|
||||
materials = list(MAT_METAL = 2000, MAT_PLASMA = 2000, MAT_GOLD = 2000)
|
||||
build_path = /obj/item/grenade/nuclear_starter
|
||||
category = list("Power", "Misc")
|
||||
|
||||
|
||||
@@ -143,3 +143,8 @@
|
||||
status_display_data = "deltaalert"
|
||||
elevating_to_announcement_title = "Attention! Delta security level reached!"
|
||||
elevating_to_announcement_text = "The station's self-destruct mechanism has been engaged. All crew are instructed to abandon the station immediately. This is not a drill."
|
||||
|
||||
/datum/security_level/delta/overload
|
||||
number_level = SEC_LEVEL_DELTA_REACTOR
|
||||
elevating_to_announcement_title = "Attention! Delta-AZ5 security level reached!"
|
||||
elevating_to_announcement_text = "Central Command has disabled all nuclear fission reactor failsafes. Crew are instructed to ensure detonation of the station fission reactor at all costs."
|
||||
|
||||
83
code/modules/smithing/components/reactor_components.dm
Normal file
83
code/modules/smithing/components/reactor_components.dm
Normal file
@@ -0,0 +1,83 @@
|
||||
/obj/item/smithed_item/component/rod_housing
|
||||
name = "Debug rod housing"
|
||||
desc = ABSTRACT_TYPE_DESC
|
||||
icon_state = "rod_housing"
|
||||
part_type = PART_PRIMARY
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/plasma_agitator
|
||||
name = "plasma agitator cladding"
|
||||
desc = "The primary structural housing of a plasma agitator."
|
||||
materials = list(MAT_METAL = 6000, MAT_GOLD = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/plasma_agitator
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/aluminum_reflector
|
||||
name = "aluminum reflector cladding"
|
||||
desc = "The primary structural housing of an aluminum reflector."
|
||||
materials = list(MAT_METAL = 6000, MAT_GOLD = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/aluminum_reflector
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/molten_salt
|
||||
name = "molten salt circulator cladding"
|
||||
desc = "The primary structural housing of a molten salt circultor."
|
||||
materials = list(MAT_METAL = 6000, MAT_GLASS = 4000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/molten_salt
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/steam_hammerjet
|
||||
name = "steam hammerjet cladding"
|
||||
desc = "The primary structural housing of a steam hammerjet."
|
||||
materials = list(MAT_METAL = 6000, MAT_GLASS = 4000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/steam_hammerjet
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/platinum_refelctor
|
||||
name = "platinum plate cladding"
|
||||
desc = "The primary structural housing of a platinum reflector plate."
|
||||
materials = list(MAT_METAL = 6000, MAT_TITANIUM = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/platinum_plating
|
||||
|
||||
/obj/item/smithed_item/component/rod_housing/iridium_conductor
|
||||
name = "iridium conductor cladding"
|
||||
desc = "The primary structural housing of an iridium conductor."
|
||||
materials = list(MAT_METAL = 6000, MAT_TITANIUM = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/iridium_conductor
|
||||
|
||||
/obj/item/smithed_item/component/rod_core
|
||||
name = "Debug rod core"
|
||||
desc = ABSTRACT_TYPE_DESC
|
||||
icon_state = "rod_core"
|
||||
part_type = PART_SECONDARY
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/plasma_agitator
|
||||
name = "plasma agitator core"
|
||||
desc = "This is the primary core structure of a plasma agitator."
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_PLASMA = 6000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/plasma_agitator
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/aluminum_reflector
|
||||
name = "aluminum reflector core"
|
||||
desc = "This is the primary core structure of an aluminum reflector."
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_SILVER = 4000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/aluminum_reflector
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/molten_salt
|
||||
name = "molten salt circulator core"
|
||||
desc = "This is the primary core structure of a molten salt circulator."
|
||||
materials = list(MAT_TITANIUM = 4000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/molten_salt
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/steam_hammerjet
|
||||
name = "steam hammerjet core"
|
||||
desc = "This is the primary core structure of a steam hammerjet."
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_GOLD = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/steam_hammerjet
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/platinum_refelctor
|
||||
name = "platinum reflector core"
|
||||
desc = "This is the primary core structure of a platinum reflector."
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_PLATINUM = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/moderator/platinum_plating
|
||||
|
||||
/obj/item/smithed_item/component/rod_core/iridium_conductor
|
||||
name = "iridium conductor core"
|
||||
desc = "This is the primary core structure of an iridium conductor."
|
||||
materials = list(MAT_TITANIUM = 2000, MAT_IRIDIUM = 2000)
|
||||
finished_product = /obj/item/nuclear_rod/coolant/iridium_conductor
|
||||
@@ -289,6 +289,8 @@
|
||||
extra_product.material = current_product.material
|
||||
extra_product.set_stats()
|
||||
product = extra_product
|
||||
else if(istype(finished_product, /obj/item/nuclear_rod))
|
||||
product = new finished_product.type(get_turf(src))
|
||||
product.update_appearance(UPDATE_NAME)
|
||||
product.scatter_atom()
|
||||
|
||||
|
||||
@@ -180,6 +180,26 @@
|
||||
product_type = /obj/item/smithed_item/component/knife_handle
|
||||
basin_state = "cast_knife_handle"
|
||||
|
||||
/obj/item/smithing_cast/component/rod_housing
|
||||
name = "rod housing cast"
|
||||
icon_state = "rod_housing_cast"
|
||||
desc = "A cast for creating a nuclear rod housing frame."
|
||||
product_type = /obj/item/smithed_item/component/rod_housing
|
||||
basin_state = "cast_rod_housing"
|
||||
|
||||
/obj/item/smithing_cast/component/rod_housing/AltClick(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/smithing_cast/component/rod_core
|
||||
name = "rod core cast"
|
||||
icon_state = "rod_core_cast"
|
||||
desc = "A cast for creating a nuclear rod core."
|
||||
product_type = /obj/item/smithed_item/component/rod_core
|
||||
basin_state = "cast_rod_core"
|
||||
|
||||
/obj/item/smithing_cast/component/rod_core/AltClick(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/smithing_cast/component/trim
|
||||
name = "trim cast"
|
||||
icon_state = "trim_cast"
|
||||
|
||||
@@ -134,6 +134,12 @@ GLOBAL_LIST_INIT(non_simple_animals, typecacheof(list(/mob/living/carbon/human/m
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
invisibility = 101
|
||||
/// Keeps track of what the multitile is connected to
|
||||
var/parent
|
||||
|
||||
/obj/structure/filler/Destroy()
|
||||
parent = null
|
||||
. = ..()
|
||||
|
||||
/obj/structure/filler/ex_act()
|
||||
return
|
||||
|
||||
@@ -216,6 +216,54 @@
|
||||
cost = 750 //So cargo thinks twice before killing themselves with it
|
||||
containername = "supermatter shard crate"
|
||||
|
||||
/datum/supply_packs/engineering/nuclear_supermatter_rod
|
||||
name = "Nuclear Supermatter Rod Crate"
|
||||
contains = list(
|
||||
/obj/item/nuclear_rod/fuel/supermatter,
|
||||
/obj/item/nuclear_rod/fuel/supermatter,
|
||||
)
|
||||
cost = 400
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "nuclear supermatter rod crate"
|
||||
|
||||
/datum/supply_packs/engineering/nuclear_supermatter_kit
|
||||
name = "Nuclear Supermatter Rods Starter Crate"
|
||||
contains = list(
|
||||
/obj/item/nuclear_rod/fuel/supermatter,
|
||||
/obj/item/nuclear_rod/fuel/supermatter,
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet,
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet,
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator,
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator
|
||||
)
|
||||
cost = 800
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "nuclear supermatter starter crate"
|
||||
|
||||
/datum/supply_packs/engineering/nuclear_moderator_rods
|
||||
name = "Forged Nuclear Moderator crate"
|
||||
contains = list(
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator,
|
||||
/obj/item/nuclear_rod/moderator/plasma_agitator,
|
||||
/obj/item/nuclear_rod/moderator/aluminum_reflector,
|
||||
/obj/item/nuclear_rod/moderator/aluminum_reflector
|
||||
)
|
||||
cost = 600
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "Forged Nuclear Moderator crate"
|
||||
|
||||
/datum/supply_packs/engineering/nuclear_coolant_rods
|
||||
name = "Forged Nuclear Coolant crate"
|
||||
contains = list(
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet,
|
||||
/obj/item/nuclear_rod/coolant/steam_hammerjet,
|
||||
/obj/item/nuclear_rod/coolant/molten_salt,
|
||||
/obj/item/nuclear_rod/coolant/molten_salt
|
||||
)
|
||||
cost = 600
|
||||
containertype = /obj/structure/closet/crate/secure/engineering
|
||||
containername = "Forged Nuclear Coolant crate"
|
||||
|
||||
/* Commented out as the TEG is fully problematic. If the syndie base is changed to be dependant on another powersource, we can look at a rework.
|
||||
/datum/supply_packs/engineering/engine/teg
|
||||
name = "Thermo-Electric Generator Crate"
|
||||
|
||||
Reference in New Issue
Block a user