mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Ports R-UST from Baystation12 + small admin debug verb
This commit is contained in:
@@ -158,6 +158,17 @@
|
||||
default_type = "osmium"
|
||||
apply_colour = 1
|
||||
|
||||
//R-UST port
|
||||
// Fusion fuel.
|
||||
/obj/item/stack/material/deuterium
|
||||
name = "deuterium"
|
||||
icon_state = "sheet-silver"
|
||||
default_type = "deuterium"
|
||||
apply_colour = 1
|
||||
|
||||
/obj/item/stack/material/deuterium/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/material/steel
|
||||
name = DEFAULT_WALL_MATERIAL
|
||||
icon_state = "sheet-metal"
|
||||
|
||||
@@ -69,6 +69,7 @@ var/list/name_to_material
|
||||
var/flags = 0 // Various status modifiers.
|
||||
var/sheet_singular_name = "sheet"
|
||||
var/sheet_plural_name = "sheets"
|
||||
var/is_fusion_fuel
|
||||
|
||||
// Shards/tables/structures
|
||||
var/shard_type = SHARD_SHRAPNEL // Path of debris object.
|
||||
@@ -97,6 +98,7 @@ var/list/name_to_material
|
||||
var/conductive = 1 // Objects with this var add CONDUCTS to flags on spawn.
|
||||
var/conductivity = null // How conductive the material is. Iron acts as the baseline, at 10.
|
||||
var/list/composite_material // If set, object matter var will be a list containing these values.
|
||||
var/luminescence
|
||||
|
||||
// Placeholder vars for the time being, todo properly integrate windows/light tiles/rods.
|
||||
var/created_window
|
||||
@@ -270,6 +272,22 @@ var/list/name_to_material
|
||||
sheet_singular_name = "ingot"
|
||||
sheet_plural_name = "ingots"
|
||||
|
||||
//R-UST port
|
||||
/material/supermatter
|
||||
name = "supermatter"
|
||||
icon_colour = "#FFFF00"
|
||||
radioactivity = 20
|
||||
stack_type = null
|
||||
luminescence = 3
|
||||
ignition_point = PHORON_MINIMUM_BURN_TEMPERATURE
|
||||
icon_base = "stone"
|
||||
shard_type = SHARD_SHARD
|
||||
hardness = 30
|
||||
door_icon_base = "stone"
|
||||
sheet_singular_name = "crystal"
|
||||
sheet_plural_name = "crystals"
|
||||
is_fusion_fuel = 1
|
||||
|
||||
/material/phoron
|
||||
name = "phoron"
|
||||
stack_type = /obj/item/stack/material/phoron
|
||||
@@ -567,6 +585,16 @@ var/list/name_to_material
|
||||
stack_origin_tech = list(TECH_MATERIAL = 5)
|
||||
sheet_singular_name = "ingot"
|
||||
sheet_plural_name = "ingots"
|
||||
is_fusion_fuel = 1
|
||||
|
||||
/material/deuterium
|
||||
name = "deuterium"
|
||||
stack_type = /obj/item/stack/material/deuterium
|
||||
icon_colour = "#999999"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 3)
|
||||
sheet_singular_name = "ingot"
|
||||
sheet_plural_name = "ingots"
|
||||
is_fusion_fuel = 1
|
||||
|
||||
/material/mhydrogen
|
||||
name = "mhydrogen"
|
||||
@@ -574,6 +602,7 @@ var/list/name_to_material
|
||||
icon_colour = "#E6C5DE"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 6, TECH_POWER = 6, TECH_MAGNET = 5)
|
||||
conductivity = 100
|
||||
is_fusion_fuel = 1
|
||||
|
||||
/material/platinum
|
||||
name = "platinum"
|
||||
|
||||
83
code/modules/power/fusion/_setup.dm
Normal file
83
code/modules/power/fusion/_setup.dm
Normal file
@@ -0,0 +1,83 @@
|
||||
// temperature of the core of the sun
|
||||
#define FUSION_HEAT_CAP 1.57e7
|
||||
|
||||
#define SETUP_OK 1 // All good
|
||||
#define SETUP_WARNING 2 // Something that shouldn't happen happened, but it's not critical so we will continue
|
||||
#define SETUP_ERROR 3 // Something bad happened, and it's important so we won't continue setup.
|
||||
#define SETUP_DELAYED 4 // Wait for other things first.
|
||||
|
||||
/datum/admins/proc/setup_fusion()
|
||||
set category = "Debug"
|
||||
set name = "Setup Fusion Core"
|
||||
set desc = "Allows you to start the R-UST engine."
|
||||
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
|
||||
if(!(locate(/obj/machinery/power/fusion_core/mapped) in world))
|
||||
to_chat(usr, "This map is not appropriate for this verb.")
|
||||
return
|
||||
|
||||
var/response = input(usr, "Are you sure?", "Engine setup") as null|anything in list("No", "Yes")
|
||||
if(!response || response == "No")
|
||||
return
|
||||
|
||||
var/errors = 0
|
||||
var/warnings = 0
|
||||
var/success = 0
|
||||
|
||||
log_and_message_admins("## FUSION CORE SETUP - Setup initiated by [usr].")
|
||||
|
||||
for(var/obj/machinery/fusion_fuel_injector/mapped/injector in machines)
|
||||
injector.cur_assembly = new /obj/item/weapon/fuel_assembly/deuterium(injector)
|
||||
injector.BeginInjecting()
|
||||
|
||||
var/obj/machinery/power/fusion_core/mapped/core = locate() in machines
|
||||
if(core.jumpstart(15000))
|
||||
var/list/delayed_objects = list()
|
||||
|
||||
// SETUP PHASE
|
||||
for(var/obj/effect/engine_setup/S in world)
|
||||
var/result = S.activate(0)
|
||||
switch(result)
|
||||
if(SETUP_OK)
|
||||
success++
|
||||
continue
|
||||
if(SETUP_WARNING)
|
||||
warnings++
|
||||
continue
|
||||
if(SETUP_ERROR)
|
||||
errors++
|
||||
log_and_message_admins("## FUSION CORE SETUP - Error encountered! Aborting.")
|
||||
break
|
||||
if(SETUP_DELAYED)
|
||||
delayed_objects.Add(S)
|
||||
continue
|
||||
|
||||
if(!errors)
|
||||
for(var/obj/effect/engine_setup/S in delayed_objects)
|
||||
var/result = S.activate(1)
|
||||
switch(result)
|
||||
if(SETUP_OK)
|
||||
success++
|
||||
continue
|
||||
if(SETUP_WARNING)
|
||||
warnings++
|
||||
continue
|
||||
if(SETUP_ERROR)
|
||||
errors++
|
||||
log_and_message_admins("## FUSION CORE SETUP - Error encountered! Aborting.")
|
||||
break
|
||||
else
|
||||
log_and_message_admins("## FUSION CORE SETUP - Error encountered! Aborting.")
|
||||
errors++
|
||||
|
||||
log_and_message_admins("## FUSION CORE SETUP - Setup completed with [errors] errors, [warnings] warnings and [success] successful steps.")
|
||||
|
||||
#undef SETUP_OK
|
||||
#undef SETUP_WARNING
|
||||
#undef SETUP_ERROR
|
||||
#undef SETUP_DELAYED
|
||||
131
code/modules/power/fusion/core/_core.dm
Normal file
131
code/modules/power/fusion/core/_core.dm
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
TODO README
|
||||
*/
|
||||
|
||||
var/list/fusion_cores = list()
|
||||
|
||||
#define MAX_FIELD_STR 1000
|
||||
#define MIN_FIELD_STR 1
|
||||
|
||||
/obj/machinery/power/fusion_core
|
||||
name = "\improper R-UST Mk. 8 Tokamak core"
|
||||
desc = "An enormous solenoid for generating extremely high power electromagnetic fields. It includes a kinetic energy harvester."
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "core0"
|
||||
density = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 500 //multiplied by field strength
|
||||
anchored = 0
|
||||
|
||||
var/obj/effect/fusion_em_field/owned_field
|
||||
var/field_strength = 1//0.01
|
||||
var/id_tag
|
||||
|
||||
/obj/machinery/power/fusion_core/mapped
|
||||
anchored = 1
|
||||
|
||||
/obj/machinery/power/fusion_core/initialize()
|
||||
. = ..()
|
||||
connect_to_network()
|
||||
fusion_cores += src
|
||||
|
||||
/obj/machinery/power/fusion_core/Destroy()
|
||||
for(var/obj/machinery/computer/fusion_core_control/FCC in machines)
|
||||
FCC.connected_devices -= src
|
||||
if(FCC.cur_viewed_device == src)
|
||||
FCC.cur_viewed_device = null
|
||||
fusion_cores -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/fusion_core/process()
|
||||
if((stat & BROKEN) || !powernet || !owned_field)
|
||||
Shutdown()
|
||||
|
||||
/obj/machinery/power/fusion_core/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["str"])
|
||||
var/dif = text2num(href_list["str"])
|
||||
field_strength = min(max(field_strength + dif, MIN_FIELD_STR), MAX_FIELD_STR)
|
||||
active_power_usage = 500 * field_strength
|
||||
if(owned_field)
|
||||
owned_field.ChangeFieldStrength(field_strength)
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/Startup()
|
||||
if(owned_field)
|
||||
return
|
||||
owned_field = new(loc, src)
|
||||
owned_field.ChangeFieldStrength(field_strength)
|
||||
icon_state = "core1"
|
||||
use_power = 2
|
||||
. = 1
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/Shutdown(var/force_rupture)
|
||||
if(owned_field)
|
||||
icon_state = "core0"
|
||||
if(force_rupture || owned_field.plasma_temperature > 1000)
|
||||
owned_field.Rupture()
|
||||
else
|
||||
owned_field.RadiateAll()
|
||||
qdel(owned_field)
|
||||
owned_field = null
|
||||
use_power = 1
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/AddParticles(var/name, var/quantity = 1)
|
||||
if(owned_field)
|
||||
owned_field.AddParticles(name, quantity)
|
||||
. = 1
|
||||
|
||||
/obj/machinery/power/fusion_core/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(owned_field)
|
||||
. = owned_field.bullet_act(Proj)
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/set_strength(var/value)
|
||||
value = Clamp(value, MIN_FIELD_STR, MAX_FIELD_STR)
|
||||
field_strength = value
|
||||
active_power_usage = 5 * value
|
||||
if(owned_field)
|
||||
owned_field.ChangeFieldStrength(value)
|
||||
|
||||
/obj/machinery/power/fusion_core/attack_hand(var/mob/user)
|
||||
if(!Adjacent(user)) // As funny as it was for the AI to hug-kill the tokamak field from a distance...
|
||||
return
|
||||
visible_message("<span class='notice'>\The [user] hugs \the [src] to make it feel better!</span>")
|
||||
if(owned_field)
|
||||
Shutdown()
|
||||
|
||||
/obj/machinery/power/fusion_core/attackby(var/obj/item/W, var/mob/user)
|
||||
|
||||
if(owned_field)
|
||||
to_chat(user,"<span class='warning'>Shut \the [src] off first!</span>")
|
||||
return
|
||||
|
||||
if(ismultitool(W))
|
||||
var/new_ident = input("Enter a new ident tag.", "Fusion Core", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
return
|
||||
|
||||
else if(iswrench(W))
|
||||
anchored = !anchored
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
|
||||
if(anchored)
|
||||
user.visible_message("[user.name] secures [src.name] to the floor.", \
|
||||
"You secure the [src.name] to the floor.", \
|
||||
"You hear a ratchet")
|
||||
else
|
||||
user.visible_message("[user.name] unsecures [src.name] from the floor.", \
|
||||
"You unsecure the [src.name] from the floor.", \
|
||||
"You hear a ratchet")
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/fusion_core/proc/jumpstart(var/field_temperature)
|
||||
field_strength = 501 // Generally a good size.
|
||||
Startup()
|
||||
if(!owned_field)
|
||||
return FALSE
|
||||
owned_field.plasma_temperature = field_temperature
|
||||
return TRUE
|
||||
176
code/modules/power/fusion/core/core_control.dm
Normal file
176
code/modules/power/fusion/core/core_control.dm
Normal file
@@ -0,0 +1,176 @@
|
||||
/obj/machinery/computer/fusion_core_control
|
||||
name = "\improper R-UST Mk. 8 core control"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "core_control"
|
||||
light_color = COLOR_ORANGE
|
||||
|
||||
var/id_tag
|
||||
var/scan_range = 25
|
||||
var/list/connected_devices = list()
|
||||
var/obj/machinery/power/fusion_core/cur_viewed_device
|
||||
|
||||
/obj/machinery/computer/fusion_core_control/attackby(var/obj/item/thing, var/mob/user)
|
||||
if(ismultitool(thing))
|
||||
var/new_ident = input("Enter a new ident tag.", "Core Control", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
cur_viewed_device = null
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/fusion_core_control/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/fusion_core_control/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/computer/fusion_core_control/interact(mob/user)
|
||||
|
||||
if(!cur_viewed_device || !check_core_status(cur_viewed_device))
|
||||
cur_viewed_device = null
|
||||
|
||||
if(!id_tag)
|
||||
to_chat(user, "<span class='warning'>This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>")
|
||||
return
|
||||
|
||||
if(cur_viewed_device && (cur_viewed_device.id_tag != id_tag || get_dist(src, cur_viewed_device) > scan_range))
|
||||
cur_viewed_device = null
|
||||
|
||||
var/dat = "<B>Core Control #[id_tag]</B><BR>"
|
||||
|
||||
if(cur_viewed_device)
|
||||
dat += {"
|
||||
<a href='?src=\ref[src];goto_scanlist=1'>Back to overview</a><hr>
|
||||
Device ident '[cur_viewed_device.id_tag]' <span style='color: [cur_viewed_device.owned_field ? "green" : "red"]'>[cur_viewed_device.owned_field ? "active" : "inactive"].</span><br>
|
||||
<b>Power status:</b> [cur_viewed_device.avail()]/[cur_viewed_device.active_power_usage] W<br>
|
||||
<hr>
|
||||
<a href='?src=\ref[src];toggle_active=1'>Bring field [cur_viewed_device.owned_field ? "offline" : "online"].</a><br>
|
||||
<hr>
|
||||
<b>Field power density (W.m<sup>-3</sup>):</b><br>
|
||||
<a href='?src=\ref[src];str=-1000'>----</a>
|
||||
<a href='?src=\ref[src];str=-100'>--- </a>
|
||||
<a href='?src=\ref[src];str=-10'>-- </a>
|
||||
<a href='?src=\ref[src];str=-1'>- </a>
|
||||
<a href='?src=\ref[src];str=0'>[cur_viewed_device.field_strength]</a>
|
||||
<a href='?src=\ref[src];str=1'>+ </a>
|
||||
<a href='?src=\ref[src];str=10'>++ </a>
|
||||
<a href='?src=\ref[src];str=100'>+++ </a>
|
||||
<a href='?src=\ref[src];str=1000'>++++</a><hr>
|
||||
"}
|
||||
|
||||
if(cur_viewed_device.owned_field)
|
||||
dat += {"
|
||||
<b>Approximate field diameter (m):</b> [cur_viewed_device.owned_field.size]<br>
|
||||
<b>Field instability:</b> [cur_viewed_device.owned_field.percent_unstable * 100]%<br>
|
||||
<b>Plasma temperature:</b> [cur_viewed_device.owned_field.plasma_temperature + 295]K<hr>
|
||||
<b>Fuel:</b><br>
|
||||
<table><tr><th><b>Name</b></th><th><b>Amount</b></th></tr>
|
||||
"}
|
||||
for(var/reagent in cur_viewed_device.owned_field.dormant_reactant_quantities)
|
||||
dat += "<tr><td>[reagent]</td><td>[cur_viewed_device.owned_field.dormant_reactant_quantities[reagent]]</td></tr>"
|
||||
dat += "</table><hr>"
|
||||
|
||||
else
|
||||
|
||||
connected_devices.Cut()
|
||||
for(var/obj/machinery/power/fusion_core/C in fusion_cores)
|
||||
if(C.id_tag == id_tag && get_dist(src, C) <= scan_range)
|
||||
connected_devices += C
|
||||
for(var/obj/machinery/power/fusion_core/C in gyrotrons)
|
||||
if(C.id_tag == id_tag && get_dist(src, C) <= scan_range)
|
||||
connected_devices += C
|
||||
|
||||
if(connected_devices.len)
|
||||
dat += {"
|
||||
<b>Connected EM field generators:</b><hr>
|
||||
<table>
|
||||
<tr>
|
||||
<th><b>Device tag</b></th>
|
||||
<th><b>Status</b></th>
|
||||
<th><b>Controls</b></th>
|
||||
</tr>
|
||||
"}
|
||||
|
||||
for(var/obj/machinery/power/fusion_core/C in connected_devices)
|
||||
var/status
|
||||
var/can_access = 1
|
||||
if(!check_core_status(C))
|
||||
status = "<span style='color: red'>Unresponsive</span>"
|
||||
can_access = 0
|
||||
else if(C.avail() < C.active_power_usage)
|
||||
status = "<span style='color: orange'>Underpowered</span>"
|
||||
else
|
||||
status = "<span style='color: green'>Good</span>"
|
||||
|
||||
dat += {"
|
||||
<tr>
|
||||
<td>[C.id_tag]</td>
|
||||
<td>[status]</td>
|
||||
"}
|
||||
|
||||
if(!can_access)
|
||||
dat += {"
|
||||
<td><span style='color: red'>ERROR</span></td>
|
||||
"}
|
||||
else
|
||||
dat += {"
|
||||
<td><a href=?src=\ref[src];access_device=[connected_devices.Find(C)]'>ACCESS</a></td>
|
||||
"}
|
||||
dat += {"
|
||||
</tr>
|
||||
"}
|
||||
|
||||
else
|
||||
dat += "<span style='color: red'>No electromagnetic field generators connected.</span>"
|
||||
|
||||
var/datum/browser/popup = new(user, "fusion_control", name, 500, 400, src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/computer/fusion_core_control/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(href_list["access_device"])
|
||||
var/idx = Clamp(text2num(href_list["toggle_active"]), 1, connected_devices.len)
|
||||
cur_viewed_device = connected_devices[idx]
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
//All HREFs from this point on require a device anyways.
|
||||
if(!cur_viewed_device || !check_core_status(cur_viewed_device) || cur_viewed_device.id_tag != id_tag || get_dist(src, cur_viewed_device) > scan_range)
|
||||
return
|
||||
|
||||
if(href_list["goto_scanlist"])
|
||||
cur_viewed_device = null
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_active"])
|
||||
if(!cur_viewed_device.Startup()) //Startup() whilst the device is active will return null.
|
||||
cur_viewed_device.Shutdown()
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
if(href_list["str"])
|
||||
var/val = text2num(href_list["str"])
|
||||
if(!val) //Value is 0, which is manual entering.
|
||||
cur_viewed_device.set_strength(input("Enter the new field power density (W.m^-3)", "Fusion Control", cur_viewed_device.field_strength) as num)
|
||||
else
|
||||
cur_viewed_device.set_strength(cur_viewed_device.field_strength + val)
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
//Returns 1 if the machine can be interacted with via this console.
|
||||
/obj/machinery/computer/fusion_core_control/proc/check_core_status(var/obj/machinery/power/fusion_core/C)
|
||||
if(isnull(C))
|
||||
return
|
||||
if(C.stat & BROKEN)
|
||||
return
|
||||
if(C.idle_power_usage > C.avail())
|
||||
return
|
||||
. = 1
|
||||
494
code/modules/power/fusion/core/core_field.dm
Normal file
494
code/modules/power/fusion/core/core_field.dm
Normal file
@@ -0,0 +1,494 @@
|
||||
#define FUSION_ENERGY_PER_K 20
|
||||
|
||||
/obj/effect/fusion_em_field
|
||||
name = "electromagnetic field"
|
||||
desc = "A coruscating, barely visible field of energy. It is shaped like a slightly flattened torus."
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "emfield_s1"
|
||||
alpha = 50
|
||||
layer = 4
|
||||
light_color = COLOR_BLUE
|
||||
|
||||
var/size = 1
|
||||
var/energy = 0
|
||||
var/plasma_temperature = 0
|
||||
var/radiation = 0
|
||||
var/field_strength = 0.01
|
||||
var/tick_instability = 0
|
||||
var/percent_unstable = 0
|
||||
|
||||
var/obj/machinery/power/fusion_core/owned_core
|
||||
var/list/dormant_reactant_quantities = list()
|
||||
var/list/particle_catchers = list()
|
||||
|
||||
var/list/ignore_types = list(
|
||||
/obj/item/projectile,
|
||||
/obj/effect,
|
||||
/obj/fire,
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/atmospherics,
|
||||
/obj/machinery/air_sensor,
|
||||
/mob/observer/dead
|
||||
)
|
||||
|
||||
var/light_min_range = 2
|
||||
var/light_min_power = 3
|
||||
var/light_max_range = 10
|
||||
var/light_max_power = 10
|
||||
|
||||
var/last_range
|
||||
var/last_power
|
||||
|
||||
/obj/effect/fusion_em_field/New(loc, var/obj/machinery/power/fusion_core/new_owned_core)
|
||||
..()
|
||||
|
||||
set_light(light_min_range,light_min_power)
|
||||
last_range = light_min_range
|
||||
last_power = light_min_power
|
||||
|
||||
owned_core = new_owned_core
|
||||
if(!owned_core)
|
||||
qdel(src)
|
||||
|
||||
//create the gimmicky things to handle field collisions
|
||||
var/obj/effect/fusion_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)
|
||||
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/effect/fusion_em_field/process()
|
||||
//make sure the field generator is still intact
|
||||
if(!owned_core || QDELETED(owned_core))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// Take some gas up from our environment.
|
||||
var/added_particles = FALSE
|
||||
var/datum/gas_mixture/uptake_gas = owned_core.loc.return_air()
|
||||
if(uptake_gas)
|
||||
uptake_gas = uptake_gas.remove_by_flag(XGM_GAS_FUSION_FUEL, rand(50,100))
|
||||
if(uptake_gas && uptake_gas.total_moles)
|
||||
for(var/gasname in uptake_gas.gas)
|
||||
if(uptake_gas.gas[gasname]*10 > dormant_reactant_quantities[gasname])
|
||||
AddParticles(gasname, uptake_gas.gas[gasname]*10)
|
||||
uptake_gas.adjust_gas(gasname, -(uptake_gas.gas[gasname]), update=FALSE)
|
||||
added_particles = TRUE
|
||||
if(added_particles)
|
||||
uptake_gas.update_values()
|
||||
|
||||
//let the particles inside the field react
|
||||
React()
|
||||
|
||||
// Dump power to our powernet.
|
||||
owned_core.add_avail(FUSION_ENERGY_PER_K * plasma_temperature)
|
||||
|
||||
// Energy decay.
|
||||
if(plasma_temperature >= 1)
|
||||
var/lost = plasma_temperature*0.01
|
||||
radiation += lost
|
||||
plasma_temperature -= lost
|
||||
|
||||
//handle some reactants formatting
|
||||
for(var/reactant in dormant_reactant_quantities)
|
||||
var/amount = dormant_reactant_quantities[reactant]
|
||||
if(amount < 1)
|
||||
dormant_reactant_quantities.Remove(reactant)
|
||||
else if(amount >= 1000000)
|
||||
var/radiate = rand(3 * amount / 4, amount / 4)
|
||||
dormant_reactant_quantities[reactant] -= radiate
|
||||
radiation += radiate
|
||||
|
||||
var/use_range
|
||||
var/use_power
|
||||
if(plasma_temperature <= 6000)
|
||||
use_range = light_min_range
|
||||
use_power = light_min_power
|
||||
else if(plasma_temperature >= 25000)
|
||||
use_range = light_max_range
|
||||
use_power = light_max_power
|
||||
else
|
||||
var/temp_mod = ((plasma_temperature-5000)/20000)
|
||||
use_range = light_min_range + ceil((light_max_range-light_min_range)*temp_mod)
|
||||
use_power = light_min_power + ceil((light_max_power-light_min_power)*temp_mod)
|
||||
|
||||
if(last_range != use_range || last_power != use_power)
|
||||
set_light(use_range,use_power)
|
||||
last_range = use_range
|
||||
last_power = use_power
|
||||
|
||||
check_instability()
|
||||
Radiate()
|
||||
if(radiation)
|
||||
radiation_repository.radiate(src, radiation)
|
||||
return 1
|
||||
|
||||
/obj/effect/fusion_em_field/proc/check_instability()
|
||||
if(tick_instability > 0)
|
||||
percent_unstable += (tick_instability*size)/10000
|
||||
tick_instability = 0
|
||||
else
|
||||
if(percent_unstable < 0)
|
||||
percent_unstable = 0
|
||||
else
|
||||
if(percent_unstable > 100)
|
||||
percent_unstable = 100
|
||||
if(percent_unstable > 0)
|
||||
percent_unstable = max(0, percent_unstable-rand(0.01,0.03))
|
||||
|
||||
if(percent_unstable >= 1)
|
||||
owned_core.Shutdown(force_rupture=1)
|
||||
else
|
||||
if(percent_unstable > 0.5 && prob(percent_unstable*100))
|
||||
if(plasma_temperature < 2000)
|
||||
visible_message("<span class='danger'>\The [src] ripples uneasily, like a disturbed pond.</span>")
|
||||
else
|
||||
var/flare
|
||||
var/fuel_loss
|
||||
var/rupture
|
||||
if(percent_unstable < 0.7)
|
||||
visible_message("<span class='danger'>\The [src] ripples uneasily, like a disturbed pond.</span>")
|
||||
fuel_loss = prob(5)
|
||||
else if(percent_unstable < 0.9)
|
||||
visible_message("<span class='danger'>\The [src] undulates violently, shedding plumes of plasma!</span>")
|
||||
flare = prob(50)
|
||||
fuel_loss = prob(20)
|
||||
rupture = prob(5)
|
||||
else
|
||||
visible_message("<span class='danger'>\The [src] is wracked by a series of horrendous distortions, buckling and twisting like a living thing!</span>")
|
||||
flare = 1
|
||||
fuel_loss = prob(50)
|
||||
rupture = prob(25)
|
||||
|
||||
if(rupture)
|
||||
owned_core.Shutdown(force_rupture=1)
|
||||
else
|
||||
var/lost_plasma = (plasma_temperature*percent_unstable)
|
||||
radiation += lost_plasma
|
||||
if(flare)
|
||||
radiation += plasma_temperature/2
|
||||
plasma_temperature -= lost_plasma
|
||||
|
||||
if(fuel_loss)
|
||||
for(var/particle in dormant_reactant_quantities)
|
||||
var/lost_fuel = dormant_reactant_quantities[particle]*percent_unstable
|
||||
radiation += lost_fuel
|
||||
dormant_reactant_quantities[particle] -= lost_fuel
|
||||
if(dormant_reactant_quantities[particle] <= 0)
|
||||
dormant_reactant_quantities.Remove(particle)
|
||||
Radiate()
|
||||
return
|
||||
|
||||
/obj/effect/fusion_em_field/proc/Rupture()
|
||||
visible_message("<span class='danger'>\The [src] shudders like a dying animal before flaring to eye-searing brightness and rupturing!</span>")
|
||||
set_light(15, 15, "#CCCCFF")
|
||||
empulse(get_turf(src), ceil(plasma_temperature/1000), ceil(plasma_temperature/300))
|
||||
sleep(5)
|
||||
RadiateAll()
|
||||
explosion(get_turf(owned_core),-1,-1,8,10) // Blow out all the windows.
|
||||
return
|
||||
|
||||
/obj/effect/fusion_em_field/proc/ChangeFieldStrength(var/new_strength)
|
||||
var/calc_size = 1
|
||||
if(new_strength <= 50)
|
||||
calc_size = 1
|
||||
else if(new_strength <= 200)
|
||||
calc_size = 3
|
||||
else if(new_strength <= 500)
|
||||
calc_size = 5
|
||||
else
|
||||
calc_size = 7
|
||||
field_strength = new_strength
|
||||
change_size(calc_size)
|
||||
|
||||
/obj/effect/fusion_em_field/proc/AddEnergy(var/a_energy, var/a_plasma_temperature)
|
||||
energy += a_energy
|
||||
plasma_temperature += a_plasma_temperature
|
||||
if(a_energy && percent_unstable > 0)
|
||||
percent_unstable -= a_energy/10000
|
||||
if(percent_unstable < 0)
|
||||
percent_unstable = 0
|
||||
while(energy >= 100)
|
||||
energy -= 100
|
||||
plasma_temperature += 1
|
||||
|
||||
/obj/effect/fusion_em_field/proc/AddParticles(var/name, var/quantity = 1)
|
||||
if(name in dormant_reactant_quantities)
|
||||
dormant_reactant_quantities[name] += quantity
|
||||
else if(name != "proton" && name != "electron" && name != "neutron")
|
||||
dormant_reactant_quantities.Add(name)
|
||||
dormant_reactant_quantities[name] = quantity
|
||||
|
||||
/obj/effect/fusion_em_field/proc/RadiateAll(var/ratio_lost = 1)
|
||||
|
||||
// Create our plasma field and dump it into our environment.
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T))
|
||||
var/datum/gas_mixture/plasma = new
|
||||
plasma.adjust_gas("oxygen", (size*100), 0)
|
||||
plasma.adjust_gas("phoron", (size*100), 0)
|
||||
plasma.temperature = (plasma_temperature/2)
|
||||
plasma.update_values()
|
||||
T.assume_air(plasma)
|
||||
T.hotspot_expose(plasma_temperature)
|
||||
plasma = null
|
||||
|
||||
// Radiate all our unspent fuel and energy.
|
||||
for(var/particle in dormant_reactant_quantities)
|
||||
radiation += dormant_reactant_quantities[particle]
|
||||
dormant_reactant_quantities.Remove(particle)
|
||||
radiation += plasma_temperature/2
|
||||
plasma_temperature = 0
|
||||
|
||||
radiation_repository.radiate(src, radiation)
|
||||
Radiate()
|
||||
|
||||
/obj/effect/fusion_em_field/proc/Radiate()
|
||||
if(istype(loc, /turf))
|
||||
var/empsev = max(1, min(3, ceil(size/2)))
|
||||
for(var/atom/movable/AM in range(max(1,Floor(size/2)), loc))
|
||||
|
||||
if(AM == src || AM == owned_core || !AM.simulated)
|
||||
continue
|
||||
|
||||
var/skip_obstacle
|
||||
for(var/ignore_path in ignore_types)
|
||||
if(istype(AM, ignore_path))
|
||||
skip_obstacle = TRUE
|
||||
break
|
||||
if(skip_obstacle)
|
||||
continue
|
||||
|
||||
log_debug("R-UST DEBUG: [AM] is [AM.type]")
|
||||
AM.visible_message("<span class='danger'>The field buckles visibly around \the [AM]!</span>")
|
||||
tick_instability += rand(15,30)
|
||||
AM.emp_act(empsev)
|
||||
|
||||
if(owned_core && owned_core.loc)
|
||||
var/datum/gas_mixture/environment = owned_core.loc.return_air()
|
||||
if(environment && environment.temperature < (T0C+1000)) // Putting an upper bound on it to stop it being used in a TEG.
|
||||
environment.add_thermal_energy(plasma_temperature*20000)
|
||||
radiation = 0
|
||||
|
||||
/obj/effect/fusion_em_field/proc/change_size(var/newsize = 1)
|
||||
var/changed = 0
|
||||
switch(newsize)
|
||||
if(1)
|
||||
size = 1
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "emfield_s1"
|
||||
pixel_x = 0
|
||||
pixel_y = 0
|
||||
//
|
||||
changed = 1
|
||||
if(3)
|
||||
size = 3
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "emfield_s3"
|
||||
pixel_x = -32 * PIXEL_MULTIPLIER
|
||||
pixel_y = -32 * PIXEL_MULTIPLIER
|
||||
//
|
||||
changed = 3
|
||||
if(5)
|
||||
size = 5
|
||||
icon = 'icons/effects/160x160.dmi'
|
||||
icon_state = "emfield_s5"
|
||||
pixel_x = -64 * PIXEL_MULTIPLIER
|
||||
pixel_y = -64 * PIXEL_MULTIPLIER
|
||||
//
|
||||
changed = 5
|
||||
if(7)
|
||||
size = 7
|
||||
icon = 'icons/effects/224x224.dmi'
|
||||
icon_state = "emfield_s7"
|
||||
pixel_x = -96 * PIXEL_MULTIPLIER
|
||||
pixel_y = -96 * PIXEL_MULTIPLIER
|
||||
//
|
||||
changed = 7
|
||||
for(var/obj/effect/fusion_particle_catcher/catcher in particle_catchers)
|
||||
catcher.UpdateSize()
|
||||
return changed
|
||||
|
||||
//the !!fun!! part
|
||||
/obj/effect/fusion_em_field/proc/React()
|
||||
//loop through the reactants in random order
|
||||
var/list/react_pool = dormant_reactant_quantities.Copy()
|
||||
|
||||
//cant have any reactions if there aren't any reactants present
|
||||
if(react_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 react_pool)
|
||||
react_pool[reactant] = rand(Floor(react_pool[reactant]/2),react_pool[reactant])
|
||||
dormant_reactant_quantities[reactant] -= react_pool[reactant]
|
||||
if(!react_pool[reactant])
|
||||
react_pool -= reactant
|
||||
|
||||
//loop through all the reacting reagents, picking out random reactions for them
|
||||
var/list/produced_reactants = new/list
|
||||
var/list/p_react_pool = react_pool.Copy()
|
||||
while(p_react_pool.len)
|
||||
//pick one of the unprocessed reacting reagents randomly
|
||||
var/cur_p_react = pick(p_react_pool)
|
||||
p_react_pool.Remove(cur_p_react)
|
||||
|
||||
//grab all the possible reactants to have a reaction with
|
||||
var/list/possible_s_reacts = react_pool.Copy()
|
||||
//if there is only one of a particular reactant, then it can not react with itself so remove it
|
||||
possible_s_reacts[cur_p_react] -= 1
|
||||
if(possible_s_reacts[cur_p_react] < 1)
|
||||
possible_s_reacts.Remove(cur_p_react)
|
||||
|
||||
//loop through and work out all the possible reactions
|
||||
var/list/possible_reactions = new/list
|
||||
for(var/cur_s_react in possible_s_reacts)
|
||||
if(possible_s_reacts[cur_s_react] < 1)
|
||||
continue
|
||||
var/decl/fusion_reaction/cur_reaction = get_fusion_reaction(cur_p_react, cur_s_react)
|
||||
if(cur_reaction && plasma_temperature >= cur_reaction.minimum_energy_level)
|
||||
possible_reactions.Add(cur_reaction)
|
||||
|
||||
//if there are no possible reactions here, abandon this primary reactant and move on
|
||||
if(!possible_reactions.len)
|
||||
continue
|
||||
|
||||
//split up the reacting atoms between the possible reactions
|
||||
while(possible_reactions.len)
|
||||
var/decl/fusion_reaction/cur_reaction = pick(possible_reactions)
|
||||
possible_reactions.Remove(cur_reaction)
|
||||
|
||||
//set the randmax to be the lower of the two involved reactants
|
||||
var/max_num_reactants = react_pool[cur_reaction.p_react] > react_pool[cur_reaction.s_react] ? \
|
||||
react_pool[cur_reaction.s_react] : react_pool[cur_reaction.p_react]
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//make sure we have enough energy
|
||||
if(plasma_temperature < cur_reaction.minimum_reaction_temperature)
|
||||
continue
|
||||
|
||||
if(plasma_temperature < max_num_reactants * cur_reaction.energy_consumption)
|
||||
max_num_reactants = round(plasma_temperature / cur_reaction.energy_consumption)
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//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( react_pool[cur_reaction.p_react] - amount_reacting >= 0 )
|
||||
react_pool[cur_reaction.p_react] -= amount_reacting
|
||||
else
|
||||
amount_reacting = react_pool[cur_reaction.p_react]
|
||||
react_pool[cur_reaction.p_react] = 0
|
||||
//same again for secondary reactant
|
||||
if(react_pool[cur_reaction.s_react] - amount_reacting >= 0 )
|
||||
react_pool[cur_reaction.s_react] -= amount_reacting
|
||||
else
|
||||
react_pool[cur_reaction.p_react] += amount_reacting - react_pool[cur_reaction.p_react]
|
||||
amount_reacting = react_pool[cur_reaction.s_react]
|
||||
react_pool[cur_reaction.s_react] = 0
|
||||
|
||||
plasma_temperature -= max_num_reactants * cur_reaction.energy_consumption // Remove the consumed energy.
|
||||
plasma_temperature += max_num_reactants * cur_reaction.energy_production // Add any produced energy.
|
||||
radiation += max_num_reactants * cur_reaction.radiation // Add any produced radiation.
|
||||
tick_instability += max_num_reactants * cur_reaction.instability
|
||||
|
||||
// Create the reaction products.
|
||||
for(var/reactant in cur_reaction.products)
|
||||
var/success = 0
|
||||
for(var/check_reactant in produced_reactants)
|
||||
if(check_reactant == reactant)
|
||||
produced_reactants[reactant] += cur_reaction.products[reactant] * amount_reacting
|
||||
success = 1
|
||||
break
|
||||
if(!success)
|
||||
produced_reactants[reactant] = cur_reaction.products[reactant] * amount_reacting
|
||||
|
||||
// Handle anything special. If this proc returns true, abort the current reaction.
|
||||
if(cur_reaction.handle_reaction_special(src))
|
||||
return
|
||||
|
||||
// This reaction is done, and can't be repeated this sub-cycle.
|
||||
possible_reactions.Remove(cur_reaction.s_react)
|
||||
|
||||
// Loop through the newly produced reactants and add them to the pool.
|
||||
for(var/reactant in produced_reactants)
|
||||
AddParticles(reactant, produced_reactants[reactant])
|
||||
|
||||
// Check whether there are reactants left, and add them back to the pool.
|
||||
for(var/reactant in react_pool)
|
||||
AddParticles(reactant, react_pool[reactant])
|
||||
|
||||
/obj/effect/fusion_em_field/Destroy()
|
||||
set_light(0)
|
||||
RadiateAll()
|
||||
for(var/obj/effect/fusion_particle_catcher/catcher in particle_catchers)
|
||||
qdel(catcher)
|
||||
if(owned_core)
|
||||
owned_core.owned_field = null
|
||||
owned_core = null
|
||||
processing_objects.Remove(src)
|
||||
. = ..()
|
||||
|
||||
/obj/effect/fusion_em_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
AddEnergy(Proj.damage)
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
#undef FUSION_HEAT_CAP
|
||||
67
code/modules/power/fusion/fuel_assembly/fuel_assembly.dm
Normal file
67
code/modules/power/fusion/fuel_assembly/fuel_assembly.dm
Normal file
@@ -0,0 +1,67 @@
|
||||
/obj/item/weapon/fuel_assembly
|
||||
name = "fuel rod assembly"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "fuel_assembly"
|
||||
layer = 4
|
||||
|
||||
var/material_name
|
||||
|
||||
var/percent_depleted = 1
|
||||
var/list/rod_quantities = list()
|
||||
var/fuel_type = "composite"
|
||||
var/fuel_colour
|
||||
var/radioactivity = 0
|
||||
var/const/initial_amount = 300
|
||||
|
||||
/obj/item/weapon/fuel_assembly/New(var/newloc, var/_material, var/_colour)
|
||||
fuel_type = _material
|
||||
fuel_colour = _colour
|
||||
..(newloc)
|
||||
|
||||
/obj/item/weapon/fuel_assembly/initialize()
|
||||
. = ..()
|
||||
var/material/material = get_material_by_name(fuel_type)
|
||||
if(istype(material))
|
||||
name = "[material.use_name] fuel rod assembly"
|
||||
desc = "A fuel rod for a fusion reactor. This one is made from [material.use_name]."
|
||||
fuel_colour = material.icon_colour
|
||||
fuel_type = material.use_name
|
||||
if(material.radioactivity)
|
||||
radioactivity = material.radioactivity
|
||||
desc += " It is warm to the touch."
|
||||
processing_objects += src
|
||||
if(material.luminescence)
|
||||
set_light(material.luminescence, material.luminescence, material.icon_colour)
|
||||
else
|
||||
name = "[fuel_type] fuel rod assembly"
|
||||
desc = "A fuel rod for a fusion reactor. This one is made from [fuel_type]."
|
||||
|
||||
icon_state = "blank"
|
||||
var/image/I = image(icon, "fuel_assembly")
|
||||
I.color = fuel_colour
|
||||
overlays += list(I, image(icon, "fuel_assembly_bracket"))
|
||||
rod_quantities[fuel_type] = initial_amount
|
||||
|
||||
/obj/item/weapon/fuel_assembly/process()
|
||||
if(!radioactivity)
|
||||
return PROCESS_KILL
|
||||
|
||||
if(istype(loc, /turf))
|
||||
radiation_repository.radiate(src, max(1,ceil(radioactivity/30)))
|
||||
|
||||
/obj/item/weapon/fuel_assembly/Destroy()
|
||||
processing_objects -= src
|
||||
return ..()
|
||||
|
||||
// Mapper shorthand.
|
||||
/obj/item/weapon/fuel_assembly/deuterium/New(var/newloc)
|
||||
..(newloc, "deuterium")
|
||||
|
||||
/obj/item/weapon/fuel_assembly/tritium/New(var/newloc)
|
||||
..(newloc, "tritium")
|
||||
|
||||
/obj/item/weapon/fuel_assembly/phoron/New(var/newloc)
|
||||
..(newloc, "phoron")
|
||||
|
||||
/obj/item/weapon/fuel_assembly/supermatter/New(var/newloc)
|
||||
..(newloc, "supermatter")
|
||||
54
code/modules/power/fusion/fuel_assembly/fuel_compressor.dm
Normal file
54
code/modules/power/fusion/fuel_assembly/fuel_compressor.dm
Normal file
@@ -0,0 +1,54 @@
|
||||
/obj/machinery/fusion_fuel_compressor
|
||||
name = "fuel compressor"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "fuel_compressor1"
|
||||
density = 1
|
||||
anchored = 1
|
||||
layer = 4
|
||||
|
||||
/obj/machinery/fusion_fuel_compressor/MouseDrop_T(var/atom/movable/target, var/mob/user)
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return
|
||||
return do_special_fuel_compression(target, user)
|
||||
|
||||
/obj/machinery/fusion_fuel_compressor/proc/do_special_fuel_compression(var/obj/item/thing, var/mob/user)
|
||||
if(istype(thing) && thing.reagents && thing.reagents.total_volume && thing.is_open_container())
|
||||
if(thing.reagents.reagent_list.len > 1)
|
||||
to_chat(user, "<span class='warning'>The contents of \the [thing] are impure and cannot be used as fuel.</span>")
|
||||
return 1
|
||||
if(thing.reagents.total_volume < 50)
|
||||
to_chat(user, "<span class='warning'>You need at least fifty units of material to form a fuel rod.</span>")
|
||||
return 1
|
||||
var/datum/reagent/R = thing.reagents.reagent_list[1]
|
||||
visible_message("<span class='notice'>\The [src] compresses the contents of \the [thing] into a new fuel assembly.</span>")
|
||||
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), R.id, R.color)
|
||||
thing.reagents.remove_reagent(R.id, R.volume)
|
||||
user.put_in_hands(F)
|
||||
|
||||
else if(istype(thing, /obj/machinery/power/supermatter/shard))
|
||||
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), "supermatter")
|
||||
visible_message("<span class='notice'>\The [src] compresses the \[thing] into a new fuel assembly.</span>")
|
||||
qdel(thing)
|
||||
user.put_in_hands(F)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/fusion_fuel_compressor/attackby(var/obj/item/thing, var/mob/user)
|
||||
if(istype(thing, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/M = thing
|
||||
var/material/mat = M.get_material()
|
||||
if(!mat.is_fusion_fuel)
|
||||
to_chat(user, "<span class='warning'>It would be pointless to make a fuel rod out of [mat.use_name].</span>")
|
||||
return
|
||||
if(M.get_amount() < 25)
|
||||
to_chat(user, "<span class='warning'>You need at least 25 [mat.sheet_plural_name] to make a fuel rod.</span>")
|
||||
return
|
||||
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), mat.name)
|
||||
visible_message("<span class='notice'>\The [src] compresses the [mat.use_name] into a new fuel assembly.</span>")
|
||||
M.use(25)
|
||||
user.put_in_hands(F)
|
||||
|
||||
else if(do_special_fuel_compression(thing, user))
|
||||
return
|
||||
|
||||
return ..()
|
||||
102
code/modules/power/fusion/fuel_assembly/fuel_control.dm
Normal file
102
code/modules/power/fusion/fuel_assembly/fuel_control.dm
Normal file
@@ -0,0 +1,102 @@
|
||||
/obj/machinery/computer/fusion_fuel_control
|
||||
name = "fuel injection control computer"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "fuel"
|
||||
|
||||
var/id_tag
|
||||
var/scan_range = 25
|
||||
|
||||
/obj/machinery/computer/fusion_fuel_control/attack_ai(mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/fusion_fuel_control/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/computer/fusion_fuel_control/interact(var/mob/user)
|
||||
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=fuel_control")
|
||||
return
|
||||
|
||||
if (!istype(user, /mob/living/silicon) && get_dist(src, user) > 1)
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=fuel_control")
|
||||
return
|
||||
|
||||
if(!id_tag)
|
||||
to_chat(user, "<span class='warning'>This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>")
|
||||
return
|
||||
|
||||
var/dat = "<B>Reactor Core Fuel Control #[id_tag]</B><BR>"
|
||||
dat += {"
|
||||
<hr>
|
||||
<table border=1 width='100%'>
|
||||
<tr>
|
||||
<td><b>Contains</b></td>
|
||||
<td><b>Assembly</b></td>
|
||||
<td><b>Remaining</b></td>
|
||||
</tr>"}
|
||||
|
||||
for(var/obj/machinery/fusion_fuel_injector/I in fuel_injectors)
|
||||
if(!id_tag || !I.id_tag || I.id_tag != id_tag || get_dist(src, I) > scan_range)
|
||||
continue
|
||||
|
||||
dat += "<tr>"
|
||||
|
||||
if(I.stat & (BROKEN|NOPOWER))
|
||||
dat += "<td><span class='danger'>ERROR</span></td>"
|
||||
dat += "<td><span class='danger'>ERROR</span></td>"
|
||||
dat += "<td><span class='danger'>ERROR</span></td>"
|
||||
else
|
||||
dat += "<td>[I.cur_assembly ? I.cur_assembly.fuel_type : "NONE"]</td>"
|
||||
if(I.cur_assembly)
|
||||
dat += "<td><a href='?src=\ref[src];toggle_injecting=\ref[I]'>\[[I.injecting ? "Halt injecting" : "Begin injecting"]\]</a></td>"
|
||||
else
|
||||
dat += "<td>None</td>"
|
||||
if(I.cur_assembly)
|
||||
dat += "<td>[I.cur_assembly.percent_depleted * 100]%</td>"
|
||||
else
|
||||
dat += "<td>NA</td>"
|
||||
|
||||
dat += "</tr>"
|
||||
|
||||
dat += {"</table><hr>
|
||||
<A href='?src=\ref[src];refresh=1'>Refresh</A>
|
||||
<A href='?src=\ref[src];close=1'>Close</A><BR>"}
|
||||
|
||||
var/datum/browser/popup = new(user, "fuel_control", "Fusion Fuel Control Console", 800, 400, src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/computer/fusion_fuel_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["toggle_injecting"])
|
||||
var/obj/machinery/fusion_fuel_injector/I = locate(href_list["toggle_injecting"])
|
||||
if(I.id_tag != id_tag || get_dist(src, I) > scan_range)
|
||||
return
|
||||
|
||||
if(istype(I))
|
||||
if(I.injecting)
|
||||
I.StopInjecting()
|
||||
else
|
||||
I.BeginInjecting()
|
||||
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=fuel_control")
|
||||
usr.unset_machine()
|
||||
|
||||
updateDialog()
|
||||
|
||||
|
||||
/obj/machinery/computer/fusion_fuel_control/attackby(var/obj/item/W, var/mob/user)
|
||||
if(ismultitool(W))
|
||||
var/new_ident = input("Enter a new ident tag.", "Fuel Control", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
return
|
||||
return ..()
|
||||
153
code/modules/power/fusion/fuel_assembly/fuel_injector.dm
Normal file
153
code/modules/power/fusion/fuel_assembly/fuel_injector.dm
Normal file
@@ -0,0 +1,153 @@
|
||||
var/list/fuel_injectors = list()
|
||||
|
||||
/obj/machinery/fusion_fuel_injector
|
||||
name = "fuel injector"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "injector0"
|
||||
density = 1
|
||||
anchored = 0
|
||||
req_access = list(access_engine)
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 500
|
||||
|
||||
var/fuel_usage = 0.0001
|
||||
var/id_tag
|
||||
var/injecting = 0
|
||||
var/obj/item/weapon/fuel_assembly/cur_assembly
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/New()
|
||||
..()
|
||||
fuel_injectors += src
|
||||
tag = null
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/Destroy()
|
||||
if(cur_assembly)
|
||||
cur_assembly.forceMove(get_turf(src))
|
||||
cur_assembly = null
|
||||
fuel_injectors -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/mapped
|
||||
anchored = 1
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/process()
|
||||
if(injecting)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
StopInjecting()
|
||||
else
|
||||
Inject()
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/attackby(obj/item/W, mob/user)
|
||||
|
||||
if(ismultitool(W))
|
||||
var/new_ident = input("Enter a new ident tag.", "Fuel Injector", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/weapon/fuel_assembly))
|
||||
|
||||
if(injecting)
|
||||
to_chat(user, "<span class='warning'>Shut \the [src] off before playing with the fuel rod!</span>")
|
||||
return
|
||||
|
||||
if(cur_assembly)
|
||||
cur_assembly.forceMove(get_turf(src))
|
||||
visible_message("<span class='notice'>\The [user] swaps \the [src]'s [cur_assembly] for \a [W].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>\The [user] inserts \a [W] into \the [src].</span>")
|
||||
|
||||
user.drop_from_inventory(W)
|
||||
W.forceMove(src)
|
||||
if(cur_assembly)
|
||||
cur_assembly.forceMove(get_turf(src))
|
||||
user.put_in_hands(cur_assembly)
|
||||
cur_assembly = W
|
||||
return
|
||||
|
||||
if(iswrench(W))
|
||||
if(injecting)
|
||||
to_chat(user, "<span class='warning'>Shut \the [src] off first!</span>")
|
||||
return
|
||||
anchored = !anchored
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] secures \the [src] to the floor.")
|
||||
else
|
||||
user.visible_message("\The [user] unsecures \the [src] from the floor.")
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/attack_hand(mob/user)
|
||||
|
||||
if(injecting)
|
||||
to_chat(user, "<span class='warning'>Shut \the [src] off before playing with the fuel rod!</span>")
|
||||
return
|
||||
|
||||
if(cur_assembly)
|
||||
cur_assembly.forceMove(get_turf(src))
|
||||
user.put_in_hands(cur_assembly)
|
||||
visible_message("<span class='notice'>\The [user] removes \the [cur_assembly] from \the [src].</span>")
|
||||
cur_assembly = null
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is no fuel rod in \the [src].</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/proc/BeginInjecting()
|
||||
if(!injecting && cur_assembly)
|
||||
icon_state = "injector1"
|
||||
injecting = 1
|
||||
use_power = 1
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/proc/StopInjecting()
|
||||
if(injecting)
|
||||
injecting = 0
|
||||
icon_state = "injector0"
|
||||
use_power = 0
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/proc/Inject()
|
||||
if(!injecting)
|
||||
return
|
||||
if(cur_assembly)
|
||||
var/amount_left = 0
|
||||
for(var/reagent in cur_assembly.rod_quantities)
|
||||
if(cur_assembly.rod_quantities[reagent] > 0)
|
||||
var/amount = cur_assembly.rod_quantities[reagent] * fuel_usage
|
||||
var/numparticles = round(amount * 1000)
|
||||
if(numparticles < 1)
|
||||
numparticles = 1
|
||||
var/obj/effect/accelerated_particle/A = new/obj/effect/accelerated_particle(get_turf(src), dir)
|
||||
A.particle_type = reagent
|
||||
A.additional_particles = numparticles - 1
|
||||
A.move(1)
|
||||
if(cur_assembly)
|
||||
cur_assembly.rod_quantities[reagent] -= amount
|
||||
amount_left += cur_assembly.rod_quantities[reagent]
|
||||
if(cur_assembly)
|
||||
cur_assembly.percent_depleted = amount_left / cur_assembly.initial_amount
|
||||
flick("injector-emitting",src)
|
||||
else
|
||||
StopInjecting()
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/verb/rotate_clock()
|
||||
set category = "Object"
|
||||
set name = "Rotate Generator (Clockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.incapacitated() || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.dir = turn(src.dir, -90)
|
||||
|
||||
/obj/machinery/fusion_fuel_injector/verb/rotate_anticlock()
|
||||
set category = "Object"
|
||||
set name = "Rotate Generator (Counter-clockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.incapacitated() || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.dir = turn(src.dir, 90)
|
||||
89
code/modules/power/fusion/fusion_circuits.dm
Normal file
89
code/modules/power/fusion/fusion_circuits.dm
Normal file
@@ -0,0 +1,89 @@
|
||||
/obj/item/weapon/circuitboard/fusion_core_control
|
||||
name = "circuit board (fusion core controller)"
|
||||
build_path = /obj/machinery/computer/fusion_core_control
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
|
||||
/obj/item/weapon/circuitboard/fusion_fuel_compressor
|
||||
name = "circuit board (fusion fuel compressor)"
|
||||
build_path = /obj/machinery/fusion_fuel_compressor
|
||||
board_type = "machine"
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/manipulator/pico = 2,
|
||||
/obj/item/weapon/stock_parts/matter_bin/super = 2,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1,
|
||||
/obj/item/stack/cable_coil = 5
|
||||
)
|
||||
|
||||
/obj/item/weapon/circuitboard/fusion_fuel_control
|
||||
name = "circuit board (fusion fuel controller)"
|
||||
build_path = /obj/machinery/computer/fusion_fuel_control
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
|
||||
/obj/item/weapon/circuitboard/gyrotron_control
|
||||
name = "circuit board (gyrotron controller)"
|
||||
build_path = /obj/machinery/computer/gyrotron_control
|
||||
origin_tech = list(TECH_DATA = 4, TECH_ENGINEERING = 4)
|
||||
|
||||
/obj/item/weapon/circuitboard/fusion_core
|
||||
name = "internal circuitry (fusion core)"
|
||||
build_path = /obj/machinery/power/fusion_core
|
||||
board_type = "machine"
|
||||
origin_tech = list(TECH_BLUESPACE = 2, TECH_MAGNET = 4, TECH_POWER = 4)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/manipulator/pico = 2,
|
||||
/obj/item/weapon/stock_parts/micro_laser/ultra = 1,
|
||||
/obj/item/weapon/stock_parts/subspace/crystal = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1,
|
||||
/obj/item/stack/cable_coil = 5
|
||||
)
|
||||
|
||||
/obj/item/weapon/circuitboard/fusion_injector
|
||||
name = "internal circuitry (fusion fuel injector)"
|
||||
build_path = /obj/machinery/fusion_fuel_injector
|
||||
board_type = "machine"
|
||||
origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 4)
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/manipulator/pico = 2,
|
||||
/obj/item/weapon/stock_parts/scanning_module/phasic = 1,
|
||||
/obj/item/weapon/stock_parts/matter_bin/super = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1,
|
||||
/obj/item/stack/cable_coil = 5
|
||||
)
|
||||
|
||||
/datum/design/circuit/fusion
|
||||
name = "fusion core control console"
|
||||
id = "fusion_core_control"
|
||||
build_path = /obj/item/weapon/circuitboard/fusion_core_control
|
||||
sort_string = "LAAAD"
|
||||
req_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_MATERIAL = 3)
|
||||
|
||||
/datum/design/circuit/fusion/fuel_compressor
|
||||
name = "fusion fuel compressor"
|
||||
id = "fusion_fuel_compressor"
|
||||
build_path = /obj/item/weapon/circuitboard/fusion_fuel_compressor
|
||||
sort_string = "LAAAE"
|
||||
|
||||
/datum/design/circuit/fusion/fuel_control
|
||||
name = "fusion fuel control console"
|
||||
id = "fusion_fuel_control"
|
||||
build_path = /obj/item/weapon/circuitboard/fusion_fuel_control
|
||||
sort_string = "LAAAF"
|
||||
|
||||
/datum/design/circuit/fusion/gyrotron_control
|
||||
name = "gyrotron control console"
|
||||
id = "gyrotron_control"
|
||||
build_path = /obj/item/weapon/circuitboard/gyrotron_control
|
||||
sort_string = "LAAAG"
|
||||
|
||||
/datum/design/circuit/fusion/core
|
||||
name = "fusion core"
|
||||
id = "fusion_core"
|
||||
build_path = /obj/item/weapon/circuitboard/fusion_core
|
||||
sort_string = "LAAAH"
|
||||
|
||||
/datum/design/circuit/fusion/injector
|
||||
name = "fusion fuel injector"
|
||||
id = "fusion_injector"
|
||||
build_path = /obj/item/weapon/circuitboard/fusion_injector
|
||||
sort_string = "LAAAI"
|
||||
41
code/modules/power/fusion/fusion_particle_catcher.dm
Normal file
41
code/modules/power/fusion/fusion_particle_catcher.dm
Normal file
@@ -0,0 +1,41 @@
|
||||
/obj/effect/fusion_particle_catcher
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
density = 1
|
||||
anchored = 1
|
||||
invisibility = 101
|
||||
var/obj/effect/fusion_em_field/parent
|
||||
var/mysize = 0
|
||||
|
||||
light_color = COLOR_BLUE
|
||||
|
||||
/obj/effect/fusion_particle_catcher/Destroy()
|
||||
. =..()
|
||||
parent.particle_catchers -= src
|
||||
parent = null
|
||||
|
||||
/obj/effect/fusion_particle_catcher/proc/SetSize(var/newsize)
|
||||
name = "collector [newsize]"
|
||||
mysize = newsize
|
||||
UpdateSize()
|
||||
|
||||
/obj/effect/fusion_particle_catcher/proc/AddParticles(var/name, var/quantity = 1)
|
||||
if(parent && parent.size >= mysize)
|
||||
parent.AddParticles(name, quantity)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/effect/fusion_particle_catcher/proc/UpdateSize()
|
||||
if(parent.size >= mysize)
|
||||
density = 1
|
||||
name = "collector [mysize] ON"
|
||||
else
|
||||
density = 0
|
||||
name = "collector [mysize] OFF"
|
||||
|
||||
/obj/effect/fusion_particle_catcher/bullet_act(var/obj/item/projectile/Proj)
|
||||
parent.AddEnergy(Proj.damage)
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
/obj/effect/fusion_particle_catcher/CanPass(var/atom/movable/mover, var/turf/target, var/height=0, var/air_group=0)
|
||||
return ismob(mover)
|
||||
164
code/modules/power/fusion/fusion_reactions.dm
Normal file
164
code/modules/power/fusion/fusion_reactions.dm
Normal file
@@ -0,0 +1,164 @@
|
||||
var/list/fusion_reactions
|
||||
|
||||
/decl/fusion_reaction
|
||||
var/p_react = "" // Primary reactant.
|
||||
var/s_react = "" // Secondary reactant.
|
||||
var/minimum_energy_level = 1
|
||||
var/energy_consumption = 0
|
||||
var/energy_production = 0
|
||||
var/radiation = 0
|
||||
var/instability = 0
|
||||
var/list/products = list()
|
||||
var/minimum_reaction_temperature = 100
|
||||
|
||||
/decl/fusion_reaction/proc/handle_reaction_special(var/obj/effect/fusion_em_field/holder)
|
||||
return 0
|
||||
|
||||
proc/get_fusion_reaction(var/p_react, var/s_react, var/m_energy)
|
||||
if(!fusion_reactions)
|
||||
fusion_reactions = list()
|
||||
for(var/rtype in typesof(/decl/fusion_reaction) - /decl/fusion_reaction)
|
||||
var/decl/fusion_reaction/cur_reaction = new rtype()
|
||||
if(!fusion_reactions[cur_reaction.p_react])
|
||||
fusion_reactions[cur_reaction.p_react] = list()
|
||||
fusion_reactions[cur_reaction.p_react][cur_reaction.s_react] = cur_reaction
|
||||
if(!fusion_reactions[cur_reaction.s_react])
|
||||
fusion_reactions[cur_reaction.s_react] = list()
|
||||
fusion_reactions[cur_reaction.s_react][cur_reaction.p_react] = cur_reaction
|
||||
|
||||
if(fusion_reactions.Find(p_react))
|
||||
var/list/secondary_reactions = fusion_reactions[p_react]
|
||||
if(secondary_reactions.Find(s_react))
|
||||
return fusion_reactions[p_react][s_react]
|
||||
|
||||
// Material fuels
|
||||
// deuterium
|
||||
// tritium
|
||||
// phoron
|
||||
// supermatter
|
||||
|
||||
// Virtual fuels
|
||||
// helium-3
|
||||
// lithium-6
|
||||
// boron-11
|
||||
|
||||
// Basic power production reactions.
|
||||
/decl/fusion_reaction/deuterium_deuterium
|
||||
p_react = "deuterium"
|
||||
s_react = "deuterium"
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
|
||||
// Advanced production reactions (todo)
|
||||
/decl/fusion_reaction/deuterium_helium
|
||||
p_react = "deuterium"
|
||||
s_react = "helium-3"
|
||||
energy_consumption = 1
|
||||
energy_production = 5
|
||||
radiation = 2
|
||||
|
||||
/decl/fusion_reaction/deuterium_tritium
|
||||
p_react = "deuterium"
|
||||
s_react = "tritium"
|
||||
energy_consumption = 1
|
||||
energy_production = 1
|
||||
products = list("helium-3" = 1)
|
||||
instability = 0.5
|
||||
radiation = 3
|
||||
|
||||
/decl/fusion_reaction/deuterium_lithium
|
||||
p_react = "deuterium"
|
||||
s_react = "lithium"
|
||||
energy_consumption = 2
|
||||
energy_production = 0
|
||||
radiation = 3
|
||||
products = list("tritium"= 1)
|
||||
instability = 1
|
||||
|
||||
// Unideal/material production reactions
|
||||
/decl/fusion_reaction/oxygen_oxygen
|
||||
p_react = "oxygen"
|
||||
s_react = "oxygen"
|
||||
energy_consumption = 10
|
||||
energy_production = 0
|
||||
instability = 5
|
||||
radiation = 5
|
||||
products = list("silicon"= 1)
|
||||
|
||||
/decl/fusion_reaction/iron_iron
|
||||
p_react = "iron"
|
||||
s_react = "iron"
|
||||
products = list("silver" = 1, "gold" = 1, "platinum" = 1) // Not realistic but w/e
|
||||
energy_consumption = 10
|
||||
energy_production = 0
|
||||
instability = 2
|
||||
minimum_reaction_temperature = 10000
|
||||
|
||||
/decl/fusion_reaction/phoron_hydrogen
|
||||
p_react = "hydrogen"
|
||||
s_react = "phoron"
|
||||
energy_consumption = 10
|
||||
energy_production = 0
|
||||
instability = 5
|
||||
products = list("mydrogen" = 1)
|
||||
minimum_reaction_temperature = 8000
|
||||
|
||||
// VERY UNIDEAL REACTIONS.
|
||||
/decl/fusion_reaction/phoron_supermatter
|
||||
p_react = "supermatter"
|
||||
s_react = "phoron"
|
||||
energy_consumption = 0
|
||||
energy_production = 5
|
||||
radiation = 20
|
||||
instability = 20
|
||||
|
||||
/decl/fusion_reaction/phoron_supermatter/handle_reaction_special(var/obj/effect/fusion_em_field/holder)
|
||||
|
||||
wormhole_event()
|
||||
|
||||
var/turf/origin = get_turf(holder)
|
||||
holder.Rupture()
|
||||
qdel(holder)
|
||||
var/radiation_level = rand(100, 200)
|
||||
|
||||
// Copied from the SM for proof of concept. //Not any more --Cirra //Use the whole z proc --Leshana
|
||||
radiation_repository.z_radiate(locate(1, 1, holder.z), radiation_level, 1)
|
||||
|
||||
for(var/mob/living/mob in living_mob_list)
|
||||
var/turf/T = get_turf(mob)
|
||||
if(T && (holder.z == T.z))
|
||||
if(istype(mob, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = mob
|
||||
H.hallucination += rand(100,150)
|
||||
|
||||
for(var/obj/machinery/fusion_fuel_injector/I in range(world.view, origin))
|
||||
if(I.cur_assembly && I.cur_assembly.fuel_type == "supermatter")
|
||||
explosion(get_turf(I), 1, 2, 3)
|
||||
spawn(5)
|
||||
if(I && I.loc)
|
||||
qdel(I)
|
||||
|
||||
sleep(5)
|
||||
explosion(origin, 1, 2, 5)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
// High end reactions.
|
||||
/decl/fusion_reaction/boron_hydrogen
|
||||
p_react = "boron"
|
||||
s_react = "hydrogen"
|
||||
minimum_energy_level = FUSION_HEAT_CAP * 0.5
|
||||
energy_consumption = 3
|
||||
energy_production = 15
|
||||
radiation = 3
|
||||
instability = 3
|
||||
|
||||
/decl/fusion_reaction/hydrogen_hydrogen
|
||||
p_react = "hydrogen"
|
||||
s_react = "hydrogen"
|
||||
minimum_energy_level = FUSION_HEAT_CAP * 0.75
|
||||
energy_consumption = 0
|
||||
energy_production = 20
|
||||
radiation = 5
|
||||
instability = 5
|
||||
57
code/modules/power/fusion/gyrotron/gyrotron.dm
Normal file
57
code/modules/power/fusion/gyrotron/gyrotron.dm
Normal file
@@ -0,0 +1,57 @@
|
||||
var/list/gyrotrons = list()
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron
|
||||
name = "gyrotron"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
desc = "It is a heavy duty industrial gyrotron suited for powering fusion reactors."
|
||||
icon_state = "emitter-off"
|
||||
req_access = list(access_engine)
|
||||
use_power = 1
|
||||
active_power_usage = 50000
|
||||
|
||||
var/id_tag
|
||||
var/rate = 3
|
||||
var/mega_energy = 1
|
||||
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/anchored
|
||||
anchored = 1
|
||||
state = 2
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/initialize()
|
||||
gyrotrons += src
|
||||
active_power_usage = mega_energy * 50000
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/Destroy()
|
||||
gyrotrons -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/process()
|
||||
active_power_usage = mega_energy * 50000
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/get_rand_burst_delay()
|
||||
return rate * 10
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/get_burst_delay()
|
||||
return rate * 10
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/get_emitter_beam()
|
||||
var/obj/item/projectile/beam/emitter/E = ..()
|
||||
E.damage = mega_energy * 50
|
||||
return E
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/update_icon()
|
||||
if (active && powernet && avail(active_power_usage))
|
||||
icon_state = "emitter-on"
|
||||
else
|
||||
icon_state = "emitter-off"
|
||||
|
||||
/obj/machinery/power/emitter/gyrotron/attackby(var/obj/item/W, var/mob/user)
|
||||
if(ismultitool(W))
|
||||
var/new_ident = input("Enter a new ident tag.", "Gyrotron", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
return
|
||||
return ..()
|
||||
97
code/modules/power/fusion/gyrotron/gyrotron_control.dm
Normal file
97
code/modules/power/fusion/gyrotron/gyrotron_control.dm
Normal file
@@ -0,0 +1,97 @@
|
||||
/obj/machinery/computer/gyrotron_control
|
||||
name = "gyrotron control console"
|
||||
icon = 'icons/obj/machines/power/fusion.dmi'
|
||||
icon_state = "engine"
|
||||
light_color = COLOR_BLUE
|
||||
|
||||
var/id_tag
|
||||
var/scan_range = 25
|
||||
|
||||
/obj/machinery/computer/gyrotron_control/attack_ai(var/mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/gyrotron_control/attack_hand(var/mob/user)
|
||||
add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/computer/gyrotron_control/interact(var/mob/user)
|
||||
|
||||
if(!id_tag)
|
||||
to_chat(user, "<span class='warning'>This console has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>")
|
||||
return
|
||||
|
||||
var/dat = "<td><b>Gyrotron controller #[id_tag]</b>"
|
||||
|
||||
dat = "<table><tr>"
|
||||
dat += "<td><b>Mode</b></td>"
|
||||
dat += "<td><b>Fire Delay</b></td>"
|
||||
dat += "<td><b>Power</b></td>"
|
||||
dat += "</tr>"
|
||||
|
||||
for(var/obj/machinery/power/emitter/gyrotron/G in gyrotrons)
|
||||
if(!G || G.id_tag != id_tag || get_dist(src, G) > scan_range)
|
||||
continue
|
||||
|
||||
dat += "<tr>"
|
||||
if(G.state != 2 || (G.stat & (NOPOWER | BROKEN))) //Error data not found.
|
||||
dat += "<td><span style='color: red'>ERROR</span></td>"
|
||||
dat += "<td><span style='color: red'>ERROR</span></td>"
|
||||
dat += "<td><span style='color: red'>ERROR</span></td>"
|
||||
else
|
||||
dat += "<td><a href='?src=\ref[src];machine=\ref[G];toggle=1'>[G.active ? "Emitting" : "Standing By"]</a></td>"
|
||||
dat += "<td><a href='?src=\ref[src];machine=\ref[G];modifyrate=1'>[G.rate]</a></td>"
|
||||
dat += "<td><a href='?src=\ref[src];machine=\ref[G];modifypower=1'>[G.mega_energy]</a></td>"
|
||||
|
||||
dat += "</tr></table>"
|
||||
|
||||
var/datum/browser/popup = new(user, "gyrotron_controller_[id_tag]", "Gyrotron Remote Control Console", 500, 400, src)
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
add_fingerprint(user)
|
||||
user.set_machine(src)
|
||||
|
||||
/obj/machinery/computer/gyrotron_control/Topic(var/href, var/list/href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
if(stat & (NOPOWER | BROKEN))
|
||||
return
|
||||
|
||||
var/obj/machinery/power/emitter/gyrotron/G = locate(href_list["machine"])
|
||||
if(!G || G.id_tag != id_tag || get_dist(src, G) > scan_range)
|
||||
return
|
||||
|
||||
if(href_list["modifypower"])
|
||||
var/new_val = input("Enter new emission power level (1 - 50)", "Modifying power level", G.mega_energy) as num
|
||||
if(!new_val)
|
||||
to_chat(usr, "<span class='warning'>That's not a valid number.</span>")
|
||||
return 1
|
||||
G.mega_energy = Clamp(new_val, 1, 50)
|
||||
G.active_power_usage = G.mega_energy * 1500
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
if(href_list["modifyrate"])
|
||||
var/new_val = input("Enter new emission delay between 1 and 10 seconds.", "Modifying emission rate", G.rate) as num
|
||||
if(!new_val)
|
||||
to_chat(usr, "<span class='warning'>That's not a valid number.</span>")
|
||||
return 1
|
||||
G.rate = Clamp(new_val, 1, 10)
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
if(href_list["toggle"])
|
||||
G.activate(usr)
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/computer/gyrotron_control/attackby(var/obj/item/W, var/mob/user)
|
||||
if(ismultitool(W))
|
||||
var/new_ident = input("Enter a new ident tag.", "Gyrotron Control", id_tag) as null|text
|
||||
if(new_ident && user.Adjacent(src))
|
||||
id_tag = new_ident
|
||||
return
|
||||
return ..()
|
||||
@@ -75,7 +75,7 @@
|
||||
src.active = 1
|
||||
user << "You turn on [src]."
|
||||
src.shot_number = 0
|
||||
src.fire_delay = 100
|
||||
src.fire_delay = get_initial_fire_delay()
|
||||
message_admins("Emitter turned on by [key_name(user, user.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Emitter turned on by [user.ckey]([user]) in ([x],[y],[z])")
|
||||
investigate_log("turned <font color='green'>on</font> by [user.key]","singulo")
|
||||
@@ -119,10 +119,10 @@
|
||||
|
||||
src.last_shot = world.time
|
||||
if(src.shot_number < burst_shots)
|
||||
src.fire_delay = 2
|
||||
src.fire_delay = get_burst_delay() //R-UST port
|
||||
src.shot_number ++
|
||||
else
|
||||
src.fire_delay = rand(min_burst_delay, max_burst_delay)
|
||||
src.fire_delay = get_rand_burst_delay() //R-UST port
|
||||
src.shot_number = 0
|
||||
|
||||
//need to calculate the power per shot as the emitter doesn't fire continuously.
|
||||
@@ -135,7 +135,7 @@
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
var/obj/item/projectile/beam/emitter/A = get_emitter_beam()
|
||||
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
|
||||
A.launch( get_step(src.loc, src.dir) )
|
||||
|
||||
@@ -266,3 +266,16 @@
|
||||
user << "<span class='danger'>\The [src] is damaged.</span>"
|
||||
if(77 to 99)
|
||||
user << "<span class='warning'>\The [src] is slightly damaged.</span>"
|
||||
|
||||
//R-UST port
|
||||
/obj/machinery/power/emitter/proc/get_initial_fire_delay()
|
||||
return 100
|
||||
|
||||
/obj/machinery/power/emitter/proc/get_rand_burst_delay()
|
||||
return rand(min_burst_delay, max_burst_delay)
|
||||
|
||||
/obj/machinery/power/emitter/proc/get_burst_delay()
|
||||
return 2
|
||||
|
||||
/obj/machinery/power/emitter/proc/get_emitter_beam()
|
||||
return new /obj/item/projectile/beam/emitter(get_turf(src))
|
||||
@@ -43,6 +43,21 @@
|
||||
toxmob(A)
|
||||
if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/singularity/)))
|
||||
A:energy += energy
|
||||
//R-UST port
|
||||
else if(istype(A,/obj/machinery/power/fusion_core))
|
||||
var/obj/machinery/power/fusion_core/collided_core = A
|
||||
if(particle_type && particle_type != "neutron")
|
||||
if(collided_core.AddParticles(particle_type, 1 + additional_particles))
|
||||
collided_core.owned_field.plasma_temperature += mega_energy
|
||||
collided_core.owned_field.energy += energy
|
||||
loc = null
|
||||
else if(istype(A, /obj/effect/fusion_particle_catcher))
|
||||
var/obj/effect/fusion_particle_catcher/PC = A
|
||||
if(particle_type && particle_type != "neutron")
|
||||
if(PC.parent.owned_core.AddParticles(particle_type, 1 + additional_particles))
|
||||
PC.parent.plasma_temperature += mega_energy
|
||||
PC.parent.energy += energy
|
||||
loc = null
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,31 @@
|
||||
color = "#003333"
|
||||
strength = 10
|
||||
|
||||
//R-UST port
|
||||
// Produced during deuterium synthesis. Super poisonous, SUPER flammable (doesn't need oxygen to burn).
|
||||
/datum/reagent/toxin/phoroxygen
|
||||
name = "Oxyphoron"
|
||||
id = "oxyphoron"
|
||||
description = "An exceptionally flammable molecule formed from deuterium synthesis."
|
||||
strength = 80
|
||||
var/fire_mult = 30
|
||||
|
||||
/datum/reagent/toxin/phoroxygen/touch_mob(var/mob/living/L, var/amount)
|
||||
if(istype(L))
|
||||
L.adjust_fire_stacks(amount / fire_mult)
|
||||
|
||||
/datum/reagent/toxin/phoroxygen/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.take_organ_damage(0, removed * 0.1) //being splashed directly with oxyphoron causes minor chemical burns
|
||||
if(prob(10 * fire_mult))
|
||||
M.pl_effects()
|
||||
|
||||
/datum/reagent/toxin/phoroxygen/touch_turf(var/turf/simulated/T)
|
||||
if(!istype(T))
|
||||
return
|
||||
T.assume_gas("oxygen", ceil(volume/2), T20C)
|
||||
T.assume_gas("phoron", ceil(volume/2), T20C)
|
||||
remove_self(volume)
|
||||
|
||||
/datum/reagent/toxin/spidertoxin
|
||||
name = "Spidertoxin"
|
||||
id = "spidertoxin"
|
||||
|
||||
@@ -1842,7 +1842,6 @@
|
||||
required_reagents = list("tea" = 5, "berryjuice" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/sakebomb
|
||||
name = "Sake Bomb"
|
||||
id = "sakebomb"
|
||||
result = "sakebomb"
|
||||
@@ -1863,7 +1862,6 @@
|
||||
required_reagents = list("sake" = 2, "vodka" = 2, "tomatojuice" = 1)
|
||||
result_amount = 5
|
||||
|
||||
/datum/chemical_reaction/drinks/tokyorose
|
||||
name = "Tokyo Rose"
|
||||
id = "tokyorose"
|
||||
result = "tokyorose"
|
||||
@@ -1906,9 +1904,6 @@
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/euphoria
|
||||
name = "Euphoria"
|
||||
id = "euphoria"
|
||||
result = "euphoria"
|
||||
required_reagents = list("specialwhiskey" = 1, "cognac" = 2)
|
||||
result_amount = 3
|
||||
|
||||
@@ -1916,7 +1911,6 @@
|
||||
name = "Xanadu Cannon"
|
||||
id = "xanaducannon"
|
||||
result = "xanaducannon"
|
||||
required_reagents = list("ale" = 1, "dr_gibb" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/drinks/debugger
|
||||
@@ -1945,4 +1939,17 @@
|
||||
id = "chrysanthemum"
|
||||
result = "chrysanthemum"
|
||||
required_reagents = list("sake" = 1, "melonliquor" = 1)
|
||||
result_amount = 2
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/deuterium
|
||||
name = "Deuterium"
|
||||
id = "deuterium"
|
||||
result = null
|
||||
required_reagents = list("water" = 10)
|
||||
catalysts = list("oxyphoron" = 5)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/deuterium/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/turf/T = get_turf(holder.my_atom)
|
||||
if(istype(T)) new /obj/item/stack/material/deuterium(T, created_volume)
|
||||
return
|
||||
251
code/modules/supermatter/setup_supermatter.dm
Normal file
251
code/modules/supermatter/setup_supermatter.dm
Normal file
@@ -0,0 +1,251 @@
|
||||
#define SETUP_OK 1 // All good
|
||||
#define SETUP_WARNING 2 // Something that shouldn't happen happened, but it's not critical so we will continue
|
||||
#define SETUP_ERROR 3 // Something bad happened, and it's important so we won't continue setup.
|
||||
#define SETUP_DELAYED 4 // Wait for other things first.
|
||||
|
||||
|
||||
#define ENERGY_NITROGEN 115 // Roughly 8 emitter shots.
|
||||
#define ENERGY_CARBONDIOXIDE 150 // Roughly 10 emitter shots.
|
||||
#define ENERGY_PHORON 300 // Roughly 20 emitter shots. Phoron can take more but this is enough to max out both SMESs anyway.
|
||||
|
||||
|
||||
/datum/admins/proc/setup_supermatter()
|
||||
set category = "Debug"
|
||||
set name = "Setup Supermatter"
|
||||
set desc = "Allows you to start the Supermatter engine."
|
||||
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
return
|
||||
|
||||
var/response = input(usr, "Are you sure? This will start up the engine with selected gas as coolant.", "Engine setup") as null|anything in list("N2", "CO2", "PH", "Abort")
|
||||
if(!response || response == "Abort")
|
||||
return
|
||||
|
||||
var/errors = 0
|
||||
var/warnings = 0
|
||||
var/success = 0
|
||||
|
||||
log_and_message_admins("## SUPERMATTER SETUP - Setup initiated by [usr] using coolant type [response].")
|
||||
|
||||
// CONFIGURATION PHASE
|
||||
// Coolant canisters, set types according to response.
|
||||
for(var/obj/effect/engine_setup/coolant_canister/C in world)
|
||||
switch(response)
|
||||
if("N2")
|
||||
C.canister_type = /obj/machinery/portable_atmospherics/canister/nitrogen/engine_setup/
|
||||
continue
|
||||
if("CO2")
|
||||
C.canister_type = /obj/machinery/portable_atmospherics/canister/carbon_dioxide/engine_setup/
|
||||
continue
|
||||
if("PH")
|
||||
C.canister_type = /obj/machinery/portable_atmospherics/canister/phoron/engine_setup/
|
||||
continue
|
||||
|
||||
for(var/obj/effect/engine_setup/core/C in world)
|
||||
switch(response)
|
||||
if("N2")
|
||||
C.energy_setting = ENERGY_NITROGEN
|
||||
continue
|
||||
if("CO2")
|
||||
C.energy_setting = ENERGY_CARBONDIOXIDE
|
||||
continue
|
||||
if("PH")
|
||||
C.energy_setting = ENERGY_PHORON
|
||||
continue
|
||||
|
||||
for(var/obj/effect/engine_setup/filter/F in world)
|
||||
F.coolant = response
|
||||
|
||||
var/list/delayed_objects = list()
|
||||
// SETUP PHASE
|
||||
for(var/obj/effect/engine_setup/S in world)
|
||||
var/result = S.activate(0)
|
||||
switch(result)
|
||||
if(SETUP_OK)
|
||||
success++
|
||||
continue
|
||||
if(SETUP_WARNING)
|
||||
warnings++
|
||||
continue
|
||||
if(SETUP_ERROR)
|
||||
errors++
|
||||
log_and_message_admins("## SUPERMATTER SETUP - Error encountered! Aborting.")
|
||||
break
|
||||
if(SETUP_DELAYED)
|
||||
delayed_objects.Add(S)
|
||||
continue
|
||||
|
||||
if(!errors)
|
||||
for(var/obj/effect/engine_setup/S in delayed_objects)
|
||||
var/result = S.activate(1)
|
||||
switch(result)
|
||||
if(SETUP_OK)
|
||||
success++
|
||||
continue
|
||||
if(SETUP_WARNING)
|
||||
warnings++
|
||||
continue
|
||||
if(SETUP_ERROR)
|
||||
errors++
|
||||
log_and_message_admins("## SUPERMATTER SETUP - Error encountered! Aborting.")
|
||||
break
|
||||
|
||||
log_and_message_admins("## SUPERMATTER SETUP - Setup completed with [errors] errors, [warnings] warnings and [success] successful steps.")
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/effect/engine_setup/
|
||||
name = "Engine Setup Marker"
|
||||
desc = "You shouldn't see this."
|
||||
invisibility = 101
|
||||
anchored = 1
|
||||
density = 0
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
icon_state = "x3"
|
||||
|
||||
/obj/effect/engine_setup/proc/activate(var/last = 0)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
// Tries to locate a pump, enables it, and sets it to MAX. Triggers warning if unable to locate a pump.
|
||||
/obj/effect/engine_setup/pump_max/
|
||||
name = "Pump Setup Marker"
|
||||
|
||||
/obj/effect/engine_setup/pump_max/activate()
|
||||
..()
|
||||
var/obj/machinery/atmospherics/binary/pump/P = locate() in get_turf(src)
|
||||
if(!P)
|
||||
log_and_message_admins("## WARNING: Unable to locate pump at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
P.target_pressure = P.max_pressure_setting
|
||||
P.use_power = 1
|
||||
P.update_icon()
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
|
||||
// Spawns an empty canister on this turf, if it has a connector port. Triggers warning if unable to find a connector port
|
||||
/obj/effect/engine_setup/empty_canister/
|
||||
name = "Empty Canister Marker"
|
||||
|
||||
/obj/effect/engine_setup/empty_canister/activate()
|
||||
..()
|
||||
var/obj/machinery/atmospherics/portables_connector/P = locate() in get_turf(src)
|
||||
if(!P)
|
||||
log_and_message_admins("## WARNING: Unable to locate connector port at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
new/obj/machinery/portable_atmospherics/canister(get_turf(src)) // Canisters automatically connect to connectors in New()
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
|
||||
|
||||
// Spawns a coolant canister on this turf, if it has a connector port.
|
||||
// Triggers error when unable to locate connector port or when coolant canister type is unset.
|
||||
/obj/effect/engine_setup/coolant_canister/
|
||||
name = "Coolant Canister Marker"
|
||||
var/canister_type = null
|
||||
|
||||
/obj/effect/engine_setup/coolant_canister/activate()
|
||||
..()
|
||||
var/obj/machinery/atmospherics/portables_connector/P = locate() in get_turf(src)
|
||||
if(!P)
|
||||
log_and_message_admins("## ERROR: Unable to locate coolant connector port at [x] [y] [z]!")
|
||||
return SETUP_ERROR
|
||||
if(!canister_type)
|
||||
log_and_message_admins("## ERROR: Canister type unset at [x] [y] [z]!")
|
||||
return SETUP_ERROR
|
||||
new canister_type(get_turf(src))
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
|
||||
// Energises the supermatter. Errors when unable to locate supermatter.
|
||||
/obj/effect/engine_setup/core/
|
||||
name = "Supermatter Core Marker"
|
||||
var/energy_setting = 0
|
||||
|
||||
/obj/effect/engine_setup/core/activate(var/last = 0)
|
||||
if(!last)
|
||||
return SETUP_DELAYED
|
||||
..()
|
||||
var/obj/machinery/power/supermatter/SM = locate() in get_turf(src)
|
||||
if(!SM)
|
||||
log_and_message_admins("## ERROR: Unable to locate supermatter core at [x] [y] [z]!")
|
||||
return SETUP_ERROR
|
||||
if(!energy_setting)
|
||||
log_and_message_admins("## ERROR: Energy setting unset at [x] [y] [z]!")
|
||||
return SETUP_ERROR
|
||||
SM.power = energy_setting
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
|
||||
// Tries to enable the SMES on max input/output settings. With load balancing it should be fine as long as engine outputs at least ~500kW
|
||||
/obj/effect/engine_setup/smes/
|
||||
name = "SMES Marker"
|
||||
|
||||
/obj/effect/engine_setup/smes/activate()
|
||||
..()
|
||||
var/obj/machinery/power/smes/S = locate() in get_turf(src)
|
||||
if(!S)
|
||||
log_and_message_admins("## WARNING: Unable to locate SMES unit at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
S.input_attempt = 1
|
||||
S.output_attempt = 1
|
||||
S.input_level = S.input_level_max
|
||||
S.output_level = S.output_level_max
|
||||
S.update_icon()
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
|
||||
// Sets up filters. This assumes filters are set to filter out N2 back to the core loop by default!
|
||||
/obj/effect/engine_setup/filter/
|
||||
name = "Omni Filter Marker"
|
||||
var/coolant = null
|
||||
|
||||
/obj/effect/engine_setup/filter/activate()
|
||||
..()
|
||||
var/obj/machinery/atmospherics/omni/filter/F = locate() in get_turf(src)
|
||||
if(!F)
|
||||
log_and_message_admins("## WARNING: Unable to locate omni filter at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
if(!coolant)
|
||||
log_and_message_admins("## WARNING: No coolant type set at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
|
||||
// Non-nitrogen coolant, adjust the filter's config first.
|
||||
if(coolant != "N2")
|
||||
for(var/datum/omni_port/P in F.ports)
|
||||
if(P.mode != ATM_N2)
|
||||
continue
|
||||
if(coolant == "PH")
|
||||
P.mode = ATM_P
|
||||
break
|
||||
else if(coolant == "CO2")
|
||||
P.mode = ATM_CO2
|
||||
break
|
||||
else
|
||||
log_and_message_admins("## WARNING: Inapropriate filter coolant type set at [x] [y] [z]!")
|
||||
return SETUP_WARNING
|
||||
F.rebuild_filtering_list()
|
||||
|
||||
F.use_power = 1
|
||||
F.update_icon()
|
||||
return SETUP_OK
|
||||
|
||||
|
||||
#undef SETUP_OK
|
||||
#undef SETUP_WARNING
|
||||
#undef SETUP_ERROR
|
||||
#undef SETUP_DELAYED
|
||||
#undef ENERGY_NITROGEN
|
||||
#undef ENERGY_CARBONDIOXIDE
|
||||
#undef ENERGY_PHORON
|
||||
Reference in New Issue
Block a user