files for alpha version of rust fusion reactor.

rust integrated into antiqua, no breakroom.
lots of fusion bugs, missing features and imbas but it works.

Signed-off-by: CaelAislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
CaelAislinn
2012-04-19 01:20:35 +10:00
parent d10fd2568c
commit 2a82b40740
30 changed files with 4151 additions and 2231 deletions

View File

@@ -157,7 +157,10 @@
#define FILE_DIR "code/WorkInProgress" #define FILE_DIR "code/WorkInProgress"
#define FILE_DIR "code/WorkInProgress/Apples" #define FILE_DIR "code/WorkInProgress/Apples"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Jumper"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Rust"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara" #define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Tajara"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/tajara_sprites"
#define FILE_DIR "code/WorkInProgress/Chinsky" #define FILE_DIR "code/WorkInProgress/Chinsky"
#define FILE_DIR "code/WorkInProgress/mapload" #define FILE_DIR "code/WorkInProgress/mapload"
#define FILE_DIR "code/WorkInProgress/Mini" #define FILE_DIR "code/WorkInProgress/Mini"
@@ -238,6 +241,7 @@
#include "code\ATMOSPHERICS\components\unary\heat_source.dm" #include "code\ATMOSPHERICS\components\unary\heat_source.dm"
#include "code\ATMOSPHERICS\components\unary\outlet_injector.dm" #include "code\ATMOSPHERICS\components\unary\outlet_injector.dm"
#include "code\ATMOSPHERICS\components\unary\oxygen_generator.dm" #include "code\ATMOSPHERICS\components\unary\oxygen_generator.dm"
#include "code\ATMOSPHERICS\components\unary\thermal_plate.dm"
#include "code\ATMOSPHERICS\components\unary\unary_base.dm" #include "code\ATMOSPHERICS\components\unary\unary_base.dm"
#include "code\ATMOSPHERICS\components\unary\vent_pump.dm" #include "code\ATMOSPHERICS\components\unary\vent_pump.dm"
#include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm" #include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm"
@@ -1093,6 +1097,18 @@
#include "code\WorkInProgress\AI_Visibility.dm" #include "code\WorkInProgress\AI_Visibility.dm"
#include "code\WorkInProgress\buildmode.dm" #include "code\WorkInProgress\buildmode.dm"
#include "code\WorkInProgress\explosion_particles.dm" #include "code\WorkInProgress\explosion_particles.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_field.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\core_monitor.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_assembly_port.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_compressor.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_control.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\fuel_injector.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\gyrotron_controller.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\radiation.dm"
#include "code\WorkInProgress\Cael_Aislinn\Rust\virtual_particle_catcher.dm"
#include "code\WorkInProgress\Cael_Aislinn\Tajara\say.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\say.dm"
#include "code\WorkInProgress\Cael_Aislinn\Tajara\tajara_transformation.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\tajara_transformation.dm"
#include "code\WorkInProgress\Cael_Aislinn\Tajara\tajaran.dm" #include "code\WorkInProgress\Cael_Aislinn\Tajara\tajaran.dm"
@@ -1135,5 +1151,5 @@
#include "code\WorkInProgress\virus2\Prob.dm" #include "code\WorkInProgress\virus2\Prob.dm"
#include "code\WorkInProgress\Wrongnumber\weldbackpack.dm" #include "code\WorkInProgress\Wrongnumber\weldbackpack.dm"
#include "interface\skin.dmf" #include "interface\skin.dmf"
#include "maps\tgstation.2.0.8.dmm" #include "maps\Antiqua.dmm"
// END_INCLUDE // END_INCLUDE

View File

@@ -0,0 +1,81 @@
#define RADIATION_CAPACITY 30000 //Radiation isn't particularly effective (TODO BALANCE)
/obj/machinery/atmospherics/unary/thermal_plate
//Based off Heat Reservoir and Space Heater
//Transfers heat between a pipe system and environment, based on which has a greater thermal energy concentration
icon = 'cold_sink.dmi'
icon_state = "intact_off"
name = "Thermal Transfer Plate"
desc = "Transfers heat to and from an area"
update_icon()
if(node)
icon_state = "intact_off"
else
icon_state = "exposed"
return
process()
..()
var/datum/gas_mixture/environment = loc.return_air()
//Get processable air sample and thermal info from environment
var/transfer_moles = 0.25 * environment.total_moles()
var/datum/gas_mixture/external_removed = environment.remove(transfer_moles)
if (!external_removed)
return radiate()
if (external_removed.total_moles() < 10)
return radiate()
//Get same info from connected gas
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
if (!internal_removed)
environment.merge(external_removed)
return 1
var/combined_heat_capacity = internal_removed.heat_capacity() + external_removed.heat_capacity()
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + external_removed.heat_capacity() * external_removed.temperature
if(!combined_heat_capacity) combined_heat_capacity = 1
var/final_temperature = combined_energy / combined_heat_capacity
external_removed.temperature = final_temperature
environment.merge(external_removed)
internal_removed.temperature = final_temperature
air_contents.merge(internal_removed)
network.update = 1
return 1
proc/radiate()
var/internal_transfer_moles = 0.25 * air_contents.total_moles()
var/datum/gas_mixture/internal_removed = air_contents.remove(internal_transfer_moles)
if (!internal_removed)
return 1
var/combined_heat_capacity = internal_removed.heat_capacity() + RADIATION_CAPACITY
var/combined_energy = internal_removed.temperature * internal_removed.heat_capacity() + (RADIATION_CAPACITY * 6.4)
var/final_temperature = combined_energy / combined_heat_capacity
internal_removed.temperature = final_temperature
air_contents.merge(internal_removed)
if (network)
network.update = 1
return 1

View File

