fission rectors but with less goto (#37435)
* mm code * size detection and setup * it actually compiles now * smore changes * fixes, additions * making things buildable pt 1 * buildability pt2 * grammar, because i was making this at 3 in the morning * file seperation and fixes * adds a new reagent * placeholder sprites pt1 * conflict resolution (i hope) * more icons, reactor assembly works on spawned obj need to add things to material construction menus, as well as make datum code a bit better. * rework to fuel mechanics, constructability additions * fixes, changes, stuff * cargo orders, construciton, bugs * runtime fixes, errors and isues. it just werks. * Update datums.dm * ENGAGE HYPERSHITCODE THRUSTERS!!!1!111!! * suggested changes pt1 * changes pt2 goto goto goto while true * SCRAM actually works now. better controller examine text. * FIX IT FIX IT FIX IT FIX IT * the candle the burns twice as long burns half as bright (fuel number change) * nerf starter * new cargo order * reactor UI * UI refactor * reactor UI functional * construction fixes * fuel creation UI * deconstruction * adjustable units * new fuelrod subtype * fuel recycling * rads * meltdown framework * rads, guide * finishing touches * UI autoclose, explosion changes * oops wrong side * nevermind i'm dumb * explosion tweak * ex_act * seconds are 2 digits * more rod icons * more heatcap * TWO SECONDS * file rename * updated control rod code for 2 secs * sprite changes, system changes, ui changes * reactor controller sounds * scram sound manually * post-review code fixes * BEGONE SUBSYSTEM, CURSE YE TO THE SHADOWS * movment fix * UI recolred to look more similar * case icon updates * enhanced detection of reactor construction, fixed runtimes * fixes lmao * changed sprites, overlay reworks * changed controller sprites * nu reactor ui * new fuel machine UI * more ui, expanded funcs, changed radium's role * regenerate calcium nerf * meltdowns are slower * nu sprites * areas, runtimes, guides, oh my! * new reagent! runtime fix! * removed old files * updated corium, tweaked meltdowns * removed gotos --------- Co-authored-by: west3436 <66280799+west3436@users.noreply.github.com>
@@ -6,3 +6,4 @@
|
||||
#define GAS_CRYOTHEUM "cryotheum"
|
||||
#define GAS_VOLATILE "volatile_fuel"
|
||||
#define GAS_OXAGENT "oxygen_agent_b"
|
||||
#define GAS_RADON "radon"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define CHEMFLAG_DISHONORABLE 1
|
||||
#define CHEMFLAG_OBSCURING 2
|
||||
#define CHEMFLAG_PIGMENT 4
|
||||
#define CHEMFLAG_NOTREMOVABLE 8 //cannot be rid of by charcoal (or other reagent tomfoolery means).
|
||||
|
||||
#define EXPLICITLY_INVALID_REAGENT_ID "Use this ID if the reagent is not supposed to be used, like for the base type of other reagents."
|
||||
|
||||
@@ -541,6 +542,13 @@
|
||||
#define FLAXOIL "flax_oil"
|
||||
#define WAX "wax"
|
||||
|
||||
#define PLUTONIUM "plutonium"
|
||||
#define RADON "radon"
|
||||
#define LEAD "lead"
|
||||
#define THALLIUM "thallium"
|
||||
#define REGENERATECALCIUM "regeneratecalcium"
|
||||
#define EQUALIZONE "equalizone"
|
||||
|
||||
#define DYE_DANDELIONS "dandelion_dye"
|
||||
|
||||
// How many units of reagent are consumed per tick, by default.
|
||||
|
||||
@@ -1775,6 +1775,7 @@ var/proccalls = 1
|
||||
#define COMPUTER "computer"
|
||||
#define EMBEDDED_CONTROLLER "embedded controller"
|
||||
#define OTHER "other"
|
||||
#define MACHINE_REINFORCED "reinforced machine"
|
||||
|
||||
// Bedsheet altering
|
||||
#define PLAIDPATTERN_INCOMPATIBLE 0
|
||||
|
||||
10
code/ZAS/Radon.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
/mob/proc/radon_effects()
|
||||
|
||||
/mob/living/radon_effects()
|
||||
if(flags & INVULNERABLE)
|
||||
return
|
||||
if(!src.loc)
|
||||
return
|
||||
|
||||
var/molesofradon=src.loc.return_air().molar_density(GAS_RADON)*CELL_VOLUME
|
||||
src.apply_radiation(molesofradon*1.5, RAD_EXTERNAL)
|
||||
@@ -143,3 +143,21 @@
|
||||
/obj/effect/overlay/gas_overlay/cryotheum
|
||||
name = "cryotheum"
|
||||
icon_state = "cryotheum"
|
||||
|
||||
/datum/gas/radon
|
||||
id = GAS_RADON
|
||||
name = "Radon"
|
||||
short_name = "Rn"
|
||||
specific_heat = 20
|
||||
|
||||
molar_mass = 0.222 //i think i did this right
|
||||
|
||||
flags = XGM_GAS_NOTEWORTHY | XGM_GAS_LOGGED
|
||||
|
||||
/datum/gas/radon/is_human_safe(moles, datum/gas_mixture/mixture)
|
||||
return moles/mixture.total_moles() < 0.01
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ var/datum/subsystem/machinery/SSmachinery
|
||||
|
||||
var/list/machines = list()
|
||||
|
||||
var/list/global/fissionreactorlist=list()
|
||||
|
||||
/datum/subsystem/machinery
|
||||
name = "Machinery"
|
||||
@@ -32,6 +33,11 @@ var/list/machines = list()
|
||||
if (!resumed)
|
||||
currentrun = get_currenrun()
|
||||
|
||||
for(var/datum/fission_reactor_holder/reactor in fissionreactorlist)
|
||||
reactor.fissioncycle()
|
||||
reactor.coolantcycle()
|
||||
reactor.misccycle()
|
||||
|
||||
var/obj/machinery/M
|
||||
var/c = currentrun_index
|
||||
while (c)
|
||||
|
||||
@@ -420,3 +420,71 @@
|
||||
access = list(access_engine_minor)
|
||||
group = "Engineering"
|
||||
containsdesc = "A cutting edge machine that tears into a universe orthogonal to ours and applies alternative laws of physics to gaseous oxygen in its immediate vicinity. Requires a bluespace crystal to work (an artificial crystal comes with this crate!)."
|
||||
|
||||
/datum/supply_packs/fissionreactor_starterkit
|
||||
contains = list(
|
||||
/obj/item/weapon/fuelrod/small/starter,
|
||||
/obj/item/weapon/book/manual/engineering_fissionreactor_guide,
|
||||
/obj/item/weapon/storage/box/fissionsupply_controller, //makes a crappy 1x2 interior. but it'll do.
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly,
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly,
|
||||
/obj/item/weapon/storage/box/fissionsupply_fuelmaker,
|
||||
/obj/item/weapon/circuitboard/fission_control_rod,
|
||||
/obj/item/weapon/circuitboard/fission_fuel_rod,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
|
||||
)
|
||||
name = "Fission reactor starter kit"
|
||||
cost = 500 //Includes a lot of plasteel. Fuck you, ask the miners for more you socially inept jobbie.
|
||||
containertype = /obj/structure/closet/crate/secure/large/reinforced/shard/empty
|
||||
containername = "Fission reactor starter kit"
|
||||
group = "Engineering"
|
||||
access = list(access_engine_major)
|
||||
containsdesc = "Everything you need to build a very basic fission reactor. Comes with a pre-filled (albeit small) fuel rod."
|
||||
|
||||
/datum/supply_packs/fissionreactor_expansion
|
||||
contains = list(
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly,
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly,
|
||||
/obj/item/weapon/circuitboard/fission_control_rod, //gives you 2 expansion parts (control/fuel rod) and the casing needed to add.
|
||||
/obj/item/weapon/circuitboard/fission_fuel_rod,
|
||||
/obj/item/weapon/circuitboard/fission_control_rod,
|
||||
/obj/item/weapon/circuitboard/fission_fuel_rod,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing,
|
||||
)
|
||||
name = "Fission reactor expansion pak"
|
||||
cost = 200 //See above.
|
||||
containertype = /obj/structure/closet/crate/secure/large/reinforced/shard/empty
|
||||
containername = "Fission reactor expansion pak"
|
||||
group = "Engineering"
|
||||
access = list(access_engine_major)
|
||||
containsdesc = "Contains supplies to expand an existing fission reactor. Remember to turn it off and drain the coolant first!"
|
||||
|
||||
/datum/supply_packs/fissionreactor_bigrod
|
||||
contains = list(
|
||||
/obj/item/weapon/fuelrod/large
|
||||
)
|
||||
name = "High-capacity fuel rod"
|
||||
cost = 100 //It's a one time purchance, really. somewhat costy, but not that much for a department. watch for meltdowns.
|
||||
containertype = /obj/structure/closet/crate/secure/large/reinforced/shard/empty
|
||||
containername = "Large fuel rod"
|
||||
group = "Engineering"
|
||||
access = list(access_engine_major)
|
||||
containsdesc = "An extra-large fuel rod, for extra power or for more complex fuel mixes. Use with extreme caution and control rods inserted."
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1351,6 +1351,10 @@ var/global/list/adminbusteleportlocs = list()
|
||||
name = "Antimatter Engine Room"
|
||||
icon_state = "antimatter"
|
||||
|
||||
/area/engineering/reactor_room
|
||||
name = "Fission Reactor Room"
|
||||
icon_state = "fission"
|
||||
|
||||
/area/engineering/engineering_auxiliary
|
||||
name = "Auxiliary Engineering"
|
||||
icon_state = "engiaux"
|
||||
|
||||
@@ -105,7 +105,8 @@
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, -1, -1) )
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, -1, -1))
|
||||
// Partial pressure, kpa threshold for any gas not included in gas_thresholds. These gasses are added up.
|
||||
var/datum/airalarm_threshold/other_gas_threshold = new /datum/airalarm_threshold(-1, -1, -1, -1)
|
||||
// Kpa thresholds for what pressures are acceptable.
|
||||
@@ -196,6 +197,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, 5, 10),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, 0.2, 0.5),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.05, 0.1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, 0.5, 1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
@@ -212,6 +214,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(16, 18, 135, 140),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, 5, 10),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, 0.2, 0.5),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.05, 0.1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, 0.5, 1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
@@ -228,6 +231,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, 5, 10),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, 0.2, 0.5),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.05, 0.1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, 0.5, 1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
@@ -244,6 +248,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, 5, 10),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(16, 18, 135, 140),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.05, 0.1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, 0.5, 1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
@@ -260,6 +265,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, 0.5, 1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, 0.5, 1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
@@ -276,6 +282,7 @@
|
||||
GAS_NITROGEN = new /datum/airalarm_threshold(16, 18, 135, 140),
|
||||
GAS_CARBON = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_PLASMA = new /datum/airalarm_threshold(-1, -1, 0.2, 0.5),
|
||||
GAS_RADON = new /datum/airalarm_threshold(-1, -1, 0.05, 0.1),
|
||||
GAS_SLEEPING = new /datum/airalarm_threshold(-1, -1, -1, -1),
|
||||
GAS_CRYOTHEUM = new /datum/airalarm_threshold(-1, -1, -1, -1) )
|
||||
other_gas_threshold = new /datum/airalarm_threshold(-1, -1, 0.5, 1)
|
||||
|
||||
@@ -80,6 +80,12 @@
|
||||
canister_color = "grey"
|
||||
can_label = 0
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/radon //for testing (or admin shittery)
|
||||
name = "Canister \[Rn\]"
|
||||
icon_state = "green"
|
||||
canister_color = "green"
|
||||
can_label = 0
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/update_icon()
|
||||
if(destroyed)
|
||||
icon_state = "[canister_color]-1"
|
||||
@@ -399,6 +405,7 @@
|
||||
"\[CO2\]" = "black", \
|
||||
"\[Air\]" = "grey", \
|
||||
"\[CAUTION\]" = "yellow", \
|
||||
"\[Rn\]" = "green", \
|
||||
)
|
||||
var/label = input("Choose canister label", "Gas canister") as null|anything in colors
|
||||
if (label)
|
||||
@@ -446,6 +453,12 @@
|
||||
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/radon/New(loc)
|
||||
..(loc)
|
||||
air_contents.adjust_gas(GAS_RADON, (maximum_pressure * filled) * air_contents.volume / (R_IDEAL_GAS_EQUATION * air_contents.temperature))
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/portable_atmospherics/canister/proc/weld(var/obj/item/tool/weldingtool/WT, var/mob/user)
|
||||
|
||||
|
||||
|
||||
@@ -355,6 +355,8 @@
|
||||
build_path = /obj/machinery/computer/stacking_unit
|
||||
origin_tech = Tc_PROGRAMMING + "=2;" + Tc_MATERIALS + "=2"
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(issolder(I))
|
||||
var/obj/item/tool/solder/S = I
|
||||
@@ -391,6 +393,8 @@
|
||||
to_chat(user, "<span class='notice'>You [contraband_enabled ? "" : "un"]connect the mysterious fuse.</span>")
|
||||
contraband_enabled = !contraband_enabled
|
||||
|
||||
|
||||
|
||||
/obj/structure/computerframe/attackby(obj/item/P as obj, mob/user as mob)
|
||||
switch(state)
|
||||
if(0)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
var/list/components_in_use = null
|
||||
var/build_state = 1
|
||||
var/build_path = 0 //0 = Default path. 1 = Glass Frame
|
||||
var/required_circuit_type = null
|
||||
|
||||
// For pods
|
||||
var/list/connected_parts = list()
|
||||
@@ -43,6 +44,9 @@
|
||||
amt += req_components[path]
|
||||
return amt
|
||||
|
||||
/obj/machinery/constructable_frame/machine_frame
|
||||
required_circuit_type=MACHINE
|
||||
|
||||
/obj/machinery/constructable_frame/machine_frame/attackby(obj/item/P as obj, mob/user as mob)
|
||||
if(P.crit_fail)
|
||||
to_chat(user, "<span class='warning'>This part is faulty, you cannot add this to the machine!</span>")
|
||||
@@ -125,7 +129,7 @@
|
||||
if(!..())
|
||||
if(istype(P, /obj/item/weapon/circuitboard))
|
||||
var/obj/item/weapon/circuitboard/B = P
|
||||
if(B.board_type == MACHINE)
|
||||
if(B.board_type == required_circuit_type)
|
||||
if(!user.drop_item(B, src, failmsg = TRUE))
|
||||
return
|
||||
|
||||
@@ -1729,3 +1733,4 @@ to destroy them and players will be able to make replacements.
|
||||
/obj/item/weapon/stock_parts/manipulator = 2,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
)
|
||||
|
||||
|
||||
@@ -446,6 +446,11 @@ var/list/datum/stack_recipe/plasteel_recipes = list (
|
||||
new/datum/stack_recipe("shuttle bed", /obj/structure/bed/racecar/shuttle, 2, one_per_turf = 1, on_floor = 1),
|
||||
new/datum/stack_recipe("fire truck bed", /obj/structure/bed/racecar/firetruck, 2, one_per_turf = 1, on_floor = 1),
|
||||
)),
|
||||
null,
|
||||
new/datum/stack_recipe("Reinforced machine frame", /obj/machinery/constructable_frame/machine_frame/reinforced, 5, time = 60, one_per_turf = 1 ),
|
||||
null,
|
||||
new/datum/stack_recipe("Reactor casing frame", /obj/structure/girder/reactor, 4, time = 50, one_per_turf = 1 ),
|
||||
new/datum/stack_recipe("Reactor fuel rod", /obj/item/weapon/fuelrod, 2, time = 25),
|
||||
)
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
@@ -1293,3 +1293,442 @@ var/virology_encyclopedia = ""
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
|
||||
/obj/item/weapon/book/manual/engineering_fissionreactor_guide
|
||||
name = "Fission Reactor User's Guide"
|
||||
icon_state ="bookEngineering2"
|
||||
author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
|
||||
title = "Fission Reactor User's Guide"
|
||||
//big pile of shit below.
|
||||
id = 26
|
||||
dat= {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1{
|
||||
text-align:center;
|
||||
}
|
||||
.reactor_schematic{
|
||||
border-collapse:collapse;
|
||||
font-family:monospace;
|
||||
font-size:200%;
|
||||
}
|
||||
.reactor_schematic > * > tr{
|
||||
/*height:2em;*/
|
||||
}
|
||||
.reactor_schematic > * > * > td{
|
||||
/*width:2em;*/
|
||||
border:2px black solid;
|
||||
}
|
||||
.r_case{
|
||||
background-color:grey;
|
||||
}
|
||||
.r_port{
|
||||
background-color:DarkSlateGray;
|
||||
}
|
||||
.r_frod{
|
||||
background-color:red;
|
||||
}
|
||||
.r_crod{
|
||||
background-color:dodgerblue;
|
||||
}
|
||||
.r_cont{
|
||||
background-color:DarkViolet;
|
||||
}
|
||||
|
||||
.byproduct_display{
|
||||
display:inline-block;
|
||||
width:20em;
|
||||
}
|
||||
|
||||
.reagent_lead{
|
||||
display:inline-block;
|
||||
background-color:grey;
|
||||
color:white;
|
||||
}
|
||||
|
||||
.reagent_plutonium{
|
||||
display:inline-block;
|
||||
background-color:burlywood;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.reagent_radium{
|
||||
display:inline-block;
|
||||
background-color:yellowgreen;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.reagent_radon{
|
||||
display:inline-block;
|
||||
background-color:orange;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.reagent_thalium{
|
||||
display:inline-block;
|
||||
background-color:MediumAquamarine;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.reagent_uranium{
|
||||
display:inline-block;
|
||||
background-color:darkolivegreen;
|
||||
color:white;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Fission Reactors: a quick guide</h1>
|
||||
<p>
|
||||
Though often said to be old, outdated technology, fission power should not be underestimated. Even a modest reactor is capable of powering a medium-sized station for several hours with no upkeep, and the dismissal of fission technology has delayed the uncovering of more recent discoveries in material sciences which may have been known decades earlier.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<h2>What you'll need</h2>
|
||||
building a reactor is an expensive endeavor, costing a lot of both time and resources. For the most basic of reactor designs, here is the bare minimum needed to set one up and start generating power. Most of the materials are either provided in the starter kit, or should be available on-site.
|
||||
<ul>
|
||||
<li>69 sheets of plasteel</li>
|
||||
<li>42 metal rods</li>
|
||||
<li>15 lengths of wire</li>
|
||||
<li>3 mater bins</li>
|
||||
<li>2 scanning modules</li>
|
||||
<li>2 micro-manipulators</li>
|
||||
<li>1 console screen</li>
|
||||
<li>fissile material and a fuel rod (provided in the starter kit)</li>
|
||||
<li>circuit boards for the controller, fuel rod, and control rod assemblies</li>
|
||||
<li>piping (partially included)</li>
|
||||
<li>at least 1 thermoelectric generator (not included)</li>
|
||||
<li>a welder, crowbar, screwdriver, wrench, and wirecutters (not included)</li>
|
||||
</ul>
|
||||
|
||||
<b>additionally</b>, to make a isotopic separational combiner (the machine used to fill and additionally recycle spent fuel) you will need the following materials (provided in the starter kit):
|
||||
<ul>
|
||||
<li>5 sheets of metal</li>
|
||||
<li>5 lengths of wire</li>
|
||||
<li>2 mater bins</li>
|
||||
<li>2 scanning modules</li>
|
||||
<li>1 micro-manipulator</li>
|
||||
<li>1 console screen</li>
|
||||
<li>the associated circuit board</li>
|
||||
<li>piping (not included)</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h2>How to construct the parts</h2>
|
||||
<h3>Reactor casing</h3>
|
||||
<ol>
|
||||
<li>use 4 plasteel to construct a reactor casing frame in the desired location</li>
|
||||
<li>insert 4 metal rods inside of the frame</li>
|
||||
<li>use a screwdriver to fasten the rods</li>
|
||||
<li>(optional) insert a straight pipe into the frame to make it a coolant port</li>
|
||||
<li>(optional) use a crowbar to change the direction of the port</li>
|
||||
<li>apply 2 plasteel as external plating</li>
|
||||
<li>weld the external plating to the frame</li>
|
||||
</ol>
|
||||
|
||||
<h3>Control & Fuel rod assembly</h3>
|
||||
<ol>
|
||||
<li>use 5 plasteel to construct a reinforced machine frame in the desired location</li>
|
||||
<li>add 5 lengths of wiring to the machine</li>
|
||||
<li>insert the corresponding circuit board</li>
|
||||
<li>insert 2 metal rods inside of the frame</li>
|
||||
<li>add a matter bin to the frame</li>
|
||||
<li><b>if control rod:</b> add a micro-manipulator<br><b>if fuel rod:</b> add a scanning module</li>
|
||||
<li>use a screwdriver to finish assembly</li>
|
||||
</ol>
|
||||
|
||||
<h3>Reactor controller</h3>
|
||||
<ol>
|
||||
<li>use 5 plasteel to construct a reinforced machine frame in the desired location</li>
|
||||
<li>add 5 lengths of wiring to the machine</li>
|
||||
<li>insert the circuit board</li>
|
||||
<li>insert 2 metal rods inside of the frame</li>
|
||||
<li>add a matter bin, micro-manipulator, scanning module, and a console screen to the frame</li>
|
||||
<li>use a screwdriver to finish assembly</li>
|
||||
</ol>
|
||||
|
||||
<h3>Isotopic separational combiner</h3>
|
||||
<ol>
|
||||
<li>Use 5 metal to construct a machine frame in the desired location</li>
|
||||
<li>add 5 lengths of wiring to the machine</li>
|
||||
<li>insert the circuit board</li>
|
||||
<li>add a 2 matter bins, micro-manipulator, 2 scanning modules, and a console screen to the frame</li>
|
||||
<li>use a screwdriver to finish assembly</li>
|
||||
</ol>
|
||||
|
||||
<h2>Design considerations</h2>
|
||||
<p>
|
||||
The design of a nuclear reactor is very important. build it wrong, and you may find yourself having a meltdown.
|
||||
|
||||
<h3>casing</h3>
|
||||
the casing of a reactor should include the whole perimeter of it, with no gaps.
|
||||
<h3>coolant ports</h3>
|
||||
a reactor should have at least 2 ports, one for a coolant input, and another for output. coolant ports can be placed at any point in the casing.
|
||||
<h3>controller</h3>
|
||||
a reactor can only have 1 controller to it, and must be placed at a corner of a reactor.
|
||||
<h3>fuel rods</h3>
|
||||
fuel rods should be placed in the interior of the reactor. for each cardinally-adjacent fuel rod, a fuel rod will gain bonus power production without affecting fuel duration. Fuel duration is only affected by the number of fuel rod assemblies.
|
||||
<h3>control rods</h3>
|
||||
control rods are able to affect fuel rods in every ordinal direction around them. if a control rod is not affecting a fuel rod, then the reaction is unable to be stopped. it is recommended to have all fuel rods be controlled for safety reasons.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Example designs</h3>
|
||||
|
||||
<div style='border:2px black solid;background-color:LightSteelBlue;'>
|
||||
<h3 style='text-decoration:underline;'>key</h3>
|
||||
<ul style='list-style-type: none;font-size:1.5em;padding:0;margin:0;margin-bottom:2px;'>
|
||||
<li><span class='r_case'> </span>casing</li>
|
||||
<li><span class='r_cont'> </span>controller</li>
|
||||
<li><span class='r_port'> </span>coolant port</li>
|
||||
<li><span class='r_frod'> </span>fuel rod</li>
|
||||
<li><span class='r_crod'> </span>control rod</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<table class='reactor_schematic'>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_cont'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_port'> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>The starter</b>
|
||||
<div>
|
||||
fuel rods: 1<br>
|
||||
control rods: 1 <br>
|
||||
fissile speed: 100%<br>
|
||||
fuel reactivity: 100%<br>
|
||||
</div>
|
||||
|
||||
<table class='reactor_schematic'>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_cont'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_port'> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>The upgrade</b>
|
||||
<div>
|
||||
fuel rods: 3<br>
|
||||
control rods: 1 <br>
|
||||
fissile speed: 300%<br>
|
||||
fuel reactivity: 700%<br>
|
||||
</div>
|
||||
|
||||
<table class='reactor_schematic'>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_port'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_crod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_port'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_frod'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='r_cont'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_port'> </td>
|
||||
<td class='r_case'> </td>
|
||||
<td class='r_case'> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<b>For those up to the challenge</b>
|
||||
<div>
|
||||
fuel rods: 32<br>
|
||||
control rods: 4 <br>
|
||||
fissile speed: 3200%<br>
|
||||
fuel reactivity: 12000%<br>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Standard operation guide</h2>
|
||||
To avoid a catastrophic meltdown, a reactor must be monitored periodically to ensure that the temperature is not climbing too high.<br>
|
||||
Reactors can withstand temperatures up to 5500K, though the controller will activate a SCRAM protocol if the temperature exceeds 4500K. Once SCRAM is enabled, the control rods will be forced downwards and will remain on until the reactor has dropped below 1000K.<br>
|
||||
<sub>The circuit board is able to be modified so that autoSCRAM is disabled, however this practice is not endorsed by NanoTrasen, and the engineer assumes all liability for any damage to the station as a result of this.</sub>
|
||||
<br>
|
||||
Once your reactor is built, you will need to insert a fuel rod (one is provided in the starter kit). A reactor accepts only a single fuel rod, so it is encouraged to carefully prepare the fuel mixture in accordance to the design of the reactor.<br>
|
||||
Next, ensure that the coolant lines are operating as normal, and that there is adequate cooling for the output of your reactor. Once this is verified, return to the controller, and raise the control rods. It is recommended that this is done gradually, so that the engineer operating it can determine how far it can be safely pushed.<br>
|
||||
<br>
|
||||
Should the controller ever become unresponsive, a crowbar can be used to pry open the shielding and remove the fuel rod. Do note that if the reactor is still undergoing fission, you will need to overcome the safety locks, and you will most likely receive a dose of radiation, so some form of protection is advised when doing so, followed up by a hasty visit to the station's medical staff for an examination.<br>
|
||||
<br>
|
||||
Depending on a few factors, such as control rod insertion, construction, and fissile materials, a reactor will take between hours or tens of minutes to churn through a fuel rod. When this occurs, eject the spent rod, and replace it with a fresh one. If you are feeling unsatisfied with the current fuel mixture, the rod may be prematurely ejected.<br>
|
||||
Spent fuel contains a wide variety of fission byproducts, dependent on what was used in the fuel. Designing a fuel mixture involves a lot of compromises, between lifespan, power output, and fission products. Beginners are advised to stick to a mixture of pure uranium, as it is a very consistent source of power, and has a relatively long lifespan, which allows a reactor to be ran with less maintenance and worries.<br>
|
||||
Different sizes of fuel rods exist, with the starter kit coming with a fairly small rod. A standard fuel rod can be constructed at the workplace, using 2 plasteel sheets and forming them into shape. Additionally, a larger fuel rod can be ordered from your station's cargo department, though newer engineers are discouraged from using this, as the higher abundance of fuel can result in an unstable reactor which melts down, and proper use will require a significant amount of modification to the piping to accommodate the much greater heat generation.<br>
|
||||
|
||||
|
||||
|
||||
|
||||
<h2>How to disassemble</h2>
|
||||
|
||||
<span style='font-weight:bold;color:red;font-size:125%;'>IMPORTANT: before disassembling a reactor, drain all coolant first, and make sure that it is not currently undergoing fission. Failure to do so may result in injury, destruction of property, or even death.</span>
|
||||
|
||||
<h3>Reactor casing</h3>
|
||||
<ol>
|
||||
<li>use a welder to detach the external plating from the frame</li>
|
||||
<li>use a crowbar to pry off the plating from the frame</li>
|
||||
<li>(optional) use a wrench to remove the piping if there is any</li>
|
||||
<li>use a screwdriver to loosen the internal rods</li>
|
||||
<li>use wirecutters to remove the rods</li>
|
||||
<li>use a wrench to disassemble the frame</li>
|
||||
</ol>
|
||||
|
||||
<h3>Control & Fuel rod assembly, reactor controller</h3>
|
||||
<ol>
|
||||
<li>use a welder to detach the external plating from the frame</li>
|
||||
<li>use a crowbar to remove the internal components from the frame</li>
|
||||
<li>use wirecutters to remove the wiring from the frame</li>
|
||||
<li>use a wrench to disassemble the frame.</li>
|
||||
</ol>
|
||||
|
||||
<h3>Isotopic separational combiner</h3>
|
||||
<ol>
|
||||
<li>use a screwdriver to open the maintenance hatch</li>
|
||||
<li>use a crowbar to pry out the electronics</li>
|
||||
<li>use wirecutters to remove the wiring from the frame</li>
|
||||
<li>use a wrench to disassemble the frame.</li>
|
||||
|
||||
</ol>
|
||||
|
||||
<h2>Other notes</h2>
|
||||
If you unscrew the maintenance hatch of a fuel rod assembly, you can add 4 metal sheets to it. Doing so will make the assembly not give any bonuses for adjacent fuel rods. You can undo this by removing the sheets with a crowbar.
|
||||
<br>
|
||||
<br>
|
||||
standard fuel rods can be made with 2 plasteel sheets. these are bigger than the small one given by the starter kit, but smaller than the one orderable from cargo.
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<h3><u>table of fuels:</u></h3>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Fuel</th>
|
||||
<th>Heat generation (Watts per unit)</th>
|
||||
<th>Lifetime (weighted average)</th>
|
||||
<th>Byproducts</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="reagent_uranium">Uranium</td>
|
||||
<td>16,667</td>
|
||||
<td>2h 30m</td>
|
||||
<td class="byproduct_display"><span class="reagent_lead" style="width:30%;">Pb</span><span class="reagent_plutonium" style="width:20%;">Pu</span><span class="reagent_radium" style="width:25%;">Ra</span><span class="reagent_radon" style="width:15%;">Rn</span><span class="reagent_thalium" style="width:10%;">Tl</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="reagent_plutonium">Plutonium</td>
|
||||
<td>66,667</td>
|
||||
<td>1h 15m</td>
|
||||
<td class="byproduct_display"><span class="reagent_lead" style="width:50%;">Pb</span><span class="reagent_uranium" style="width:20%;">U</span><span class="reagent_radium" style="width:20%;">Ra</span><span class="reagent_radon" style="width:10%;">Rn</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="reagent_radon">Radon</td>
|
||||
<td>1,667</td>
|
||||
<td>25m</td>
|
||||
<td class="byproduct_display"><span class="reagent_lead" style="width:100%;">Pb</span></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>"}
|
||||
39
code/modules/fissionreactor/cleanup.dm
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
In this file:
|
||||
objects used when a reactor goes boomy boom so there's some nasty rads and things to clean up.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
//l.apply_radiation(rads, RAD_EXTERNAL)
|
||||
|
||||
/obj/machinery/corium
|
||||
name="corium"
|
||||
desc="An amalgam of fissile material and reactor structures, melted together after a meltdown."
|
||||
icon='icons/obj/fissionreactor/corium.dmi'
|
||||
icon_state="corium"
|
||||
density=1
|
||||
anchored=0
|
||||
var/rads=0
|
||||
|
||||
/obj/machinery/corium/New(var/turf/location, var/radiation=0)
|
||||
..()
|
||||
icon_state="corium_[rand(1,3)]"
|
||||
rads=radiation
|
||||
|
||||
/obj/machinery/corium/attackby(var/obj/item/I,var/mob/user)
|
||||
if(iswelder(I))
|
||||
var/obj/item/tool/weldingtool/WT = I
|
||||
user.visible_message("<span class='notice'>[user] begins trying to salvage anything useful from \the [src].</span>", "<span class='notice'>You begin trying to salvage anything useful from \the [src].</span>")
|
||||
if(WT.do_weld(user,src,80,0))
|
||||
if(rand()<0.5)
|
||||
new /obj/item/stack/rods(src.loc,rand(1,3))
|
||||
if(rand()<0.5)
|
||||
new /obj/item/stack/sheet/plasteel(src.loc,rand(1,5))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/corium/process()
|
||||
for(var/mob/living/l in range(src.loc, 5))
|
||||
l.apply_radiation(rads, RAD_EXTERNAL)
|
||||
54
code/modules/fissionreactor/fission.css
Normal file
@@ -0,0 +1,54 @@
|
||||
body{
|
||||
background-color:#000;
|
||||
color:#0f0;
|
||||
font-family:monospace;
|
||||
margin:5px;
|
||||
line-height:110%;
|
||||
}
|
||||
path{
|
||||
stroke-width:2px;
|
||||
stroke:#0f0;
|
||||
fill:none;
|
||||
}
|
||||
table{
|
||||
font-size:inherit;
|
||||
border-collapse:collapse;
|
||||
}
|
||||
td{
|
||||
padding:0px;
|
||||
}
|
||||
a{
|
||||
text-decoration:inherit;
|
||||
color:inherit;
|
||||
background-color:#00f;
|
||||
}
|
||||
a.blocked{
|
||||
background-color:#707;
|
||||
}
|
||||
#scram{
|
||||
background-color:#700;
|
||||
animation-name:a;
|
||||
animation-duration:2s;
|
||||
animation-iteration-count:infinite;
|
||||
}
|
||||
@keyframes scramon{
|
||||
0%{background-color:#700;}
|
||||
49%{background-color:#700;}
|
||||
50%{background-color:#f00;}
|
||||
99%{background-color:#f00;}
|
||||
}
|
||||
.status_ok{
|
||||
color:#fff;
|
||||
}
|
||||
.status_halt{
|
||||
color:#f0f;
|
||||
}
|
||||
.status_danger{
|
||||
color:#f00;
|
||||
}
|
||||
.status_done{
|
||||
color:#0ff;
|
||||
}
|
||||
.status_nofuel{
|
||||
color:#ff0;
|
||||
}
|
||||
693
code/modules/fissionreactor/fission_datums.dm
Normal file
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
IN THIS FILE:
|
||||
datums for the fission reactor, which includes the fuel and reactor
|
||||
*/
|
||||
#define FISSIONREACTOR_MELTDOWNTEMP 5500 //temp when shit goes wrong
|
||||
#define FISSIONREACTOR_DANGERTEMP 4500 //temp to start warning you and to SCRAM
|
||||
#define FISSIONREACTOR_SAFEENUFFTEMP 1000 //temp where SCRAM resets
|
||||
|
||||
/datum/fission_reactor_holder
|
||||
var/list/fuel_rods=list() //phase 0 vars, set upon construction
|
||||
var/list/control_rods=list()
|
||||
var/list/coolant_ports=list()
|
||||
var/list/casing_parts=list()
|
||||
var/list/breaches=list()
|
||||
var/obj/machinery/fissioncontroller/controller=null
|
||||
var/heat_capacity=0
|
||||
var/fuel_reactivity=1
|
||||
var/fuel_reactivity_with_rods=0
|
||||
var/fuel_rods_affected_by_rods=0
|
||||
var/time_last_ticked=null
|
||||
|
||||
var/coolantport_counter=0 // this varible exists to ensure that all coolant ports get treated equally, because if we didn't it would have a flow prefrence towards the ports with lower indexes.
|
||||
var/control_rod_insertion=1 //phase 1 vars. modified during runtime
|
||||
var/control_rod_target=1 // this is to create a bit of input lag to make things a bit more tense. also allows autoscram to work while the controller is unpowered.
|
||||
var/SCRAM=FALSE //all caps because AAAAAAAAAAAAAAAAAAA EVERYBODY PANIC WE'RE ALL GONNA DIE.
|
||||
var/temperature=T20C //this is set last
|
||||
|
||||
var/datum/gas_mixture/coolant
|
||||
|
||||
var/graceperiodtick=3.0 // extra time before a meltdown actually occurs (in seconds). gives you a bit of time to GTFO or save it. this will result in peak kino (i hope)
|
||||
|
||||
var/zlevel=0 //positional varibles
|
||||
var/origin_x=0
|
||||
var/origin_y=0
|
||||
var/corner_x=0 //uses corner calculations. this is for the sake of being easier to calculate.
|
||||
var/corner_y=0
|
||||
var/datum/fission_fuel/fuel=null
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/New()
|
||||
..()
|
||||
coolant = new /datum/gas_mixture
|
||||
coolant.temperature = T20C //vaguely room temp.
|
||||
coolant.volume = CELL_VOLUME
|
||||
fissionreactorlist+=src
|
||||
time_last_ticked=world.time
|
||||
|
||||
/datum/fission_reactor_holder/Destroy()
|
||||
fissionreactorlist-=src //remove from global list
|
||||
for(var/obj/machinery/fissionreactor/fissionreactor_fuelrod/fuelrod in fuel_rods) //dissassociate all parts (if any still exist).
|
||||
fuelrod.associated_reactor=null
|
||||
fuel_rods=list()
|
||||
for(var/obj/machinery/fissionreactor/fissionreactor_controlrod/controlrod in control_rods)
|
||||
controlrod.associated_reactor=null
|
||||
control_rods=list()
|
||||
for(var/obj/structure/fission_reactor_case/casing in casing_parts)
|
||||
casing.associated_reactor=null
|
||||
casing_parts=list()
|
||||
for(var/obj/machinery/atmospherics/unary/fissionreactor_coolantport/coolport in coolant_ports)
|
||||
coolport.associated_reactor=null
|
||||
coolant_ports=list()
|
||||
if(controller)
|
||||
controller.associated_reactor=null
|
||||
controller=null
|
||||
fuel=null
|
||||
var/turf/originloc=locate(origin_x,origin_y,zlevel)
|
||||
originloc?.return_air().merge(coolant.remove(coolant.total_moles,TRUE,TRUE),TRUE) //dump all coolant to atmos.
|
||||
..()
|
||||
|
||||
/datum/fission_reactor_holder/proc/verify_integrity() //destroys the reactor if too many parts are missing. fixes stuff lingering.
|
||||
var/notlookinggood_points=0
|
||||
|
||||
var/exterior_elements=0
|
||||
exterior_elements+=coolant_ports.len
|
||||
exterior_elements+=casing_parts.len
|
||||
exterior_elements+=controller?1:0
|
||||
var/expected_exterior=2*abs(origin_x-corner_x)+2*abs(origin_y-corner_y) //also the perimeter. kind of.
|
||||
|
||||
if(exterior_elements<expected_exterior) //missing any at all? (for deconstruction)
|
||||
notlookinggood_points++
|
||||
if(exterior_elements/expected_exterior < 0.5) //half the case remaining?
|
||||
notlookinggood_points++
|
||||
if(!fuel_rods.len) //no fuel rods?
|
||||
notlookinggood_points++
|
||||
if(!controller) //no controller?
|
||||
notlookinggood_points++
|
||||
if(!coolant_ports.len) //no coolant ports?
|
||||
notlookinggood_points++
|
||||
if(!fuel) //no fuel? (to handle deconstruction)
|
||||
notlookinggood_points++
|
||||
if(coolant.total_moles < 0.5*(coolant.volume/CELL_VOLUME) ) //less than .5 mole per tile of coolant? (draining to deconstruct)
|
||||
notlookinggood_points++
|
||||
|
||||
if(notlookinggood_points>=3) //if 3 or more criteria are met, something really bad has happened, so just destroy the whole thing.
|
||||
qdel(src)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/fission_reactor_holder/proc/handledestruction(var/obj/shitgettingfucked)
|
||||
if(istype(shitgettingfucked, /obj/machinery/fissioncontroller ))
|
||||
controller=null
|
||||
breaches+=shitgettingfucked.loc
|
||||
if(istype(shitgettingfucked, /obj/machinery/fissionreactor/fissionreactor_fuelrod ))
|
||||
fuel_rods-=shitgettingfucked
|
||||
if(istype(shitgettingfucked, /obj/machinery/fissionreactor/fissionreactor_controlrod ))
|
||||
control_rods-=shitgettingfucked
|
||||
if(istype(shitgettingfucked, /obj/structure/fission_reactor_case ))
|
||||
casing_parts-=shitgettingfucked
|
||||
breaches+=shitgettingfucked.loc
|
||||
if(istype(shitgettingfucked, /obj/machinery/atmospherics/unary/fissionreactor_coolantport ))
|
||||
coolant_ports-=shitgettingfucked
|
||||
breaches+=shitgettingfucked.loc
|
||||
|
||||
|
||||
|
||||
recalculatereactorstats() //re-scan the parts to generate the new stats. the show must go on!
|
||||
verify_integrity() //unless we are too far gone
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/adopt_part(var/obj/thepart) //for construction on an existing reactor. dangerous.
|
||||
if(istype(thepart, /obj/machinery/fissioncontroller ))
|
||||
if(controller)
|
||||
return FALSE
|
||||
controller=thepart
|
||||
var/obj/machinery/fissioncontroller/nc=thepart
|
||||
nc.associated_reactor=src
|
||||
if(istype(thepart, /obj/machinery/fissionreactor/fissionreactor_fuelrod ))
|
||||
var/obj/machinery/fissionreactor/fissionreactor_fuelrod/nfr=thepart
|
||||
nfr.associated_reactor=src
|
||||
fuel_rods+=thepart
|
||||
if(istype(thepart, /obj/machinery/fissionreactor/fissionreactor_controlrod ))
|
||||
var/obj/machinery/fissionreactor/fissionreactor_controlrod/nfr=thepart
|
||||
nfr.associated_reactor=src
|
||||
control_rods+=thepart
|
||||
if(istype(thepart, /obj/structure/fission_reactor_case ))
|
||||
var/obj/structure/fission_reactor_case/nc=thepart
|
||||
nc.associated_reactor=src
|
||||
casing_parts+=thepart
|
||||
for(var/turf/t in breaches)
|
||||
if(t==nc.loc)
|
||||
breaches-=t
|
||||
break
|
||||
if(istype(thepart, /obj/machinery/atmospherics/unary/fissionreactor_coolantport ))
|
||||
var/obj/machinery/atmospherics/unary/fissionreactor_coolantport/ncp=thepart
|
||||
ncp.associated_reactor=src
|
||||
coolant_ports+=thepart
|
||||
for(var/turf/t in breaches)
|
||||
if(t==ncp.loc)
|
||||
breaches-=t
|
||||
break
|
||||
recalculatereactorstats()
|
||||
return TRUE
|
||||
|
||||
/datum/fission_reactor_holder/proc/considered_on()
|
||||
if(!fuel) //no fuel? not on.
|
||||
return FALSE
|
||||
if(fuel.life<=0.0) //depleted? not on.
|
||||
return FALSE
|
||||
if(control_rod_insertion>=1.0 && fuel_rods_affected_by_rods==fuel_rods.len ) //if the reaction is halted, it's not on.
|
||||
return FALSE
|
||||
return TRUE //otherwise, it is.
|
||||
|
||||
/datum/fission_reactor_holder/proc/init_resize(var/turf/origin) //code responsible for setting up the parameters of the reactor.
|
||||
if(!origin) //something has gone wrong.
|
||||
return "unable to locate self"
|
||||
|
||||
var/turf/wall_up=get_step(origin,NORTH) //locate(origin.x,origin.y+1,origin.z)
|
||||
var/turf/wall_down=get_step(origin,SOUTH)
|
||||
var/turf/wall_left=get_step(origin,WEST)
|
||||
var/turf/wall_right=get_step(origin,EAST)
|
||||
|
||||
var/directions=0
|
||||
|
||||
//copy
|
||||
var/list/wc = wall_up.contents
|
||||
for (var/i=1,i<=wc.len,i++)
|
||||
if(istype(wc[i],/obj/structure/fission_reactor_case) || istype(wc[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
directions|=NORTH
|
||||
break
|
||||
|
||||
wc = wall_down.contents
|
||||
for (var/i=1,i<=wc.len,i++)
|
||||
if(istype(wc[i],/obj/structure/fission_reactor_case) || istype(wc[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
directions|=SOUTH
|
||||
break
|
||||
|
||||
wc = wall_left.contents
|
||||
for (var/i=1,i<=wc.len,i++)
|
||||
if(istype(wc[i],/obj/structure/fission_reactor_case) || istype(wc[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
directions|=WEST
|
||||
break
|
||||
|
||||
wc = wall_right.contents
|
||||
for (var/i=1,i<=wc.len,i++)
|
||||
if(istype(wc[i],/obj/structure/fission_reactor_case) || istype(wc[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
directions|=EAST
|
||||
break
|
||||
//paste
|
||||
|
||||
//abort if we have an invalid placment (not at a corner)
|
||||
if ( ((directions & NORTH) && (directions & SOUTH)) || ((directions & EAST) && (directions & WEST))) //if there are walls on north+south/east+west, it is not in the right spot
|
||||
return "reactor controller should be placed in a corner, not a side."
|
||||
if ( !(directions & (NORTH | SOUTH) ) || !(directions & (EAST | WEST) ) ) //if there is not a wall at north/south + east/west, it is not in the right spot
|
||||
return "reactor controller should be placed in a corner, not on an edge."
|
||||
|
||||
var/xs=0
|
||||
var/ys=0
|
||||
|
||||
//get the lengths of the reactor.
|
||||
if(directions&WEST) //x-
|
||||
xs=-1
|
||||
while(TRUE) //it'll be fiiiiiiiine.
|
||||
var/turf/turftosearch=locate(origin.x+xs-1,origin.y,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
xs--
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound) //protip: do not use goto, because the linters are not robust enough for the POWER.
|
||||
break
|
||||
if(directions&EAST) //x+
|
||||
xs=1
|
||||
while(TRUE)
|
||||
var/turf/turftosearch=locate(origin.x+xs+1,origin.y,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
xs++
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
break
|
||||
if(directions&NORTH)//y+
|
||||
ys=1
|
||||
while(TRUE)
|
||||
var/turf/turftosearch=locate(origin.x,origin.y+ys+1,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
ys++
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
break
|
||||
if(directions&SOUTH)//y-
|
||||
ys=-1
|
||||
while(TRUE)
|
||||
var/turf/turftosearch=locate(origin.x,origin.y+ys-1,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
ys--
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
break
|
||||
|
||||
//now we have to close the corners into a box.
|
||||
//we have this:
|
||||
// O
|
||||
// O
|
||||
// O
|
||||
// O
|
||||
// XOOOOO
|
||||
//but need to make it this
|
||||
// OOOOOO
|
||||
// O O
|
||||
// O O
|
||||
// O O
|
||||
// XOOOOO
|
||||
|
||||
if(directions&WEST)
|
||||
for (var/searchx=0,searchx>=xs,searchx--) //hey at least this one isn't an infinite loop :)
|
||||
var/turf/turftosearch=locate(origin.x+searchx,origin.y+ys,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
return "failed to find casing at offset [searchx],[ys]" //return because the setup is invalid.
|
||||
if(directions&EAST)
|
||||
for (var/searchx=0,searchx<=xs,searchx++)
|
||||
var/turf/turftosearch=locate(origin.x+searchx,origin.y+ys,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
return "failed to find casing at offset [searchx],[ys]"
|
||||
if(directions&SOUTH)
|
||||
for (var/searchy=0,searchy>=ys,searchy--)
|
||||
var/turf/turftosearch=locate(origin.x+xs,origin.y+searchy,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
return "failed to find casing at offset [xs],[searchy]"
|
||||
if(directions&NORTH)
|
||||
for (var/searchy=0,searchy<=ys,searchy++)
|
||||
var/turf/turftosearch=locate(origin.x+xs,origin.y+searchy,origin.z)
|
||||
var/list/contents = turftosearch.contents
|
||||
var/casewasfound=FALSE
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
if(istype(contents[i],/obj/structure/fission_reactor_case) || istype(contents[i],/obj/machinery/atmospherics/unary/fissionreactor_coolantport) )
|
||||
casewasfound=TRUE
|
||||
break
|
||||
if(!casewasfound)
|
||||
return "failed to find casing at offset [xs],[searchy]"
|
||||
|
||||
//horray, we have verified the case makes a box!
|
||||
|
||||
origin_x=origin.x
|
||||
origin_y=origin.y
|
||||
zlevel=origin.z
|
||||
corner_x=origin.x+xs
|
||||
corner_y=origin.y+ys
|
||||
|
||||
var/sizex=abs(corner_x-origin_x)+1
|
||||
var/sizey=abs(corner_y-origin_y)+1
|
||||
|
||||
coolant.volume=CELL_VOLUME* (sizex-2)*(sizey-2) //sub 2 to make sure there's no casing involved in the internal volume.
|
||||
coolant.volume=max(coolant.volume,1) //atmos code will probably shit itself if this is 0.
|
||||
|
||||
heat_capacity=sizex*sizey*2500 // this scales with area as well.
|
||||
return null
|
||||
|
||||
/datum/fission_reactor_holder/proc/determineexplosionsize()
|
||||
if(!fuel)
|
||||
return list(0,0,0)
|
||||
var/TRP=((fuel.wattage-fuel.absorbance)*fuel.life)
|
||||
var/powerfactor=((fuel_reactivity) - ( (fuel_reactivity-fuel_reactivity_with_rods)*control_rod_insertion))
|
||||
TRP=ceil(sqrt(0.000001+((powerfactor)+1)*(TRP/25000))) //every 25kw of power nets us 1 tile
|
||||
|
||||
return list( floor(TRP*0.55),floor(TRP*0.75),TRP)
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/randomtileinreactor()
|
||||
return locate( rand( min(origin_x,corner_x),max(origin_x,corner_x) ) , rand(min(origin_y,corner_y),max(origin_y,corner_y)) , zlevel )
|
||||
|
||||
/datum/fission_reactor_holder/proc/meltdown()
|
||||
var/dt=(world.time-time_last_ticked)/10
|
||||
var/turf/centerturf=locate(origin_x,origin_y,zlevel)
|
||||
|
||||
message_admins("Fission reactor meltdown occured in area [centerturf.loc.name] ([formatJumpTo(centerturf,"JMP")])")
|
||||
log_game("Fission reactor meltdown occured in area [centerturf.loc.name]")
|
||||
var/reactorarea=(max(origin_x,corner_x)-min(origin_x,corner_x)) * (max(origin_y,corner_y)-min(origin_y,corner_y))
|
||||
var/reactorarea2=ceil(reactorarea/5) // 1 fith of the tiles will be eligable to explode
|
||||
var/explodeprob = 1
|
||||
|
||||
if(fuel)
|
||||
explodeprob=max(0,(1-(1/( log(1+max(0,fuel.wattage-fuel.absorbance)/15000) ))))
|
||||
|
||||
for(var/i=1,i<=reactorarea2,i++)
|
||||
if(rand()<=0.1*explodeprob*dt)
|
||||
var/list/eplodies=determineexplosionsize()
|
||||
if(eplodies[3]>0)
|
||||
explosion( randomtileinreactor() ,eplodies[1],eplodies[2],eplodies[3])
|
||||
|
||||
reactorarea2=ceil(reactorarea/2) //half can melt into radioactive slag
|
||||
var/crads=0
|
||||
if(fuel)
|
||||
crads=((fuel.wattage-fuel.absorbance)*fuel.life)/100000 //100kw nets 1 rad.
|
||||
for(var/i=1,i<=reactorarea2,i++)
|
||||
if(rand()<=0.5*dt)
|
||||
for (var/obj/o in randomtileinreactor().contents)
|
||||
|
||||
if(istype(o, /obj/machinery/fissioncontroller))
|
||||
new /obj/machinery/corium(o.loc,crads+crads*0.5*(rand()-0.5)) //25% variance on the radiation levels.
|
||||
qdel(o)
|
||||
else if(istype(o,/obj/machinery/fissionreactor/fissionreactor_fuelrod))
|
||||
new /obj/machinery/corium(o.loc,crads+crads*0.5*(rand()-0.5))
|
||||
qdel(o)
|
||||
else if(istype(o,/obj/machinery/fissionreactor/fissionreactor_controlrod))
|
||||
new /obj/machinery/corium(o.loc,crads+crads*0.5*(rand()-0.5))
|
||||
qdel(o)
|
||||
else if(istype(o,/obj/structure/fission_reactor_case))
|
||||
new /obj/machinery/corium(o.loc,crads+crads*0.5*(rand()-0.5))
|
||||
qdel(o)
|
||||
else if(istype(o,/obj/machinery/atmospherics/unary/fissionreactor_coolantport))
|
||||
new /obj/machinery/corium(o.loc,crads+crads*0.5*(rand()-0.5))
|
||||
qdel(o)
|
||||
for(var/mob/living/l in range(locate(origin_x,origin_y,zlevel), 5))
|
||||
l.apply_radiation(crads*5, RAD_EXTERNAL)
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/clear_parts()
|
||||
for (var/i=1,i<=casing_parts.len,i++)
|
||||
casing_parts[i].associated_reactor=null
|
||||
casing_parts=list()
|
||||
|
||||
for (var/i=1,i<=coolant_ports.len,i++)
|
||||
coolant_ports[i].associated_reactor=null
|
||||
coolant_ports=list()
|
||||
|
||||
for (var/i=1,i<=control_rods.len,i++)
|
||||
control_rods[i].associated_reactor=null
|
||||
control_rods=list()
|
||||
|
||||
for (var/i=1,i<=fuel_rods.len,i++)
|
||||
fuel_rods[i].associated_reactor=null
|
||||
fuel_rods=list()
|
||||
|
||||
fuel_reactivity=0
|
||||
fuel_rods_affected_by_rods=0
|
||||
fuel_reactivity_with_rods=0
|
||||
|
||||
/datum/fission_reactor_holder/proc/init_parts() //this assigns the reactor to the parts and vice versa
|
||||
clear_parts()
|
||||
for (var/y=min(origin_y,corner_y), y<=max(origin_y,corner_y),y++ )
|
||||
for (var/x=min(origin_x,corner_x), x<=max(origin_x,corner_x),x++ )
|
||||
var/turf/turftosearch=locate(x,y,zlevel)//locate(origin_x+x,origin_y+y,zlevel)
|
||||
var/list/contents = turftosearch.contents
|
||||
for (var/i=1,i<=contents.len,i++)
|
||||
|
||||
if(istype(contents[i], /obj/structure/fission_reactor_case )) //look, i don't like all the copy paste either.
|
||||
var/obj/structure/fission_reactor_case/this_thing=contents[i]
|
||||
this_thing.associated_reactor=src
|
||||
casing_parts.Add(this_thing)
|
||||
break
|
||||
if(istype(contents[i], /obj/machinery/atmospherics/unary/fissionreactor_coolantport )) //but these are different subtypes
|
||||
var/obj/machinery/atmospherics/unary/fissionreactor_coolantport/this_thing=contents[i]
|
||||
this_thing.associated_reactor=src
|
||||
coolant_ports.Add(this_thing)
|
||||
break
|
||||
if(istype(contents[i], /obj/machinery/fissionreactor/fissionreactor_controlrod )) //so we kind of have to snowflake it to hell
|
||||
var/obj/machinery/fissionreactor/fissionreactor_controlrod/this_thing=contents[i]
|
||||
this_thing.associated_reactor=src
|
||||
control_rods.Add(this_thing)
|
||||
break
|
||||
if(istype(contents[i], /obj/machinery/fissionreactor/fissionreactor_fuelrod ))
|
||||
var/obj/machinery/fissionreactor/fissionreactor_fuelrod/this_thing=contents[i]
|
||||
this_thing.associated_reactor=src
|
||||
fuel_rods.Add(this_thing)
|
||||
break
|
||||
|
||||
for (var/i=1,i<=control_rods.len,i++)
|
||||
control_rods[i].update_icon()
|
||||
|
||||
for (var/i=1,i<=fuel_rods.len,i++)
|
||||
fuel_rods[i].update_icon()
|
||||
recalculatereactorstats()
|
||||
|
||||
/datum/fission_reactor_holder/proc/recalculatereactorstats()
|
||||
fuel_reactivity_with_rods=0
|
||||
fuel_reactivity=0
|
||||
fuel_rods_affected_by_rods=0
|
||||
|
||||
for (var/i=1,i<=fuel_rods.len,i++)
|
||||
var/reactivity=fuel_rods[i].get_reactivity()
|
||||
var/controlled=fuel_rods[i].get_iscontrolled()
|
||||
|
||||
fuel_reactivity+=reactivity
|
||||
fuel_reactivity_with_rods+=(controlled ? 0 : reactivity)
|
||||
fuel_rods_affected_by_rods+=(controlled ? 1 : 0)
|
||||
if(fuel_rods.len)
|
||||
fuel_reactivity/=fuel_rods.len //average them out.
|
||||
fuel_reactivity_with_rods/=fuel_rods.len
|
||||
|
||||
/datum/fission_reactor_holder/proc/update_all_icos()
|
||||
for (var/i=1,i<=control_rods.len,i++)
|
||||
control_rods[i].update_icon()
|
||||
|
||||
for (var/i=1,i<=fuel_rods.len,i++)
|
||||
fuel_rods[i].update_icon()
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/turf_in_reactor(var/turf/location) //returns 0 if it is not in. 1 if it is exterior, and 2 if it is interior
|
||||
if(location.z!=zlevel)
|
||||
return 0
|
||||
var/xs=min(origin_x,corner_x)
|
||||
var/xe=max(origin_x,corner_x)
|
||||
var/ys=min(origin_y,corner_y)
|
||||
var/ye=max(origin_y,corner_y)
|
||||
|
||||
if(location.x>=xs && location.x<=xe && location.y>=ys && location.y<=ye) //within the bounds of the reactor?
|
||||
if(location.x==xs || location.x==xe || location.y==ys || location.y==ye) //if we are on an edge
|
||||
return 1
|
||||
return 2
|
||||
return 0
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/fissioncycle() //what makes the heat.
|
||||
var/dt=(world.time-time_last_ticked)/10
|
||||
if (SCRAM)
|
||||
control_rod_target=1
|
||||
if(temperature<=FISSIONREACTOR_SAFEENUFFTEMP)
|
||||
SCRAM=FALSE
|
||||
|
||||
|
||||
if(control_rod_target>control_rod_insertion) //5% insertion increment per second
|
||||
control_rod_insertion=min((0.05*dt*(SCRAM ? 1.5 : 1.0))+control_rod_insertion,control_rod_target) //rods fall 50% faster when shit is going down to hitting the fan town.
|
||||
else if(control_rod_target<control_rod_insertion)
|
||||
control_rod_insertion=max(control_rod_insertion-0.05*dt,control_rod_target)
|
||||
|
||||
|
||||
if(!fuel)
|
||||
return
|
||||
if(fuel.life<=0)
|
||||
return
|
||||
if(fuel.wattage<=0)
|
||||
return
|
||||
|
||||
var/speedfactor=fuel_rods.len - (fuel_rods_affected_by_rods*control_rod_insertion)
|
||||
var/powerfactor=fuel_rods.len*((fuel_reactivity) - ( (fuel_reactivity-fuel_reactivity_with_rods)*control_rod_insertion))
|
||||
|
||||
var/totalpowertodump=0
|
||||
if(fuel.wattage < fuel.absorbance) //slow down the reaction if there's not enuff powah
|
||||
totalpowertodump=0
|
||||
speedfactor*=(fuel.absorbance-fuel.wattage)/fuel.wattage
|
||||
else
|
||||
totalpowertodump=(fuel.wattage-fuel.absorbance)*dt
|
||||
|
||||
|
||||
if (fuel.lifetime>0)
|
||||
fuel.life-= (speedfactor*dt)/fuel.lifetime
|
||||
fuel.life=max(0,fuel.life)
|
||||
else
|
||||
fuel.life=0
|
||||
return
|
||||
|
||||
temperature+=totalpowertodump*powerfactor/heat_capacity
|
||||
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/coolantcycle()
|
||||
var/dt=(world.time-time_last_ticked)/10
|
||||
if(coolant_ports.len)
|
||||
for(var/i=1, i<=coolant_ports.len,i++)
|
||||
var/real_index= ((i+coolantport_counter)%coolant_ports.len)+1 //this way we spread out any first index prefrence.
|
||||
var/obj/machinery/atmospherics/unary/fissionreactor_coolantport/coolant_port=coolant_ports[real_index]
|
||||
coolant_port.transfer_reactor()
|
||||
coolantport_counter++
|
||||
coolantport_counter=(coolantport_counter%coolant_ports.len)+1 //shift it around.
|
||||
|
||||
//unrealistically, the heat transfer is 100% between the 2 sources.
|
||||
//too bad.
|
||||
var/chp=coolant.heat_capacity()
|
||||
var/newtemp=(chp*coolant.temperature + heat_capacity*temperature)/(chp+heat_capacity)
|
||||
|
||||
var/heatconductivitycoeff=1- (0.5**dt) //dt=2 seconds: 75% heat transference. dt->inf, %->100. dt=0:0%
|
||||
|
||||
coolant.temperature=newtemp*heatconductivitycoeff + (1-heatconductivitycoeff)*coolant.temperature
|
||||
temperature=newtemp*heatconductivitycoeff + (1-heatconductivitycoeff)*temperature
|
||||
|
||||
|
||||
/datum/fission_reactor_holder/proc/misccycle() //cleanup and other checks
|
||||
var/dt=(world.time-time_last_ticked)/10
|
||||
var/powerfactor=fuel_rods.len*((fuel_reactivity) - ( (fuel_reactivity-fuel_reactivity_with_rods)*control_rod_insertion))
|
||||
var/fuelpower=0
|
||||
if(fuel)
|
||||
fuelpower=max( (fuel.wattage+(fuel.wattage-fuel.absorbance))/2 ,0)
|
||||
|
||||
for(var/turf/breachlocation in breaches)
|
||||
if(rand()>0.5) //50% chance every tick to leak
|
||||
var/datum/gas_mixture/removed= coolant.remove(coolant.total_moles*0.5*dt*rand(),TRUE,TRUE) //when we leak, leak 0-50% of the coolant
|
||||
breachlocation.return_air().merge(removed,TRUE)
|
||||
for(var/mob/living/l in range(breachlocation, 5))
|
||||
var/rads = ( fuelpower*powerfactor/100000 ) * sqrt(1/(max(get_dist(l, breachlocation), 1)))
|
||||
l.apply_radiation(rads, RAD_EXTERNAL)
|
||||
|
||||
if(temperature>=FISSIONREACTOR_MELTDOWNTEMP)
|
||||
if(graceperiodtick<=0)
|
||||
meltdown()
|
||||
else
|
||||
if(graceperiodtick==3.0)
|
||||
var/turf/centerturf=locate(origin_x,origin_y,zlevel)
|
||||
message_admins("A meltdown is probably just about to occur in area [centerturf.loc.name] ([formatJumpTo(centerturf,"JMP")]).")
|
||||
graceperiodtick-=dt
|
||||
else
|
||||
graceperiodtick=3.0
|
||||
|
||||
verify_integrity()
|
||||
time_last_ticked=world.time
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/fission_fuel
|
||||
var/datum/reagents/fuel= null
|
||||
var/life=1.0 //1.0 is full life, 0 is depleted. MAKE SURE it is always 0-1 or shit WILL go wrong.
|
||||
|
||||
//these are rederived when making a new one, so these can be whatever.
|
||||
var/lifetime=0 //time in seconds that the fuel will burn for at base.
|
||||
var/wattage=0 // heat which will be added.
|
||||
var/absorbance=0 //subtraced from above to get total emission.
|
||||
|
||||
/datum/fission_fuel/New(storage_size)
|
||||
fuel= new /datum/reagents(storage_size) //this probably isn't the best way to do things, but that's a problem for future me (someone else) to deal with.
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/fission_fuel/proc/add_shit_to(var/reagent, var/amount,var/datum/reagents/holder) //this exists because reagent code really wants an atom. but this is a datum. sux to be them. this is simpler, anyways.
|
||||
for (var/datum/reagent/R in holder.reagent_list)
|
||||
if (R.id == reagent)
|
||||
R.volume += amount
|
||||
holder.amount_cache[R.id]=R.volume
|
||||
holder.update_total()
|
||||
rederive_stats()
|
||||
return 0
|
||||
var/datum/reagent/D = chemical_reagents_list[reagent]
|
||||
if(D)
|
||||
var/datum/reagent/R = new D.type()
|
||||
|
||||
holder.reagent_list += R
|
||||
R.holder = holder
|
||||
R.volume = amount
|
||||
holder.amount_cache[R.id]=amount
|
||||
holder.update_total()
|
||||
rederive_stats()
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
/datum/fission_fuel/proc/take_shit_from(var/reagent, var/amount,var/datum/reagents/holder)
|
||||
for (var/datum/reagent/R in holder.reagent_list)
|
||||
if(R.id==reagent)
|
||||
var/taken=min(amount,R.volume)
|
||||
R.volume=max(R.volume-amount,0)
|
||||
holder.amount_cache[R.id]=amount
|
||||
holder.update_total()
|
||||
rederive_stats()
|
||||
return taken
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/fission_fuel/proc/rederive_stats() //should be called whenever you change the materials
|
||||
if(!fuel)
|
||||
lifetime=0
|
||||
wattage=0
|
||||
absorbance=0
|
||||
return
|
||||
var/thislifetime=0
|
||||
var/thiswattage=0
|
||||
var/thisabsorbance=0
|
||||
|
||||
for(var/datum/reagent/R in fuel.reagent_list)
|
||||
if (R.fission_time)
|
||||
thislifetime+=R.fission_time* (fuel.amount_cache[R.id] + 0)/(fuel.total_volume) //fuel time is a weighted average
|
||||
thiswattage+=R.fission_power*fuel.amount_cache[R.id]
|
||||
thisabsorbance+=R.fission_absorbtion*fuel.amount_cache[R.id]
|
||||
|
||||
lifetime=max(thislifetime,0)
|
||||
wattage=max(thiswattage,0)
|
||||
absorbance=max(thisabsorbance,0)
|
||||
|
||||
/datum/fission_fuel/proc/get_products() //fission products.
|
||||
var/datum/reagents/products = new /datum/reagents(fuel.maximum_volume)
|
||||
|
||||
if(!fuel)
|
||||
return products
|
||||
|
||||
var/list/normal_reagents=new()
|
||||
for(var/datum/reagent/R in fuel.reagent_list)
|
||||
normal_reagents[R.id]=fuel.amount_cache[R.id]
|
||||
var/highest=0
|
||||
for(var/Rid in normal_reagents)
|
||||
highest=max(highest,normal_reagents[Rid])
|
||||
if(highest>0)
|
||||
for(var/Rid in normal_reagents)
|
||||
normal_reagents[Rid]/=highest
|
||||
|
||||
for(var/datum/reagent/R in fuel.reagent_list)
|
||||
var/reagamt=fuel.amount_cache[R.id] //reagent amount.
|
||||
if (reagamt<=0) //skip reagents we don't have.
|
||||
continue
|
||||
var/fissionprods=R.irradiate(normal_reagents)
|
||||
for(var/RID in fissionprods) //associative lists hurt my brain. don't think too hard about how they work, ok?
|
||||
var/RCT=fissionprods[RID]
|
||||
add_shit_to(RID, reagamt*RCT*(1.0-life),products) // we multiply the proportion of outputs by the amount of that fuel type, by the amount we actually processed.
|
||||
add_shit_to(R.id, life*reagamt ,products) //add unspent fuel back.
|
||||
|
||||
|
||||
return products
|
||||
368
code/modules/fissionreactor/fuelmaker.dm
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
in this file:
|
||||
the machine which makes fuel rods have things in them.
|
||||
*/
|
||||
|
||||
//because radon is a gas, we need to interface with gasses. yeah, this kind of sucks, but what are you gonna do? (inb4 make better code lol)
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker
|
||||
name="isotopic separational combiner" //just about the most technobable you could get.
|
||||
var/datum/reagents/held_elements=new /datum/reagents
|
||||
use_power = MACHINE_POWER_USE_IDLE
|
||||
idle_power_usage = 200
|
||||
anchored=1
|
||||
density=1
|
||||
active_power_usage = 1000
|
||||
icon='icons/obj/fissionreactor/fuelmaker.dmi'
|
||||
icon_state="fuelmaker"
|
||||
var/hatchopen=FALSE
|
||||
var/obj/item/weapon/fuelrod/heldrod = null
|
||||
var/obj/item/weapon/reagent_containers/container=null
|
||||
var/datum/html_interface/interface
|
||||
var/pipename="isotopic separational combiner"
|
||||
var/reagent_wiki=null //stores a reagent id. if not null, displays some info instead of the regular ui.
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/proc/get_pipe_dir() //the atmos gods demand a sacrifice.
|
||||
return dir
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/New()
|
||||
..()
|
||||
src.buildFrom(usr,src)
|
||||
interface=new /datum/html_interface(src,"isotopic separational combiner",500,300,"<link rel='stylesheet' href='nanotrasen.css'>")
|
||||
buildui()
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/attackby(var/obj/item/I,var/mob/user)
|
||||
if(istype(I,/obj/item/weapon/fuelrod))
|
||||
if(heldrod)
|
||||
to_chat(user,"There's already a fuel rod inserted into \the [src].")
|
||||
else
|
||||
if(!user.drop_item(I))
|
||||
return
|
||||
to_chat(user,"You insert the fuel rod into \the [src].")
|
||||
I.forceMove(src)
|
||||
heldrod=I
|
||||
heldrod.fueldata.fuel=heldrod.fueldata.get_products() //process the fuel turning
|
||||
heldrod.fueldata.life=1
|
||||
heldrod.fueldata.rederive_stats()
|
||||
ask_remakeUI()
|
||||
playsound(src,'sound/items/crowbar.ogg',50)
|
||||
update_icon()
|
||||
return
|
||||
if(iscrowbar(I) && heldrod)
|
||||
user.visible_message("<span class='notice'>[user] starts prying the fuel rod out of \the [src].</span>", "<span class='notice'>You start prying the fuel rod out of \the [src].</span>")
|
||||
playsound(src,'sound/items/crowbar.ogg',50)
|
||||
if(do_after(user, src,20))
|
||||
heldrod.forceMove(loc)
|
||||
heldrod=null
|
||||
ask_remakeUI()
|
||||
playsound(src,'sound/machines/door_unbolt.ogg',50)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(I.is_screwdriver(user))
|
||||
I.playtoolsound(src, 100)
|
||||
user.visible_message("<span class='notice'>[user] [hatchopen ? "closes" : "opens"] the maintenance hatch of the [src].</span>", "<span class='notice'>You [hatchopen ? "close" : "open"] the maintenance hatch of the [src].</span>")
|
||||
hatchopen=!hatchopen
|
||||
if(iscrowbar(I))
|
||||
I.playtoolsound(src, 100)
|
||||
user.visible_message("<span class='warning'>[user] starts prying the electronics out of \the [src].</span>", "<span class='notice'>You start prying the electronics out of \the [src].</span>")
|
||||
if(do_after(user, src, 30 ))
|
||||
user.visible_message("<span class='warning'>[user] pries the electronics out of \the [src]</span>","<span class='notice'>You pry the electronics out of \the [src].</span>")
|
||||
var/obj/machinery/constructable_frame/machine_frame/newframe= new /obj/machinery/constructable_frame/machine_frame(loc)
|
||||
newframe.set_build_state(3)
|
||||
newframe.forceMove(loc)
|
||||
newframe.circuit= new /obj/item/weapon/circuitboard/fission_fuelmaker
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/console_screen
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/manipulator
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/matter_bin
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/matter_bin
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/scanning_module
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/scanning_module
|
||||
qdel(src)
|
||||
if( istype(I,/obj/item/weapon/reagent_containers) )
|
||||
var/obj/item/weapon/reagent_containers/C=I
|
||||
if(container)
|
||||
to_chat(user,"There's already a container inside of \the [src].")
|
||||
return TRUE
|
||||
if(!user.drop_item(C))
|
||||
return
|
||||
C.forceMove(src)
|
||||
container=C
|
||||
to_chat(user,"You add \the [C] to \the [src]")
|
||||
ask_remakeUI()
|
||||
return TRUE
|
||||
|
||||
|
||||
//..()
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/attack_hand(mob/user)
|
||||
if(..())
|
||||
if(container)
|
||||
to_chat(user,"You remove \the [container] from \the [src]")
|
||||
container.forceMove(src.loc)
|
||||
container=null
|
||||
ask_remakeUI()
|
||||
return
|
||||
|
||||
interface.show(user)
|
||||
register_asset("nanotrasen.css", 'code/modules/html_interface/nanotrasen/nanotrasen.css')
|
||||
send_asset(user, "nanotrasen.css")
|
||||
register_asset("uiBg.png", 'code/modules/html_interface/nanotrasen/uiBg.png')
|
||||
send_asset(user, "uiBg.png")
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/Topic(var/href, var/list/href_list , var/datum/html_interface_client/hclient)
|
||||
if(!powered())
|
||||
return
|
||||
if(stat & BROKEN)
|
||||
return
|
||||
|
||||
if(!canGhostWrite(usr,src,"",0))
|
||||
if(usr.restrained() || usr.lying || usr.stat)
|
||||
return 1
|
||||
if (!usr.dexterity_check())
|
||||
to_chat(usr, "<span class='warning'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
if(!is_on_same_z(usr))
|
||||
to_chat(usr, "<span class='warning'>WARNING: Unable to interface with \the [src.name].</span>")
|
||||
return 1
|
||||
if(!is_in_range(usr))
|
||||
to_chat(usr, "<span class='warning'>WARNING: Connection failure. Reduce range.</span>")
|
||||
return 1
|
||||
|
||||
if(href_list["action"])
|
||||
switch(href_list["action"])
|
||||
if("eject_fuel")
|
||||
if(!heldrod)
|
||||
to_chat(hclient.client,"There's no fuel rod to eject.")
|
||||
else
|
||||
heldrod.forceMove(src.loc)
|
||||
heldrod.update_icon()
|
||||
heldrod=null
|
||||
update_icon()
|
||||
if("eject_cont")
|
||||
if(!container)
|
||||
to_chat(hclient.client,"There's no container to eject.")
|
||||
else
|
||||
container.forceMove(src.loc)
|
||||
container.update_icon()
|
||||
container=null
|
||||
|
||||
if(href_list["reagent"])
|
||||
if(href_list["dir"]=="to_fuel")
|
||||
var/error=transfer_to_fuelrod( href_list["reagent"] , text2num(href_list["amount"]) || 0 )
|
||||
if(error)
|
||||
to_chat(hclient.client,"could not transfer reagent: [error]!")
|
||||
else if(href_list["dir"]=="from_fuel")
|
||||
var/error=transfer_from_fuelrod( href_list["reagent"] , text2num(href_list["amount"]) || 0 )
|
||||
if(error)
|
||||
to_chat(hclient.client,"could not transfer reagent: [error]!")
|
||||
else if(href_list["dir"]=="goto_wiki")
|
||||
reagent_wiki=href_list["reagent"]
|
||||
if(href_list["dir"]=="exit_wiki")
|
||||
reagent_wiki=null
|
||||
|
||||
|
||||
ask_remakeUI()
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/proc/transfer_from_fuelrod(var/reagent_id,var/amount)
|
||||
if(!heldrod)
|
||||
return "no fuel rod"
|
||||
if(reagent_id==RADON || reagent_id=="RADON")
|
||||
if(air_contents)
|
||||
var/actually_taken=heldrod.fueldata.take_shit_from(reagent_id,amount ,heldrod.fueldata.fuel)
|
||||
if(!air_contents.gas[GAS_RADON])
|
||||
air_contents.gas[GAS_RADON]=0
|
||||
air_contents.gas[GAS_RADON]+=actually_taken
|
||||
air_contents.update_values()
|
||||
if(network)
|
||||
network.update=1
|
||||
return
|
||||
if(!container)
|
||||
return "no container"
|
||||
|
||||
amount=min(amount,container.volume-container.reagents.total_volume)
|
||||
|
||||
var/actually_taken=heldrod.fueldata.take_shit_from(reagent_id,amount ,heldrod.fueldata.fuel)
|
||||
|
||||
container.reagents.add_reagent(reagent_id, actually_taken)
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/proc/transfer_to_fuelrod(var/reagent_id,var/amount)
|
||||
if(!heldrod)
|
||||
return "no fuel rod"
|
||||
if(reagent_id==RADON || reagent_id=="RADON")
|
||||
if(air_contents)
|
||||
var/avalible_gas=air_contents.gas[GAS_RADON] || 0
|
||||
amount=min(amount,avalible_gas,heldrod.units_of_storage-heldrod.fueldata.fuel.total_volume)
|
||||
air_contents.gas[GAS_RADON]= max(0,avalible_gas-amount)
|
||||
heldrod.fueldata.add_shit_to(reagent_id,amount ,heldrod.fueldata.fuel)
|
||||
air_contents.update_values()
|
||||
if(network)
|
||||
network.update=1
|
||||
return
|
||||
if(!container)
|
||||
return "no container"
|
||||
amount=min(amount,heldrod.units_of_storage-heldrod.fueldata.fuel.total_volume,container.reagents.amount_cache[reagent_id] || 0)
|
||||
|
||||
heldrod.fueldata.add_shit_to(reagent_id,amount ,heldrod.fueldata.fuel)
|
||||
|
||||
container.reagents.remove_reagent(reagent_id, amount, TRUE)
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/proc/ask_remakeUI()
|
||||
buildui()
|
||||
for (var/client/C in interface.clients)
|
||||
if(C.mob && get_dist(C.mob.loc,src.loc)<=1)
|
||||
interface.show( interface._getClient(interface.clients[C]) )
|
||||
else
|
||||
interface.hide(interface._getClient(interface.clients[C]))
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/proc/buildui()
|
||||
var/html=""
|
||||
|
||||
var/current_rodamt=0
|
||||
var/estimated_time=0
|
||||
var/estimated_power=0
|
||||
|
||||
if(heldrod)
|
||||
for(var/datum/reagent/R in heldrod.fueldata.fuel.reagent_list)
|
||||
current_rodamt+=R.volume
|
||||
|
||||
estimated_time=floor(heldrod.fueldata.lifetime/60)
|
||||
if(heldrod.fueldata.absorbance>heldrod.fueldata.wattage)
|
||||
if(heldrod.fueldata.wattage>0)
|
||||
estimated_time/= (heldrod.fueldata.absorbance-heldrod.fueldata.wattage)/heldrod.fueldata.wattage
|
||||
estimated_time=floor(estimated_time)
|
||||
else
|
||||
estimated_time="never"
|
||||
else
|
||||
estimated_power=heldrod.fueldata.wattage - heldrod.fueldata.absorbance
|
||||
|
||||
|
||||
if (reagent_wiki)
|
||||
var/datum/reagent/sample=chemical_reagents_list[reagent_wiki]
|
||||
var/byproducts="unknown"
|
||||
if(sample)
|
||||
var/list/prod=sample.irradiate()
|
||||
byproducts=""
|
||||
for(var/id in prod)
|
||||
var/datum/reagent/prd=chemical_reagents_list[id]
|
||||
if(prd)
|
||||
byproducts+="[prd.name]: [floor(prod[id]*100)]% "
|
||||
|
||||
html={"<div style='margin-left:5px;margin-right:5px;'><br>
|
||||
<a href='?src=\ref[interface];dir=exit_wiki'>Return</a><br>
|
||||
|
||||
<b>[sample ? sample.name : "unknown"]</b><br>
|
||||
|
||||
<i>[sample? sample.description : "unable to identify reagent"]</i><br>
|
||||
<hr>
|
||||
Power: [sample? sample.fission_power - sample.fission_absorbtion : "?"] Watts<br>
|
||||
Lifespan: [sample? (sample.fission_time || "non-fissile") : "?"] [sample? (sample.fission_time!=null ? "Seconds" : "") : "Seconds"]<br>
|
||||
|
||||
Products: [byproducts]
|
||||
|
||||
|
||||
</div>"}
|
||||
else
|
||||
var/producttext="none"
|
||||
if(heldrod)
|
||||
var/list/temp_list=new()
|
||||
producttext = heldrod.fueldata.fuel.reagent_list.len==0 ? "none" : ""
|
||||
var/high=0
|
||||
for(var/datum/reagent/R in heldrod.fueldata.fuel.reagent_list)
|
||||
temp_list[R.id]=R.volume
|
||||
high=max(high,R.volume)
|
||||
if (high>0)
|
||||
for(var/i in temp_list)
|
||||
temp_list[i]/=high
|
||||
var/list/prods=new()
|
||||
for(var/datum/reagent/R in heldrod.fueldata.fuel.reagent_list)
|
||||
var/list/l=R.irradiate(temp_list)
|
||||
for(var/regid in l)
|
||||
prods[regid] = (prods[regid]==null ? 0 : prods[regid]) + l[regid]*R.volume
|
||||
for(var/i in prods)
|
||||
producttext+="[chemical_reagents_list[i]?.name ]: [prods[i]] units "
|
||||
|
||||
html={"<div style='margin-left:5px;margin-right:5px;'>
|
||||
<div >
|
||||
Baseline fuel lifespan: [estimated_time] minutes <br>
|
||||
Baseline heat generation: [floor(estimated_power)] Watts <br>
|
||||
<table><tr><td style='white-space: nowrap;'>Expected byproducts: </td><td>[producttext]</td></tr></table>
|
||||
</div>"}
|
||||
|
||||
|
||||
html+={"<hr> <table style='width:100%;'><tr><td> Fuel Rod: [ heldrod ? "[heldrod.name] \[[current_rodamt]/[heldrod.units_of_storage]\]" : "none" ] <a href='?src=\ref[interface];action=eject_fuel'>Eject</a></td> <td style='text-align:right;'>Transfer To Container</td> </tr>"}
|
||||
|
||||
if(heldrod)
|
||||
for(var/datum/reagent/R in heldrod.fueldata.fuel.reagent_list)
|
||||
html+="<tr><td> [R.name] <a href='?src=\ref[interface];reagent=[R.id];dir=goto_wiki'>(?)</a> [R.volume] unit[R.volume!=1?"s":""] </td>"
|
||||
html+="<td style='text-align:right;'><a <a href='?src=\ref[interface];reagent=[R.id];dir=from_fuel;amount=1'>1u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=from_fuel;amount=5'>5u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=from_fuel;amount=10'>10u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=from_fuel;amount=25'>25u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=from_fuel;amount=999999'>All</a></td></tr>"
|
||||
|
||||
|
||||
html+={"</table><hr><table style='width:100%;'><tr><td>
|
||||
Container: [container ? container : "none"][container ? " \[[container.reagents.total_volume]/[container.volume]\]" : ""] <a href='?src=\ref[interface];action=eject_cont'>Eject</a></td><td style='text-align:right;'> Transfer To Fuel Rod</td> </tr>"}
|
||||
|
||||
if(container)
|
||||
for(var/datum/reagent/R in container.reagents.reagent_list)
|
||||
html+="<tr><td> [R.name] <a href='?src=\ref[interface];reagent=[R.id];dir=goto_wiki'>(?)</a> [R.volume] unit[R.volume!=1?"s":""] </td>"
|
||||
html+="<td style='text-align:right;'><a <a href='?src=\ref[interface];reagent=[R.id];dir=to_fuel;amount=1'>1u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=to_fuel;amount=5'>5u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=to_fuel;amount=10'>10u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=to_fuel;amount=25'>25u</a> <a href='?src=\ref[interface];reagent=[R.id];dir=to_fuel;amount=999999'>All</a></td></tr>"
|
||||
if(air_contents)
|
||||
if(air_contents.gas[GAS_RADON])
|
||||
html+="<tr><td> Radon <a href='?src=\ref[interface];reagent=RADON;dir=goto_wiki'>(?)</a> [air_contents.gas[GAS_RADON]] units </td>"
|
||||
html+="<td style='text-align:right;'><a <a href='?src=\ref[interface];reagent=RADON;dir=to_fuel;amount=1'>1u</a> <a href='?src=\ref[interface];reagent=RADON;dir=to_fuel;amount=5'>5u</a> <a href='?src=\ref[interface];reagent=RADON;dir=to_fuel;amount=10'>10u</a> <a href='?src=\ref[interface];reagent=RADON;dir=to_fuel;amount=25'>25u</a> <a href='?src=\ref[interface];reagent=RADON;dir=to_fuel;amount=999999'>All</a></td></tr>"
|
||||
|
||||
|
||||
|
||||
html+={"</table></div>"}
|
||||
|
||||
|
||||
interface.updateLayout(html)
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/process() //because atmos fuckery, we have to periodically update it.
|
||||
ask_remakeUI()
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/update_icon()
|
||||
..()
|
||||
if(!powered())
|
||||
icon_state="fuelmaker_off[heldrod?"_insert":""]"
|
||||
else if(stat & BROKEN)
|
||||
icon_state="fuelmaker_broken[heldrod?"_insert":""]"
|
||||
else
|
||||
icon_state="fuelmaker[heldrod?"_insert":""]"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/unary/fissionfuelmaker/examine()
|
||||
..()
|
||||
to_chat(usr,"The maintenance hatch is [hatchopen ? "open" : "closed"]. It's affixed by some screws.")
|
||||
if(hatchopen)
|
||||
to_chat(usr,"It looks like you could pry out the electronics.")
|
||||
if(heldrod)
|
||||
to_chat(usr,"There is a fuel rod inserted into it.")
|
||||
else
|
||||
to_chat(usr,"The fuel rod receptacle is empty.")
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/fission_fuelmaker
|
||||
name = "Circuit board (isotopic separational combiner)"
|
||||
desc = "A circuit board for combining various isotopes together, as well as separating them."
|
||||
build_path = /obj/machinery/atmospherics/unary/fissionfuelmaker
|
||||
board_type = MACHINE
|
||||
origin_tech = Tc_PROGRAMMING + "=3;" + Tc_ENGINEERING + "=4"
|
||||
var/safety_disabled=FALSE
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 2,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen=1,
|
||||
)
|
||||
|
||||
|
||||
59
code/modules/fissionreactor/items.dm
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
in this file:
|
||||
items for the fission reactor which don't have another place to be.
|
||||
|
||||
includes:
|
||||
fuel rod (item)
|
||||
'*/
|
||||
|
||||
|
||||
/obj/item/weapon/fuelrod
|
||||
name="fuel rod"
|
||||
desc="holds various reagents for use in nuclear reactions."
|
||||
icon='icons/obj/fissionreactor/items.dmi'
|
||||
icon_state="i_fuelrod_empty"
|
||||
var/datum/fission_fuel/fueldata=null
|
||||
var/units_of_storage=90
|
||||
|
||||
|
||||
/obj/item/weapon/fuelrod/New()
|
||||
fueldata = new /datum/fission_fuel(units_of_storage)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/weapon/fuelrod/update_icon()
|
||||
..()
|
||||
icon_state="i_fuelrod_empty"
|
||||
if(!fueldata)
|
||||
return
|
||||
if(fueldata.fuel.total_volume>0)
|
||||
icon_state="i_fuelrod[fueldata.life>0 ? "" : "_depleted"]"
|
||||
|
||||
|
||||
/obj/item/weapon/fuelrod/small
|
||||
name="small fuel rod"
|
||||
desc="a smaller fuel rod, for lower-power applications."
|
||||
icon_state="i_fuelrod_s_empty"
|
||||
units_of_storage=30
|
||||
|
||||
/obj/item/weapon/fuelrod/small/update_icon()
|
||||
..()
|
||||
icon_state="i_fuelrod_s_empty"
|
||||
if(!fueldata)
|
||||
return
|
||||
if(fueldata.fuel.total_volume>0)
|
||||
icon_state="i_fuelrod_s[fueldata.life>0 ? "" : "_depleted"]"
|
||||
|
||||
/obj/item/weapon/fuelrod/large
|
||||
name="large fuel rod"
|
||||
icon_state="i_fuelrod_l_empty"
|
||||
desc="a very large fuel rod, for high-power or complex mixes. use with caution."
|
||||
units_of_storage=210
|
||||
|
||||
/obj/item/weapon/fuelrod/large/update_icon()
|
||||
..()
|
||||
icon_state="i_fuelrod_l_empty"
|
||||
if(!fueldata)
|
||||
return
|
||||
if(fueldata.fuel.total_volume>0)
|
||||
icon_state="i_fuelrod_l[fueldata.life>0 ? "" : "_depleted"]"
|
||||
74
code/modules/fissionreactor/misc.dm
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
in this file:
|
||||
boxes used for cargo orders to make my life easier.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_controller
|
||||
name="fission reactor controller parts"
|
||||
desc="Contains all the materials needed to assemble a fission reactor controller."
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_controller/New()
|
||||
..()
|
||||
new /obj/item/weapon/circuitboard/fission_reactor(src)
|
||||
new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
new /obj/item/weapon/stock_parts/console_screen(src)
|
||||
new /obj/item/stack/rods(src,2)//2 rods
|
||||
new /obj/item/stack/sheet/plasteel(src,5)//5 plasteel
|
||||
new /obj/item/stack/cable_coil(src,5)//5 wire
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly //include seperate boards
|
||||
name="fission reactor assembly parts"
|
||||
desc="Contains all the materials needed to assemble a fission assembly, minus the appropriate circuit board."
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_genericassembly/New()
|
||||
..()
|
||||
new /obj/item/stack/sheet/plasteel(src,5)//5 plasteel
|
||||
new /obj/item/stack/rods(src,2)//2 rods
|
||||
new /obj/item/stack/cable_coil(src,5)//5 wire
|
||||
|
||||
new /obj/item/weapon/stock_parts/manipulator(src) //1 scanning module OR 1 micro-manipulator
|
||||
new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
new /obj/item/weapon/stock_parts/matter_bin(src) // 1 matter bin
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing
|
||||
name="fission reactor casing parts"
|
||||
desc="Contains all the materials needed to assemble a single fission reactor casing."
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_casing/New()
|
||||
..()
|
||||
new /obj/item/stack/sheet/plasteel(src,6)//6 plasteel
|
||||
new /obj/item/stack/rods(src,4) //4 rods
|
||||
new /obj/item/pipe(src,0) //1 pipe (optional)
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_fuelmaker
|
||||
name="seperational isotopic combiner parts"
|
||||
desc="Contains all the materials needed to assemble a seperational isotopic combiner."
|
||||
|
||||
/obj/item/weapon/storage/box/fissionsupply_fuelmaker/New()
|
||||
..()
|
||||
new /obj/item/weapon/circuitboard/fission_fuelmaker(src)
|
||||
new /obj/item/stack/sheet/metal(src,5)//5 metal
|
||||
new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
new /obj/item/weapon/stock_parts/scanning_module(src)
|
||||
new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
new /obj/item/weapon/stock_parts/matter_bin(src)
|
||||
new /obj/item/weapon/stock_parts/manipulator(src)
|
||||
new /obj/item/weapon/stock_parts/console_screen(src)
|
||||
new /obj/item/stack/cable_coil(src,5)//5 wire
|
||||
|
||||
/obj/item/weapon/fuelrod/small/starter
|
||||
icon_state="i_fuelrod_s"
|
||||
|
||||
/obj/item/weapon/fuelrod/small/starter/New()
|
||||
..()
|
||||
//fueldata.fuel.add_reagent(URANIUM,150)
|
||||
fueldata.add_shit_to(URANIUM,units_of_storage,fueldata.fuel)
|
||||
fueldata.rederive_stats()
|
||||
fueldata.life=1
|
||||
|
||||
|
||||
1013
code/modules/fissionreactor/objects_external.dm
Normal file
368
code/modules/fissionreactor/objects_internal.dm
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
IN THIS FILE:
|
||||
objects that make up the interior (inside) of the reactor.
|
||||
included:
|
||||
control rods
|
||||
fuel rods (machine)
|
||||
*/
|
||||
|
||||
/obj/machinery/fissionreactor
|
||||
anchored=1
|
||||
density=1
|
||||
var/datum/fission_reactor_holder/associated_reactor=null
|
||||
name="fission reactor part"
|
||||
|
||||
/obj/machinery/fissionreactor/New() //update surrounding so that they are colored
|
||||
..()
|
||||
for(var/obj/machinery/fissionreactor/part in range(src,1) )
|
||||
part.update_icon()
|
||||
|
||||
/obj/machinery/fissionreactor/Destroy()
|
||||
for(var/obj/machinery/fissionreactor/part in range(src,1) )
|
||||
loc=null
|
||||
part.update_icon()
|
||||
if(associated_reactor)
|
||||
associated_reactor.handledestruction(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod
|
||||
name="fission reactor control rod assembly"
|
||||
desc="Monitors a nuclear reactor and can slow or halt the fission process if needed."
|
||||
icon='icons/obj/fissionreactor/controlrod.dmi'
|
||||
icon_state="controlrod_off"
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod/examine()
|
||||
..()
|
||||
if(associated_reactor)
|
||||
to_chat(usr,"The lights indicate that there are [overlays.len] adjacent fuel rod assemblies")
|
||||
switch(icon_state)
|
||||
if("controlrod_0")
|
||||
to_chat(usr,"The rod is hardly inserted.") //haha that's what she said
|
||||
if("controlrod_1")
|
||||
to_chat(usr,"The rod is partially inserted.")
|
||||
if("controlrod_2")
|
||||
to_chat(usr,"The rod is just under halfway inserted.")
|
||||
if("controlrod_3")
|
||||
to_chat(usr,"The rod is just over halfway inserted.")
|
||||
if("controlrod_4")
|
||||
to_chat(usr,"The rod is mostly inserted.")
|
||||
if("controlrod_5")
|
||||
to_chat(usr,"The rod is nearly fully inserted.")
|
||||
to_chat(usr,"The structure is held together firmly, it'll have to be cut in order to part it.")
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod/New()
|
||||
for(var/datum/fission_reactor_holder/r in fissionreactorlist)
|
||||
if(r.turf_in_reactor(src.loc))
|
||||
if(r.adopt_part(src))
|
||||
break
|
||||
..()
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod/attackby(var/obj/item/O,var/mob/user)
|
||||
if(iswelder(O))
|
||||
if(associated_reactor && associated_reactor.considered_on())
|
||||
if(user.a_intent==I_HELP)
|
||||
to_chat(usr,"<span class='danger'>this seems like a really bad idea.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts welding \the [src]'s external plating off its frame.</span>", "<span class='notice'>You start welding \the [src]'s external plating off its frame.</span>")
|
||||
var/obj/item/tool/weldingtool/WT = O
|
||||
if(WT.do_weld(user,src,60,0))
|
||||
var/obj/machinery/constructable_frame/machine_frame/reinforced/newframe= new /obj/machinery/constructable_frame/machine_frame/reinforced(loc)
|
||||
newframe.forceMove(loc)
|
||||
newframe.set_build_state(3)
|
||||
newframe.circuit= new /obj/item/weapon/circuitboard/fission_control_rod
|
||||
newframe.components=list()
|
||||
newframe.components+= new /obj/item/stack/rods(null,2)
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/manipulator
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/matter_bin
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod/update_icon()
|
||||
icon_state="controlrod_off"
|
||||
if(associated_reactor)
|
||||
var/statetouse=floor(associated_reactor.control_rod_insertion*5+0.5)
|
||||
icon_state="controlrod_[statetouse]"
|
||||
overlays=null
|
||||
if(!associated_reactor)
|
||||
return
|
||||
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTH) )
|
||||
overlays+=image(icon, src,"cr_overlay_N-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTH) )
|
||||
overlays+=image(icon, src,"cr_overlay_S-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, EAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_E-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, WEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_W-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTHEAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_NE-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTHEAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_SE-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTHWEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_NW-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTHWEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_SW-off")
|
||||
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, NORTH) )
|
||||
overlays+=image(icon, src,"cr_overlay_N")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, SOUTH) )
|
||||
overlays+=image(icon, src,"cr_overlay_S")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, EAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_E")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, WEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_W")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, NORTHEAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_NE")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, SOUTHEAST) )
|
||||
overlays+=image(icon, src,"cr_overlay_SE")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, NORTHWEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_NW")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, SOUTHWEST) )
|
||||
overlays+=image(icon, src,"cr_overlay_SW")
|
||||
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_controlrod/ex_act(var/severity, var/child=null, var/mob/whodunnit)
|
||||
switch(severity)
|
||||
if(1) //dev
|
||||
if(rand()>0.1) //90% chance to destroy
|
||||
qdel(src)
|
||||
if(2) //heavy
|
||||
if(rand()<0.25) //25% chance to destroy
|
||||
qdel(src)
|
||||
if(3) //light
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod
|
||||
icon='icons/obj/fissionreactor/fuelrod.dmi'
|
||||
desc="Monitors and stores a fuel rod for nuclear reactions."
|
||||
icon_state="fuelrod_off"
|
||||
name="fission reactor fuel rod assembly"
|
||||
var/adjacencybonus=1.0
|
||||
var/hatchopen=FALSE
|
||||
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/New()
|
||||
for(var/datum/fission_reactor_holder/r in fissionreactorlist)
|
||||
if(r.turf_in_reactor(src.loc))
|
||||
if(r.adopt_part(src))
|
||||
break
|
||||
..()
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/examine()
|
||||
..()
|
||||
if(associated_reactor)
|
||||
to_chat(usr,"The lights indicate that there are [overlays.len] adjacent fuel rod assemblies")
|
||||
if(icon_state=="fuelrod_active")
|
||||
to_chat(usr,"The center emits a blue glow.")
|
||||
|
||||
to_chat(usr,"The structure is held together firmly, it'll have to be cut in order to part it.")
|
||||
to_chat(usr,"There is a maitinance hatch at the top, it is [hatchopen?"open":"screwed shut"].")
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/update_icon()
|
||||
icon_state="fuelrod_off"
|
||||
if(associated_reactor)
|
||||
icon_state="fuelrod[associated_reactor.considered_on() ?"_active" : ""]"
|
||||
overlays=null
|
||||
if(!associated_reactor)
|
||||
return
|
||||
|
||||
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTH) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_N-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTH) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_S-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, EAST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_E-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, WEST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_W-off")
|
||||
|
||||
|
||||
|
||||
var/obj/machinery/fissionreactor/fissionreactor_fuelrod/CFR= locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, NORTH)
|
||||
if( CFR )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_N[ (CFR.adjacencybonus<=0 || adjacencybonus<=0) ? "-off" : "" ]")
|
||||
CFR= locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, SOUTH)
|
||||
if( CFR )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_S[ (CFR.adjacencybonus<=0 || adjacencybonus<=0) ? "-off" : "" ]")
|
||||
CFR= locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, EAST)
|
||||
if( CFR )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_E[ (CFR.adjacencybonus<=0 || adjacencybonus<=0) ? "-off" : "" ]")
|
||||
CFR= locate(/obj/machinery/fissionreactor/fissionreactor_fuelrod) in get_step(src, WEST)
|
||||
if( CFR )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_W[ (CFR.adjacencybonus<=0 || adjacencybonus<=0) ? "-off" : "" ]")
|
||||
|
||||
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTHEAST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_NE-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTHEAST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_SE-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, NORTHWEST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_NW-off")
|
||||
if( locate(/obj/machinery/fissionreactor/fissionreactor_controlrod) in get_step(src, SOUTHWEST) )
|
||||
overlays+=image(icon, src,"fuelrod_overlay_SW-off")
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/proc/get_reactivity()
|
||||
var/currentbonus=0.0
|
||||
var/list/lofrds=associated_reactor.fuel_rods
|
||||
for (var/obj/machinery/fissionreactor/fissionreactor_fuelrod/fuel_rod in lofrds) //probably not the most efficent way... but it works well enough
|
||||
if (fuel_rod.loc.y==src.loc.y)
|
||||
if (fuel_rod.loc.x==src.loc.x+1 || fuel_rod.loc.x==src.loc.x-1)
|
||||
currentbonus+=fuel_rod.adjacencybonus
|
||||
if (fuel_rod.loc.x==src.loc.x)
|
||||
if (fuel_rod.loc.y==src.loc.y+1 || fuel_rod.loc.y==src.loc.y-1)
|
||||
currentbonus+=fuel_rod.adjacencybonus
|
||||
return 1.0+currentbonus
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/proc/get_iscontrolled()
|
||||
var/list/lofrds=associated_reactor.control_rods
|
||||
for (var/obj/machinery/fissionreactor/fissionreactor_controlrod/control_rod in lofrds)
|
||||
if ((control_rod.loc.x-src.loc.x)**2<=1 && (control_rod.loc.y-src.loc.y)**2<=1 ) //ensure it's within 1 tile
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/attackby(var/obj/item/O,var/mob/user)
|
||||
if(iswelder(O))
|
||||
if(associated_reactor && associated_reactor.considered_on())
|
||||
if(user.a_intent==I_HELP)
|
||||
to_chat(usr,"<span class='danger'>this seems like a really bad idea.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts welding \the [src]'s external plating off its frame.</span>", "<span class='notice'>You start welding \the [src]'s external plating off its frame.</span>")
|
||||
var/obj/item/tool/weldingtool/WT = O
|
||||
if(WT.do_weld(user,src,60,0))
|
||||
var/obj/machinery/constructable_frame/machine_frame/reinforced/newframe= new /obj/machinery/constructable_frame/machine_frame/reinforced(loc)
|
||||
newframe.forceMove(loc)
|
||||
newframe.set_build_state(3)
|
||||
newframe.circuit= new /obj/item/weapon/circuitboard/fission_fuel_rod
|
||||
newframe.components=list()
|
||||
newframe.components+= new /obj/item/stack/rods(null,2)
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/scanning_module
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/matter_bin
|
||||
qdel(src)
|
||||
if(O.is_screwdriver(user))
|
||||
O.playtoolsound(src, 100)
|
||||
user.visible_message("<span class='notice'>[user] [hatchopen ? "closes" : "opens"] the maintenance hatch of the [src].</span>", "<span class='notice'>You [hatchopen ? "close" : "open"] the maintenance hatch of the [src].</span>")
|
||||
hatchopen=!hatchopen
|
||||
if(hatchopen && istype(O, /obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/mmmmmetal=O
|
||||
if(mmmmmetal.amount<4)
|
||||
to_chat(usr,"you don't have enough sheets to do this!")
|
||||
return
|
||||
mmmmmetal.use(4)
|
||||
var/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert/newfrd=new /obj/machinery/fissionreactor/fissionreactor_fuelrod/inert(src.loc)
|
||||
playsound(src,'sound/items/crowbar.ogg',50)
|
||||
newfrd.hatchopen=TRUE
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/proc/boom(var/mob/whodunnit)
|
||||
if(!associated_reactor)
|
||||
return
|
||||
if(!associated_reactor.fuel)
|
||||
return
|
||||
var/expow= sqrt(associated_reactor.fuel.wattage/100000)
|
||||
message_admins("An explosion [whodunnit? "caused by [whodunnit]" : ""] caused a fuel rod with [expow] power to explode [src.loc.name] ([formatJumpTo(src,"JMP")])")
|
||||
explosion(src.loc,floor(expow*0.5),floor(expow*0.75),floor(expow))
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/ex_act(var/severity, var/child=null, var/mob/whodunnit)
|
||||
switch(severity)
|
||||
if(1) //dev
|
||||
if(rand()>0.1) //90% chance to destroy
|
||||
boom(whodunnit)
|
||||
qdel(src)
|
||||
if(2) //heavy
|
||||
if(rand()<0.25) //25% chance to destroy
|
||||
boom(whodunnit)
|
||||
qdel(src)
|
||||
if(3) //light
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert
|
||||
adjacencybonus=0.0
|
||||
desc="Monitors and stores a fuel rod for nuclear reactions. This unit has been modified with metal plating to remove the influence of nearby fuel rods."
|
||||
icon_state="fuelrod-inert_off"
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert/examine()
|
||||
to_chat(usr,"The adjacency lights are covered up.")
|
||||
if(icon_state=="fuelrod_active")
|
||||
to_chat(usr,"The center emits a blue glow.")
|
||||
to_chat(usr,"The structure is held together firmly, it'll have to be cut in order to part it.")
|
||||
to_chat(usr,"There is a maitinance hatch at the top, it is [hatchopen?"open":"screwed shut"].")
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert/update_icon()
|
||||
..()
|
||||
icon_state="fuelrod-inert_off"
|
||||
if(associated_reactor)
|
||||
icon_state="fuelrod-inert[associated_reactor.considered_on() ? "_active" : ""]"
|
||||
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert/attackby(var/obj/item/O,var/mob/user)
|
||||
if(iswelder(O))
|
||||
if(associated_reactor && associated_reactor.considered_on())
|
||||
if(user.a_intent==I_HELP)
|
||||
to_chat(usr,"<span class='danger'>this seems like a really bad idea.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts welding \the [src]'s external plating off its frame.</span>", "<span class='notice'>You start welding \the [src]'s external plating off its frame.</span>")
|
||||
var/obj/item/tool/weldingtool/WT = O
|
||||
if(WT.do_weld(user,src,60,0))
|
||||
var/obj/machinery/constructable_frame/machine_frame/reinforced/newframe= new /obj/machinery/constructable_frame/machine_frame/reinforced(loc)
|
||||
newframe.forceMove(loc)
|
||||
newframe.set_build_state(3)
|
||||
newframe.circuit= new /obj/item/weapon/circuitboard/fission_fuel_rod
|
||||
newframe.components=list()
|
||||
newframe.components+= new /obj/item/stack/rods(null,2)
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/scanning_module
|
||||
newframe.components+=new /obj/item/weapon/stock_parts/matter_bin
|
||||
new /obj/item/stack/sheet/metal(src.loc,4)
|
||||
qdel(src)
|
||||
if(O.is_screwdriver(user))
|
||||
O.playtoolsound(src, 100)
|
||||
user.visible_message("<span class='notice'>[user] [hatchopen ? "closes" : "opens"] the maintenance hatch of the [src].</span>", "<span class='notice'>You [hatchopen ? "close" : "open"] the maintenance hatch of the [src].</span>")
|
||||
hatchopen=!hatchopen
|
||||
if(hatchopen && iscrowbar(O))
|
||||
new /obj/item/stack/sheet/metal(src.loc,4)
|
||||
var/obj/machinery/fissionreactor/fissionreactor_fuelrod/newfrd=new /obj/machinery/fissionreactor/fissionreactor_fuelrod(src.loc)
|
||||
playsound(src,'sound/items/crowbar.ogg',50)
|
||||
newfrd.hatchopen=TRUE
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/fissionreactor/fissionreactor_fuelrod/inert/get_reactivity()
|
||||
return 1.0
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/circuitboard/fission_control_rod
|
||||
name = "Circuit board (Control Rod)"
|
||||
desc = "A circuit board used in control rods for safer fission reactors."
|
||||
build_path = /obj/machinery/fissionreactor/fissionreactor_controlrod
|
||||
board_type = MACHINE_REINFORCED
|
||||
origin_tech = Tc_ENGINEERING + "=4;" + Tc_PROGRAMMING + "=2;" + Tc_POWERSTORAGE + "=3"
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/stack/rods = 2,
|
||||
)
|
||||
|
||||
/obj/item/weapon/circuitboard/fission_fuel_rod
|
||||
name = "Circuit board (Fuel Rod)"
|
||||
desc = "A circuit board used in fuel rod assemblies for heat generation in fission reactors."
|
||||
build_path = /obj/machinery/fissionreactor/fissionreactor_fuelrod
|
||||
board_type = MACHINE_REINFORCED
|
||||
origin_tech = Tc_ENGINEERING + "=4;" + Tc_PROGRAMMING + "=2;" + Tc_POWERSTORAGE + "=3"
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/scanning_module = 1,
|
||||
/obj/item/weapon/stock_parts/matter_bin = 1,
|
||||
/obj/item/stack/rods = 2,
|
||||
)
|
||||
|
||||
|
||||
BIN
code/modules/fissionreactor/uiBg.png
Normal file
|
After Width: | Height: | Size: 257 B |
@@ -65,6 +65,8 @@
|
||||
|
||||
if(environment.molar_density(GAS_PLASMA) > MOLES_PLASMA_VISIBLE / CELL_VOLUME)
|
||||
plasma_effects()
|
||||
if(environment.molar_density(GAS_RADON)*CELL_VOLUME > 0.025)
|
||||
radon_effects()
|
||||
|
||||
// Helper proc to map body temperatures to its corresponding heat/cold damage value
|
||||
/mob/living/carbon/human/proc/get_body_temperature_damage(var/temperature)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
new /datum/lung_gas/metabolizable(GAS_OXYGEN, min_pp=16, max_pp=140),
|
||||
new /datum/lung_gas/waste(GAS_CARBON, max_pp=10),
|
||||
new /datum/lung_gas/toxic(GAS_PLASMA, max_pp=0.5, max_pp_mask=5, reagent_id=PLASMA, reagent_mult=0.1),
|
||||
new /datum/lung_gas/radioactive(GAS_RADON, max_pp=0.1, max_pp_mask=5, radspermole=3),
|
||||
|
||||
new /datum/lung_gas/sleep_agent(GAS_SLEEPING, min_giggle_pp=0.15, min_para_pp=1, min_sleep_pp=5),
|
||||
)
|
||||
|
||||
@@ -134,6 +136,7 @@
|
||||
new /datum/lung_gas/toxic(OXYGEN, max_pp=0.5, max_pp_mask=0, reagent_id=OXYGEN, reagent_mult=0.1),
|
||||
new /datum/lung_gas/toxic(GAS_PLASMA, max_pp=0.5, max_pp_mask=5, reagent_id=PLASMA, reagent_mult=0.1),
|
||||
new /datum/lung_gas/sleep_agent(GAS_SLEEPING, min_giggle_pp=0.15, min_para_pp=1, min_sleep_pp=5),
|
||||
new /datum/lung_gas/radioactive(GAS_RADON, max_pp=0.1, max_pp_mask=5, radspermole=3),
|
||||
)
|
||||
|
||||
|
||||
@@ -145,6 +148,7 @@
|
||||
new /datum/lung_gas/metabolizable(GAS_PLASMA, min_pp=16, max_pp=140),
|
||||
new /datum/lung_gas/waste(GAS_CARBON, max_pp=10),
|
||||
new /datum/lung_gas/sleep_agent(GAS_SLEEPING, min_giggle_pp=0.15, min_para_pp=1, min_sleep_pp=5),
|
||||
new /datum/lung_gas/radioactive(GAS_RADON, max_pp=0.1, max_pp_mask=5, radspermole=3),
|
||||
)
|
||||
|
||||
/datum/organ/internal/lungs/insectoid
|
||||
@@ -155,5 +159,6 @@
|
||||
new /datum/lung_gas/metabolizable(OXYGEN, min_pp=16, max_pp=140),
|
||||
new /datum/lung_gas/waste(GAS_CARBON, max_pp=10),
|
||||
new /datum/lung_gas/sleep_agent(GAS_SLEEPING, min_giggle_pp=0.15, min_para_pp=1, min_sleep_pp=5),
|
||||
new /datum/lung_gas/radioactive(GAS_RADON, max_pp=0.1, max_pp_mask=5, radspermole=3),
|
||||
)
|
||||
|
||||
|
||||
@@ -195,3 +195,37 @@
|
||||
if(prob(20))
|
||||
H.emote(pick("giggle", "laugh"), ignore_status = TRUE)
|
||||
set_moles(0)
|
||||
|
||||
|
||||
|
||||
/datum/lung_gas/radioactive
|
||||
var/max_pp=0 // Maximum toxins partial pressure before you get effects. (0.5)
|
||||
var/max_pp_mask=0 // Same as above, but with a mask. (5 _MOLES_; Set to 0 to disable mask blocking.)
|
||||
var/radspermole=3
|
||||
|
||||
/datum/lung_gas/radioactive/New(var/gas_id, var/max_pp=0, var/max_pp_mask=0, var/radspermole=3)
|
||||
..(gas_id)
|
||||
src.max_pp = max_pp
|
||||
src.max_pp_mask = max_pp_mask
|
||||
src.radspermole = radspermole
|
||||
|
||||
/datum/lung_gas/radioactive/handle_inhale()
|
||||
..()
|
||||
var/pp = get_pp()
|
||||
var/mob/living/carbon/human/H=lungs.owner
|
||||
if(pp > max_pp) // Too much toxins
|
||||
var/ratio = (pp/max_pp)
|
||||
if(max_pp_mask)
|
||||
if(H.wear_mask)
|
||||
if(H.wear_mask.clothing_flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
if(pp > max_pp_mask)
|
||||
ratio = (pp/max_pp_mask)
|
||||
else
|
||||
ratio = 0
|
||||
if(ratio)
|
||||
H.apply_radiation(ratio*radspermole, RAD_INTERNAL)
|
||||
H.toxins_alert = max(H.toxins_alert, 1)
|
||||
return TRUE
|
||||
return FALSE
|
||||
else
|
||||
return FALSE
|
||||
@@ -618,10 +618,11 @@ trans_to_atmos(var/datum/gas_mixture/target, var/amount=1, var/multiplier=1, var
|
||||
total_thermal_mass = get_thermal_mass()
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/clear_reagents()
|
||||
/datum/reagents/proc/clear_reagents(var/preserve_unremovable=FALSE)
|
||||
amount_cache.len = 0
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
del_reagent(R.id,update_totals=0)
|
||||
if(!preserve_unremovable || (R.flags & CHEMFLAG_NOTREMOVABLE) )
|
||||
del_reagent(R.id,update_totals=0)
|
||||
// Only call ONCE. -- N3X
|
||||
update_total()
|
||||
if(my_atom)
|
||||
|
||||
@@ -49,6 +49,9 @@
|
||||
var/tolerance_increase = null //for tolerance, if set above 0, will increase each by that amount on tick.
|
||||
var/paint_light = PAINTLIGHT_NONE
|
||||
var/adj_temp = 0//keep between -1.5,20 to prevent people from freezing/burning themselves
|
||||
var/fission_time = null //null means it will have no effect on fuel lifetime. unit is in seconds. this is assuming a 1 rod reactor with 0% insertion (this will never happen.).
|
||||
var/fission_power= 0 //watts of power. how much ooomph does it have?
|
||||
var/fission_absorbtion=0 //watts. how much energy does this sap to facilitate its reactions?
|
||||
|
||||
//adjusts the values of hydro trays and soils by this value per process
|
||||
var/plant_nutrition = 0
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
if(L.stat != DEAD)
|
||||
e.amount *= 0.5
|
||||
e.start()
|
||||
holder.clear_reagents()
|
||||
holder.clear_reagents(TRUE)
|
||||
holder.add_reagent(POTASSIUM_HYDROXIDE, created_volume)
|
||||
|
||||
/datum/chemical_reaction/explosion_potassium/holy
|
||||
@@ -785,7 +785,7 @@
|
||||
S.start()
|
||||
sleep(10)
|
||||
S.start()
|
||||
holder.clear_reagents()
|
||||
holder.clear_reagents(TRUE)
|
||||
|
||||
/datum/chemical_reaction/chemsmoke/bleach
|
||||
name = "Bleach Fumes"
|
||||
@@ -1200,7 +1200,7 @@
|
||||
var/datum/effect/system/foam_spread/s = new()
|
||||
s.set_up(created_volume, location, holder, 0)
|
||||
s.start()
|
||||
holder.clear_reagents()
|
||||
holder.clear_reagents(TRUE)
|
||||
|
||||
/datum/chemical_reaction/metalfoam
|
||||
name = "Metal Foam"
|
||||
|
||||
32
code/modules/reagents/fission.dm
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
/datum/reagent/proc/irradiate(var/list/current_reagents=null) //called when getting products in the fission reactor. The first param is a list of the reactor's current fuel (normalized so it sums to 1). you should always account for it being able to be null.
|
||||
return list(src.id=1.0) //by default, it will do nothing (return itself). this list is what percent of things to return. that is to say, return 100% of itself.
|
||||
|
||||
|
||||
|
||||
//the variables determining power output and fuel duration are in the reagent defines.
|
||||
|
||||
/datum/reagent/uranium/irradiate(var/list/current_reagents=null) //primary purpose: general purpose. gets you a bit of everything and decent power.
|
||||
return list(LEAD=0.3, PLUTONIUM=0.2, RADIUM=0.25, THALLIUM=0.1, RADON=0.15)
|
||||
|
||||
/datum/reagent/plutonium/irradiate(var/list/current_reagents=null) //primary purpose: pure power bay bee.
|
||||
return list(LEAD=0.5, URANIUM=0.2, RADIUM=0.2, RADON=0.1)
|
||||
|
||||
/datum/reagent/radium/irradiate(var/list/current_reagents=null) //primary purpose: getting you the new materials, radon, thallium, and lead.
|
||||
return list(LEAD=0.4, RADON=0.4, THALLIUM=0.2)
|
||||
|
||||
/datum/reagent/radon/irradiate(var/list/current_reagents=null) //primary purpose: wasting radon.
|
||||
return list(LEAD=1.0)
|
||||
|
||||
/datum/reagent/plasma/irradiate(var/list/current_reagents=null) //primary purpose: a very lossy way to get phazon via plasma. powergaymers rejoice.
|
||||
return list(PHAZON=0.05) //fun fact. 1 sheet of plas = 20 units. 1 sheet of phaz = 1 unit. funny, huh?
|
||||
|
||||
/datum/reagent/degeneratecalcium/irradiate(var/list/current_reagents=null)
|
||||
return list(REGENERATECALCIUM=1.0)
|
||||
|
||||
//these give the same reagent, but in different ratios. DD is far more efficent, but to support our ghetto chem brothers, we let them get some of this, too. not as much, though.
|
||||
/datum/reagent/tricordrazine/irradiate(var/list/current_reagents=null)
|
||||
return list(EQUALIZONE=0.1)
|
||||
|
||||
/datum/reagent/drink/doctor_delight/irradiate(var/list/current_reagents=null)
|
||||
return list(EQUALIZONE=0.25)
|
||||
@@ -161,6 +161,8 @@
|
||||
specheatcap = 0.094
|
||||
flags = CHEMFLAG_PIGMENT
|
||||
paint_light = PAINTLIGHT_LIMITED
|
||||
fission_time=4500 //75 minutes. (1hr 15)
|
||||
fission_absorbtion = 3333.3 // 5:1 ratio with uranium
|
||||
|
||||
/datum/reagent/radium/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
|
||||
@@ -696,6 +696,8 @@
|
||||
glass_icon_state = "doctorsdelightglass"
|
||||
glass_name = "\improper Doctor's Delight"
|
||||
glass_desc = "A rejuvenating mixture of juices, guaranteed to keep you healthy until the next toolboxing takes place."
|
||||
fission_time=3500 // 50 minutes (0hr 50m)
|
||||
fission_absorbtion=3000
|
||||
|
||||
/datum/reagent/drink/doctor_delight/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
description = "Plasma in its liquid form."
|
||||
reagent_state = REAGENT_STATE_LIQUID
|
||||
color = "#500064" //rgb: 80, 0, 100
|
||||
fission_time=18000 //5 hours.
|
||||
fission_absorbtion=8333.333
|
||||
|
||||
/datum/reagent/plasma/New()
|
||||
..()
|
||||
@@ -141,6 +143,8 @@
|
||||
color = "#B8B8C0" //rgb: 184, 184, 192
|
||||
density = 19.05
|
||||
specheatcap = 0.124
|
||||
fission_time=9000 //2.5 hours.
|
||||
fission_power=16666.667
|
||||
|
||||
/datum/reagent/uranium/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
@@ -222,3 +226,71 @@
|
||||
if ("color" in additional_data)
|
||||
data["color"] = additional_data["color"]
|
||||
color = data["color"]
|
||||
|
||||
|
||||
|
||||
//TODO: give these an effect.
|
||||
/datum/reagent/plutonium
|
||||
name ="Plutonium"
|
||||
id = PLUTONIUM
|
||||
description = "A silvery-white metallic chemical element in the actinide series, very radioactive."
|
||||
reagent_state = REAGENT_STATE_SOLID
|
||||
color = "#CACAD2" //rgb: 202, 202, 210
|
||||
density = 19.85
|
||||
specheatcap = 0.124
|
||||
fission_time=4500 //1.25 hours.
|
||||
fission_power=66666.67 //spooky
|
||||
|
||||
/datum/reagent/plutonium/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
return 1
|
||||
M.apply_radiation(4, RAD_INTERNAL)
|
||||
|
||||
/datum/reagent/radon
|
||||
name ="Radon"
|
||||
id = RADON
|
||||
description = "A colorless, odorless, highly radioactive noble gas."
|
||||
reagent_state = REAGENT_STATE_GAS
|
||||
color = "#808080" //rgb: 128, 128, 128
|
||||
density = 9.73
|
||||
specheatcap = 0.936
|
||||
custom_metabolism = 1 //decays really fast, so it shouldn't linger long.
|
||||
fission_time=1500 //25 minutes.
|
||||
fission_power=1666.6666
|
||||
|
||||
/datum/reagent/radon/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
return 1
|
||||
M.apply_radiation(7.5, RAD_INTERNAL)
|
||||
|
||||
|
||||
/datum/reagent/lead
|
||||
name ="Lead"
|
||||
id = LEAD
|
||||
description = "A dull grey metallic element and heavy metal. Ingestion leads to brain damage"
|
||||
reagent_state = REAGENT_STATE_SOLID
|
||||
color = "#676767" //rgb: 103, 103, 103
|
||||
density = 11.34
|
||||
specheatcap = 0.129
|
||||
|
||||
/datum/reagent/lead/on_mob_life(var/mob/living/M) //less potent mercury
|
||||
if(..())
|
||||
return 1
|
||||
M.adjustBrainLoss(1)
|
||||
|
||||
|
||||
/datum/reagent/thallium
|
||||
name ="Thallium"
|
||||
id = THALLIUM
|
||||
description = "A silvery-grey metallic chemical element in the post-transition metal series. Toxic when touched, ingested, or inhaled. Very difficult to remove from the body once exposed."
|
||||
reagent_state = REAGENT_STATE_SOLID
|
||||
color = "#CACAD2" //rgb: 202, 202, 210
|
||||
density = 11.87
|
||||
custom_metabolism = 0.1
|
||||
flags = CHEMFLAG_NOTREMOVABLE
|
||||
specheatcap = 0.128
|
||||
|
||||
/datum/reagent/thallium/on_mob_life(var/mob/living/M) //the point of this is to be a nuisance. stays in you no matter what, but not really *that* deadly, just kind of annoying. You'd have to really piss someone off to get a mouthfull of this.
|
||||
if(..())
|
||||
return 1
|
||||
M.adjustToxLoss(0.5)
|
||||
|
||||
@@ -439,7 +439,7 @@ var/global/list/charcoal_doesnt_remove=list(
|
||||
|
||||
var/found_any = FALSE
|
||||
for(var/datum/reagent/reagent in holder.reagent_list)
|
||||
if(reagent.id in charcoal_doesnt_remove)
|
||||
if((reagent.flags & CHEMFLAG_NOTREMOVABLE) || (reagent.id in charcoal_doesnt_remove))
|
||||
continue
|
||||
holder.remove_reagent(reagent.id, 15*REM)
|
||||
found_any = TRUE
|
||||
@@ -632,6 +632,8 @@ var/global/list/charcoal_doesnt_remove=list(
|
||||
density = 3.9
|
||||
specheatcap = 0.12812
|
||||
custom_metabolism = 0.1
|
||||
fission_time=6000 // 100 minutes (1hr 40)
|
||||
fission_absorbtion=5000
|
||||
|
||||
/datum/reagent/degeneratecalcium/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
@@ -1682,6 +1684,8 @@ var/global/list/charcoal_doesnt_remove=list(
|
||||
color = "#C8A5DC" //rgb: 200, 165, 220
|
||||
density = 1.58
|
||||
specheatcap = 0.44
|
||||
fission_time=4800 // 80 minutes (1hr 20)
|
||||
fission_absorbtion=3500
|
||||
|
||||
/datum/reagent/tricordrazine/on_mob_life(var/mob/living/M)
|
||||
if(..())
|
||||
@@ -1760,3 +1764,87 @@ var/global/list/charcoal_doesnt_remove=list(
|
||||
color = "#899613" //rgb: 137, 150, 19
|
||||
density = 0.67
|
||||
specheatcap = 4.18
|
||||
|
||||
|
||||
/datum/reagent/regenerate_calcium
|
||||
name = "Regenerate Calcium"
|
||||
description = "Highly irradiated degenerate calcium whose structure has been altered, causing it to fuse and set bones with far more efficiency and grace than the original chemical, albeit with the cost of being extremely volatile once introduced into the body, not to mention its production process leaving it with lingering radioactivity."
|
||||
id = REGENERATECALCIUM
|
||||
density = 4.1
|
||||
specheatcap = 0.15
|
||||
custom_metabolism= 0.5 //the candle the burns twice as bright...
|
||||
reagent_state = REAGENT_STATE_LIQUID
|
||||
color = "#088c2e"
|
||||
|
||||
/datum/reagent/regenerate_calcium/on_mob_life(var/mob/living/M) //burns half as long...
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(ishuman(M))
|
||||
M.apply_radiation(0.5, RAD_INTERNAL) //it is made in a reactor, after all.
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.anatomy_flags & NO_BONES)
|
||||
return
|
||||
|
||||
var/remaininghealing=2
|
||||
for(var/datum/organ/external/E in H.organs)
|
||||
if(!E.is_organic())
|
||||
continue
|
||||
|
||||
for(var/datum/wound/W in E.wounds)
|
||||
if(W.damage_type==CUT || W.damage_type==BRUISE) //fixes limb brute damage
|
||||
remaininghealing=W.heal_damage(remaininghealing,1)
|
||||
if(!remaininghealing)
|
||||
break
|
||||
|
||||
if(E.brute_dam<=E.max_damage*0.5)
|
||||
if(E.status&ORGAN_BROKEN)
|
||||
H.custom_pain("You feel a flash of pain as the bones in your [E.display_name] rapidly set into their correct place.",50)
|
||||
playsound(H.loc, "fracture", 100, 1, -2)
|
||||
H.pain_level +=100
|
||||
E.status&= ~ORGAN_BROKEN //fixes broken limbs
|
||||
if(!remaininghealing)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/datum/reagent/equalizone
|
||||
name = "Equalizone"
|
||||
description = "An experimental drug synthesized through subjecting particular chemicals to high levels of neutron radiation. Effects while inside the system are still being studied, and are highly unpredictable. Subjects report wounds of different types appearing and disappearing at incredible rates, or falling ill after trials."
|
||||
id = EQUALIZONE
|
||||
density = 2.78
|
||||
specheatcap = 0.103
|
||||
reagent_state = REAGENT_STATE_LIQUID
|
||||
color = "#4ee7e6"
|
||||
|
||||
/datum/reagent/equalizone/on_mob_life(var/mob/living/M)
|
||||
var/efficacy=0.5 //how much this thing does what it does per tick.
|
||||
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
var/toxmod=M.tox_damage_modifier
|
||||
var/brutemod=M.brute_damage_modifier
|
||||
var/firemod=M.burn_damage_modifier
|
||||
|
||||
if(toxmod==0 || brutemod==0 || firemod==0) //no div 0 here, so sireeeeee, nope.
|
||||
return 1
|
||||
|
||||
var/brut=M.getBruteLoss()
|
||||
var/brn=M.getFireLoss()
|
||||
var/tox=M.getToxLoss()
|
||||
|
||||
var/totaldamage = brut+tox+brn
|
||||
if(totaldamage>0.0) //no need to do anything if no damage.
|
||||
totaldamage/=3.0 //average it
|
||||
|
||||
var/tox_target = tox*(1-efficacy) + efficacy*totaldamage //linear interpolation to get the damage.
|
||||
var/brute_target = brut*(1-efficacy) + efficacy*totaldamage
|
||||
var/burn_target = brn*(1-efficacy) + efficacy*totaldamage
|
||||
|
||||
|
||||
M.adjustToxLoss( 0.2*ceil( 5.0*((tox_target-tox)/toxmod) ) )
|
||||
M.adjustBruteLoss( 0.2*ceil( 5.0*( (brute_target-brut)/brutemod) ) ) //we divide by the damage modifier, because adjust_loss will multiply by it. we don't want that.
|
||||
M.adjustFireLoss( 0.2*ceil( 5.0*( (burn_target-brn)/firemod) ) ) //why are we rounding to .2? because the damage system acts funky with low fractional numbers, so we avoid that. why ceil instead of floor? fuck you, that's why.
|
||||
|
||||
M.updatehealth()
|
||||
@@ -183,4 +183,26 @@
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20)
|
||||
category = "Console Boards"
|
||||
build_path = /obj/item/weapon/circuitboard/security/engineering
|
||||
build_path = /obj/item/weapon/circuitboard/security/engineering
|
||||
|
||||
/datum/design/fission_reactor_controller
|
||||
name = "Circuit Design (Fission Reactor Controller)"
|
||||
desc = "Allows for the construction of circuit boards used to safely control a fission reactor."
|
||||
id = "fission_control"
|
||||
req_tech = list(Tc_PROGRAMMING = 4, Tc_ENGINEERING = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20)
|
||||
category = "Misc"
|
||||
build_path = /obj/item/weapon/circuitboard/fission_reactor
|
||||
|
||||
/datum/design/fission_fuel_maker
|
||||
name = "Circuit Design (Isotopic Seperational Combiner)"
|
||||
desc = "Allows for the construction of circuit boards used to seperate and combine different isotopes of materials"
|
||||
id = "fission_control"
|
||||
req_tech = list(Tc_PROGRAMMING = 4, Tc_ENGINEERING = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20)
|
||||
category = "Misc"
|
||||
build_path = /obj/item/weapon/circuitboard/fission_fuelmaker
|
||||
|
||||
|
||||
@@ -315,3 +315,30 @@
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20, MAT_GOLD = 2000)
|
||||
build_path = /obj/item/weapon/circuitboard/shield_cap
|
||||
|
||||
// fission (machine) boards.
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/design/fission_control_rod
|
||||
name = "Internal circuitry (Control rod)"
|
||||
desc = "Allows for the construction of circuit boards used to build control rods for a fission reactor"
|
||||
id = "fission_control_rod"
|
||||
req_tech = list(Tc_ENGINEERING = 4, Tc_MATERIALS = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20)
|
||||
category = "Misc"
|
||||
build_path = /obj/item/weapon/circuitboard/fission_control_rod
|
||||
|
||||
/datum/design/fission_fuel_rod
|
||||
name = "Internal circuitry (Fuel rod)"
|
||||
desc = "Allows for the construction of circuit boards used to build fuel rods for a fission reactor"
|
||||
id = "fission_fuel_rod"
|
||||
req_tech = list(Tc_ENGINEERING = 4, Tc_MATERIALS = 4)
|
||||
build_type = IMPRINTER
|
||||
materials = list(MAT_GLASS = 2000, SACID = 20)
|
||||
category = "Misc"
|
||||
build_path = /obj/item/weapon/circuitboard/fission_fuel_rod
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#define PLASMA_RELEASE_MODIFIER 1500 //Higher == less plasma released by reaction
|
||||
#define OXYGEN_RELEASE_MODIFIER 750 //Higher == less oxygen released at high temperature/power
|
||||
#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power
|
||||
#define RADON_EXCITATION_FACTOR 1 // Higher == radon creates more energy. each mole the shard absorbs adds this to a multiplier to the power generated by emitters, oxygen, and temperature. 0 moles = 1x, 1 mole = 1+[factor]x, 2 moles = 1+2*[factor]x, ect.
|
||||
|
||||
//These would be what you would get at point blank, decreases with distance
|
||||
#define DETONATION_RADS 200
|
||||
@@ -236,8 +237,9 @@
|
||||
return
|
||||
|
||||
// Let's add beam energy first.
|
||||
var/emitterpower=0
|
||||
for(var/obj/effect/beam/emitter/B in beams)
|
||||
power += B.get_damage() * config_bullet_energy
|
||||
emitterpower += B.get_damage() * config_bullet_energy
|
||||
|
||||
var/stability = stability()
|
||||
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
|
||||
@@ -296,15 +298,21 @@
|
||||
|
||||
//Ok, get the air from the turf
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
|
||||
|
||||
//Remove gas from surrounding area
|
||||
var/datum/gas_mixture/removed = env.remove_volume(gasefficency * CELL_VOLUME)
|
||||
|
||||
var/radonenergyfactor=1.0+removed[GAS_RADON]*RADON_EXCITATION_FACTOR //wowza power. prepare your butts for delams.
|
||||
|
||||
power+=emitterpower*radonenergyfactor //radon affects emitter power (as well as temp+atmos related power gen.)
|
||||
|
||||
if(!removed || !removed.total_moles)
|
||||
damage += max((power-1600)/10, 0)
|
||||
power = min(power, 1600)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
damage_archived = damage
|
||||
damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 )
|
||||
//Ok, 100% oxygen atmosphere = best reaction
|
||||
@@ -321,7 +329,7 @@
|
||||
temp_factor = 60
|
||||
icon_state = base_icon_state
|
||||
|
||||
power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload
|
||||
power = max( radonenergyfactor*((removed.temperature * temp_factor / T0C) * oxygen) + power, 0) //Total laser power plus an overload
|
||||
|
||||
//We've generated power, now let's transfer it to the collectors for storing/usage
|
||||
transfer_energy()
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
BIN
icons/obj/fissionreactor/controller.dmi
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
icons/obj/fissionreactor/controlrod.dmi
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
icons/obj/fissionreactor/corium.dmi
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
icons/obj/fissionreactor/fuelmaker.dmi
Normal file
|
After Width: | Height: | Size: 782 B |
BIN
icons/obj/fissionreactor/fuelrod.dmi
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
icons/obj/fissionreactor/items.dmi
Normal file
|
After Width: | Height: | Size: 873 B |
BIN
icons/obj/fissionreactor/reactorcase.dmi
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
BIN
sound/machines/fission/rc_alert.ogg
Normal file
BIN
sound/machines/fission/rc_fueladd.ogg
Normal file
BIN
sound/machines/fission/rc_fuelnone.ogg
Normal file
BIN
sound/machines/fission/rc_scram.ogg
Normal file
@@ -1710,6 +1710,13 @@
|
||||
#include "code\modules\fish\fish_eggs.dm"
|
||||
#include "code\modules\fish\fish_items.dm"
|
||||
#include "code\modules\fish\fish_tank.dm"
|
||||
#include "code\modules\fissionreactor\cleanup.dm"
|
||||
#include "code\modules\fissionreactor\fission_datums.dm"
|
||||
#include "code\modules\fissionreactor\fuelmaker.dm"
|
||||
#include "code\modules\fissionreactor\items.dm"
|
||||
#include "code\modules\fissionreactor\misc.dm"
|
||||
#include "code\modules\fissionreactor\objects_external.dm"
|
||||
#include "code\modules\fissionreactor\objects_internal.dm"
|
||||
#include "code\modules\flufftext\Dreaming.dm"
|
||||
#include "code\modules\flufftext\Hallucination.dm"
|
||||
#include "code\modules\flufftext\TextFilters.dm"
|
||||
@@ -2471,6 +2478,7 @@
|
||||
#include "code\modules\reagents\Chemistry-Reagents.dm"
|
||||
#include "code\modules\reagents\Chemistry-Recipes.dm"
|
||||
#include "code\modules\reagents\dartgun.dm"
|
||||
#include "code\modules\reagents\fission.dm"
|
||||
#include "code\modules\reagents\grenade_launcher.dm"
|
||||
#include "code\modules\reagents\randomized_reagent.dm"
|
||||
#include "code\modules\reagents\reagent_containers.dm"
|
||||
@@ -2940,6 +2948,7 @@
|
||||
#include "code\ZAS\Fire.dm"
|
||||
#include "code\ZAS\NewSettings.dm"
|
||||
#include "code\ZAS\Plasma.dm"
|
||||
#include "code\ZAS\Radon.dm"
|
||||
#include "code\ZAS\Turf.dm"
|
||||
#include "code\ZAS\XGM.dm"
|
||||
#include "code\ZAS\XGM_gases.dm"
|
||||
|
||||