mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 12:29:46 +01:00
INDRA, general nuclear fusion update (#21285)
Fixes https://github.com/Aurorastation/Aurora.3/issues/18951 Fixes https://github.com/Aurorastation/Aurora.3/issues/19447 Fixes https://github.com/Aurorastation/Aurora.3/issues/20283 Fixes https://github.com/Aurorastation/Aurora.3/issues/21395 Overhauls a wide variety of INDRA behaviors and related gas/material properties. changes: - balance: "Fusion reaction modifications. Higher radiation and temperature output, comparable power output." - balance: "Increased rad resistance modifier of Borosilicate Windows from 1 -> 4 and (closed) Blast Doors from 1 -> 6." - balance: "INDRA Field Strength minima/maxima changed from 1-100 -> 20-120. Power costs increased significantly." - balance: "INDRA instability increase per tick now limited, similar to Supermatter (prevents sudden instability spike from instantly nuking it)." - balance: "APC cell charge rate increased 10x." - balance: "Rebalanced contents of INDRA hard storage compartment." - balance: "SMES coils capacities halved, throughputs doubled." - balance: "SMES unit maximum coil capacity increased from 6 -> 8." - balance: "TEG maximum power output increased from 500000 -> 2500000." - balance: "Power wasted from exceeding TEG maximum power output decreased from 50% to 33%." - balance: "Portable generators of all types have had their power generation capacity doubled." - rscadd: "New 'Fusion Codex' app added for all crew with ACCESS_ENGINE that details all available nuclear fusion chains." - rscadd: "Boron added as a singleton/reagent. Poisonous to vaurca, still usable in nuclear fusion as fuel assembly rods." - rscadd: "INDRA Field Strength now scales plasma temperature entropy, power output from temperature multiplier, and instability increase per tick." - refactor: "'Boron' gas renamed to 'Helium-3'. Boron is not a gas. Deal with it." - refactor: "'Steam' gas renamed to 'Water Vapor'." - code_imp: "Descriptions added to gas singletons for future use." - qol: "Minor remap of INDRA control room for usability." - qol: "Standardized gas canister naming conventions." - qol: "INDRA and APC TGUI interfaces now use use kW, MW abbreviations for high wattages." - bugfix: "INDRA Kinetic Harvester no longer rapidly deselects materials for harvest when too many are being generated at once." - bugfix: "INDRA EM Field effect no longer considers the camera within its reactor chamber a destabilizing influence." - bugfix: "INDRA reactor core now produces radiation as intended." - bugfix: "Deuterium and Tritium canisters no longer contain 50% standard hydrogen (inheritance issue)." --------- Signed-off-by: Batrachophreno <Batrochophreno@gmail.com> Co-authored-by: Matt Atlas <mattiathebest2000@hotmail.it> Co-authored-by: Geeves <22774890+Geevies@users.noreply.github.com>
This commit is contained in:
co-authored by
Matt Atlas
Geeves
parent
93b7dbba83
commit
b3b4f4b9c6
@@ -14,11 +14,11 @@
|
||||
#define ATM_2H 9 //Deuterium
|
||||
#define ATM_3H 10 //Tritium
|
||||
#define ATM_HE 11 //Helium
|
||||
#define ATM_B 12 //Boron
|
||||
#define ATM_3HE 12 //Helium-3
|
||||
#define ATM_SO2 13 //Sulfur Dioxide
|
||||
#define ATM_NO2 14 //Nitrogen Dioxide
|
||||
#define ATM_CL2 15 //Chlorine
|
||||
#define ATM_H2O 16 //Steam
|
||||
#define ATM_H2O 16 //Water vapor
|
||||
|
||||
//--------------------------------------------
|
||||
// Omni port datum
|
||||
@@ -121,8 +121,8 @@
|
||||
return GAS_TRITIUM
|
||||
if(ATM_HE)
|
||||
return GAS_HELIUM
|
||||
if(ATM_B)
|
||||
return GAS_BORON
|
||||
if(ATM_3HE)
|
||||
return GAS_HELIUMFUEL
|
||||
if(ATM_SO2)
|
||||
return GAS_SULFUR
|
||||
if(ATM_NO2)
|
||||
@@ -130,6 +130,6 @@
|
||||
if(ATM_CL2)
|
||||
return GAS_CHLORINE
|
||||
if(ATM_H2O)
|
||||
return GAS_STEAM
|
||||
return GAS_WATERVAPOR
|
||||
else
|
||||
return null
|
||||
|
||||
@@ -166,8 +166,8 @@
|
||||
return "Tritium"
|
||||
if(ATM_HE)
|
||||
return "Helium"
|
||||
if(ATM_B)
|
||||
return "Boron"
|
||||
if(ATM_3HE)
|
||||
return "Helium-3"
|
||||
if(ATM_SO2)
|
||||
return "Sulfur Dioxide"
|
||||
if(ATM_NO2)
|
||||
@@ -175,7 +175,7 @@
|
||||
if(ATM_CL2)
|
||||
return "Chlorine"
|
||||
if(ATM_H2O)
|
||||
return "Steam"
|
||||
return "Water Vapor"
|
||||
else
|
||||
return null
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
|
||||
if("switch_filter")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide", "Hydrogen", "Deuterium", "Tritium", "Helium", "Boron", "Sulfur Dioxide", "Nitrogen Dioxide", "Chlorine", "Steam")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Phoron", "Nitrous Oxide", "Hydrogen", "Deuterium", "Tritium", "Helium", "Helium-3", "Sulfur Dioxide", "Nitrogen Dioxide", "Chlorine", "Water Vapor")
|
||||
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
|
||||
|
||||
update_icon()
|
||||
@@ -228,15 +228,15 @@
|
||||
return ATM_3H
|
||||
if("Helium")
|
||||
return ATM_HE
|
||||
if("Boron")
|
||||
return ATM_B
|
||||
if("Helium-3")
|
||||
return ATM_3HE
|
||||
if("Sulfur Dioxide")
|
||||
return ATM_SO2
|
||||
if("Nitrogen Dioxide")
|
||||
return ATM_NO2
|
||||
if("Chlorine")
|
||||
return ATM_CL2
|
||||
if("Steam")
|
||||
if("Water Vapor")
|
||||
return ATM_H2O
|
||||
if("in")
|
||||
return ATM_INPUT
|
||||
|
||||
@@ -163,11 +163,11 @@
|
||||
"filter_2h" = (GAS_DEUTERIUM in scrubbing_gas),
|
||||
"filter_3h" = (GAS_TRITIUM in scrubbing_gas),
|
||||
"filter_he" = (GAS_HELIUM in scrubbing_gas),
|
||||
"filter_b" = (GAS_BORON in scrubbing_gas),
|
||||
"filter_b" = (GAS_HELIUMFUEL in scrubbing_gas),
|
||||
"filter_so2" = (GAS_SULFUR in scrubbing_gas),
|
||||
"filter_no2" = (GAS_NO2 in scrubbing_gas),
|
||||
"filter_cl" = (GAS_CHLORINE in scrubbing_gas),
|
||||
"filter_h2o" = (GAS_STEAM in scrubbing_gas),
|
||||
"filter_h2o" = (GAS_WATERVAPOR in scrubbing_gas),
|
||||
"sigtype" = "status"
|
||||
)
|
||||
|
||||
@@ -312,10 +312,10 @@
|
||||
else if(signal.data["toggle_he_scrub"])
|
||||
toggle += GAS_HELIUM
|
||||
|
||||
if(!isnull(signal.data["b_scrub"]) && text2num(signal.data["b_scrub"]) != (GAS_BORON in scrubbing_gas))
|
||||
toggle += GAS_BORON
|
||||
if(!isnull(signal.data["b_scrub"]) && text2num(signal.data["b_scrub"]) != (GAS_HELIUMFUEL in scrubbing_gas))
|
||||
toggle += GAS_HELIUMFUEL
|
||||
else if(signal.data["toggle_b_scrub"])
|
||||
toggle += GAS_BORON
|
||||
toggle += GAS_HELIUMFUEL
|
||||
|
||||
if(!isnull(signal.data["so2_scrub"]) && text2num(signal.data["so2_scrub"]) != (GAS_SULFUR in scrubbing_gas))
|
||||
toggle += GAS_SULFUR
|
||||
@@ -332,10 +332,10 @@
|
||||
else if(signal.data["toggle_cl_scrub"])
|
||||
toggle += GAS_CHLORINE
|
||||
|
||||
if(!isnull(signal.data["h2o_scrub"]) && text2num(signal.data["h2o_scrub"]) != (GAS_STEAM in scrubbing_gas))
|
||||
toggle += GAS_STEAM
|
||||
if(!isnull(signal.data["h2o_scrub"]) && text2num(signal.data["h2o_scrub"]) != (GAS_WATERVAPOR in scrubbing_gas))
|
||||
toggle += GAS_WATERVAPOR
|
||||
else if(signal.data["toggle_h2o_scrub"])
|
||||
toggle += GAS_STEAM
|
||||
toggle += GAS_WATERVAPOR
|
||||
|
||||
scrubbing_gas ^= toggle
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
/datum/export/material/mhydrogen
|
||||
cost = 10
|
||||
material_id = "mhydrogen"
|
||||
material_id = "metallic hydrogen"
|
||||
message = "metallic hydrogen sheets"
|
||||
|
||||
/datum/export/material/aluminium
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
category = "atmos"
|
||||
name = "Canister (Air)"
|
||||
supplier = "hephaestus"
|
||||
description = "Holds nitrogen-oxygen breatheable air. Has a built-in valve to allow for filling portable tanks."
|
||||
description = "Holds a nitrogen-oxygen mixture of breathable air. Has a built-in valve to allow for filling portable tanks."
|
||||
price = 180
|
||||
items = list(
|
||||
/obj/machinery/portable_atmospherics/canister/air
|
||||
@@ -82,14 +82,14 @@
|
||||
groupable = FALSE
|
||||
spawn_amount = 1
|
||||
|
||||
/singleton/cargo_item/canister_bo
|
||||
/singleton/cargo_item/canister_3he
|
||||
category = "atmos"
|
||||
name = "Canister (Boron)"
|
||||
name = "Canister (Helium-3)"
|
||||
supplier = "hephaestus"
|
||||
description = "Holds boron gas. Has a built-in valve to allow for filling portable tanks."
|
||||
price = 380
|
||||
description = "Holds Helium-3 gas, a valuable fusion fuel. Has a built-in valve to allow for filling portable tanks."
|
||||
price = 3800
|
||||
items = list(
|
||||
/obj/machinery/portable_atmospherics/canister/boron
|
||||
/obj/machinery/portable_atmospherics/canister/heliumfuel
|
||||
)
|
||||
access = ACCESS_ENGINE
|
||||
container_type = "box"
|
||||
@@ -100,7 +100,7 @@
|
||||
category = "atmos"
|
||||
name = "Canister (CO2)"
|
||||
supplier = "hephaestus"
|
||||
description = "Holds heavy CO2 gas. Has a built-in valve to allow for filling portable tanks."
|
||||
description = "Holds heavy CO2 gas, whatever that is. Has a built-in valve to allow for filling portable tanks."
|
||||
price = 300
|
||||
items = list(
|
||||
/obj/machinery/portable_atmospherics/canister/carbon_dioxide
|
||||
|
||||
@@ -292,5 +292,5 @@
|
||||
|
||||
origin_tech = list(TECH_MATERIAL = 4,TECH_ENGINEERING = 5,TECH_MAGNET = 4,TECH_POWER = 4)
|
||||
|
||||
type_to_take = "mhydrogen"
|
||||
type_to_take = "metallic hydrogen"
|
||||
charge_per_sheet = 90
|
||||
|
||||
@@ -521,23 +521,23 @@
|
||||
complexity = 9
|
||||
inputs = list()
|
||||
outputs = list(
|
||||
"pressure" = IC_PINTYPE_NUMBER,
|
||||
"temperature" = IC_PINTYPE_NUMBER,
|
||||
GAS_OXYGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_NITROGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_CO2 = IC_PINTYPE_NUMBER,
|
||||
GAS_PHORON = IC_PINTYPE_NUMBER,
|
||||
GAS_N2O = IC_PINTYPE_NUMBER,
|
||||
GAS_HYDROGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_DEUTERIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_TRITIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_BORON = IC_PINTYPE_NUMBER,
|
||||
GAS_SULFUR = IC_PINTYPE_NUMBER,
|
||||
GAS_NO2 = IC_PINTYPE_NUMBER,
|
||||
GAS_CHLORINE = IC_PINTYPE_NUMBER,
|
||||
GAS_STEAM = IC_PINTYPE_NUMBER,
|
||||
"other" = IC_PINTYPE_NUMBER
|
||||
"pressure" = IC_PINTYPE_NUMBER,
|
||||
"temperature" = IC_PINTYPE_NUMBER,
|
||||
GAS_OXYGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_NITROGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_CO2 = IC_PINTYPE_NUMBER,
|
||||
GAS_PHORON = IC_PINTYPE_NUMBER,
|
||||
GAS_N2O = IC_PINTYPE_NUMBER,
|
||||
GAS_HYDROGEN = IC_PINTYPE_NUMBER,
|
||||
GAS_DEUTERIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_TRITIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUM = IC_PINTYPE_NUMBER,
|
||||
GAS_HELIUMFUE = IC_PINTYPE_NUMBER,
|
||||
GAS_SULFUR = IC_PINTYPE_NUMBER,
|
||||
GAS_NO2 = IC_PINTYPE_NUMBER,
|
||||
GAS_CHLORINE = IC_PINTYPE_NUMBER,
|
||||
GAS_WATERVAPOR = IC_PINTYPE_NUMBER,
|
||||
"other" = IC_PINTYPE_NUMBER
|
||||
)
|
||||
activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
|
||||
spawn_flags = IC_SPAWN_RESEARCH
|
||||
@@ -642,11 +642,11 @@
|
||||
var/deuterium_level = environment.gas[GAS_DEUTERIUM]/total_moles
|
||||
var/tritium_level = environment.gas[GAS_TRITIUM]/total_moles
|
||||
var/helium_level = environment.gas[GAS_HELIUM]/total_moles
|
||||
var/boron_level = environment.gas[GAS_BORON]/total_moles
|
||||
var/helium3_level = environment.gas[GAS_HELIUMFUEL]/total_moles
|
||||
var/sulfurdioxide_level = environment.gas[GAS_SULFUR]/total_moles
|
||||
var/nitrogendioxide_level = environment.gas[GAS_NO2]/total_moles
|
||||
var/chlorine_level = environment.gas[GAS_CHLORINE]/total_moles
|
||||
var/steam_level = environment.gas[GAS_STEAM]/total_moles
|
||||
var/watervapor_level = environment.gas[GAS_WATERVAPOR]/total_moles
|
||||
var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
|
||||
set_pin_data(IC_OUTPUT, 1, pressure)
|
||||
set_pin_data(IC_OUTPUT, 2, round(environment.temperature-T0C,0.1))
|
||||
@@ -659,11 +659,11 @@
|
||||
set_pin_data(IC_OUTPUT, 8, round(deuterium_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 9, round(tritium_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 10, round(helium_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 11, round(boron_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 11, round(helium3_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 12, round(sulfurdioxide_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 13, round(nitrogendioxide_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 14, round(chlorine_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 15, round(steam_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 15, round(watervapor_level*100,0.01))
|
||||
set_pin_data(IC_OUTPUT, 16, round(unknown_level, 0.01))
|
||||
set_pin_data(IC_OUTPUT, 17, round(unknown_level, 0.01))
|
||||
else
|
||||
@@ -812,9 +812,9 @@
|
||||
gas_name = GAS_HELIUM
|
||||
gas_display_name = GAS_HELIUM
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/boron_level
|
||||
gas_name = GAS_BORON
|
||||
gas_display_name = GAS_BORON
|
||||
/obj/item/integrated_circuit/input/gas_sensor/helium3_level
|
||||
gas_name = GAS_HELIUMFUEL
|
||||
gas_display_name = GAS_HELIUMFUEL
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/sulfurdioxide_level
|
||||
gas_name = GAS_SULFUR
|
||||
@@ -828,9 +828,9 @@
|
||||
gas_name = GAS_CHLORINE
|
||||
gas_display_name = GAS_CHLORINE
|
||||
|
||||
/obj/item/integrated_circuit/input/gas_sensor/steam_level
|
||||
gas_name = GAS_STEAM
|
||||
gas_display_name = GAS_STEAM
|
||||
/obj/item/integrated_circuit/input/gas_sensor/watervapor_level
|
||||
gas_name = GAS_WATERVAPOR
|
||||
gas_display_name = GAS_WATERVAPOR
|
||||
|
||||
/obj/item/integrated_circuit/input/turfpoint
|
||||
name = "tile pointer"
|
||||
|
||||
@@ -616,3 +616,14 @@
|
||||
. = ..()
|
||||
amount = max_amount
|
||||
update_icon()
|
||||
|
||||
// Fusion fuel.
|
||||
/obj/item/stack/material/boron
|
||||
name = "boron"
|
||||
icon_state = "puck"
|
||||
default_type = MATERIAL_BORON
|
||||
|
||||
/obj/item/stack/material/boron/full/Initialize()
|
||||
. = ..()
|
||||
amount = max_amount
|
||||
update_icon()
|
||||
|
||||
@@ -1222,3 +1222,12 @@
|
||||
sheet_singular_name = "ingot"
|
||||
sheet_plural_name = "ingots"
|
||||
is_fusion_fuel = TRUE
|
||||
|
||||
/material/boron
|
||||
name = MATERIAL_BORON
|
||||
stack_type = /obj/item/stack/material/boron
|
||||
icon_colour = "#bbbbbb"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3)
|
||||
sheet_singular_name = "ingot"
|
||||
sheet_plural_name = "ingots"
|
||||
is_fusion_fuel = TRUE
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
/obj/item/computer_hardware,
|
||||
/obj/item/pipe,
|
||||
/obj/item/smallDelivery,
|
||||
/obj/item/gift
|
||||
/obj/item/gift,
|
||||
/obj/item/fuel_assembly
|
||||
)
|
||||
|
||||
var/list/cant_hold
|
||||
|
||||
@@ -54,6 +54,7 @@ ABSTRACT_TYPE(/datum/modular_computer_app_presets)
|
||||
/datum/computer_file/program/rcon_console,\
|
||||
/datum/computer_file/program/camera_monitor,\
|
||||
/datum/computer_file/program/lighting_control,\
|
||||
/datum/computer_file/program/fusion_codex,\
|
||||
)
|
||||
|
||||
#define COMPUTER_APP_PRESET_HORIZON_MEDICAL list(\
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/datum/computer_file/program/fusion_codex
|
||||
filename = "fusioncodex"
|
||||
filedesc = "Fusion Codex"
|
||||
program_icon_state = "medcomp"
|
||||
program_key_icon_state = "teal_key"
|
||||
extended_desc = "Useful program to reference reaction chains for nuclear fusion reactors."
|
||||
size = 14
|
||||
requires_access_to_run = PROGRAM_ACCESS_LIST_ONE
|
||||
required_access_run = list(ACCESS_ENGINE)
|
||||
required_access_download = list(ACCESS_ENGINE)
|
||||
available_on_ntnet = TRUE
|
||||
tgui_id = "FusionCodex"
|
||||
|
||||
/datum/computer_file/program/fusion_codex/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
// Gather data for computer header
|
||||
var/headerdata = get_header_data(data["_PC"])
|
||||
if(headerdata)
|
||||
data["_PC"] = headerdata
|
||||
. = data
|
||||
|
||||
// Here goes listification
|
||||
if(!data["reactions"])
|
||||
data["reactions"] = SScodex.fusion_codex_data
|
||||
|
||||
return data
|
||||
@@ -443,7 +443,7 @@
|
||||
newgases -= GAS_PHORON
|
||||
if(prob(50)) //alium gas should be slightly less common than mundane shit
|
||||
newgases -= GAS_ALIEN
|
||||
newgases -= GAS_STEAM
|
||||
newgases -= GAS_WATERVAPOR
|
||||
|
||||
var/total_moles = MOLES_CELLSTANDARD * rand(80,120)/100
|
||||
var/badflag = 0
|
||||
|
||||
@@ -85,7 +85,7 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
|
||||
var/areastring = null
|
||||
var/obj/item/cell/cell
|
||||
/// Cap for how fast APC cells charge, as a percentage-per-tick (0.01 means cellcharge is capped to 1% per second)
|
||||
var/chargelevel = 0.0005
|
||||
var/chargelevel = 0.005
|
||||
var/cellused = 0
|
||||
/// Initial cell charge %
|
||||
var/start_charge = 90
|
||||
@@ -936,8 +936,8 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
|
||||
data["fail_time"] = failure_timer * 2
|
||||
data["silicon_user"] = isAdmin || issilicon(user)
|
||||
data["is_AI_or_robot"] = isAI(user) || isrobot(user)
|
||||
data["total_load"] = round(lastused_total)
|
||||
data["total_charging"] = round(lastused_charging)
|
||||
data["total_load"] = power_wattage_readable(lastused_total)
|
||||
data["total_charging"] = power_wattage_readable(lastused_charging)
|
||||
data["is_operating"] = operating
|
||||
data["charge_mode"] = chargemode
|
||||
data["external_power"] = main_status
|
||||
@@ -947,9 +947,9 @@ ABSTRACT_TYPE(/obj/machinery/power/apc)
|
||||
data["emergency_mode"] = !emergency_lights
|
||||
data["time"] = time
|
||||
data["power_channels"] = list(
|
||||
list("name" = "Equipment", "power_load" = lastused_equip, "status" = equipment),
|
||||
list("name" = "Lighting", "power_load" = round(lastused_light), "status" = lighting),
|
||||
list("name" = "Environment", "power_load" = round(lastused_environ), "status" = environ)
|
||||
list("name" = "Equipment", "power_load" = power_wattage_readable(lastused_equip), "status" = equipment),
|
||||
list("name" = "Lighting", "power_load" = power_wattage_readable(lastused_light), "status" = lighting),
|
||||
list("name" = "Environment", "power_load" = power_wattage_readable(lastused_environ), "status" = environ)
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
icon_keyboard_emis = "yellow_key_mask"
|
||||
icon_screen = "solar"
|
||||
light_color = COLOR_ORANGE
|
||||
idle_power_usage = 250
|
||||
active_power_usage = 500
|
||||
idle_power_usage = 2500
|
||||
active_power_usage = 10000
|
||||
manufacturer = "hephaestus"
|
||||
var/ui_template
|
||||
var/initial_id_tag
|
||||
@@ -45,5 +45,5 @@
|
||||
/obj/machinery/computer/fusion/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_template, name, 400, 500)
|
||||
ui = new(user, src, ui_template, name)
|
||||
ui.open()
|
||||
|
||||
@@ -53,15 +53,25 @@
|
||||
for(var/i = 1 to LAZYLEN(fusion_cores))
|
||||
var/list/core = list()
|
||||
var/obj/machinery/power/fusion_core/C = fusion_cores[i]
|
||||
var/power_available = C.avail()
|
||||
var/power_usage = C.active_power_usage
|
||||
var/power_generated = C.owned_field?.output_avg
|
||||
|
||||
core["id"] = "#[i]"
|
||||
core["ref"] = "[REF(C)]"
|
||||
core["field"] = !isnull(C.owned_field)
|
||||
core["power"] = "[C.field_strength / 10]"
|
||||
core["field_strength"] = C.field_strength
|
||||
core["field_strength_max"] = C.field_strength_max
|
||||
core["entropy_multiplier"] = C.owned_field ? round(C.owned_field.field_strength_entropy_multiplier, 0.01) : 1
|
||||
core["instability_multiplier"] = C.owned_field ? round(C.owned_field.field_strength_instability_multiplier, 0.01) : 1
|
||||
core["power_multiplier"] = C.owned_field ? round(C.owned_field.field_strength_power_multiplier, 0.01) : 1
|
||||
core["size"] = C.owned_field ? C.owned_field.size : 0
|
||||
core["instability"] = C.owned_field ? C.owned_field.percent_unstable * 100 : -1 //%
|
||||
core["temperature"] = C.owned_field ? C.owned_field.plasma_temperature + 295 : -1 //K
|
||||
core["power_status"] = "[C.avail()]/[C.active_power_usage]"
|
||||
core["power_available"] = "[power_wattage_readable(power_available)]"
|
||||
core["power_usage"] = "[power_wattage_readable(power_usage)]"
|
||||
core["power_generated"] = "[power_wattage_readable(power_generated)]"
|
||||
core["shutdown_safe"] = C.owned_field ? C.owned_field.is_shutdown_safe() : TRUE
|
||||
|
||||
var/list/reactants = list()
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
switch(action)
|
||||
if("modifypower")
|
||||
G.mega_energy = clamp(params["modifypower"], 1, 50)
|
||||
G.mega_energy = clamp(params["modifypower"], 1, 250)
|
||||
G.change_power_consumption(G.mega_energy * GYRO_POWER, POWER_USE_ACTIVE)
|
||||
return TRUE
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
gyrotron["active"] = G.active
|
||||
gyrotron["firedelay"] = G.rate
|
||||
gyrotron["energy"] = G.mega_energy
|
||||
gyrotron["power_status"] = power_wattage_readable(G.mega_energy * GYRO_POWER)
|
||||
gyrotrons += list(gyrotron)
|
||||
data["gyro_power_constant"] = GYRO_POWER
|
||||
data["gyrotrons"] = gyrotrons
|
||||
return data
|
||||
|
||||
@@ -9,13 +9,16 @@
|
||||
layer = ABOVE_HUMAN_LAYER
|
||||
density = TRUE
|
||||
use_power = POWER_USE_IDLE
|
||||
idle_power_usage = 50
|
||||
idle_power_usage = 10000
|
||||
/// Gets multiplied by field strength
|
||||
active_power_usage = 500
|
||||
active_power_usage = 50000
|
||||
anchored = FALSE
|
||||
|
||||
var/obj/effect/fusion_em_field/owned_field
|
||||
var/field_strength = 1//0.01
|
||||
/// The currently configured Field Strength (1 = 100 Tesla).
|
||||
var/field_strength = 1
|
||||
/// This is for the INDRA, allowing a maximum 5-radius field. Change this for larger/smaller reactors.
|
||||
var/field_strength_max = 1.2
|
||||
var/initial_id_tag
|
||||
|
||||
/obj/machinery/power/fusion_core/mapped
|
||||
@@ -26,6 +29,13 @@
|
||||
connect_to_network()
|
||||
AddComponent(/datum/component/local_network_member, initial_id_tag)
|
||||
|
||||
/obj/machinery/power/fusion_core/Destroy()
|
||||
if(owned_field)
|
||||
qdel(owned_field)
|
||||
owned_field = null
|
||||
set_light(0)
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* If there's no powernet or no owned field, shutdown() in those cases too.
|
||||
*/
|
||||
@@ -44,6 +54,7 @@
|
||||
owned_field.ChangeFieldStrength(field_strength)
|
||||
icon_state = "core1"
|
||||
update_use_power(POWER_USE_ACTIVE)
|
||||
set_light(3, 0.7, COLOR_PALE_BLUE_GRAY)
|
||||
. = 1
|
||||
|
||||
/**
|
||||
@@ -52,13 +63,16 @@
|
||||
/obj/machinery/power/fusion_core/proc/Shutdown(force_rupture)
|
||||
if(owned_field)
|
||||
icon_state = "core0"
|
||||
if(force_rupture || owned_field.plasma_temperature > 1000)
|
||||
// Blow the whole fucking thing up.
|
||||
if(force_rupture || owned_field.plasma_temperature > 720000)
|
||||
owned_field.Rupture()
|
||||
// Just radiate all that temperature into the environment. Unless you're under 1000 K, its still a big 'fuck you,' but admittedly better than EMP/explosion.
|
||||
else
|
||||
owned_field.RadiateAll()
|
||||
qdel(owned_field)
|
||||
owned_field = null
|
||||
update_use_power(POWER_USE_IDLE)
|
||||
set_light(0)
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/AddParticles(name, quantity = 1)
|
||||
if(owned_field)
|
||||
@@ -76,7 +90,7 @@
|
||||
/obj/machinery/power/fusion_core/proc/set_strength(value)
|
||||
value = clamp(value, MIN_FIELD_STR, MAX_FIELD_STR)
|
||||
field_strength = value
|
||||
change_power_consumption(5 * value, POWER_USE_ACTIVE)
|
||||
change_power_consumption(1500 * (value ** 1.5), POWER_USE_ACTIVE)
|
||||
if(owned_field)
|
||||
owned_field.ChangeFieldStrength(value)
|
||||
|
||||
@@ -115,7 +129,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/jumpstart(field_temperature)
|
||||
field_strength = 501 // Generally a good size.
|
||||
field_strength = 120 // Generally a good size.
|
||||
Startup()
|
||||
if(!owned_field)
|
||||
return FALSE
|
||||
|
||||
@@ -1,24 +1,53 @@
|
||||
#define FUSION_ENERGY_PER_K 20
|
||||
#define FUSION_INSTABILITY_DIVISOR 50000
|
||||
#define FUSION_RUPTURE_THRESHOLD 10000
|
||||
#define FUSION_REACTANT_CAP 10000
|
||||
#define FUSION_WARNING_DELAY 20
|
||||
#define FUSION_INSTABILITY_DIVISOR 100000
|
||||
#define FUSION_RUPTURE_THRESHOLD 25000
|
||||
#define FUSION_REACTANT_CAP 10000
|
||||
#define FUSION_WARNING_DELAY 20
|
||||
#define FUSION_BLACKBODY_MULTIPLIER 28
|
||||
#define FUSION_INTEGRITY_RATE_LIMIT 0.11
|
||||
#define FUSION_TICK_MAX_TEMP_CHANGE 0.2
|
||||
|
||||
/obj/effect/fusion_em_field
|
||||
name = "electromagnetic field"
|
||||
desc = "A coruscating, barely visible field of energy. It is shaped like a slightly flattened torus."
|
||||
alpha = 30
|
||||
layer = 4
|
||||
layer = ABOVE_ABOVE_HUMAN_LAYER
|
||||
light_color = COLOR_RED
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
|
||||
/// Temporary pool for energy being added to the field from a Gyrotron.
|
||||
var/energy = 0
|
||||
/// Actual core field energy (temperature).
|
||||
var/plasma_temperature = 0
|
||||
/// Effective core field energy (temperature) as modified by field magnitude constriction or relaxation.
|
||||
// var/plasma_temperature_effective
|
||||
/// Current excess radiation from ongoing reactions.
|
||||
var/radiation = 0
|
||||
/// The currently configured Field Strength (0.01 = 1 Tesla).
|
||||
var/field_strength = 0.01
|
||||
/// Radiation of the previous three ticks averaged out (if != 0).
|
||||
var/radiation_avg = 0
|
||||
/// Archived radiation. Used for averaging out new SSradiation.radiate() source creation.
|
||||
var/radiation_archive_1 = 0
|
||||
var/radiation_archive_2 = 0
|
||||
var/radiation_archive_3 = 0
|
||||
var/radiation_archive_4 = 0
|
||||
var/radiation_archive_5 = 0
|
||||
/**
|
||||
* The currently configured Field Strength (0.2 = 20 Tesla). Capped by TGUI at 1.2 (120 Tesla).
|
||||
*
|
||||
* Field Strength scales plasma temperature entropy. With higher field strength, each tick will lose more temp and produce more radiation.
|
||||
* Field Strength scales power output per temperature. With higher field strength, each degree Kelvin will produce more electricity.
|
||||
* Field Strength scales instability increase. With higher field strength, more instability for a given reaction will be produced each tick.
|
||||
*/
|
||||
var/field_strength = 20
|
||||
/// Current field strength multiplier applied to entropy.
|
||||
var/field_strength_entropy_multiplier = 1.0
|
||||
/// Current field strength multiplier applied to instability.
|
||||
var/field_strength_instability_multiplier = 1.0
|
||||
/// Current field strength multiplier applied to power output.
|
||||
var/field_strength_power_multiplier = 1.0
|
||||
/// Radius of the EM field. Scales with Field Strength.
|
||||
var/size = 1
|
||||
|
||||
/// Instability generated on this current tick.
|
||||
var/tick_instability = 0
|
||||
/// Ranges from 0-1. At or over 1, boom.
|
||||
var/percent_unstable = 0
|
||||
@@ -33,7 +62,8 @@
|
||||
/obj/effect,
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/atmospherics,
|
||||
/obj/machinery/air_sensor
|
||||
/obj/machinery/air_sensor,
|
||||
/obj/machinery/camera
|
||||
)
|
||||
|
||||
var/light_min_range = 2
|
||||
@@ -58,27 +88,51 @@
|
||||
var/emergency_alert = "DANGER: INDRA REACTOR MELTDOWN IMMINENT!"
|
||||
var/lastwarning = 0
|
||||
|
||||
/// Power output this tick. We average this like we do radiation for player-presenting data.
|
||||
var/power_output
|
||||
/// Power of the previous five ticks averaged out (if != 0).
|
||||
var/output_avg = 0
|
||||
/// Archived power. Used for averaging out the power dumped into the powernet for players to see.
|
||||
var/output_archive_1 = 0
|
||||
var/output_archive_2 = 0
|
||||
var/output_archive_3 = 0
|
||||
var/output_archive_4 = 0
|
||||
var/output_archive_5 = 0
|
||||
|
||||
var/vfx_radius_actual
|
||||
//var/vfx_radius_visual
|
||||
var/pause_rupture = TRUE
|
||||
|
||||
var/power_log_base = 1.4
|
||||
var/power_multiplier = 3
|
||||
var/power_power = 3.2
|
||||
|
||||
var/aaa_minimum_energy_level_multiplier = 1.0
|
||||
|
||||
/obj/effect/fusion_em_field/proc/UpdateVisuals()
|
||||
//Take the particle system and edit it
|
||||
|
||||
//size
|
||||
var/radius = ((size-1) / 2) * WORLD_ICON_SIZE
|
||||
|
||||
particles.position = generator("circle", radius - size, radius + size, NORMAL_RAND)
|
||||
vfx_radius_actual = ((size-1) / 2) * WORLD_ICON_SIZE
|
||||
/*
|
||||
var/vfx_radius_next = ((size+1) / 2) * WORLD_ICON_SIZE
|
||||
var/percent_to_next_size = round(((field_strength + (size * 50)) - (size * 50)) / (((size + 1) / 2) * 50),0.01)
|
||||
var/radius_add = round(percent_to_next_size * WORLD_ICON_SIZE, 1)
|
||||
vfx_radius_visual = min(max(vfx_radius_actual + radius_add, vfx_radius_actual), vfx_radius_next)
|
||||
*/
|
||||
particles.position = generator("circle", vfx_radius_actual - size, vfx_radius_actual, NORMAL_RAND)
|
||||
|
||||
//Radiation affects drift
|
||||
var/radiationfactor = clamp((radiation * 0.001), 0, 0.5)
|
||||
var/radiationfactor = clamp((radiation_avg * 0.001), 0, 0.75)
|
||||
particles.drift = generator("circle", (0.2 + radiationfactor), NORMAL_RAND)
|
||||
|
||||
particles.spawning = last_reactants * 0.9 + Interpolate(0, 200, clamp(plasma_temperature / 70000, 0, 1))
|
||||
|
||||
|
||||
/obj/effect/fusion_em_field/New(loc, obj/machinery/power/fusion_core/new_owned_core)
|
||||
..()
|
||||
|
||||
filters = list(filter(type = "ripple", size = 4, "radius" = 1, "falloff" = 1)
|
||||
, filter(type="outline", size = 2, color = COLOR_RED)
|
||||
, filter(type="bloom", size=3, offset = 0.5, alpha = 235))
|
||||
, filter(type="bloom", size = 3, offset = 0.5, alpha = 235))
|
||||
|
||||
set_light(light_min_power, light_min_range / 10, light_min_range)
|
||||
last_range = light_min_range
|
||||
@@ -127,49 +181,6 @@
|
||||
addtimer(CALLBACK(src, PROC_REF(update_light_colors)), 10 SECONDS, TIMER_LOOP)
|
||||
radio = new /obj/item/device/radio{channels=list("Engineering")}(src)
|
||||
|
||||
/**
|
||||
* Not blackbody radiation- with these colors, is some sort of space magic?
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/update_light_colors()
|
||||
var/use_range
|
||||
var/use_power = 0
|
||||
var/temp_mod = ((plasma_temperature-5000)/20000)
|
||||
use_range = light_min_range + Ceil((light_max_range-light_min_range)*temp_mod)
|
||||
use_power = light_min_power + Ceil((light_max_power-light_min_power)*temp_mod)
|
||||
switch (plasma_temperature)
|
||||
if (-INFINITY to 1000)
|
||||
light_color = COLOR_RED
|
||||
alpha = 30
|
||||
if (1000 to 6000)
|
||||
light_color = COLOR_ORANGE
|
||||
alpha = 50
|
||||
if (6000 to 20000)
|
||||
light_color = COLOR_YELLOW
|
||||
alpha = 80
|
||||
if (20000 to 50000)
|
||||
light_color = COLOR_GREEN
|
||||
alpha = 120
|
||||
if (50000 to 70000)
|
||||
light_color = COLOR_CYAN
|
||||
alpha = 160
|
||||
if (70000 to 100000)
|
||||
light_color = COLOR_BLUE
|
||||
alpha = 200
|
||||
if (100000 to INFINITY)
|
||||
light_color = COLOR_VIOLET
|
||||
alpha = 230
|
||||
|
||||
if (last_range != use_range || last_power != use_power || color != light_color)
|
||||
set_light(use_range / 6, use_power ? 6 : 0, light_color)
|
||||
last_range = use_range
|
||||
last_power = use_power
|
||||
//Temperature based color
|
||||
particles.gradient = list(0, COLOR_WHITE, 0.85, light_color)
|
||||
UNLINT(var/dm_filter/outline = filters[2])
|
||||
UNLINT(outline.color = light_color)
|
||||
UNLINT(var/dm_filter/bloom = filters[3])
|
||||
UNLINT(bloom.alpha = alpha)
|
||||
|
||||
/**
|
||||
* What are we doing every tick? A lot.
|
||||
* * Grab some gas from the env and convert it to reactants for the pool.
|
||||
@@ -203,14 +214,27 @@
|
||||
// Let the particles inside the field react.
|
||||
React()
|
||||
|
||||
field_strength_power_multiplier = max((owned_core.field_strength ** 1.2) / 100, 1)
|
||||
// Dump power to our powernet.
|
||||
owned_core.add_avail(FUSION_ENERGY_PER_K * plasma_temperature)
|
||||
power_output = ((log(power_log_base, plasma_temperature) * power_multiplier) ** power_power) * field_strength_power_multiplier
|
||||
output_archive_5 = output_archive_4
|
||||
output_archive_4 = output_archive_3
|
||||
output_archive_3 = output_archive_2
|
||||
output_archive_2 = output_archive_1
|
||||
output_archive_1 = power_output
|
||||
output_avg = ((output_archive_1 + output_archive_2 + output_archive_3 + output_archive_4 + output_archive_5 ) / 5)
|
||||
owned_core.add_avail(power_output)
|
||||
|
||||
// Roundstart update
|
||||
if(field_strength < 20)
|
||||
field_strength = 20
|
||||
field_strength_entropy_multiplier = clamp((owned_core.field_strength ** 1.075) / 40, 0.8, 2.0)
|
||||
// Energy decay (entropy tax).
|
||||
if(plasma_temperature >= 1)
|
||||
var/lost = plasma_temperature*0.01
|
||||
var/lost = plasma_temperature * 0.0045
|
||||
radiation += lost
|
||||
plasma_temperature -= lost
|
||||
var/temp_change = 0 - (lost * field_strength_entropy_multiplier)
|
||||
adjust_temperature(temp_change, cause = "Containment Entropy")
|
||||
|
||||
// Handle some reactants formatting.
|
||||
for(var/reactant in reactants)
|
||||
@@ -218,7 +242,7 @@
|
||||
if(amount < 1)
|
||||
reactants.Remove(reactant)
|
||||
else if(amount >= FUSION_REACTANT_CAP)
|
||||
var/radiate = rand(3 * amount / 4, amount / 4)
|
||||
var/radiate = rand(amount / 16, 3 * amount / 16)
|
||||
reactants[reactant] -= radiate
|
||||
radiation += radiate
|
||||
|
||||
@@ -229,8 +253,6 @@
|
||||
warning()
|
||||
|
||||
Radiate()
|
||||
if(radiation)
|
||||
SSradiation.radiate(src, round(radiation*0.001))
|
||||
return 1
|
||||
|
||||
/**
|
||||
@@ -247,9 +269,12 @@
|
||||
* document details later.
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/check_instability()
|
||||
field_strength_instability_multiplier = max((owned_core.field_strength ** 1.1)/20, 1)
|
||||
if(tick_instability > 0)
|
||||
percent_unstable_archive = percent_unstable
|
||||
percent_unstable += (tick_instability*size)/FUSION_INSTABILITY_DIVISOR
|
||||
// Apply any modifiers to instability imparted by current field strength, but only apply up to FUSION_INTEGRITY_RATE_LIMIT additional instability.
|
||||
var/new_instability = min((tick_instability * field_strength_instability_multiplier)/FUSION_INSTABILITY_DIVISOR, FUSION_INTEGRITY_RATE_LIMIT)
|
||||
percent_unstable += new_instability
|
||||
tick_instability = 0
|
||||
UpdateVisuals()
|
||||
else
|
||||
@@ -259,14 +284,14 @@
|
||||
if(percent_unstable > 1)
|
||||
percent_unstable = 1
|
||||
if(percent_unstable > 0)
|
||||
percent_unstable = max(0, percent_unstable-rand(0.01,0.03))
|
||||
percent_unstable = max(0, percent_unstable-rand(0.02,0.08))
|
||||
UpdateVisuals()
|
||||
|
||||
if(percent_unstable >= 1)
|
||||
owned_core.Shutdown(force_rupture=1)
|
||||
else
|
||||
if(percent_unstable > 0.5 && prob(percent_unstable*100))
|
||||
var/ripple_radius = (((size-1) / 2) * WORLD_ICON_SIZE) + WORLD_ICON_SIZE
|
||||
var/ripple_radius = ((size-1) / 2) + WORLD_ICON_SIZE
|
||||
var/wave_size = 4
|
||||
if(plasma_temperature < FUSION_RUPTURE_THRESHOLD)
|
||||
visible_message(SPAN_DANGER("\The [src] ripples uneasily, like a disturbed pond."))
|
||||
@@ -291,7 +316,7 @@
|
||||
rupture = prob(25)
|
||||
wave_size += 4
|
||||
|
||||
if(rupture)
|
||||
if(rupture && !pause_rupture)
|
||||
owned_core.Shutdown(force_rupture=1)
|
||||
else
|
||||
var/lost_plasma = (plasma_temperature*percent_unstable)
|
||||
@@ -299,7 +324,8 @@
|
||||
if(flare)
|
||||
radiation += plasma_temperature/2
|
||||
wave_size += 6
|
||||
plasma_temperature -= lost_plasma
|
||||
var/temp_change = 0 - lost_plasma
|
||||
adjust_temperature(temp_change, cause = "Instability Bleed-off")
|
||||
|
||||
if(fuel_loss)
|
||||
for(var/particle in reactants)
|
||||
@@ -375,13 +401,17 @@
|
||||
* EMP, rads, and a big fuckoff explosion.
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/Rupture()
|
||||
visible_message(SPAN_DANGER("\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!"))
|
||||
set_light(1, 0.1, 15, 2, "#ccccff")
|
||||
empulse(get_turf(src), Ceil(plasma_temperature/1000), Ceil(plasma_temperature/300))
|
||||
sleep(5)
|
||||
if(pause_rupture)
|
||||
return
|
||||
visible_message(SPAN_DANGER("\The [src] convulses violently as gouts of plasma spill forth!"))
|
||||
set_light(1, 0.1, "#ccccff", 15, 2)
|
||||
empulse(get_turf(src), Ceil(plasma_temperature/1000000), Ceil(plasma_temperature/300000))
|
||||
RadiateAll()
|
||||
explosion(get_turf(owned_core), 8, 8)
|
||||
return
|
||||
addtimer(CALLBACK(src, PROC_REF(RuptureExplosion)), 45 SECONDS)
|
||||
|
||||
/obj/effect/fusion_em_field/proc/RuptureExplosion()
|
||||
visible_message(SPAN_DANGER("\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!"))
|
||||
explosion(get_turf(owned_core), 6, 8)
|
||||
|
||||
/**
|
||||
* Sets field strength in Tesla, and corresponding field size.
|
||||
@@ -389,17 +419,18 @@
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/ChangeFieldStrength(new_strength)
|
||||
var/calc_size = 1
|
||||
if(new_strength <= 50)
|
||||
if(new_strength < 40)
|
||||
calc_size = 1
|
||||
else if(new_strength <= 200)
|
||||
else if(new_strength < 80)
|
||||
calc_size = 3
|
||||
else if(new_strength <= 500)
|
||||
// Right now the max value allowed by the interface is 120. Change this from 121->120 if we want to allow bigger reactors.
|
||||
else if(new_strength < 121)
|
||||
calc_size = 5
|
||||
else if(new_strength <= 1000)
|
||||
else if(new_strength < 160)
|
||||
calc_size = 7
|
||||
else if(new_strength <= 2000)
|
||||
else if(new_strength < 200)
|
||||
calc_size = 9
|
||||
else if(new_strength <= 5000)
|
||||
else if(new_strength < 240)
|
||||
calc_size = 11
|
||||
else
|
||||
calc_size = 13
|
||||
@@ -407,8 +438,17 @@
|
||||
change_size(calc_size)
|
||||
|
||||
/obj/effect/fusion_em_field/proc/AddEnergy(a_energy, a_plasma_temperature)
|
||||
energy += a_energy
|
||||
// Boost gyro effects at low temperatures for faster startup
|
||||
if(plasma_temperature <= 75000)
|
||||
a_energy = a_energy * 32
|
||||
else if(plasma_temperature <= 250000)
|
||||
a_energy = a_energy * 8
|
||||
else if(plasma_temperature <= 1000000)
|
||||
a_energy = a_energy * 2
|
||||
energy += a_energy / 2
|
||||
|
||||
plasma_temperature += a_plasma_temperature
|
||||
|
||||
if(a_energy && percent_unstable > 0)
|
||||
percent_unstable = max(percent_unstable - (a_energy/10000), 0)
|
||||
while(energy >= 100)
|
||||
@@ -450,10 +490,10 @@
|
||||
for(var/particle in reactants)
|
||||
radiation += reactants[particle]
|
||||
reactants.Remove(particle)
|
||||
radiation += plasma_temperature/2
|
||||
radiation += plasma_temperature/8
|
||||
plasma_temperature = 0
|
||||
|
||||
SSradiation.radiate(src, round(radiation*0.001))
|
||||
SSradiation.radiate(src, radiation)
|
||||
Radiate()
|
||||
|
||||
/**
|
||||
@@ -465,14 +505,8 @@
|
||||
*
|
||||
* After that, it'll return the air it stole this tick, just heated up.
|
||||
* The max temperature is capped so it can't be used for TEGs or shit.
|
||||
*
|
||||
* I don't know why radiation is set to 0 after that, because it means
|
||||
* that the INDRA is COMPLETELY radiation-free short of exploding it.
|
||||
*
|
||||
* Probably need to delete radiation = 0 after testing it doesn't generate
|
||||
* unreasonable amounts of rads with current values.
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/Radiate()
|
||||
/obj/effect/fusion_em_field/proc/Radiate(safe = TRUE)
|
||||
if(istype(loc, /turf))
|
||||
for(var/atom/movable/AM in range(max(1,FLOOR(size/2, 1)), loc))
|
||||
|
||||
@@ -488,7 +522,7 @@
|
||||
continue
|
||||
|
||||
AM.visible_message(SPAN_DANGER("The field buckles visibly around \the [AM]!"))
|
||||
tick_instability += rand(30,50)
|
||||
tick_instability += rand(10,25)
|
||||
AM.emp_act(EMP_LIGHT)
|
||||
|
||||
if(owned_core && owned_core.loc)
|
||||
@@ -496,6 +530,19 @@
|
||||
// Putting an upper bound on it to stop it being used in a TEG.
|
||||
if(environment && environment.temperature < (T0C+1000))
|
||||
environment.add_thermal_energy(plasma_temperature*20000)
|
||||
|
||||
// Radiation levels can spike unpredictably based on how many reagents we're throwing out, which reactions ran this cycle, etc.
|
||||
// And while we like some unpredictability, it gets a little excessive with the INDRA. Use these vars to balance out actual rad output.
|
||||
radiation_archive_5 = radiation_archive_4
|
||||
radiation_archive_4 = radiation_archive_3
|
||||
radiation_archive_3 = radiation_archive_2
|
||||
radiation_archive_2 = radiation_archive_1
|
||||
radiation_archive_1 = radiation
|
||||
|
||||
if(radiation >= 1000)
|
||||
radiation_avg = ((radiation_archive_1 + radiation_archive_2 + radiation_archive_3 + radiation_archive_4 + radiation_archive_5 ) / 5)
|
||||
SSradiation.radiate(src, radiation_avg * 0.01)
|
||||
|
||||
radiation = 0
|
||||
|
||||
/obj/effect/fusion_em_field/proc/change_size(newsize = 1)
|
||||
@@ -519,63 +566,66 @@
|
||||
* *
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/React()
|
||||
// Loop through the reactants in random order
|
||||
// Loop through the reactants in random order.
|
||||
var/list/react_pool = reactants.Copy()
|
||||
last_reactants = 0
|
||||
|
||||
// Can't have any reactions if there aren't any reactants present
|
||||
// Can't have any reactions if there aren't any reactants present.
|
||||
if(length(react_pool))
|
||||
//determine a random amount to actually react this cycle, and remove it from the standard pool
|
||||
//this is a hack, and quite nonrealistic :(
|
||||
// Determine a random amount to actually react this cycle, and remove it from the standard pool.
|
||||
// This is a hack, and quite nonrealistic :(
|
||||
for(var/reactant in react_pool)
|
||||
react_pool[reactant] = rand(FLOOR(react_pool[reactant]/2, 1),react_pool[reactant])
|
||||
reactants[reactant] -= react_pool[reactant]
|
||||
if(!react_pool[reactant])
|
||||
react_pool -= reactant
|
||||
|
||||
//loop through all the reacting reagents, picking out random reactions for them
|
||||
// Loop through all the reacting reagents, picking out random reactions for them.
|
||||
var/list/produced_reactants = new/list
|
||||
var/list/p_react_pool = react_pool.Copy()
|
||||
while(length(p_react_pool))
|
||||
//pick one of the unprocessed reacting reagents randomly
|
||||
// Pick one of the unprocessed reacting reagents randomly.
|
||||
var/cur_p_react = pick(p_react_pool)
|
||||
p_react_pool.Remove(cur_p_react)
|
||||
|
||||
//grab all the possible reactants to have a reaction with
|
||||
// Grab all the possible reactants to have a reaction with.
|
||||
var/list/possible_s_reacts = react_pool.Copy()
|
||||
//if there is only one of a particular reactant, then it can not react with itself so remove it
|
||||
// If there is only one of a particular reactant, then it can not react with itself so remove it.
|
||||
possible_s_reacts[cur_p_react] -= 1
|
||||
if(possible_s_reacts[cur_p_react] < 1)
|
||||
possible_s_reacts.Remove(cur_p_react)
|
||||
|
||||
//loop through and work out all the possible reactions
|
||||
// Loop through and work out all the possible reactions.
|
||||
var/list/possible_reactions
|
||||
for(var/cur_s_react in possible_s_reacts)
|
||||
if(possible_s_reacts[cur_s_react] < 1)
|
||||
continue
|
||||
var/singleton/fusion_reaction/cur_reaction = get_fusion_reaction(cur_p_react, cur_s_react)
|
||||
if(cur_reaction && plasma_temperature >= cur_reaction.minimum_energy_level)
|
||||
if(cur_reaction && plasma_temperature >= (cur_reaction.minimum_energy_level * aaa_minimum_energy_level_multiplier)&& possible_s_reacts[cur_p_react] >= cur_reaction.minimum_p_react)
|
||||
LAZYDISTINCTADD(possible_reactions, cur_reaction)
|
||||
|
||||
//if there are no possible reactions here, abandon this primary reactant and move on
|
||||
// If there are no possible reactions here, abandon this primary reactant and move on.
|
||||
if(!LAZYLEN(possible_reactions))
|
||||
continue
|
||||
|
||||
/// Sort based on reaction priority to avoid deut-deut eating all the deut before deut-trit can run etc.
|
||||
// Sort based on reaction priority to avoid deut-deut eating all the deut before deut-trit can run etc.
|
||||
sortTim(possible_reactions, /proc/cmp_fusion_reaction_des)
|
||||
|
||||
//split up the reacting atoms between the possible reactions
|
||||
// Split up the reacting atoms between the possible reactions.
|
||||
while(length(possible_reactions))
|
||||
var/singleton/fusion_reaction/cur_reaction = possible_reactions[1]
|
||||
possible_reactions.Remove(cur_reaction)
|
||||
|
||||
//set the randmax to be the lower of the two involved reactants
|
||||
// Set the randmax to be the lower of the two involved reactants.
|
||||
var/max_num_reactants = react_pool[cur_reaction.p_react] > react_pool[cur_reaction.s_react] ? \
|
||||
react_pool[cur_reaction.s_react] : react_pool[cur_reaction.p_react]
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//make sure we have enough energy
|
||||
// Make sure we have enough energy.
|
||||
// First, if minimum_reaction_temperature not set, make it the same as minimum_energy_level.
|
||||
if(!cur_reaction.minimum_reaction_temperature)
|
||||
cur_reaction.minimum_reaction_temperature = (cur_reaction.minimum_energy_level * 0.8 * aaa_minimum_energy_level_multiplier)
|
||||
if(plasma_temperature < cur_reaction.minimum_reaction_temperature)
|
||||
continue
|
||||
|
||||
@@ -584,17 +634,19 @@
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//randomly determined amount to react
|
||||
var/amount_reacting = rand(1, max_num_reactants)
|
||||
// Randomly determined amount to react. Starts at up to 1/20th, scales to up to 2/3rd at 20x min temp
|
||||
var/temp_over_min = plasma_temperature / (cur_reaction.minimum_energy_level * 20 * aaa_minimum_energy_level_multiplier)
|
||||
var/max_react_percent = clamp(temp_over_min, (1/20), (2/3))
|
||||
var/amount_reacting = rand(1, (max_num_reactants * max_react_percent))
|
||||
|
||||
//removing the reacting substances from the list of substances that are primed to react this cycle
|
||||
//if there aren't enough of that substance (there should be) then modify the reactant amounts accordingly
|
||||
// Removing the reacting substances from the list of substances that are primed to react this cycle.
|
||||
// If there aren't enough of that substance (there should be) then modify the reactant amounts accordingly.
|
||||
if( react_pool[cur_reaction.p_react] - amount_reacting >= 0 )
|
||||
react_pool[cur_reaction.p_react] -= amount_reacting
|
||||
else
|
||||
amount_reacting = react_pool[cur_reaction.p_react]
|
||||
react_pool[cur_reaction.p_react] = 0
|
||||
//same again for secondary reactant
|
||||
// Same again for secondary reactant
|
||||
if(react_pool[cur_reaction.s_react] - amount_reacting >= 0 )
|
||||
react_pool[cur_reaction.s_react] -= amount_reacting
|
||||
else
|
||||
@@ -602,9 +654,18 @@
|
||||
amount_reacting = react_pool[cur_reaction.s_react]
|
||||
react_pool[cur_reaction.s_react] = 0
|
||||
|
||||
plasma_temperature -= max_num_reactants * cur_reaction.energy_consumption // Remove the consumed energy.
|
||||
plasma_temperature += max_num_reactants * cur_reaction.energy_production // Add any produced energy.
|
||||
radiation += max_num_reactants * cur_reaction.radiation // Add any produced radiation.
|
||||
// Attempt to run temperature changes in isolation to prevent weird drops
|
||||
var/plasma_temperature_change
|
||||
var/current_reaction_energy_production = cur_reaction.energy_production
|
||||
if(cur_reaction.maximum_effective_temperature && plasma_temperature > cur_reaction.maximum_effective_temperature)
|
||||
current_reaction_energy_production = current_reaction_energy_production * 0.4
|
||||
plasma_temperature_change -= max_num_reactants * cur_reaction.energy_consumption
|
||||
plasma_temperature_change += max_num_reactants * current_reaction_energy_production
|
||||
|
||||
adjust_temperature(plasma_temperature_change, cur_reaction.max_temp_change_rate, cur_reaction.name)
|
||||
|
||||
// Add any produced radiation.
|
||||
radiation += max_num_reactants * cur_reaction.radiation
|
||||
tick_instability += max_num_reactants * cur_reaction.instability
|
||||
last_reactants += amount_reacting
|
||||
|
||||
@@ -658,6 +719,118 @@
|
||||
/obj/effect/fusion_em_field/add_point_filter()
|
||||
return
|
||||
|
||||
/**
|
||||
* Handles clamping temperature changes to the core field to prevent excessive second-by-second shifts.
|
||||
* Lives in its own function to ensure consistent behavior across all potential core field temperature interactions.
|
||||
*
|
||||
* * var/temperature : The amount temperature is being changed by. Can be positive or negative.
|
||||
* * var/max_percentage : Limiting value on how much temp can change per tick. Only overriden by specific fusion reactions.
|
||||
* * var/cause : For debugging only.
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/adjust_temperature(var/temp_change, var/max_percentage = FUSION_TICK_MAX_TEMP_CHANGE, var/cause)
|
||||
var/adjusted_plasma_temperature_change = min(temp_change, temp_change * FUSION_TICK_MAX_TEMP_CHANGE)
|
||||
plasma_temperature += adjusted_plasma_temperature_change
|
||||
|
||||
/**
|
||||
* Accurate(ish***) black-body radiation colors. Fuck you purple light; save it for a phoronics update!
|
||||
*/
|
||||
/obj/effect/fusion_em_field/proc/update_light_colors()
|
||||
var/use_range
|
||||
var/use_power = 0
|
||||
var/temp_mod = ((plasma_temperature-5000)/28000)
|
||||
|
||||
// Using real values for black-body radiation means the fusion reactor will almost always zip to top temp color.
|
||||
// This multiplier scales the below temperatures to better match intended range of temps in gameplay.
|
||||
var/effective_plasma_temperature = plasma_temperature / FUSION_BLACKBODY_MULTIPLIER
|
||||
|
||||
use_range = light_min_range + Ceil((light_max_range-light_min_range)*temp_mod)
|
||||
use_power = light_min_power + Ceil((light_max_power-light_min_power)*temp_mod)
|
||||
switch (effective_plasma_temperature)
|
||||
if (-INFINITY to 1000)
|
||||
light_color = "#ff5800"
|
||||
alpha = 30
|
||||
if (1000 to 1400)
|
||||
light_color = "#ff6500"
|
||||
alpha = 40
|
||||
if (1400 to 1800)
|
||||
light_color = "#ff7e00"
|
||||
alpha = 50
|
||||
if (1800 to 2200)
|
||||
light_color = "#ff932c"
|
||||
alpha = 60
|
||||
if (2200 to 2600)
|
||||
light_color = "#ffa54f"
|
||||
alpha = 70
|
||||
if (2600 to 3000)
|
||||
light_color = "#ffb46b"
|
||||
alpha = 80
|
||||
if (3000 to 4000)
|
||||
light_color = "#ffd1a3"
|
||||
alpha = 90
|
||||
if (4000 to 5400)
|
||||
light_color = "#ffebdc"
|
||||
alpha = 100
|
||||
if (5400 to 6200)
|
||||
light_color = "#fff5f5"
|
||||
alpha = 110
|
||||
if (6200 to 7000)
|
||||
light_color = "#f5f3ff"
|
||||
alpha = 120
|
||||
if (7000 to 8000)
|
||||
light_color = "#e3e9ff"
|
||||
alpha = 130
|
||||
if (8000 to 9000)
|
||||
light_color = "#d6e1ff"
|
||||
alpha = 140
|
||||
if (9000 to 10000)
|
||||
light_color = "#ccdbff"
|
||||
alpha = 150
|
||||
if (1000 to 11000)
|
||||
light_color = "#c4d7ff"
|
||||
alpha = 160
|
||||
if (11000 to 12000)
|
||||
light_color = "#bfd3ff"
|
||||
alpha = 170
|
||||
if (12000 to 13000)
|
||||
light_color = "#bad0ff"
|
||||
alpha = 180
|
||||
if (13000 to 14000)
|
||||
light_color = "#b6ceff"
|
||||
alpha = 190
|
||||
if (14000 to 15000)
|
||||
light_color = "#b3ccff"
|
||||
alpha = 200
|
||||
if (15000 to 16000)
|
||||
light_color = "#b0caff"
|
||||
alpha = 210
|
||||
if (16000 to 17000)
|
||||
light_color = "#aec8ff"
|
||||
alpha = 220
|
||||
if (17000 to 18000)
|
||||
light_color = "#acc7ff"
|
||||
alpha = 230
|
||||
if (18000 to 20000)
|
||||
light_color = "#a8c5ff"
|
||||
alpha = 230
|
||||
if (20000 to 23000)
|
||||
light_color = "#94c2ff"
|
||||
alpha = 230
|
||||
if (23000 to INFINITY)
|
||||
light_color = "#74a2ff"
|
||||
alpha = 240
|
||||
|
||||
if (last_range != use_range || last_power != use_power || color != light_color)
|
||||
set_light(use_range / 6, use_power ? 6 : 0, light_color)
|
||||
last_range = use_range
|
||||
last_power = use_power
|
||||
//Temperature based color
|
||||
|
||||
particles.gradient = list(0, COLOR_WHITE, 0.85, light_color)
|
||||
UNLINT(var/dm_filter/outline = filters[2])
|
||||
UNLINT(outline.color = light_color)
|
||||
UNLINT(var/dm_filter/bloom = filters[3])
|
||||
UNLINT(bloom.alpha = alpha)
|
||||
|
||||
/particles/fusion
|
||||
width = 500
|
||||
height = 500
|
||||
@@ -673,7 +846,10 @@
|
||||
color = 0
|
||||
drift = generator("circle", 0.2, NORMAL_RAND)
|
||||
|
||||
#undef FUSION_ENERGY_PER_K
|
||||
#undef FUSION_INSTABILITY_DIVISOR
|
||||
#undef FUSION_RUPTURE_THRESHOLD
|
||||
#undef FUSION_REACTANT_CAP
|
||||
#undef FUSION_WARNING_DELAY
|
||||
#undef FUSION_BLACKBODY_MULTIPLIER
|
||||
#undef FUSION_INTEGRITY_RATE_LIMIT
|
||||
#undef FUSION_TICK_MAX_TEMP_CHANGE
|
||||
|
||||
@@ -77,3 +77,9 @@
|
||||
|
||||
/obj/item/fuel_assembly/hydrogen/New(newloc)
|
||||
..(newloc, MATERIAL_HYDROGEN_METALLIC)
|
||||
|
||||
/obj/item/fuel_assembly/iron/New(newloc)
|
||||
..(newloc, MATERIAL_IRON)
|
||||
|
||||
/obj/item/fuel_assembly/boron/New(newloc)
|
||||
..(newloc, MATERIAL_BORON)
|
||||
|
||||
@@ -1,16 +1,30 @@
|
||||
GLOBAL_LIST(fusion_reactions)
|
||||
|
||||
/singleton/fusion_reaction
|
||||
var/p_react = "" // Primary reactant.
|
||||
var/s_react = "" // Secondary reactant.
|
||||
var/minimum_energy_level = 1
|
||||
/// Used in Fusion Codex. The name will default to "[p_react]-[s_react]" unless set.
|
||||
var/name
|
||||
/// Primary reactant.
|
||||
var/p_react = ""
|
||||
/// Minimum # of p required to react.
|
||||
var/minimum_p_react = 0
|
||||
/// Secondary reactant.
|
||||
var/s_react = ""
|
||||
/// This is the minimum energy to initiate a given reaction.
|
||||
var/minimum_energy_level = 250000
|
||||
/// This is the minimum energy to continue a given reaction, once started. Used for halting energy-consuming reactions.
|
||||
/// When not set, it will default to (minimum_energy_level * 0.8) to avoid tanking plasma temp in a single tick.
|
||||
var/minimum_reaction_temperature
|
||||
/// Gameplay balancing. If set, this reaction will produce less power when above the given temperature level.
|
||||
var/maximum_effective_temperature
|
||||
var/energy_consumption = 0
|
||||
var/energy_production = 0
|
||||
var/radiation = 0
|
||||
var/instability = 0
|
||||
var/list/products = list()
|
||||
var/minimum_reaction_temperature = 100
|
||||
/// In what order will reactions be carried out? Default 100, less important reactions have priority reduced.
|
||||
var/priority = 100
|
||||
/// Cap on what % of current plasma temperature the reaction is allowed to increase or reduce in a single tick. Higher values for more volatile reactions.
|
||||
var/max_temp_change_rate = 0.2
|
||||
|
||||
/singleton/fusion_reaction/proc/handle_reaction_special(obj/effect/fusion_em_field/holder)
|
||||
return 0
|
||||
@@ -32,100 +46,267 @@ GLOBAL_LIST(fusion_reactions)
|
||||
if(secondary_reactions.Find(s_react))
|
||||
return GLOB.fusion_reactions[p_react][s_react]
|
||||
|
||||
// Material fuels
|
||||
// deuterium
|
||||
// tritium
|
||||
// phoron
|
||||
// supermatter
|
||||
|
||||
// Gaseous/reagent fuels
|
||||
// hydrogen
|
||||
// helium
|
||||
// lithium
|
||||
// boron
|
||||
|
||||
// Basic power production reactions.
|
||||
// This is not necessarily realistic, but it makes a basic failure more spectacular.
|
||||
/singleton/fusion_reaction/hydrogen_hydrogen
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_HYDROGEN
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
products = list(GAS_HELIUM = 1)
|
||||
priority = 10
|
||||
|
||||
/singleton/fusion_reaction/deuterium_deuterium
|
||||
p_react = GAS_DEUTERIUM
|
||||
s_react = GAS_DEUTERIUM
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
priority = 0
|
||||
|
||||
// Advanced production reactions (todo)
|
||||
/singleton/fusion_reaction/deuterium_helium
|
||||
p_react = GAS_DEUTERIUM
|
||||
s_react = GAS_HELIUM
|
||||
energy_consumption = 1
|
||||
energy_production = 5
|
||||
radiation = 2
|
||||
|
||||
/singleton/fusion_reaction/deuterium_tritium
|
||||
p_react = GAS_DEUTERIUM
|
||||
s_react = GAS_TRITIUM
|
||||
energy_consumption = 1
|
||||
energy_production = 1
|
||||
energy_production = 32
|
||||
products = list(GAS_HELIUM = 1)
|
||||
instability = 0.5
|
||||
radiation = 3
|
||||
instability = 3.5
|
||||
// deut-trit bad!!!
|
||||
radiation = 280
|
||||
minimum_energy_level = 500
|
||||
maximum_effective_temperature = 350000
|
||||
priority = 1
|
||||
|
||||
/singleton/fusion_reaction/deuterium_lithium
|
||||
/singleton/fusion_reaction/deuterium_deuterium
|
||||
name = "Deuterium Burning"
|
||||
p_react = GAS_DEUTERIUM
|
||||
s_react = "lithium"
|
||||
energy_consumption = 2
|
||||
energy_production = 0
|
||||
radiation = 3
|
||||
products = list(GAS_TRITIUM= 1)
|
||||
instability = 1
|
||||
s_react = GAS_DEUTERIUM
|
||||
energy_consumption = 6
|
||||
energy_production = 24
|
||||
products = list(GAS_HELIUM = 1)
|
||||
radiation = 8
|
||||
minimum_energy_level = 200000
|
||||
priority = 0
|
||||
|
||||
// Unideal/material production reactions
|
||||
/singleton/fusion_reaction/hydrogen_hydrogen
|
||||
name = "Hydrogen Burning"
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_HYDROGEN
|
||||
energy_consumption = 4
|
||||
energy_production = 19
|
||||
products = list(GAS_DEUTERIUM = 1)
|
||||
radiation = 3
|
||||
minimum_energy_level = 400000
|
||||
priority = 1
|
||||
|
||||
/singleton/fusion_reaction/hydrogen_deuterium
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_DEUTERIUM
|
||||
energy_consumption = 7
|
||||
energy_production = 12
|
||||
products = list(GAS_HELIUMFUEL = 1)
|
||||
radiation = 16
|
||||
minimum_energy_level = 300000
|
||||
priority = 2
|
||||
|
||||
/singleton/fusion_reaction/hydrogen_helium3
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_HELIUMFUEL
|
||||
energy_consumption = 2
|
||||
energy_production = 12
|
||||
products = list(GAS_HYDROGEN = 2)
|
||||
radiation = 32
|
||||
instability = 1.8
|
||||
minimum_energy_level = 450000
|
||||
priority = 10
|
||||
|
||||
/singleton/fusion_reaction/hydrogen_helium
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_HELIUM
|
||||
energy_consumption = 6
|
||||
energy_production = 18
|
||||
products = list(GAS_DEUTERIUM = 1)
|
||||
radiation = 48
|
||||
instability = 2.8
|
||||
minimum_energy_level = 200000
|
||||
priority = 9
|
||||
|
||||
/singleton/fusion_reaction/helium_helium
|
||||
name = "Helium Burning"
|
||||
p_react = GAS_HELIUM
|
||||
s_react = GAS_HELIUM
|
||||
energy_consumption = 3
|
||||
energy_production = 20
|
||||
products = list(GAS_DEUTERIUM = 2, GAS_HYDROGEN = 1)
|
||||
radiation = 6
|
||||
instability = 0.75
|
||||
minimum_energy_level = 800000
|
||||
priority = 12
|
||||
|
||||
/singleton/fusion_reaction/helium3_helium
|
||||
p_react = GAS_HELIUM
|
||||
s_react = GAS_HELIUMFUEL
|
||||
energy_consumption = 3
|
||||
energy_production = 18
|
||||
products = list("beryllium-7" = 1)
|
||||
radiation = 6
|
||||
minimum_energy_level = 850000
|
||||
priority = 13
|
||||
|
||||
/singleton/fusion_reaction/beryllium7_decay
|
||||
name = "Beryllium-7 Decay"
|
||||
p_react = "beryllium-7"
|
||||
s_react = "beryllium-7"
|
||||
energy_consumption = 2
|
||||
energy_production = 7
|
||||
products = list("lithium" = 2)
|
||||
radiation = 54
|
||||
instability = 2.25
|
||||
minimum_energy_level = 1000
|
||||
priority = 15
|
||||
|
||||
/singleton/fusion_reaction/lithium_hydrogen
|
||||
p_react = "lithium"
|
||||
s_react = GAS_HYDROGEN
|
||||
energy_consumption = 3
|
||||
energy_production = 5
|
||||
products = list(GAS_DEUTERIUM = 1, GAS_HELIUM = 1)
|
||||
radiation = 22
|
||||
instability = 0.35
|
||||
minimum_energy_level = 1480000
|
||||
priority = 16
|
||||
|
||||
/singleton/fusion_reaction/lithium_deuterium
|
||||
p_react = "lithium"
|
||||
minimum_p_react = 2000
|
||||
s_react = GAS_DEUTERIUM
|
||||
energy_consumption = 1
|
||||
energy_production = 40
|
||||
radiation = 18
|
||||
instability = 2.8
|
||||
products = list(GAS_TRITIUM = 2)
|
||||
minimum_energy_level = 2000000
|
||||
priority = 30
|
||||
|
||||
/singleton/fusion_reaction/beryllium7_hydrogen
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = "beryllium-7"
|
||||
energy_consumption = 4
|
||||
energy_production = 12
|
||||
products = list("boron-8" = 1)
|
||||
radiation = 3
|
||||
instability = 0.5
|
||||
minimum_energy_level = 1720000
|
||||
priority = 17
|
||||
|
||||
/singleton/fusion_reaction/boron8_decay
|
||||
name = "Boron-8 Decay"
|
||||
p_react = "boron-8"
|
||||
s_react = "boron-8"
|
||||
energy_consumption = 4
|
||||
energy_production = 6
|
||||
products = list("beryllium-8" = 2)
|
||||
radiation = 64
|
||||
instability = 2.5
|
||||
minimum_energy_level = 1000
|
||||
priority = 18
|
||||
|
||||
/singleton/fusion_reaction/beryllium8_fission
|
||||
name = "Beryllium-8 Fission Branch A"
|
||||
p_react = "beryllium-8"
|
||||
s_react = "beryllium-8"
|
||||
energy_consumption = 14
|
||||
energy_production = 10
|
||||
products = list(GAS_HELIUM = 2)
|
||||
radiation = 36
|
||||
instability = 5
|
||||
minimum_energy_level = 25000
|
||||
priority = 19
|
||||
|
||||
// This is just to delete lone beryllium-8 reactants that might get left over somehow
|
||||
/singleton/fusion_reaction/beryllium8_hydrogen
|
||||
name = "Beryllium-8 Fission Branch B"
|
||||
p_react = "beryllium-8"
|
||||
s_react = GAS_HYDROGEN
|
||||
energy_consumption = 18
|
||||
energy_production = 10
|
||||
products = list(GAS_HELIUM = 2)
|
||||
radiation = 72
|
||||
minimum_energy_level = 400000
|
||||
priority = 18
|
||||
|
||||
/singleton/fusion_reaction/helium3_helium3
|
||||
name = "Helium-3 Burning"
|
||||
p_react = GAS_HELIUMFUEL
|
||||
s_react = GAS_HELIUMFUEL
|
||||
energy_consumption = 2
|
||||
energy_production = 96
|
||||
products = list(GAS_HELIUM = 1, GAS_HYDROGEN = 2)
|
||||
radiation = 1
|
||||
minimum_energy_level = 3200000
|
||||
priority = 30
|
||||
|
||||
// bad!!!
|
||||
/singleton/fusion_reaction/oxygen_oxygen
|
||||
name = "Oxygen Burning"
|
||||
p_react = GAS_OXYGEN
|
||||
s_react = GAS_OXYGEN
|
||||
energy_consumption = 10
|
||||
energy_production = 0
|
||||
instability = 5
|
||||
radiation = 5
|
||||
instability = 8
|
||||
radiation = 250
|
||||
products = list("silicon"= 1)
|
||||
|
||||
/singleton/fusion_reaction/iron_iron
|
||||
// Iron poisoning
|
||||
/singleton/fusion_reaction/iron_poison
|
||||
name = "Iron Poisoning"
|
||||
p_react = "iron"
|
||||
s_react = "iron"
|
||||
products = list("silver" = 10, "gold" = 10, "platinum" = 10) // Not realistic but w/e
|
||||
energy_consumption = 10
|
||||
energy_consumption = 32
|
||||
energy_production = 0
|
||||
radiation = 48
|
||||
minimum_energy_level = 1000
|
||||
priority = 35
|
||||
|
||||
// Gold poisoning
|
||||
/singleton/fusion_reaction/gold_poison
|
||||
name = "Gold Poisoning"
|
||||
p_react = "gold"
|
||||
s_react = "gold"
|
||||
energy_consumption = 48
|
||||
energy_production = 0
|
||||
instability = 2
|
||||
minimum_reaction_temperature = 10000
|
||||
minimum_energy_level = 1000
|
||||
radiation = 96
|
||||
|
||||
/singleton/fusion_reaction/phoron_hydrogen
|
||||
p_react = GAS_HYDROGEN
|
||||
s_react = GAS_PHORON
|
||||
energy_consumption = 10
|
||||
/singleton/fusion_reaction/iron_iron
|
||||
name = "Iron Burning"
|
||||
p_react = "iron"
|
||||
s_react = "iron"
|
||||
// Much of the gold is going to be consumed to poison the reactor.
|
||||
products = list("silver" = 12, "gold" = 32, "platinum" = 12, "lead" = 12, ) // Not realistic but w/e
|
||||
energy_consumption = 32
|
||||
energy_production = 0
|
||||
instability = 5
|
||||
products = list("mhydrogen" = 1)
|
||||
minimum_reaction_temperature = 8000
|
||||
instability = 0.5
|
||||
radiation = 49
|
||||
minimum_energy_level = 2800000
|
||||
priority = 40
|
||||
|
||||
/singleton/fusion_reaction/mhydrogen
|
||||
name = "Metallic Hydrogen Stabilization"
|
||||
p_react = "metallic hydrogen"
|
||||
s_react = "metallic hydrogen"
|
||||
energy_consumption = 0
|
||||
energy_production = 50
|
||||
instability = -8
|
||||
radiation = 10
|
||||
products = list("deuterium" = 1, "metallic hydrogen" = 1)
|
||||
minimum_energy_level = 800000
|
||||
|
||||
/singleton/fusion_reaction/iron_phoron
|
||||
name = "Phoron Shot"
|
||||
p_react = "iron"
|
||||
s_react = GAS_PHORON
|
||||
energy_consumption = 64
|
||||
energy_production = 18
|
||||
radiation = 64
|
||||
instability = 6.5
|
||||
products = list("uranium" = 30, "borosilicate glass" = 80, "osmium" = 20) // Psuedoscience but here we are
|
||||
minimum_energy_level = 4000000
|
||||
priority = 40
|
||||
|
||||
// VERY UNIDEAL REACTIONS.
|
||||
/singleton/fusion_reaction/phoron_supermatter
|
||||
p_react = "supermatter"
|
||||
s_react = GAS_PHORON
|
||||
energy_consumption = 0
|
||||
energy_production = 5
|
||||
radiation = 40
|
||||
instability = 20
|
||||
energy_production = 800
|
||||
radiation = 4000
|
||||
instability = 30
|
||||
|
||||
/singleton/fusion_reaction/phoron_supermatter/handle_reaction_special(obj/effect/fusion_em_field/holder)
|
||||
|
||||
wormhole_event(GetConnectedZlevels(holder))
|
||||
|
||||
var/turf/origin = get_turf(holder)
|
||||
@@ -153,26 +334,3 @@ GLOBAL_LIST(fusion_reactions)
|
||||
explosion(origin, 8)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
// High end reactions.
|
||||
/singleton/fusion_reaction/boron_hydrogen
|
||||
p_react = GAS_BORON
|
||||
s_react = GAS_HYDROGEN
|
||||
minimum_energy_level = 15000
|
||||
energy_consumption = 3
|
||||
energy_production = 12
|
||||
radiation = 3
|
||||
instability = 2.5
|
||||
products = list(GAS_HELIUM = 1)
|
||||
|
||||
// Any now we go even further beyond!!!!
|
||||
/singleton/fusion_reaction/iron_phoron
|
||||
p_react = "iron"
|
||||
s_react = GAS_PHORON
|
||||
minimum_energy_level = 100000
|
||||
energy_consumption = 10
|
||||
energy_production = 4
|
||||
radiation = 30
|
||||
instability = 5
|
||||
products = list("uranium" = 10, "lead" = 10, "borosilicate glass" = 10) // Psuedoscience but here we are
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
for(var/mat in stored)
|
||||
var/material/material = SSmaterials.get_material_by_name(mat)
|
||||
if(material)
|
||||
var/sheets = FLOOR(stored[mat]/(SHEET_MATERIAL_AMOUNT * 1.5), 1)
|
||||
var/sheets = FLOOR(stored[mat]/(SHEET_MATERIAL_AMOUNT * 2), 1)
|
||||
data["materials"] += list(list("material" = mat, "rawamount" = stored[mat], "amount" = sheets, "harvest" = harvesting[mat]))
|
||||
return data
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
harvesting -= mat
|
||||
else
|
||||
var/harvest = min(harvest_from.owned_field.reactants[mat], rand(100,200))
|
||||
harvest_from.owned_field.reactants[mat] -= harvest
|
||||
// Leave a few counts of the reactant to avoid deactivating harvest mode
|
||||
harvest_from.owned_field.reactants[mat] -= (harvest - rand(0,5))
|
||||
if(harvest_from.owned_field.reactants[mat] <= 0)
|
||||
harvest_from.owned_field.reactants -= mat
|
||||
stored[mat] += harvest
|
||||
@@ -112,7 +113,7 @@
|
||||
var/material/material = SSmaterials.get_material_by_name(mat)
|
||||
if(material)
|
||||
var/sheet_cost = (SHEET_MATERIAL_AMOUNT * 1.5)
|
||||
var/sheets = FLOOR(stored[mat]/sheet_cost, 1)
|
||||
var/sheets = min(FLOOR(stored[mat]/sheet_cost, 1), 50)
|
||||
if(sheets > 0)
|
||||
var/obj/item/stack/material/M = new material.stack_type(get_turf(src), sheets)
|
||||
M.update_icon()
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
obj_flags = OBJ_FLAG_ROTATABLE
|
||||
|
||||
use_power = POWER_USE_OFF
|
||||
idle_power_usage = 100 //Watts, I hope. Just enough to do the computer and display things.
|
||||
idle_power_usage = 1000
|
||||
|
||||
var/max_power = 500000
|
||||
var/max_power = 2500000
|
||||
var/thermal_efficiency = 0.65
|
||||
|
||||
var/obj/machinery/atmospherics/binary/circulator/circ1
|
||||
@@ -146,7 +146,7 @@
|
||||
//Exceeding maximum power leads to some power loss
|
||||
if(effective_gen > max_power && prob(5))
|
||||
spark_system.queue()
|
||||
stored_energy *= 0.5
|
||||
stored_energy *= 0.67
|
||||
|
||||
//Power
|
||||
last_circ1_gen = circ1.return_stored_energy()
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
temperature_gain and max_temperature are set so that the max safe power level is 4.
|
||||
Setting to 5 or higher can only be done temporarily before the generator overheats.
|
||||
*/
|
||||
power_gen = 25000 //Watts output per power_output level
|
||||
power_gen = 50000 //Watts output per power_output level
|
||||
var/max_power_output = 5 //The maximum power setting without emagging.
|
||||
var/max_safe_output = 4 // For UI use, maximal output that won't cause overheat.
|
||||
var/time_per_sheet = 576 //fuel efficiency - how long 1 sheet lasts at power level 1
|
||||
@@ -416,7 +416,7 @@
|
||||
sheet_path = /obj/item/stack/material/uranium
|
||||
board_path = "/obj/item/circuitboard/portgen/advanced"
|
||||
|
||||
power_gen = 50000 // 200 kW = safe max, 250 kW = unsafe max.
|
||||
power_gen = 100000 // 400 kW = safe max, 500 kW = unsafe max.
|
||||
max_temperature = 340
|
||||
temperature_gain = 60
|
||||
|
||||
@@ -448,7 +448,7 @@
|
||||
sheet_path = /obj/item/stack/material/tritium
|
||||
board_path = "/obj/item/circuitboard/portgen/super"
|
||||
|
||||
power_gen = 80000 // 400 kW = safe max, 640 kW = unsafe max
|
||||
power_gen = 160000 // 800 kW = safe max, 960 kW = unsafe max
|
||||
max_power_output = 8
|
||||
max_safe_output = 5
|
||||
time_per_sheet = 576
|
||||
@@ -462,7 +462,7 @@
|
||||
/obj/machinery/power/portgen/basic/fusion
|
||||
name = "minature fusion reactor"
|
||||
desc = "The RT7-0, an industrial all-in-one nuclear fusion power plant created by Hephaestus. It uses tritium as a fuel source and relies on coolant to keep the reactor cool. Rated for 500 kW max safe output."
|
||||
power_gen = 100000
|
||||
power_gen = 200000
|
||||
icon_state = "reactor"
|
||||
base_icon = "reactor"
|
||||
portgen_lightcolour = "#458943"
|
||||
|
||||
@@ -57,6 +57,27 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
// Proc: power_wattage_readable()
|
||||
// Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW)
|
||||
// Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter)
|
||||
/obj/machinery/proc/power_wattage_readable(var/amount = 0)
|
||||
var/units = ""
|
||||
// 10kW and less - Watts
|
||||
if(amount < 10000)
|
||||
units = "W"
|
||||
// 10MW and less - KiloWatts
|
||||
else if(amount < 10000000)
|
||||
units = "kW"
|
||||
amount = (round(amount/100) / 10)
|
||||
// More than 10MW - MegaWatts
|
||||
else
|
||||
units = "MW"
|
||||
amount = (round(amount/10000) / 100)
|
||||
if (units == "W")
|
||||
return "[amount] W"
|
||||
else
|
||||
return "[amount] [units]"
|
||||
|
||||
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
|
||||
return
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
buckle_lying = FALSE
|
||||
buckle_require_restraints = TRUE
|
||||
|
||||
var/power_gen = 1000 // Enough to power a single APC. 4000 output with T4 capacitor.
|
||||
var/power_gen = 4000 // Enough to power a single APC. 16000 output with T4 capacitor.
|
||||
|
||||
var/irradiate = TRUE // RTGs irradiate surroundings, but only when panel is open.
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
/obj/machinery/power/rtg/advanced
|
||||
desc = "An advanced RTG capable of moderating isotope decay, increasing power output but reducing lifetime. It uses phoron-fueled radiation collectors to increase output even further."
|
||||
power_gen = 1250 // 2500 on T1, 10000 on T4.
|
||||
power_gen = 5000 // 10000 on T1, 20000 on T4.
|
||||
|
||||
component_types = list(
|
||||
/obj/item/stack/cable_coil{amount = 5},
|
||||
|
||||
@@ -47,27 +47,6 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
// Proc: reading_to_text()
|
||||
// Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW)
|
||||
// Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter)
|
||||
/obj/machinery/power/sensor/proc/reading_to_text(var/amount = 0)
|
||||
var/units = ""
|
||||
// 10kW and less - Watts
|
||||
if(amount < 10000)
|
||||
units = "W"
|
||||
// 10MW and less - KiloWatts
|
||||
else if(amount < 10000000)
|
||||
units = "kW"
|
||||
amount = (round(amount/100) / 10)
|
||||
// More than 10MW - MegaWatts
|
||||
else
|
||||
units = "MW"
|
||||
amount = (round(amount/10000) / 100)
|
||||
if (units == "W")
|
||||
return "[amount] W"
|
||||
else
|
||||
return "~[amount] [units]" //kW and MW are only approximate readings, therefore add "~"
|
||||
|
||||
// Proc: find_apcs()
|
||||
// Parameters: None
|
||||
// Description: Searches powernet for APCs and returns them in a list.
|
||||
@@ -119,13 +98,13 @@
|
||||
out += "<td>NO CELL"
|
||||
var/load = A.lastused_total // Load.
|
||||
total_apc_load += load
|
||||
load = reading_to_text(load)
|
||||
load = power_wattage_readable(load)
|
||||
out += "<td>[load]"
|
||||
|
||||
out += "<br><b>AREA_USAGE_TOTAL AVAILABLE: [reading_to_text(powernet.avail)]</b>"
|
||||
out += "<br><b>APC LOAD: [reading_to_text(total_apc_load)]</b>"
|
||||
out += "<br><b>OTHER LOAD: [reading_to_text(max(powernet.load - total_apc_load, 0))]</b>"
|
||||
out += "<br><b>AREA_USAGE_TOTAL GRID LOAD: [reading_to_text(powernet.viewload)] ([round((powernet.load / powernet.avail) * 100)]%)</b>"
|
||||
out += "<br><b>AREA_USAGE_TOTAL AVAILABLE: [power_wattage_readable(powernet.avail)]</b>"
|
||||
out += "<br><b>APC LOAD: [power_wattage_readable(total_apc_load)]</b>"
|
||||
out += "<br><b>OTHER LOAD: [power_wattage_readable(max(powernet.load - total_apc_load, 0))]</b>"
|
||||
out += "<br><b>AREA_USAGE_TOTAL GRID LOAD: [power_wattage_readable(powernet.viewload)] ([round((powernet.load / powernet.avail) * 100)]%)</b>"
|
||||
|
||||
if(powernet.problem)
|
||||
out += "<br><b>WARNING: Abnormal grid activity detected!</b>"
|
||||
@@ -163,7 +142,7 @@
|
||||
APC_entry["cell_charge"] = A.cell ? round(A.cell.percent()) : 0
|
||||
APC_entry["cell_status"] = A.cell ? chg[A.charging+1] : 0
|
||||
// Other info
|
||||
APC_entry["total_load"] = reading_to_text(A.lastused_total)
|
||||
APC_entry["total_load"] = power_wattage_readable(A.lastused_total)
|
||||
var/area_display_name = get_area_display_name(A.area)
|
||||
APC_entry["name"] = area_display_name
|
||||
// Add data into main list of APC data.
|
||||
@@ -171,10 +150,10 @@
|
||||
// Add load of this APC to total APC load calculation
|
||||
total_apc_load += A.lastused_total
|
||||
data["apc_data"] = APC_data
|
||||
data["total_avail"] = reading_to_text(max(powernet.avail, 0))
|
||||
data["total_used_apc"] = reading_to_text(max(total_apc_load, 0))
|
||||
data["total_used_other"] = reading_to_text(max(powernet.viewload - total_apc_load, 0))
|
||||
data["total_used_all"] = reading_to_text(max(powernet.viewload, 0))
|
||||
data["total_avail"] = power_wattage_readable(max(powernet.avail, 0))
|
||||
data["total_used_apc"] = power_wattage_readable(max(total_apc_load, 0))
|
||||
data["total_used_other"] = power_wattage_readable(max(powernet.viewload - total_apc_load, 0))
|
||||
data["total_used_all"] = power_wattage_readable(max(powernet.viewload, 0))
|
||||
// Prevents runtimes when avail is 0 (division by zero)
|
||||
if(powernet.avail)
|
||||
data["load_percentage"] = round((powernet.viewload / powernet.avail) * 100)
|
||||
|
||||
@@ -52,14 +52,14 @@
|
||||
else if(istype(A, /obj/machinery/power/fusion_core))
|
||||
var/obj/machinery/power/fusion_core/collided_core = A
|
||||
if(particle_type && particle_type != "neutron")
|
||||
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
|
||||
if(collided_core.AddParticles(particle_type, 12 + additional_particles))
|
||||
collided_core.owned_field.plasma_temperature += mega_energy
|
||||
collided_core.owned_field.energy += energy
|
||||
qdel(src)
|
||||
else if(istype(A, /obj/effect/fusion_particle_catcher))
|
||||
var/obj/effect/fusion_particle_catcher/PC = A
|
||||
if(particle_type && particle_type != "neutron")
|
||||
if(PC.parent.owned_core.AddParticles(particle_type, 1 + additional_particles))
|
||||
if(PC.parent.owned_core.AddParticles(particle_type, 12 + additional_particles))
|
||||
PC.parent.plasma_temperature += mega_energy
|
||||
PC.parent.energy += energy
|
||||
qdel(src)
|
||||
|
||||
+49
-25
@@ -1,5 +1,14 @@
|
||||
// the SMES
|
||||
// stores power
|
||||
/**
|
||||
* BUILDABLE SMES (Superconducting Magnetic Energy Storage) UNIT
|
||||
* AKA PSUs- both 'SMES unit' and 'PSU' will be used interchangeably in documentation and in-game.
|
||||
*
|
||||
* PSUs are linked by the RCON System, allowing for remote management of all linked
|
||||
* It also supports RCON System which allows you to operate it remotely, if properly set.
|
||||
*
|
||||
* This file contains the main code and definition information for SMES units.
|
||||
* For instantiation of buildable SMES units (the ones you'll see 99% of the time),
|
||||
* please refer to 'code/modules/power/smes_construction.dm'
|
||||
*/
|
||||
|
||||
#define SMESRATE 0.05
|
||||
#define SMESMAXCHARGELEVEL 250000
|
||||
@@ -28,30 +37,41 @@
|
||||
clicksound = /singleton/sound_category/switch_sound
|
||||
|
||||
var/health = 500
|
||||
var/busted = FALSE // this it to prevent the damage text from playing repeatedly
|
||||
|
||||
var/capacity = 5e6 // maximum charge
|
||||
var/charge = 1e6 // actual charge
|
||||
/// this it to prevent the damage text from playing repeatedly
|
||||
var/busted = FALSE
|
||||
/// maximum charge
|
||||
var/capacity = 5e6
|
||||
var/charge = 1e6 /// actual charge
|
||||
var/max_coils = 0
|
||||
|
||||
var/input_attempt = 0 // 1 = attempting to charge, 0 = not attempting to charge
|
||||
var/inputting = 0 // 1 = actually inputting, 0 = not inputting
|
||||
var/input_level = 50000 // amount of power the SMES attempts to charge by
|
||||
var/input_level_max = 200000 // cap on input_level
|
||||
var/input_taken = 0 // amount that we received from powernet last tick
|
||||
/// 1 = attempting to charge, 0 = not attempting to charge
|
||||
var/input_attempt = 0
|
||||
/// 1 = actually inputting, 0 = not inputting
|
||||
var/inputting = 0
|
||||
/// amount of power the SMES attempts to charge by
|
||||
var/input_level = 250000
|
||||
/// cap on input_level
|
||||
var/input_level_max = 2000000
|
||||
/// amount that we received from powernet last tick
|
||||
var/input_taken = 0
|
||||
|
||||
var/output_attempt = 0 // 1 = attempting to output, 0 = not attempting to output
|
||||
var/outputting = 0 // 1 = actually outputting, 0 = not outputting
|
||||
var/output_level = 50000 // amount of power the SMES attempts to output
|
||||
var/output_level_max = 200000 // cap on output_level
|
||||
var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power
|
||||
/// 1 = attempting to output, 0 = not attempting to output
|
||||
var/output_attempt = 0
|
||||
/// 1 = actually outputting, 0 = not outputting
|
||||
var/outputting = 0
|
||||
/// amount of power the SMES attempts to output
|
||||
var/output_level = 250000
|
||||
/// cap on output_level
|
||||
var/output_level_max = 2000000
|
||||
/// amount of power actually outputted. may be less than output_level if the powernet returns excess power
|
||||
var/output_used = 0
|
||||
|
||||
//Holders for powerout event.
|
||||
//var/last_output_attempt = 0
|
||||
//var/last_input_attempt = 0
|
||||
//var/last_charge = 0
|
||||
///Holders for powerout event.
|
||||
///var/last_output_attempt = 0
|
||||
///var/last_input_attempt = 0
|
||||
///var/last_charge = 0
|
||||
|
||||
//For icon overlay updates
|
||||
///For icon overlay updates
|
||||
var/last_disp
|
||||
var/last_chrg
|
||||
var/last_onln
|
||||
@@ -60,14 +80,18 @@
|
||||
var/input_pulsed = 0
|
||||
var/output_cut = 0
|
||||
var/output_pulsed = 0
|
||||
var/is_critical = FALSE // Use by gridcheck event, if set to true we do not disable it
|
||||
var/failure_timer = 0 // Set by gridcheck event, temporarily disables the SMES.
|
||||
/// Use by gridcheck event, if set to true we do not disable it
|
||||
var/is_critical = FALSE
|
||||
/// Set by gridcheck event, temporarily disables the SMES.
|
||||
var/failure_timer = 0
|
||||
var/target_load = 0
|
||||
var/open_hatch = 0
|
||||
var/name_tag = null
|
||||
var/building_terminal = 0 //Suggestions about how to avoid clickspam building several terminals accepted!
|
||||
///Suggestions about how to avoid clickspam building several terminals accepted!
|
||||
var/building_terminal = 0
|
||||
var/obj/machinery/power/terminal/terminal = null
|
||||
var/should_be_mapped = 0 // If this is set to 0 it will send out warning on New()
|
||||
/// If this is set to 0 it will send out warning on New()
|
||||
var/should_be_mapped = 0
|
||||
var/datum/effect_system/sparks/big_spark
|
||||
var/datum/effect_system/sparks/small_spark
|
||||
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
// BUILDABLE SMES(Superconducting Magnetic Energy Storage) UNIT
|
||||
//
|
||||
// Last Change 1.1.2015 by Atlantis - Happy New Year!
|
||||
//
|
||||
// This is subtype of SMES that should be normally used. It can be constructed, deconstructed and hacked.
|
||||
// It also supports RCON System which allows you to operate it remotely, if properly set.
|
||||
/**
|
||||
* BUILDABLE SMES (Superconducting Magnetic Energy Storage) UNIT
|
||||
* AKA PSUs- both 'SMES unit' and 'PSU' will be used interchangeably in documentation and in-game.
|
||||
*
|
||||
* PSUs are linked by the RCON System, allowing for remote management of all linked
|
||||
* It also supports RCON System which allows you to operate it remotely, if properly set.
|
||||
*
|
||||
* This is subtype of SMES that should be normally used. It can be constructed, deconstructed and hacked.
|
||||
*/
|
||||
|
||||
//MAGNETIC COILS - These things actually store and transmit power within the SMES. Different types have different
|
||||
/// MAGNETIC COILS - These things actually store and transmit power within the SMES. Different types have different properties
|
||||
/obj/item/smes_coil
|
||||
name = "superconductive magnetic coil"
|
||||
desc = "Standard superconductive magnetic coil with balanced capacity and I/O rating."
|
||||
icon = 'icons/obj/stock_parts.dmi'
|
||||
icon_state = "smes_coil"
|
||||
w_class = WEIGHT_CLASS_BULKY // It's LARGE (backpack size)
|
||||
var/ChargeCapacity = 5000000
|
||||
var/IOCapacity = 250000
|
||||
/// It's LARGE (backpack sized)
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
var/ChargeCapacity = 2500000
|
||||
var/IOCapacity = 500000
|
||||
|
||||
/obj/item/smes_coil/get_examine_text(mob/user, distance, is_adjacent, infix, suffix)
|
||||
. = ..()
|
||||
/obj/item/smes_coil/feedback_hints(mob/user, distance, is_adjacent)
|
||||
. += ..()
|
||||
if(is_adjacent)
|
||||
. += "The label reads: Only certified professionals are allowed to handle and install this component."
|
||||
. += "Charge capacity: [ChargeCapacity/1000000] MJ."
|
||||
@@ -27,25 +31,24 @@
|
||||
name = "basic superconductive magnetic coil"
|
||||
desc = "Cheaper model of the standard superconductive magnetic coil. Its capacity and I/O rating are considerably lower."
|
||||
icon_state = "smes_coil_weak"
|
||||
ChargeCapacity = 1000000
|
||||
IOCapacity = 150000
|
||||
ChargeCapacity = 500000
|
||||
IOCapacity = 300000
|
||||
|
||||
// 1000% Charge Capacity, 20% I/O Capacity
|
||||
/obj/item/smes_coil/super_capacity
|
||||
name = "superconductive capacitance coil"
|
||||
desc = "Specialised version of the standard superconductive magnetic coil. It has significantly stronger containment field, allowing for immense power storage. However its I/O rating is much lower."
|
||||
icon_state = "smes_coil_capacitance"
|
||||
ChargeCapacity = 50000000
|
||||
IOCapacity = 50000
|
||||
ChargeCapacity = 25000000
|
||||
IOCapacity = 100000
|
||||
|
||||
// 10% Charge Capacity, 400% I/O Capacity. Technically turns SMES into large super capacitor.Ideal for shields.
|
||||
/obj/item/smes_coil/super_io
|
||||
name = "superconductive transmission coil"
|
||||
desc = "Specialised version of the standard superconductive magnetic coil. While it's almost useless for power storage it can rapidly transfer power, making it useful in systems that require large throughput."
|
||||
icon_state = "smes_coil_transmission"
|
||||
ChargeCapacity = 500000
|
||||
IOCapacity = 1000000
|
||||
|
||||
ChargeCapacity = 250000
|
||||
IOCapacity = 2000000
|
||||
|
||||
// SMES SUBTYPES - THESE ARE MAPPED IN AND CONTAIN DIFFERENT TYPES OF COILS
|
||||
|
||||
@@ -66,63 +69,85 @@
|
||||
/obj/machinery/power/smes/buildable/main_engine
|
||||
cur_coils = 4
|
||||
input_attempt = TRUE
|
||||
input_level = 500000
|
||||
input_level = 1000000
|
||||
output_attempt = TRUE
|
||||
output_level = 500000
|
||||
output_level = 1000000
|
||||
charge =1.5e+7
|
||||
|
||||
// For the substation SMES around the Horizon.
|
||||
/// For the substation SMES around the Horizon.
|
||||
/obj/machinery/power/smes/buildable/substation
|
||||
input_level = 150000
|
||||
output_level = 140000
|
||||
input_level = 250000
|
||||
output_level = 240000
|
||||
|
||||
// Telecomms substation. Based on shuttle settings; those boxes are power-hungry.
|
||||
/obj/machinery/power/smes/buildable/telecomms/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/smes_coil/super_io(src)
|
||||
input_attempt = TRUE
|
||||
output_attempt = TRUE
|
||||
input_level = 2000000
|
||||
output_level = 2000000
|
||||
charge = 5.55e+007
|
||||
|
||||
// The Horizon's shuttles want something with decent capacity to sustain themselves and enough transmission to meet their energy needs.
|
||||
/obj/machinery/power/smes/buildable/horizon_shuttle/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
input_attempt = TRUE
|
||||
output_attempt = TRUE
|
||||
input_level = 1300000
|
||||
output_level = 1300000
|
||||
charge = 5.55e+007
|
||||
|
||||
/obj/machinery/power/smes/buildable/third_party_shuttle/Initialize() //Identical to the horizon_shuttle for now as we try to work out specifics
|
||||
. = ..()
|
||||
component_parts += new /obj/item/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
input_attempt = TRUE
|
||||
output_attempt = TRUE
|
||||
input_level = 1300000
|
||||
output_level = 1300000
|
||||
input_level = 2700000
|
||||
output_level = 2700000
|
||||
charge = 5.55e+007
|
||||
|
||||
//Identical to the horizon_shuttle for now as we try to work out specifics
|
||||
/obj/machinery/power/smes/buildable/third_party_shuttle/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
input_attempt = TRUE
|
||||
output_attempt = TRUE
|
||||
input_level = 2700000
|
||||
output_level = 2700000
|
||||
charge = 5.55e+007
|
||||
|
||||
/obj/machinery/power/smes/buildable/third_party_shuttle/empty/Initialize()
|
||||
. = ..()
|
||||
charge = 0
|
||||
|
||||
/obj/machinery/power/smes/buildable/autosolars/Initialize() //for third parties that have their solars autostart, It's slightly upgraded for them
|
||||
//for third parties that have their solars autostart, It's slightly upgraded for them
|
||||
/obj/machinery/power/smes/buildable/autosolars/Initialize()
|
||||
. = ..()
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
component_parts += new /obj/item/smes_coil/super_io(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
component_parts += new /obj/item/smes_coil/super_capacity(src)
|
||||
input_attempt = TRUE
|
||||
output_attempt = TRUE
|
||||
input_level = 1000000
|
||||
output_level = 1000000
|
||||
input_level = 2700000
|
||||
output_level = 2700000
|
||||
charge = 3.02024e+006
|
||||
|
||||
// END SMES SUBTYPES
|
||||
|
||||
// SMES itself
|
||||
/obj/machinery/power/smes/buildable
|
||||
max_coils = 6 // 30M capacity, 1.5MW input/output when fully upgraded /w default coils
|
||||
var/cur_coils = 1 // Current amount of installed coils
|
||||
var/safeties_enabled = 1 // If 0 modifications can be done without discharging the SMES, at risk of critical failure.
|
||||
var/failing = 0 // If 1 critical failure has occured and SMES explosion is imminent.
|
||||
/// 20 MJ capacity, 8 MW input/output when fully upgraded /w default coils
|
||||
max_coils = 8
|
||||
/// Current amount of installed coils
|
||||
var/cur_coils = 1
|
||||
/// If 0 modifications can be done without discharging the SMES, at risk of critical failure.
|
||||
var/safeties_enabled = 1
|
||||
/// If 1 critical failure has occured and SMES explosion is imminent.
|
||||
var/failing = 0
|
||||
var/datum/wires/smes/wires
|
||||
var/grounding = 1 // Cut to quickly discharge, at cost of "minor" electrical issues in output powernet.
|
||||
var/RCon = 1 // Cut to disable AI and remote control.
|
||||
var/RCon_tag = "NO_TAG" // RCON tag, change to show it on SMES Remote control console.
|
||||
/// Cut to quickly discharge, at cost of "minor" electrical issues in output powernet.
|
||||
var/grounding = 1
|
||||
/// Cut to disable AI and remote control.
|
||||
var/RCon = 1
|
||||
/// RCON tag, change to show it on SMES Remote control console.
|
||||
var/RCon_tag = "NO_TAG"
|
||||
charge = 0
|
||||
should_be_mapped = 1
|
||||
component_types = list(
|
||||
@@ -348,8 +373,6 @@
|
||||
// Not sure if this is necessary, but just in case the SMES *somehow* survived..
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
// Proc: apcs_overload()
|
||||
// Parameters: 3 (failure_chance - chance to actually break the APC, overload_chance - Chance of breaking lights, reboot_chance - Chance of temporarily disabling the APC)
|
||||
// Description: Damages output powernet by power surge. Destroys few APCs and lights, depending on parameters.
|
||||
|
||||
@@ -78,6 +78,23 @@
|
||||
to_chat(M, SPAN_WARNING(pick("Your skin burns!", "The chemical is melting your skin!", "Wash it off, wash it off!")))
|
||||
remove_self(REAGENT_VOLUME(holder, type), holder)
|
||||
|
||||
/singleton/reagent/boron
|
||||
name = "Boron"
|
||||
description = "A dark, silvery metalloid with a small handful of industrial applications."
|
||||
reagent_state = SOLID
|
||||
color = "#888888"
|
||||
taste_description = "metal"
|
||||
taste_mult = 1.1
|
||||
fallback_specific_heat = 0.811
|
||||
value = 0.02
|
||||
|
||||
/**
|
||||
* Boron has very little affect on mammals, but is moderately toxic to arthopods and commonly used in insecticides. Hi Vaurca.
|
||||
*/
|
||||
/singleton/reagent/boron/affect_blood(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagents/holder)
|
||||
if (alien == IS_VAURCA)
|
||||
M.adjustToxLoss(2 * removed)
|
||||
|
||||
/singleton/reagent/carbon
|
||||
name = "Carbon"
|
||||
description = "A chemical element, the building block of life."
|
||||
|
||||
@@ -138,4 +138,4 @@
|
||||
..()
|
||||
|
||||
/obj/machinery/shield_capacitor/multiz
|
||||
max_charge_rate = 1250000 //1250 kW
|
||||
max_charge_rate = 1250000
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
var/global/datum/xgm_gas_data/gas_data
|
||||
|
||||
/datum/xgm_gas_data
|
||||
//Simple list of all the gas IDs.
|
||||
/// Simple list of all the gas IDs.
|
||||
var/list/gases = list()
|
||||
//The friendly, human-readable name for the gas.
|
||||
/// The friendly, human-readable name for the gas.
|
||||
var/list/name = list()
|
||||
//Specific heat of the gas. Used for calculating heat capacity.
|
||||
/// Specific heat of the gas. Used for calculating heat capacity.
|
||||
var/list/specific_heat = list()
|
||||
//Molar mass of the gas. Used for calculating specific entropy.
|
||||
/// Molar mass of the gas. Used for calculating specific entropy.
|
||||
var/list/molar_mass = list()
|
||||
//Tile overlays. /obj/gas_overlay, created from references to 'icons/effects/tile_effects.dmi'
|
||||
/// Tile overlays. /obj/gas_overlay, created from references to 'icons/effects/tile_effects.dmi'
|
||||
var/list/tile_overlay = list()
|
||||
//Optional color for tile overlay
|
||||
/// Optional color for tile overlay
|
||||
var/list/tile_overlay_color = list()
|
||||
//Overlay limits. There must be at least this many moles for the overlay to appear.
|
||||
/// Overlay limits. There must be at least this many moles for the overlay to appear.
|
||||
var/list/overlay_limit = list()
|
||||
//Flags.
|
||||
/// Flags.
|
||||
var/list/flags = list()
|
||||
|
||||
/singleton/xgm_gas
|
||||
var/id = ""
|
||||
var/name = "Unnamed Gas"
|
||||
var/desc
|
||||
var/specific_heat = 20 // J/(mol*K)
|
||||
var/molar_mass = 0.032 // kg/mol
|
||||
|
||||
|
||||
Reference in New Issue
Block a user