@@ -0,0 +1,112 @@
//the core [tokamaka generator] big funky solenoid, it generates an EM field
/*
when the core is turned on, it generates [creates] an electromagnetic field
the em field attracts plasma, and suspends it in a controlled torus (doughnut) shape, oscillating around the core
the field strength is directly controllable by the user
field strength = sqrt(energy used by the field generator)
the size of the EM field = field strength / k
(k is an arbitrary constant to make the calculated size into tilewidths)
1 tilewidth = below 5T
3 tilewidth = between 5T and 12T
5 tilewidth = between 10T and 25T
7 tilewidth = between 20T and 50T
(can't go higher than 40T)
energy is added by a gyrotron, and lost when plasma escapes
energy transferred from the gyrotron beams is reduced by how different the frequencies are (closer frequencies = more energy transferred)
frequency = field strength * (stored energy / stored moles of plasma) * x
(where x is an arbitrary constant to make the frequency something realistic)
the gyrotron beams' frequency and energy are hardcapped low enough that they won't heat the plasma much
energy is generated in considerable amounts by fusion reactions from injected particles
fusion reactions only occur when the existing energy is above a certain level, and it's near the max operating level of the gyrotron. higher energy reactions only occur at higher energy levels
a small amount of energy constantly bleeds off in the form of radiation
the field is constantly pulling in plasma from the surrounding [local] atmosphere
at random intervals, the field releases a random percentage of stored plasma in addition to a percentage of energy as intense radiation
the amount of plasma is a percentage of the field strength, increased by frequency
*/
/*
- VALUES -
max volume of plasma storeable by the field = the total volume of a number of tiles equal to the (field tilewidth)^2
*/
/obj/machinery/rust/core
name = "Tokamak core"
desc = "Enormous solenoid for generating extremely high power electromagnetic fields"
icon = 'core.dmi'
icon_state = "off"
anchored = 1
var/on = 0
var/obj/machinery/rust/em_field/owned_field
var/field_strength = 0.01
Topic(href, href_list)
..()
if( href_list["startup"] )
Startup()
return
if( href_list["shutdown"] )
Shutdown()
return
if( href_list["modify_field_strength"] )
var/new_field_str = text2num(input("Enter new field strength", "Modifying field strength", owned_field.field_strength))
if(!new_field_str)
usr << "\red That's not a valid number."
return
field_strength = max(new_field_str,0.1)
field_strength = min(new_field_str,50)
if(owned_field)
owned_field.ChangeFieldStrength(field_strength)
return
proc/Startup()
if(owned_field)
return
on = 1
owned_field = new(src.loc)
if(owned_field)
owned_field.ChangeFieldStrength(field_strength)
icon_state = "on"
return 1
proc/Shutdown()
icon_state = "off"
on = 0
del(owned_field)
proc/AddParticles(var/name, var/quantity = 1)
if(owned_field)
owned_field.AddParticles(name, quantity)
return 1
return 0
proc/AddEnergy(var/energy, var/mega_energy)
if(owned_field)
owned_field.energy += energy
owned_field.mega_energy += mega_energy
return 1
return 0
process()
..()
if(on && !owned_field)
Shutdown()
return
//
if(stat & (NOPOWER|BROKEN))
Shutdown()
bullet_act(var/obj/item/projectile/Proj)
if(Proj.flag != "bullet" && owned_field)
AddEnergy(0, Proj.damage / 600)
return 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,651 @@
//the em field is where the fun happens
/*
Deuterium-deuterium fusion : 40 x 10^7 K
Deuterium-tritium fusion: 4.5 x 10^7 K
*/
//#DEFINE MAX_STORED_ENERGY (held_plasma.toxins * held_plasma.toxins * SPECIFIC_HEAT_TOXIN)
/obj/machinery/rust/em_field
name = "EM Field"
desc = "A coruscating, barely visible field of energy. It is shaped like a slightly flattened torus."
icon = 'emfield.dmi'
icon_state = "emfield_s1"
density = 0
layer = 3.1
anchored = 1
//
var/major_radius = 0 //longer radius in meters = field_strength * 0.21875, max = 8.75
var/minor_radius = 0 //shorter radius in meters = field_strength * 0.2125, max = 8.625
var/size = 1 //diameter in tiles
var/volume_covered = 0 //atmospheric volume covered
//
var/obj/machinery/rust/core/owned_core
var/list/dormant_reactant_quantities = new
//
var/energy = 0
var/mega_energy = 0
var/radiation = 0
var/frequency = 0
var/field_strength = 0.01 //in teslas, max is 50T
var/obj/machinery/rust/rad_source/radiator
var/datum/gas_mixture/held_plasma = new
var/particle_catchers[13]
New()
..()
//create radiator
for(var/obj/machinery/rust/rad_source/rad in range(0))
radiator = rad
if(!radiator)
radiator = new()
//make sure there's a field generator
for(var/obj/machinery/rust/core/em_core in loc)
owned_core = em_core
if(!owned_core)
del(src)
if(!owned_core.on)
del(src)
//create the gimmicky things to handle field collisions
var/obj/machinery/rust/particle_catcher/catcher
//
catcher = new (locate(src.x,src.y,src.z))
catcher.parent = src
catcher.SetSize(1)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-1,src.y,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+1,src.y,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+1,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-1,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-2,src.y,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+2,src.y,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+2,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-2,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-3,src.y,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+3,src.y,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+3,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-3,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
//init values
major_radius = field_strength * 0.21875// max = 8.75
minor_radius = field_strength * 0.2125// max = 8.625
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 1000
process()
..()
//make sure the field generator is still intact
if(!owned_core)
del(src)
if(!owned_core.on)
del(src)
//handle radiation
if(!radiator)
radiator = new /obj/machinery/rust/rad_source()
radiator.mega_energy += radiation
radiator.source_alive++
radiation = 0
//update values
var/transfer_ratio = 50 / field_strength
major_radius = field_strength * 0.21875// max = 8.75
minor_radius = field_strength * 0.2125// max = 8.625
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 2.5 * 7 * 7 * transfer_ratio
//add plasma from the surrounding environment
var/datum/gas_mixture/environment = loc.return_air()
//we're going to hack in some stuff to remove plasma from the air because QUANTUM PHYSICS
//the amount of plasma pulled in each update is relative to the field strength, with 50T (max field strength) = 100% of area covered by the field
//at minimum strength, 0.25% of the field volume is pulled in per update (?)
//have a max of 1000 moles suspended
if(held_plasma.toxins < transfer_ratio * 1000)
var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION)
//
var/datum/gas_mixture/gas_covered = environment.remove(moles_covered)
var/datum/gas_mixture/plasma_captured = new
//
plasma_captured.toxins = gas_covered.toxins * transfer_ratio
plasma_captured.temperature = gas_covered.temperature
held_plasma.merge(plasma_captured)
//
gas_covered.toxins -= gas_covered.toxins * transfer_ratio
environment.merge(gas_covered)
//let the particles inside the field react
React()
//forcibly radiate any excess energy
var/energy_max = transfer_ratio * 100000
if(mega_energy > energy_max)
var/energy_lost = rand( 1.5 * (mega_energy - energy_max), 2.5 * (mega_energy - energy_max) )
mega_energy -= energy_lost
radiation += energy_lost
//change held plasma temp according to energy levels
//SPECIFIC_HEAT_TOXIN
if(mega_energy > 0)
var/heat_capacity = held_plasma.heat_capacity()//200 * number of plasma moles
if(heat_capacity > MINIMUM_HEAT_CAPACITY)
held_plasma.temperature = (heat_capacity + mega_energy * 10000)/heat_capacity
//if there is too much plasma in the field, lose some
/*if( held_plasma.toxins > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) )
LosePlasma()*/
LosePlasma()
//handle some reactants formatting
//helium-4 has no use at the moment, but a buttload of it is produced
if(dormant_reactant_quantities["Helium-4"] > 1000)
dormant_reactant_quantities["Helium-4"] = rand(0,dormant_reactant_quantities["Helium-4"])
for(var/reactant in dormant_reactant_quantities)
if(!dormant_reactant_quantities[reactant])
dormant_reactant_quantities.Remove(reactant)
return 1
Del()
..()
//radiate everything in one giant burst
for(var/obj/machinery/rust/particle_catcher/catcher in particle_catchers)
del (catcher)
RadiateAll()
proc/ChangeFieldStrength(var/new_strength)
field_strength = new_strength
var/newsize
if(new_strength <= 5)
newsize = 1
else if(new_strength <= 12)
newsize = 3
else if(new_strength <= 25)
newsize = 5
else if(new_strength <= 50)
newsize = 7
//
change_size(newsize)
proc/AddParticles(var/name, var/quantity = 1)
//world << "adding [quantity] [name]"
if(name in dormant_reactant_quantities)
dormant_reactant_quantities[name] += quantity
else if(name != "proton" && name != "electron")
dormant_reactant_quantities.Add(name)
dormant_reactant_quantities[name] = quantity
proc/RadiateAll(var/ratio_lost = 1)
for(var/particle in dormant_reactant_quantities)
radiation += dormant_reactant_quantities[particle]
dormant_reactant_quantities.Remove(particle)
radiation += mega_energy
mega_energy = 0
//lose all held plasma back into the air
var/datum/gas_mixture/environment = loc.return_air()
environment.merge(held_plasma)
proc/change_size(var/newsize = 1)
//
var/changed = 0
switch(newsize)
if(1)
size = 1
icon = 'emfield.dmi'
icon_state = "emfield_s1"
//
src.loc = get_turf(owned_core)
//
changed = 1
if(3)
size = 3
icon = '96x96.dmi'
icon_state = "emfield_s3"
//
var/turf/newloc = get_turf(owned_core)
newloc = get_step(newloc, SOUTHWEST)
src.loc = newloc
//
changed = 3
if(5)
size = 5
icon = '160x160.dmi'
icon_state = "emfield_s5"
//
var/turf/newloc = get_turf(owned_core)
newloc = get_step(newloc, SOUTHWEST)
newloc = get_step(newloc, SOUTHWEST)
src.loc = newloc
//
changed = 5
if(7)
size = 7
icon = '224x224.dmi'
icon_state = "emfield_s7"
//
var/turf/newloc = get_turf(owned_core)
newloc = get_step(newloc, SOUTHWEST)
newloc = get_step(newloc, SOUTHWEST)
newloc = get_step(newloc, SOUTHWEST)
src.loc = newloc
//
changed = 7
for(var/obj/machinery/rust/particle_catcher/catcher in particle_catchers)
catcher.UpdateSize()
return changed
proc/LosePlasma()
if(held_plasma.toxins > 1)
//lose a random amount of plasma back into the air, increased by the field strength (want to switch this over to frequency eventually)
var/datum/gas_mixture/environment = loc.return_air()
var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength))
//world << "lost [loss_ratio*100]% of held plasma"
//
var/datum/gas_mixture/plasma_lost = new
plasma_lost.temperature = held_plasma.temperature
//
plasma_lost.toxins = held_plasma.toxins * loss_ratio
held_plasma.toxins -= held_plasma.toxins * loss_ratio
//
environment.merge(plasma_lost)
radiation += loss_ratio * mega_energy * 0.1
mega_energy -= loss_ratio * mega_energy * 0.1
return 1
else
held_plasma.toxins = 0
return 0
//the !!fun!! part
//reactions have to be individually hardcoded, see AttemptReaction() below this
proc/React()
//world << "React()"
//loop through the reactants in random order
var/list/reactants_reacting_pool = dormant_reactant_quantities.Copy()
/*
for(var/reagent in dormant_reactant_quantities)
world << " before: [reagent]: [dormant_reactant_quantities[reagent]]"
*/
//cant have any reactions if there aren't any reactants present
if(reactants_reacting_pool.len)
//determine a random amount to actually react this cycle, and remove it from the standard pool
//this is a hack, and quite nonrealistic :(
for(var/reactant in reactants_reacting_pool)
reactants_reacting_pool[reactant] = rand(0,reactants_reacting_pool[reactant])
dormant_reactant_quantities[reactant] -= reactants_reacting_pool[reactant]
if(!reactants_reacting_pool[reactant])
reactants_reacting_pool -= reactant
var/list/produced_reactants = new/list
//loop through all the reacting reagents, picking out random reactions for them
var/list/primary_reactant_pool = reactants_reacting_pool.Copy()
while(primary_reactant_pool.len)
//pick one of the unprocessed reacting reagents randomly
var/cur_primary_reactant = pick(primary_reactant_pool)
primary_reactant_pool.Remove(cur_primary_reactant)
//world << "\blue primary reactant chosen: [cur_primary_reactant]"
//grab all the possible reactants to have a reaction with
var/list/possible_secondary_reactants = reactants_reacting_pool.Copy()
//if there is only one of a particular reactant, then it can not react with itself so remove it
possible_secondary_reactants[cur_primary_reactant] -= 1
if(possible_secondary_reactants[cur_primary_reactant] < 1)
possible_secondary_reactants.Remove(cur_primary_reactant)
var/list/possible_reactions = new/list
//loop through and work out all the possible reactions
while(possible_secondary_reactants.len)
var/cur_secondary_reactant = pick(possible_secondary_reactants)
if(possible_secondary_reactants[cur_secondary_reactant] < 1)
possible_secondary_reactants.Remove(cur_secondary_reactant)
continue
possible_secondary_reactants.Remove(cur_secondary_reactant)
var/list/reaction_products = AttemptReaction(cur_primary_reactant, cur_secondary_reactant)
if(reaction_products.len)
//world << "\blue secondary reactant: [cur_secondary_reactant], [reaction_products.len]"
possible_reactions[cur_secondary_reactant] = reaction_products
//if there are no possible reactions here, abandon this primary reactant and move on
if(!possible_reactions.len)
//world << "\blue no reactions"
continue
//split up the reacting atoms between the possible reactions
//the problem is in this while statement below
while(possible_reactions.len)
//pick another substance to react with
var/cur_secondary_reactant = pick(possible_reactions)
if(!reactants_reacting_pool[cur_secondary_reactant])
possible_reactions.Remove(cur_secondary_reactant)
continue
var/list/cur_reaction_products = possible_reactions[cur_secondary_reactant]
//set the randmax to be the lower of the two involved reactants
var/max_num_reactants = reactants_reacting_pool[cur_primary_reactant] > reactants_reacting_pool[cur_secondary_reactant] ? reactants_reacting_pool[cur_secondary_reactant] : reactants_reacting_pool[cur_primary_reactant]
//make sure we have enough energy
if( mega_energy < max_num_reactants*cur_reaction_products["consumption"])
max_num_reactants = round(mega_energy / cur_reaction_products["consumption"])
//randomly determined amount to react
var/amount_reacting = rand(1, max_num_reactants)
//removing the reacting substances from the list of substances that are primed to react this cycle
//if there aren't enough of that substance (there should be) then modify the reactant amounts accordingly
if( reactants_reacting_pool[cur_primary_reactant] - amount_reacting > -1 )
reactants_reacting_pool[cur_primary_reactant] -= amount_reacting
else
amount_reacting = reactants_reacting_pool[cur_primary_reactant]
reactants_reacting_pool[cur_primary_reactant] = 0
//
if( reactants_reacting_pool[cur_secondary_reactant] - amount_reacting > -1 )
reactants_reacting_pool[cur_secondary_reactant] -= amount_reacting
else
reactants_reacting_pool[cur_primary_reactant] += amount_reacting - reactants_reacting_pool[cur_primary_reactant]
amount_reacting = reactants_reacting_pool[cur_secondary_reactant]
reactants_reacting_pool[cur_secondary_reactant] = 0
//remove the consumed energy
if(cur_reaction_products["consumption"])
mega_energy -= max_num_reactants * cur_reaction_products["consumption"]
cur_reaction_products.Remove("consumption")
//grab any radiation and put it separate
//var/new_radiation = 0
if("production" in cur_reaction_products)
mega_energy += max_num_reactants * cur_reaction_products["production"]
cur_reaction_products.Remove("production")
/*for(var/i=0, i<dormant_reactant_quantities["proton_quantity"], i++)
radiation.Add("proton")
radiation_charge.Add(dormant_reactant_quantities["proton_charge"])
dormant_reactant_quantities.Remove("proton_quantity")
dormant_reactant_quantities.Remove("proton_charge")
new_radiation = 1*/
//
if("radiation" in cur_reaction_products)
radiation += max_num_reactants * cur_reaction_products["radiation"]
cur_reaction_products.Remove("radiation")
/*for(var/i=0, i<dormant_reactant_quantities["neutron_quantity"], i++)
radiation.Add("neutron")
radiation_charge.Add(dormant_reactant_quantities["neutron_charge"])
dormant_reactant_quantities.Remove("neutron_quantity")
dormant_reactant_quantities.Remove("neutron_charge")
new_radiation = 1*/
//create the reaction products
for(var/reactant in cur_reaction_products)
if(produced_reactants[reactant])
produced_reactants[reactant] += cur_reaction_products[reactant] * amount_reacting
else
produced_reactants[reactant] = cur_reaction_products[reactant] * amount_reacting
//this reaction is done, and can't be repeated this sub-cycle
possible_reactions.Remove(cur_secondary_reactant)
//
/*if(new_radiation)
if(!radiating)
radiating = 1
PeriodicRadiate()*/
//loop through the newly produced reactants and add them to the pool
//var/list/neutronic_radiation = new
//var/list/protonic_radiation = new
for(var/reactant in produced_reactants)
AddParticles(reactant, dormant_reactant_quantities[reactant])
//world << "produced: [reactant], [dormant_reactant_quantities[reactant]]"
//check whether there are reactants left, and add them back to the pool
for(var/reactant in reactants_reacting_pool)
AddParticles(reactant, reactants_reacting_pool[reactant])
//world << "retained: [reactant], [reactants_reacting_pool[reactant]]"
//default fuel assembly quantities
/*
//new_assembly_quantities["Helium-3"] = 0
//new_assembly_quantities["Deuterium"] = 200
//new_assembly_quantities["Tritium"] = 100
//new_assembly_quantities["Lithium-6"] = 0
//new_assembly_quantities["Silver"] = 0
*/
//reactions involving D-T (hydrogen) need 0.1 MeV of core energy
//reactions involving helium require 0.4 MeV of energy
//reactions involving lithium require 0.6 MeV of energy
//reactions involving boron require 1 MeV of energy
//returns a list of products, or an empty list if no reaction possible
proc/AttemptReaction(var/reactant_one, var/reactant_two)
//any charge on the atomic reactants / protons produced is abstracted away to enter the core energy pool straightaway
//atomic products remain in the core and produce more reactions next cycle
//any charged neutrons escape as radiation
var/check = 1
recheck_reactions:
var/list/products = new/list
switch(reactant_one)
if("Tritium")
switch(reactant_two)
if("Tritium")
if(mega_energy > 0.1)
products["Helium-4"] = 1
//
products["production"] = 11.3
products["radiation"] = 1
/*products["photon"] = 11.3
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 0*/
//
mega_energy -= 0.1
if("Deuterium")
if(mega_energy > 0.1)
products["Helium-4"] = 1
//
products["production"] = 3.5
products["radiation"] = 14.1
/*products["photon"] = 3.5
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 14.1
//
products["consumption"] = 0.1*/
if("Helium-3")
if(mega_energy > 0.4)
if(prob(51))
products["Helium-4"] = 1
//
products["production"] = 13.1
products["radiation"] = 1
/*products["photon"] = 12.1
//
products["proton_quantity"] = 1
products["proton_charge"] = 0
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 0*/
else if (prob(43))
products["Helium-4"] = 1
products["Deuterium"] = 1
//
products["production"] = 14.3
/*products["photon"] = 4.8 + 9.5//14.3
*/
else
products["Helium-4"] = 1
products["production"] = 2.4
products["radiation"] = 11.9
/*products["photon"] = 0.5//12.4
//
products["proton_quantity"] = 1
products["proton_charge"] = 1.9
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 11.9*/
//
products["consumption"] = 0.4
if("Deuterium")
switch(reactant_two)
if("Deuterium")
if(mega_energy > 0.1)
if(prob(50))
products["Tritium"] = 1
//
products["production"] = 4.03
/*products["photon"] = 1.01
//
products["proton_quantity"] = 1
products["proton_charge"] = 3.02*/
else
products["Helium-3"] = 1
//
products["production"] = 0.82
products["radiation"] = 2.45
/*products["photon"] = 0.82
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 2.45*/
//
products["consumption"] = 0.1
if("Helium-3")
if(mega_energy > 0.4)
products["Helium-4"] = 1
//
products["production"] = 18.3
/*products["photon"] = 3.6
//
products["proton_quantity"] = 1
products["proton_charge"] = 14.7*/
//
products["consumption"] = 0.4
if("Lithium-6")
if(mega_energy > 0.6)
if(prob(25))
products["Helium-4"] = 2
products["production"] = 1
/*products["photon"] = 22.4*/
else if(prob(33))
products["Helium-3"] = 1
products["Helium-4"] = 1
//
products["radiation"] = 1
/*products["neutron_quantity"] = 1
products["neutron_charge"] = 0*/
else if(prob(50))
products["Lithium-7"] = 1
//
products["production"] = 1
/*products["proton_quantity"] = 1
products["proton_charge"] = 0*/
else
products["Beryllium-7"] = 1
products["production"] = 3.4
products["radiation"] = 1
/*products["photon"] = 3.4
//
products["neutron_quantity"] = 1
products["neutron_charge"] = 0*/
//
products["consumption"] = 0.6
if("Helium-3")
switch(reactant_two)
if("Helium-3")
if(mega_energy > 0.4)
products["Helium-4"] = 1
products["production"] = 14.9
/*products["photon"] = 12.9
//
products["proton_quantity"] = 2
products["proton_charge"] = 0*/
//
products["consumption"] = 0.4
if("Lithium-6")
if(mega_energy > 0.6)
products["Helium-4"] = 2
//
products["production"] = 17.9
/*products["photon"] = 16.9
//
products["proton_quantity"] = 1
products["proton_charge"] = 0*/
//
products["consumption"] = 0.6
/*
if("proton")
switch(reactant_two)
if("Lithium-6")
if(mega_energy > 0.6)
products["Helium-4"] = 1
products["Helium-3"] = 1
products["photon"] = 4
//
mega_energy -= 0.6
if("Boron-11")
if(mega_energy > 1)
products["Helium-4"] = 3
products["photon"] = 8.7
//
mega_energy -= 1
*/
//if no reaction happened, switch the two reactants and try again
if(!products.len && check)
check = 0
var/temp = reactant_one
reactant_one = reactant_two
reactant_two = temp
goto recheck_reactions
/*if(products.len)
world << "\blue [reactant_one] + [reactant_two] reaction occured"
for(var/reagent in products)
world << "\blue [reagent]: [products[reagent]]"*/
/*if(products["neutron"])
products -= "neutron"
if(products["proton"])
products -= "proton"
if(products["photon"])
products -= "photon"
if(products["radiated charge"])
products -= "radiated charge"*/
return products

