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>
This commit is contained in:
CrazyAmphibian
2025-02-19 12:01:40 -08:00
committed by GitHub
parent 3921ed8ca2
commit 5a4f4d75e7
51 changed files with 3576 additions and 12 deletions

View File

@@ -6,3 +6,4 @@
#define GAS_CRYOTHEUM "cryotheum"
#define GAS_VOLATILE "volatile_fuel"
#define GAS_OXAGENT "oxygen_agent_b"
#define GAS_RADON "radon"

View File

@@ -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.

View File

@@ -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
View 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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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."

View File

@@ -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"

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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,
)

View File

@@ -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),
)
/* ====================================================================

View File

@@ -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'>&nbsp;&nbsp;&nbsp;</span>casing</li>
<li><span class='r_cont'>&nbsp;&nbsp;&nbsp;</span>controller</li>
<li><span class='r_port'>&nbsp;&nbsp;&nbsp;</span>coolant port</li>
<li><span class='r_frod'>&nbsp;&nbsp;&nbsp;</span>fuel rod</li>
<li><span class='r_crod'>&nbsp;&nbsp;&nbsp;</span>control rod</li>
</ul>
</div>
<br>
<table class='reactor_schematic'>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_cont'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</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'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_cont'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</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'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_crod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_frod'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
</tr>
<tr>
<td class='r_cont'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_port'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</td>
<td class='r_case'>&nbsp;&nbsp;</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>"}

View 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)

View 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;
}

View 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

View 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]:&nbsp;[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 ]:&nbsp;[prods[i]]&nbsp;units&emsp;"
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:&nbsp;</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,
)

View 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"]"

View 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

File diff suppressed because it is too large Load Diff

View 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,
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

View File

@@ -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)

View File

@@ -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),
)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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"

View 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)

View File

@@ -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(..())

View File

@@ -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(..())

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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"