View File

@@ -0,0 +1,78 @@
/obj/machinery/computer/rust/radiation_monitor
name = "Core Radiation Monitor"
/obj/machinery/computer/rust/energy_monitor
name = "Core Primary Monitor"
icon_state = "power"
var/obj/machinery/rust/core/core_generator = null
New()
spawn(0)
core_generator = locate() in range(15,src)
attack_ai(mob/user)
attack_hand(user)
attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
interact(user)
Topic(href, href_list)
..()
if( href_list["shutdown"] )
core_generator.Topic(href, href_list)
updateDialog()
return
if( href_list["startup"] )
core_generator.Topic(href, href_list)
updateDialog()
return
if( href_list["modify_field_strength"] )
core_generator.Topic(href, href_list)
updateDialog()
return
if( href_list["close"] )
usr << browse(null, "window=core_monitor")
usr.machine = null
return
process()
..()
updateDialog()
proc
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=core_monitor")
return
var/t = "<B>Reactor Core Primary Monitor</B><BR>"
if(core_generator)
t += "<font color=blue>[core_generator.on ? "Core Generator connected" : "Core Generator operational"]</font><br>"
if(core_generator.owned_field)
t += "<font color=green>Core suspension field online</font> <a href='?src=\ref[src];shutdown=1'>\[Bring field offline\]</a><br>"
t += "Electromagnetic plasma suspension field status:<br>"
t += " <font color=blue>Strength (T): [core_generator.owned_field.field_strength]</font> <a href='?src=\ref[src];modify_field_strength=1'>\[Modify\]</a><br>"
t += " <font color=blue>Energy levels (MeV): [core_generator.owned_field.mega_energy]</font><br>"
t += " <font color=blue>Core frequency: [core_generator.owned_field.frequency]</font><br>"
t += " <font color=blue>Moles of plasma: [core_generator.owned_field.held_plasma.toxins]</font><br>"
t += " <font color=blue>Plasma temperature: [core_generator.owned_field.held_plasma.temperature]</font><br>"
t += "<hr>"
t += "<b>Core atomic and subatomic constituents:</font></b><br>"
if(core_generator.owned_field.dormant_reactant_quantities && core_generator.owned_field.dormant_reactant_quantities.len)
for(var/reagent in core_generator.owned_field.dormant_reactant_quantities)
t += " <font color=green>[reagent]:</font> [core_generator.owned_field.dormant_reactant_quantities[reagent]]<br>"
else
t += " <font color=blue>No reactants present.</font><br>"
else
t += "<font color=red>Core suspension field offline</font> <a href='?src=\ref[src];startup=1'>\[Bring field online\]</a><br>"
else
t += "<b><font color=red>Core Generator unresponsive</font></b><br>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=core_monitor;size=500x800")
user.machine = src

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,16 @@
/obj/item/weapon/fuel_assembly
icon = 'fuel_assembly.dmi'
icon_state = "fuel_assembly"
name = "Fuel Rod Assembly"
var/list/rod_quantities
var/amount_depleted = 0 //percent depleted
//
New()
rod_quantities = new/list
//these can be abstracted away for now
/*
/obj/item/weapon/fuel_rod
/obj/item/weapon/control_rod
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

View File

@@ -0,0 +1,22 @@
/obj/machinery/rust/fuel_assembly_port
name = "Fuel Assembly Port"
icon = 'fuel_assembly_port.dmi'
icon_state = "port"
density = 0
var/stage
var/obj/item/weapon/fuel_assembly/cur_assembly = null
layer = 4
attackby(var/obj/item/I, var/mob/user)
if(istype(I,/obj/item/weapon/fuel_assembly))
if(cur_assembly)
del cur_assembly
cur_assembly = I
user.drop_item()
I.loc = src
New()
//embed the fuel port into a wall
pixel_x = (dir & 3)? 0 : (dir == 4 ? 24 : -24)
pixel_y = (dir & 3)? (dir ==1 ? 24 : -24) : 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

View File

@@ -0,0 +1,88 @@
var/const/max_assembly_amount = 300
/obj/machinery/rust/fuel_compressor
icon = 'fuel_compressor.dmi'
icon_state = "fuel_compressor"
name = "Fuel Compressor"
var/list/new_assembly_quantities
//
New()
new_assembly_quantities = new/list
spawn(0)
new_assembly_quantities["Deuterium"] = 200
new_assembly_quantities["Tritium"] = 100
//
new_assembly_quantities["Helium-3"] = 0
new_assembly_quantities["Lithium-6"] = 0
new_assembly_quantities["Silver"] = 0
attack_ai(mob/user)
attack_hand(user)
attack_hand(mob/user)
add_fingerprint(user)
/*if(stat & (BROKEN|NOPOWER))
return*/
interact(user)
/*power_change()
if(stat & BROKEN)
icon_state = "broken"
else
if( powered() )
icon_state = initial(icon_state)
stat &= ~NOPOWER
else
spawn(rand(0, 15))
src.icon_state = "c_unpowered"
stat |= NOPOWER*/
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=fuelcomp")
usr.machine = null
return
//
for(var/reagent in new_assembly_quantities)
if(href_list[reagent])
var/new_amount = text2num(input("Enter new rod amount", "Fuel Assembly Rod Composition ([reagent])", new_assembly_quantities[reagent]) as text|null)
if(!new_amount)
usr << "\red That's not a valid number."
return
var/sum_reactants = new_amount - new_assembly_quantities[reagent]
for(var/rod in new_assembly_quantities)
sum_reactants += new_assembly_quantities[rod]
if(sum_reactants > max_assembly_amount)
usr << "\red You have entered too many rods."
else
new_assembly_quantities[reagent] = new_amount
updateDialog()
return
if( href_list["activate"] )
var/obj/item/weapon/fuel_assembly/F = new(src)
//world << "\blue New fuel rod assembly"
for(var/reagent in new_assembly_quantities)
F.rod_quantities[reagent] = new_assembly_quantities[reagent]
//world << "\blue [reagent]: new_assembly_quantities[reagent]<br>"
F.loc = src.loc
return
proc
interact(mob/user)
/*if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=fuelcomp")
return*/
var/t = "<B>Reactor Fuel Rod Compressor / Assembler</B><BR>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
t += "<A href='?src=\ref[src];activate=1'><b>Activate Fuel Synthesis</b></A><BR> (fuel assemblies require no more than [max_assembly_amount] rods).<br>"
t += "<hr>"
t += "- New fuel assembly constituents:- <br>"
for(var/reagent in new_assembly_quantities)
t += " [reagent] rods: [new_assembly_quantities[reagent]] \[<A href='?src=\ref[src];reagent=1'>Modify</A>\]<br>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=fuelcomp;size=500x800")
user.machine = src

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1,141 @@
/obj/machinery/computer/rust/fuel_control
name = "Fuel Injection Control"
icon_state = "power"
var/list/fuel_injectors
var/active_stage = "Cooling"
var/announce_fueldepletion = 0
var/announce_stageprogression = 0
//var/obj/machinery/rust/fuel_injector/Injector = null
New()
//these are the only three stages we can accept
//we have another console for SCRAM
fuel_injectors = new/list
fuel_injectors.Add("One")
fuel_injectors["One"] = new/list
fuel_injectors.Add("Two")
fuel_injectors["Two"] = new/list
fuel_injectors.Add("Three")
fuel_injectors["Three"] = new/list
spawn(0)
for(var/obj/machinery/rust/fuel_injector/Injector in range(50,src))
if(Injector.stage in fuel_injectors)
var/list/targetlist = fuel_injectors[Injector.stage]
targetlist.Add(Injector)
attack_ai(mob/user)
attack_hand(user)
attack_hand(mob/user)
add_fingerprint(user)
/*if(stat & (BROKEN|NOPOWER))
return*/
interact(user)
/*updateDialog()
for(var/mob/M in range(1))
if(M.machine == src)
interact(m)*/
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=fuel_monitor")
usr.machine = null
return
if( href_list["beginstage"] )
active_stage = href_list["beginstage"]
if(active_stage in fuel_injectors)
for(var/obj/machinery/rust/fuel_injector/Injector in fuel_injectors[active_stage])
Injector.BeginInjecting()
updateDialog()
return
if( href_list["restart"] )
updateDialog()
return
if( href_list["cooldown"] )
if(active_stage in fuel_injectors)
for(var/obj/machinery/rust/fuel_injector/Injector in fuel_injectors[active_stage])
Injector.StopInjecting()
active_stage = "Cooling"
updateDialog()
return
if( href_list["update"] )
updateDialog()
return
//
if( href_list["disable_fueldepletion"] )
announce_fueldepletion = 0
updateDialog()
return
if( href_list["announce_fueldepletion"] )
announce_fueldepletion = 1
updateDialog()
return
if( href_list["broadcast_fueldepletion"] )
announce_fueldepletion = 2
updateDialog()
return
//
if( href_list["disable_stageprogression"] )
announce_stageprogression = 0
updateDialog()
return
if( href_list["announce_stageprogression"] )
announce_stageprogression = 1
updateDialog()
return
if( href_list["broadcast_stageprogression"] )
announce_stageprogression = 2
updateDialog()
return
process()
..()
updateDialog()
proc
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=fuel_monitor")
return
var/t = "<B>Reactor Core Fuel Control</B><BR>"
t += "Current fuel injection stage: [active_stage]<br>"
if(active_stage == "Cooling")
//t += "<a href='?src=\ref[src];restart=1;'>Restart injection cycle</a><br>"
t += "----<br>"
else
t += "<a href='?src=\ref[src];cooldown=1;'>Enter cooldown phase</a><br>"
t += "Fuel depletion announcement: "
t += "[announce_fueldepletion ? "<a href='?src=\ref[src];disable_fueldepletion=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_fueldepletion == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_fueldepletion=1'>Announce</a>"] "
t += "[announce_fueldepletion == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_fueldepletion=1'>Broadcast</a>"]<br>"
t += "Stage progression announcement: "
t += "[announce_stageprogression ? "<a href='?src=\ref[src];disable_stageprogression=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_stageprogression == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_stageprogression=1'>Announce</a>"] "
t += "[announce_stageprogression == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_stageprogression=1'>Broadcast</a>"] "
t += "<hr>"
t += "<table border=1><tr>"
t += "<td><b>Injector Status</b></td>"
t += "<td><b>Injection interval (sec)</b></td>"
t += "<td><b>Assembly consumption per injection</b></td>"
t += "<td><b>Fuel Assembly Port</b></td>"
t += "<td><b>Assembly depletion percentage</b></td>"
t += "</tr>"
for(var/stage in fuel_injectors)
var/list/cur_stage = fuel_injectors[stage]
t += "<tr><td colspan=5><b>Fuel Injection Stage:</b> <font color=blue>[stage]</font> [active_stage == stage ? "<font color=green> (Currently active)</font>" : "<a href='?src=\ref[src];beginstage=[stage]'>Activate</a>"]</td></tr>"
for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
t += "<tr>"
t += "<td>[Injector.on && Injector.remote_enabled ? "<font color=green>Operational</font>" : "<font color=red>Unresponsive</font>"]</td>"
t += "<td>[Injector.rate/10] <a href='?src=\ref[Injector];cyclerate=1'>Modify</a></td>"
t += "<td>[Injector.fuel_usage*100]% <a href='?src=\ref[Injector];fuel_usage=1'>Modify</a></td>"
t += "<td>[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "<font color=green>Loaded</font>": "<font color=blue>Empty</font>"]" : "<font color=red>Disconnected</font>" ]</td>"
t += "<td>[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]</td>"
t += "</tr>"
t += "</table>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=fuel_monitor;size=500x800")
user.machine = src

View File

@@ -0,0 +1,107 @@
/obj/machinery/rust/fuel_injector
name = "Fuel Injector"
icon = 'fuel_injector.dmi'
icon_state = "injector-on"
anchored = 1
density = 0
var/obj/machinery/rust/fuel_assembly_port/owned_assembly_port
//var/list/stageone_assemblyports
//var/list/stagetwo_assemblyports
//var/list/scram_assemblyports
var/obj/machinery/rust/reactor_vessel/Vessel = null
var/rate = 10 //microseconds between each cycle
var/fuel_usage = 0.0001 //percentage of available fuel to use per cycle
var/on = 1
var/remote_enabled = 1
var/injecting = 0
var/stage = "One"
var/targetting_field = 0
layer = 4
//transfer fuel wirelessly for now :P
New()
..()
name = "Stage [stage] Fuel Injector"
//pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
//pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
/*
stageone_assemblyports = new/list()
stagetwo_assemblyports = new/list()
scram_assemblyports = new/list()
spawn(1)
Vessel = locate() in range(6,src)
for(var/obj/machinery/rust/fuel_assembly_port/S in range(6,src))
switch(S.stage)
if("One")
stageone_assemblyports.Add(S)
if("Two")
stagetwo_assemblyports.Add(S)
if("SCRAM")
scram_assemblyports.Add(S)
*/
spawn(1)
var/rev_dir = reverse_direction(dir)
var/turf/mid = get_step(src, rev_dir)
for(var/obj/machinery/rust/fuel_assembly_port/port in get_step(mid, rev_dir))
owned_assembly_port = port
//
proc/BeginInjecting()
if(!injecting)
injecting = 1
spawn(rate)
Inject()
return 1
return 0
proc/StopInjecting()
if(injecting)
injecting = 0
return 1
return 0
proc/Inject()
if(!injecting)
return
if(owned_assembly_port.cur_assembly)
var/obj/machinery/rust/em_field/target_field
if(targetting_field)
for(var/obj/machinery/rust/em_field/field in range(15))
target_field = field
var/amount_left = 0
for(var/reagent in owned_assembly_port.cur_assembly.rod_quantities)
//world << "checking [reagent]"
if(owned_assembly_port.cur_assembly.rod_quantities[reagent] > 0)
//world << " rods left: [owned_assembly_port.cur_assembly.rod_quantities[reagent]]]
var/amount = owned_assembly_port.cur_assembly.rod_quantities[reagent] * fuel_usage
var/numparticles = round(amount * 1000)
if(numparticles < 1)
numparticles = 1
//world << " amount: [amount]"
//world << " numparticles: [numparticles]"
for(var/i=0, i<numparticles, i++)
var/obj/effect/accelerated_particle/particle = new(src.loc, src.dir)
particle.particle_type = reagent
particle.energy = 0
particle.icon_state = "particle_single"
particle.pixel_x = rand(-10,10)
particle.pixel_y = rand(-10,10)
var/extra_particles = round(rand(0, numparticles - i - 1))
//world << "[extra_particles + 1] [reagent] particles"
particle.additional_particles = extra_particles
particle.target = target_field
i += extra_particles
//world << "[reagent] particle injected"
owned_assembly_port.cur_assembly.rod_quantities[reagent] -= amount
amount_left += owned_assembly_port.cur_assembly.rod_quantities[reagent]
owned_assembly_port.cur_assembly.amount_depleted = amount_left / 300
if(injecting)
spawn(rate)
Inject()
else
injecting = 0
process()
..()
//

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

View File

@@ -0,0 +1,166 @@
//high frequency photon (laser beam)
/obj/item/projectile/beam/ehf_beam
var/frequency = 5
/obj/machinery/rust/gyrotron
icon = 'gyrotron.dmi'
icon_state = "emitter-off"
name = "Gyrotron"
anchored = 1
density = 0
layer = 4
var/frequency = 20
var/emitting = 0
var/rate = 10
var/mega_energy = 0.001
var/on = 1
var/remoteenabled = 1
New()
..()
//pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
//pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=gyro_monitor")
usr.machine = null
return
if( href_list["modifypower"] )
var/new_val = text2num(input("Enter new emission power level (0.001 - 0.01)", "Modifying power level (MeV)", mega_energy))
if(!new_val || new_val > 0.01 || new_val < 0.001)
usr << "\red That's not a valid number."
return
new_val = min(new_val,0.01)
new_val = max(new_val,0.001)
mega_energy = new_val
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["modifyrate"] )
var/new_val = text2num(input("Enter new emission rate (1 - 10)", "Modifying emission rate (sec)", rate))
if(!new_val || new_val > 10 || new_val < 1)
usr << "\red That's not a valid number."
return
new_val = min(new_val,1)
new_val = max(new_val,10)
rate = new_val
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["modifyfreq"] )
var/new_val = text2num(input("Enter new emission frequency (1 - 500)", "Modifying emission frequency (GHz)", frequency))
if(!new_val || new_val > 500 || new_val < 1)
usr << "\red That's not a valid number."
return
new_val = min(new_val,1)
new_val = max(new_val,500)
frequency = new_val
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["activate"] )
emitting = 1
spawn(rate)
Emit()
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["deactivate"] )
emitting = 0
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["enableremote"] )
remoteenabled = 1
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["disableremote"] )
remoteenabled = 0
for(var/obj/machinery/computer/rust/gyrotron_controller/comp in range(25))
comp.updateDialog()
return
proc/Emit()
var/obj/item/projectile/beam/ehf_beam/A = new ( src.loc )
A.icon_state = "u_laser"
A.frequency = frequency
A.damage = mega_energy * 600
playsound(src.loc, 'emitter.ogg', 25, 1)
/*if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()*/
A.dir = src.dir
if(src.dir == 1)//Up
A.yo = 20
A.xo = 0
else if(src.dir == 2)//Down
A.yo = -20
A.xo = 0
else if(src.dir == 4)//Right
A.yo = 0
A.xo = 20
else if(src.dir == 8)//Left
A.yo = 0
A.xo = -20
else // Any other
A.yo = -20
A.xo = 0
A.process()
flick("emitter-active",src)
if(emitting)
spawn(rate)
Emit()
proc/UpdateIcon()
if(on)
icon_state = "emitter-on"
else
icon_state = "emitter-off"
/obj/machinery/rust/gyrotron/control_panel
icon_state = "control_panel"
name = "Control panel"
var/obj/machinery/rust/gyrotron/owned_gyrotron
New()
..()
pixel_x = -pixel_x
pixel_y = -pixel_y
attack_ai(mob/user)
attack_hand(user)
attack_hand(mob/user)
add_fingerprint(user)
/*if(stat & (BROKEN|NOPOWER))
return*/
interact(user)
proc
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=gyro_monitor")
return
var/t = "<B>Free electron MASER (Gyrotron) Control Panel</B><BR>"
if(owned_gyrotron && owned_gyrotron.on)
t += "<font color=green>Gyrotron operational</font><br>"
t += "Operational mode: <font color=blue>"
if(owned_gyrotron.emitting)
t += "Emitting</font> <a href='?src=\ref[owned_gyrotron];deactivate=1'>\[Deactivate\]</a><br>"
else
t += "Not emitting</font> <a href='?src=\ref[owned_gyrotron];activate=1'>\[Activate\]</a><br>"
t += "Emission rate: [owned_gyrotron.rate] <a href='?src=\ref[owned_gyrotron];modifyrate=1'>\[Modify\]</a><br>"
t += "Beam frequency: [owned_gyrotron.frequency] <a href='?src=\ref[owned_gyrotron];modifyfreq=1'>\[Modify\]</a><br>"
t += "Beam power: [owned_gyrotron.mega_energy] <a href='?src=\ref[owned_gyrotron];modifypower=1'>\[Modify\]</a><br>"
else
t += "<b><font color=red>Gyrotron unresponsive</font></b>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=gyro_monitor;size=500x800")
user.machine = src

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,100 @@
/obj/machinery/computer/rust/gyrotron_controller
name = "Gyrotron Remote Controller"
icon_state = "power"
New()
..()
attack_ai(mob/user)
attack_hand(user)
attack_hand(mob/user)
add_fingerprint(user)
/*if(stat & (BROKEN|NOPOWER))
return*/
interact(user)
/*updateDialog()
for(var/mob/M in range(1))
if(M.machine == src)
interact(m)*/
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=gyrotron_controller")
usr.machine = null
return
if( href_list["target"] )
var/obj/machinery/rust/gyrotron/gyro = locate(href_list["target"])
gyro.Topic(href, href_list)
return
process()
..()
//updateDialog()
proc
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=gyrotron_controller")
return
var/t = "<B>Gyrotron Remote Control Console</B><BR>"
t += "<hr>"
for(var/obj/machinery/rust/gyrotron/gyro in range(25))
if(gyro.remoteenabled && gyro.on)
t += "<font color=green>Gyrotron operational</font><br>"
t += "Operational mode: <font color=blue>"
if(gyro.emitting)
t += "Emitting</font> <a href='?src=\ref[gyro];deactivate=1'>\[Deactivate\]</a><br>"
else
t += "Not emitting</font> <a href='?src=\ref[gyro];activate=1'>\[Activate\]</a><br>"
t += "Emission rate: [gyro.rate] <a href='?src=\ref[gyro];modifyrate=1'>\[Modify\]</a><br>"
t += "Beam frequency: [gyro.frequency] <a href='?src=\ref[gyro];modifyfreq=1'>\[Modify\]</a><br>"
t += "Beam power: [gyro.mega_energy] <a href='?src=\ref[gyro];modifypower=1'>\[Modify\]</a><br>"
else
t += "<b><font color=red>Gyrotron unresponsive</font></b>"
t += "<hr>"
/*
var/t = "<B>Reactor Core Fuel Control</B><BR>"
t += "Current fuel injection stage: [active_stage]<br>"
if(active_stage == "Cooling")
//t += "<a href='?src=\ref[src];restart=1;'>Restart injection cycle</a><br>"
t += "----<br>"
else
t += "<a href='?src=\ref[src];cooldown=1;'>Enter cooldown phase</a><br>"
t += "Fuel depletion announcement: "
t += "[announce_fueldepletion ? "<a href='?src=\ref[src];disable_fueldepletion=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_fueldepletion == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_fueldepletion=1'>Announce</a>"] "
t += "[announce_fueldepletion == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_fueldepletion=1'>Broadcast</a>"]<br>"
t += "Stage progression announcement: "
t += "[announce_stageprogression ? "<a href='?src=\ref[src];disable_stageprogression=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_stageprogression == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_stageprogression=1'>Announce</a>"] "
t += "[announce_stageprogression == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_stageprogression=1'>Broadcast</a>"] "
t += "<hr>"
t += "<table border=1><tr>"
t += "<td><b>Injector Status</b></td>"
t += "<td><b>Injection interval (sec)</b></td>"
t += "<td><b>Assembly consumption per injection</b></td>"
t += "<td><b>Fuel Assembly Port</b></td>"
t += "<td><b>Assembly depletion percentage</b></td>"
t += "</tr>"
for(var/stage in fuel_injectors)
var/list/cur_stage = fuel_injectors[stage]
t += "<tr><td colspan=5><b>Fuel Injection Stage:</b> <font color=blue>[stage]</font> [active_stage == stage ? "<font color=green> (Currently active)</font>" : "<a href='?src=\ref[src];beginstage=[stage]'>Activate</a>"]</td></tr>"
for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
t += "<tr>"
t += "<td>[Injector.on && Injector.remote_enabled ? "<font color=green>Operational</font>" : "<font color=red>Unresponsive</font>"]</td>"
t += "<td>[Injector.rate/10] <a href='?src=\ref[Injector];cyclerate=1'>Modify</a></td>"
t += "<td>[Injector.fuel_usage*100]% <a href='?src=\ref[Injector];fuel_usage=1'>Modify</a></td>"
t += "<td>[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "<font color=green>Loaded</font>": "<font color=blue>Empty</font>"]" : "<font color=red>Disconnected</font>" ]</td>"
t += "<td>[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]</td>"
t += "</tr>"
t += "</table>"
*/
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=gyrotron_controller;size=500x800")
user.machine = src

View File

@@ -0,0 +1,70 @@
/obj/machinery/rust/rad_source
var/mega_energy = 0
var/time_alive = 0
var/source_alive = 2
New()
..()
process()
..()
//fade away over time
if(source_alive > 0)
time_alive++
source_alive--
else
time_alive -= 0.1
if(time_alive < 0)
del(src)
//radiate mobs nearby here
//
/*
/obj/machinery/rust
proc/RadiateParticle(var/energy, var/ionizing, var/dir = 0)
if(!dir)
RadiateParticleRand(energy, ionizing)
var/obj/effect/accelerated_particle/particle = new
particle.dir = dir
particle.ionizing = ionizing
if(energy)
particle.energy = energy
//particle.invisibility = 2
//
return particle
proc/RadiateParticleRand(var/energy, var/ionizing)
var/turf/target
var/particle_range = 3 * round(energy) + rand(3,20)
if(energy > 1)
//for penetrating radiation
for(var/mob/M in range(particle_range))
var/dist_ratio = particle_range / get_dist(M, src)
//particles are more likely to hit a person if the person is closer
// 1/8 = 12.5% (closest)
// 1/360 = 0.27% (furthest)
// variation of 12.2%
if( rand() < (0.25 + dist_ratio * 12.5) )
target = get_turf(M)
break
if(!target)
target = pick(range(particle_range))
else
//for slower, non-penetrating radiation
for(var/mob/M in view(particle_range))
var/dist_ratio = particle_range / get_dist(M, src)
if( rand() < (0.25 + dist_ratio * 12.5) )
target = get_turf(M)
break
if(!target)
target = pick(view(particle_range))
var/obj/effect/accelerated_particle/particle = new
particle.target = target
particle.ionizing = ionizing
if(energy)
particle.energy = energy
//particle.invisibility = 2
//
return particle
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,54 @@
//gimmicky hack to collect particles and direct them into the field
//byond multitiles are basically... shit
/obj/machinery/rust/particle_catcher
invisibility = 101
icon = 'effects.dmi'
icon_state = "energynet"
density = 0
var/obj/machinery/rust/em_field/parent
var/mysize = 0
/*New()
for(var/obj/machinery/rust/em_field/field in range(6))
parent = field
if(!parent)
del(src)*/
proc/SetSize(var/newsize)
name = "collector [newsize]"
mysize = newsize
UpdateSize()
proc/AddParticles(var/name, var/quantity = 1)
if(parent && parent.size >= mysize)
parent.AddParticles(name, quantity)
return 1
return 0
proc/AddEnergy(var/energy, var/mega_energy)
if(parent && parent.size >= mysize)
parent.energy += energy
parent.mega_energy += mega_energy
return 1
return 0
proc/UpdateSize()
if(parent.size >= mysize)
density = 1
//invisibility = 101
name = "collector [mysize] ON"
else
density = 0
name = "collector [mysize] OFF"
//invisibility = 101
bullet_act(var/obj/item/projectile/Proj)
if(Proj.flag != "bullet")
AddEnergy(0, Proj.damage / 600)
return 0
process()
..()
if(!parent)
del(src)

View File

@@ -1588,3 +1588,22 @@ proc/get_opposite(var/checkdir)
if(a == character) if(a == character)
count++ count++
return count return count
/proc/reverse_direction(var/dir)
switch(dir)
if(NORTH)
return SOUTH
if(NORTHEAST)
return SOUTHWEST
if(EAST)
return WEST
if(SOUTHEAST)
return NORTHWEST
if(SOUTH)
return NORTH
if(SOUTHWEST)
return NORTHEAST
if(WEST)
return EAST
if(NORTHWEST)
return SOUTHEAST

View File

@@ -7,47 +7,59 @@
density = 1 density = 1
var var
movement_range = 10 movement_range = 10
energy = 10 energy = 10 //energy in eV?
mega_energy = 0 //energy in MeV
ionizing = 0
particle_type
additional_particles = 0
turf/target
turf/source
movetotarget = 1
weak weak
movement_range = 8 movement_range = 8
energy = 5 energy = 5
strong strong
movement_range = 15 movement_range = 15
energy = 15 energy = 15
New(loc, dir = 2) New(loc, dir = 2)
src.loc = loc src.loc = loc
source = usr
src.dir = dir src.dir = dir
if(movement_range > 20) spawn(1)
movement_range = 20
spawn(0)
move(1) move(1)
return return
Bump(atom/A) Bump(atom/A)
if (A) if (A)
if(ismob(A)) if(ismob(A))
toxmob(A) toxmob(A)
if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/machinery/singularity/))) if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/machinery/singularity/)))
A:energy += energy A:energy += energy
energy = 0
if( istype(A,/obj/machinery/rust/particle_catcher) )
var/obj/machinery/rust/particle_catcher/collided_catcher = A
if(particle_type && particle_type != "neutron")
if(collided_catcher.AddParticles(particle_type, 1 + additional_particles))
collided_catcher.AddEnergy(energy,mega_energy)
del (src)
if( istype(A,/obj/machinery/rust/core) )
var/obj/machinery/rust/core/collided_core = A
if(particle_type && particle_type != "neutron")
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
collided_core.AddEnergy(energy,mega_energy)
del (src)
return return
Bumped(atom/A) Bumped(atom/A)
if(ismob(A)) if(ismob(A))
Bump(A) Bump(A)
return return
ex_act(severity) ex_act(severity)
del(src) del(src)
return return
proc proc
toxmob(var/mob/living/M) toxmob(var/mob/living/M)
var/radiation = (energy*2) var/radiation = (energy*2)
@@ -57,13 +69,27 @@
if(istype(M,/mob/living/carbon/monkey)) if(istype(M,/mob/living/carbon/monkey))
if(M:wear_suit) //TODO: check for radiation protection if(M:wear_suit) //TODO: check for radiation protection
radiation = round(radiation/2,1) radiation = round(radiation/2,1)
if(ionizing)
//give them standard rad damage
M.radiation += radiation M.radiation += radiation
M.updatehealth() M.updatehealth()
else
//burn them
M.take_overall_damage(0, radiation)
//M << "\red You feel odd." //M << "\red You feel odd."
return return
move(var/lag) move(var/lag)
if(target)
if(movetotarget)
if(!step_towards(src,target))
src.loc = get_step(src, get_dir(src,target))
if(get_dist(src,target) < 1)
movetotarget = 0
else
if(!step(src, get_step_away(src,source)))
src.loc = get_step(src, get_step_away(src,source))
else
if(!step(src,dir)) if(!step(src,dir))
src.loc = get_step(src,dir) src.loc = get_step(src,dir)
movement_range-- movement_range--

Binary file not shown.

Before

Width:  |  Height:  |  Size: 455 KiB

After

Width:  |  Height:  |  Size: 614 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 317 KiB

After

Width:  |  Height:  |  Size: 606 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 KiB

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because it is too large Load Diff