Plumbing Splitter, reaction chamber, destroyer and pill press (#46149)

* chemical splitters

* adds the pill press

also removes a debug variable from the splitter used for getting the perfect ui size

* chem disposer

* half a reaction chamber

i forgot to fucking merge upstream so I cant do anything without making ungodly conflicts

* wip

* more work on the reaction chamber

* fixes big brain maths

* removes one / because travis is throwing a shitfit
This commit is contained in:
Time-Green
2019-09-02 23:52:29 -07:00
committed by Rob Bailey
parent 0a3b049572
commit d81e1fab5c
17 changed files with 382 additions and 18 deletions
+3 -1
View File
@@ -4,4 +4,6 @@
#define FOURTH_DUCT_LAYER 8
#define FIFTH_DUCT_LAYER 16
#define DUCT_LAYER_DEFAULT THIRD_DUCT_LAYER
#define DUCT_LAYER_DEFAULT THIRD_DUCT_LAYER
#define MACHINE_REAGENT_TRANSFER 10 //the default max plumbing machinery transfers
+3
View File
@@ -29,3 +29,6 @@
#define REM_REAGENT 3 // reagent removed (may still exist)
#define MIMEDRINK_SILENCE_DURATION 30 //ends up being 60 seconds given 1 tick every 2 seconds
//used by chem masters and pill presses
#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die
#define RANDOM_PILL_STYLE 22 //Dont change this one though
+7 -5
View File
@@ -54,7 +54,7 @@
return TRUE
///called from in process(). only calls process_request(), but can be overwritten for children with special behaviour
/datum/component/plumbing/proc/send_request(dir)
process_request(amount = 10, reagent = null, dir = dir)
process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = null, dir = dir)
///check who can give us what we want, and how many each of them will give us
/datum/component/plumbing/proc/process_request(amount, reagent, dir)
var/list/valid_suppliers = list()
@@ -71,12 +71,14 @@
give.transfer_to(src, amount / valid_suppliers.len, reagent, net)
///returns TRUE when they can give the specified amount and reagent. called by process request
/datum/component/plumbing/proc/can_give(amount, reagent, datum/ductnet/net)
if(!reagents || amount <= 0)
if(amount <= 0)
return
if(reagent) //only asked for one type of reagent
if(reagent in reagents.reagent_list)
return TRUE
for(var/A in reagents.reagent_list)
var/datum/reagent/R = A
if(R.type == reagent)
return TRUE
else if(reagents.total_volume > 0) //take whatever
return TRUE
///this is where the reagent is actually transferred and is thus the finish point of our process()
@@ -192,4 +194,4 @@
///input and output, like a holding tank
/datum/component/plumbing/tank
demand_connects = WEST
supply_connects = EAST
supply_connects = EAST
@@ -0,0 +1,18 @@
/datum/component/plumbing/acclimator
demand_connects = WEST
supply_connects = EAST
/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE)
. = ..()
if(. && istype(parent, /obj/machinery/plumbing/acclimator))
return TRUE
/datum/component/plumbing/acclimator/can_give(amount, reagent)
. = ..()
if(.)
var/obj/machinery/plumbing/acclimator/AC = parent
if(AC.reagents.chem_temp >= AC.target_temperature && AC.target_temperature + AC.allowed_temperature_difference >= AC.reagents.chem_temp) //cooling here
return TRUE
if(AC.reagents.chem_temp <= AC.target_temperature && AC.target_temperature - AC.allowed_temperature_difference <= AC.reagents.chem_temp) //heating here
return TRUE
return FALSE
@@ -0,0 +1,43 @@
/datum/component/plumbing/reaction_chamber
demand_connects = WEST
supply_connects = EAST
/datum/component/plumbing/reaction_chamber/Initialize(start=TRUE, _turn_connects=TRUE)
. = ..()
if(!istype(parent, /obj/machinery/plumbing/reaction_chamber))
return COMPONENT_INCOMPATIBLE
/datum/component/plumbing/reaction_chamber/can_give(amount, reagent)
. = ..()
var/obj/machinery/plumbing/reaction_chamber/RC = parent
if(!. || !RC.emptying)
return FALSE
/datum/component/plumbing/reaction_chamber/send_request(dir)
var/obj/machinery/plumbing/reaction_chamber/RC = parent
if(RC.emptying || !LAZYLEN(RC.required_reagents))
return
for(var/RT in RC.required_reagents)
var/has_reagent = FALSE
for(var/A in reagents.reagent_list)
var/datum/reagent/RD = A
if(RT == RD.type)
has_reagent = TRUE
if(RD.volume < RC.required_reagents[RT])
process_request(min(RC.required_reagents[RT] - RD.volume, MACHINE_REAGENT_TRANSFER) , RT, dir)
return
if(!has_reagent)
process_request(min(RC.required_reagents[RT], MACHINE_REAGENT_TRANSFER), RT, dir)
return
reagents.flags &= ~NO_REACT
RC.emptying = TRUE
/datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net)
. = ..()
var/obj/machinery/plumbing/reaction_chamber/RC = parent
if(!. || !RC.emptying)
return FALSE
@@ -0,0 +1,47 @@
/datum/component/plumbing/splitter
demand_connects = NORTH
supply_connects = SOUTH | EAST
/datum/component/plumbing/splitter/Initialize()
. = ..()
if(. && !istype(parent, /obj/machinery/plumbing/splitter))
return FALSE
/datum/component/plumbing/splitter/can_give(amount, reagent, datum/ductnet/net)
. = ..()
if(!.)
return
. = FALSE
var/direction
for(var/A in ducts)
if(ducts[A] == net)
direction = get_original_direction(text2num(A))
break
var/obj/machinery/plumbing/splitter/S = parent
switch(direction)
if(SOUTH)
if(S.turn_straight && S.transfer_straight <= amount)
S.turn_straight = FALSE
return TRUE
if(EAST)
if(!S.turn_straight && S.transfer_side <= amount)
S.turn_straight = FALSE
return TRUE
/datum/component/plumbing/splitter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
var/direction
for(var/A in ducts)
if(ducts[A] == net)
direction = get_original_direction(text2num(A))
break
var/obj/machinery/plumbing/splitter/S = parent
switch(direction)
if(SOUTH)
if(amount >= S.transfer_straight)
amount = S.transfer_straight
if(EAST)
if(amount >= S.transfer_side)
amount = S.transfer_side
. = ..()
@@ -0,0 +1,26 @@
/obj/machinery/plumbing/disposer
name = "chemical disposer"
desc = "Breaks down chemicals and annihilates them."
icon_state = "disposal"
///we remove 10 reagents per second
var/disposal_rate = 10
/obj/machinery/plumbing/disposer/Initialize()
. = ..()
AddComponent(/datum/component/plumbing/simple_demand)
/obj/machinery/plumbing/disposer/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I)
return TRUE
/obj/machinery/plumbing/disposer/process()
if(stat & NOPOWER)
return
if(reagents.total_volume)
if(icon_state != initial(icon_state) + "_working") //threw it here instead of update icon since it only has two states
icon_state = initial(icon_state) + "_working"
reagents.remove_any(disposal_rate)
else
if(icon_state != initial(icon_state))
icon_state = initial(icon_state)
+1 -5
View File
@@ -70,8 +70,4 @@
english_right -= chem_name
right -= chem_id
/obj/machinery/plumbing/filter/proc/get_chem_id(chem_name)
for(var/A in GLOB.chemical_reagents_list)
var/datum/reagent/R = GLOB.chemical_reagents_list[A]
if(chem_name == ckey(R.name))
return R.type
@@ -0,0 +1,87 @@
///We take a constant input of reagents, and produce a pill once a set volume is reached
/obj/machinery/plumbing/pill_press
name = "pill press"
desc = "A press that presses pills."
icon_state = "pill_press"
///the minimum size a pill can be
var/minimum_pill = 5
///the maximum size a pill can be
var/maximum_pill = 50
///the size of the pill
var/pill_size = 10
///pill name
var/pill_name = "factory pill"
///the icon_state number for the pill.
var/pill_number = RANDOM_PILL_STYLE
///list of id's and icons for the pill selection of the ui
var/list/pill_styles
var/xen = 500
var/yen = 500
/obj/machinery/plumbing/pill_press/Initialize(mapload)
. = ..()
AddComponent(/datum/component/plumbing/simple_demand)
//expertly copypasted from chemmasters
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
pill_styles = list()
for (var/x in 1 to PILL_STYLE_COUNT)
var/list/SL = list()
SL["id"] = x
SL["htmltag"] = assets.icon_tag("pill[x]")
pill_styles += list(SL)
/obj/machinery/plumbing/pill_press/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I)
return TRUE
/obj/machinery/plumbing/pill_press/process()
if(stat & NOPOWER)
return
if(reagents.total_volume >= pill_size)
var/obj/item/reagent_containers/pill/P = new(drop_location())
reagents.trans_to(P, pill_size)
P.name = pill_name
if(pill_number == RANDOM_PILL_STYLE)
P.icon_state = "pill[rand(1,21)]"
else
P.icon_state = "pill[pill_number]"
if(P.icon_state == "pill4") //mirrored from chem masters
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
/obj/machinery/plumbing/pill_press/ui_base_html(html)
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
/obj/machinery/plumbing/pill_press/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
assets.send(user)
ui = new(user, src, ui_key, "chem_press", name, 410, 300, master_ui, state)
ui.open()
/obj/machinery/plumbing/pill_press/ui_data(mob/user)
var/list/data = list()
data["pill_style"] = pill_number
data["pill_size"] = pill_size
data["pill_name"] = pill_name
data["pill_styles"] = pill_styles
return data
/obj/machinery/plumbing/pill_press/ui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("change_pill_style")
pill_number = CLAMP(text2num(params["id"]), 1 , PILL_STYLE_COUNT)
if("change_pill_size")
pill_size = round(CLAMP(input("New target volume", name, pill_size) as num|null, minimum_pill, maximum_pill))
if("change_pill_name")
var/new_name = stripped_input(usr, "Enter a pill name.", name, pill_name)
if(findtext(new_name, "pill")) //names like pillatron and Pilliam are thus valid
pill_name = new_name
else
pill_name = new_name + " pill"
@@ -0,0 +1,56 @@
///a reaction chamber for plumbing. pretty much everything can react, but this one keeps the reagents seperated and only reacts under your given terms
/obj/machinery/plumbing/reaction_chamber
name = "reaction chamber"
desc = "Keeps chemicals seperated until given conditions are met."
icon_state = "reaction_chamber"
buffer = 100
reagent_flags = TRANSPARENT | NO_REACT
/**list of set reagents that the reaction_chamber allows in, and must all be present before mixing is enabled.
* example: list(/datum/reagent/water = 20, /datum/reagent/oil = 50)
*/
var/list/required_reagents = list()
///our reagent goal has been reached, so now we lock our inputs and start emptying
var/emptying = FALSE
/obj/machinery/plumbing/reaction_chamber/Initialize()
. = ..()
AddComponent(/datum/component/plumbing/reaction_chamber)
/obj/machinery/plumbing/reaction_chamber/on_reagent_change()
if(reagents.total_volume == 0 && emptying) //we were emptying, but now we aren't
emptying = FALSE
reagents.flags |= NO_REACT
/obj/machinery/plumbing/reaction_chamber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "reaction_chamber", name, 500, 300, master_ui, state)
ui.open()
/obj/machinery/plumbing/reaction_chamber/ui_data(mob/user)
var/list/data = list()
var/list/text_reagents = list()
for(var/A in required_reagents) //make a list where the key is text, because that looks alot better in the ui than a typepath
var/datum/reagent/R = A
text_reagents[initial(R.name)] = required_reagents[R]
data["reagents"] = text_reagents
data["emptying"] = emptying
return data
/obj/machinery/plumbing/reaction_chamber/ui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("remove")
var/reagent = get_chem_id(params["chem"])
if(reagent)
required_reagents.Remove(reagent)
if("add")
var/input_reagent = get_chem_id(replacetext(lowertext(input("Enter the name of the reagent", "Input") as text|null), " ", ""))
if(input_reagent && !required_reagents.Find(input_reagent))
var/input_amount = CLAMP(round(input("Enter amount", "Input") as num|null), 1, 100)
if(input_amount)
required_reagents[input_reagent] = input_amount
@@ -0,0 +1,49 @@
///it splits the reagents however you want. So you can "every 60 units, 45 goes left and 15 goes straight". The side direction is EAST, you can change this in the component
/obj/machinery/plumbing/splitter
name = "Chemical Splitter"
desc = "A chemical splitter for smart chemical factorization. Waits till a set of conditions is met and then stops all input and splits the buffer evenly or other in two ducts."
icon_state = "splitter"
buffer = 100
///constantly switches between TRUE and FALSE. TRUE means the batch tick goes straight, FALSE means the next batch goes in the side duct.
var/turn_straight = TRUE
///how much we must transfer straight. note input can be as high as 10 reagents per process, usually
var/transfer_straight = 5
///how much we must transfer to the side
var/transfer_side = 5
//the maximum you can set the transfer to
var/max_transfer = 9
/obj/machinery/plumbing/splitter/Initialize()
. = ..()
AddComponent(/datum/component/plumbing/splitter)
/obj/machinery/plumbing/splitter/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I)
return TRUE
/obj/machinery/plumbing/splitter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "chem_splitter", name, 700, 200, master_ui, state)
ui.open()
/obj/machinery/plumbing/splitter/ui_data(mob/user)
var/list/data = list()
data["straight"] = transfer_straight
data["side"] = transfer_side
return data
/obj/machinery/plumbing/splitter/ui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("set_amount")
var/direction = params["target"]
switch(direction)
if("straight")
transfer_straight = CLAMP(input("New target transfer:", name, transfer_straight) as num|null, 1 , max_transfer)
if("side")
transfer_side = CLAMP(input("New target transfer:", name, transfer_side) as num|null, 1 , max_transfer)
else
return FALSE
@@ -885,3 +885,9 @@
random_reagents += R
var/picked_reagent = pick(random_reagents)
return picked_reagent
/proc/get_chem_id(chem_name)
for(var/A in GLOB.chemical_reagents_list)
var/datum/reagent/R = GLOB.chemical_reagents_list[A]
if(chem_name == ckey(R.name))
return R.type
@@ -1,6 +1,3 @@
#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die
#define RANDOM_PILL_STYLE 22 //Dont change this one though
/obj/machinery/chem_master
name = "ChemMaster 3000"
desc = "Used to separate chemicals and distribute them in a variety of forms."
@@ -404,7 +401,4 @@
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
desc = "Used to create condiments and other cooking supplies."
condi = TRUE
#undef PILL_STYLE_COUNT
#undef RANDOM_PILL_STYLE
condi = TRUE
+7
View File
@@ -419,7 +419,10 @@
#include "code\datums\components\fantasy\suffixes.dm"
#include "code\datums\components\plumbing\_plumbing.dm"
#include "code\datums\components\plumbing\acclimator.dm"
#include "code\datums\components\plumbing\chemical_acclimator.dm"
#include "code\datums\components\plumbing\filter.dm"
#include "code\datums\components\plumbing\reaction_chamber.dm"
#include "code\datums\components\plumbing\splitter.dm"
#include "code\datums\components\storage\storage.dm"
#include "code\datums\components\storage\concrete\_concrete.dm"
#include "code\datums\components\storage\concrete\bag_of_holding.dm"
@@ -2405,8 +2408,12 @@
#include "code\modules\plumbing\ducts.dm"
#include "code\modules\plumbing\plumbers\_plumb_machinery.dm"
#include "code\modules\plumbing\plumbers\acclimator.dm"
#include "code\modules\plumbing\plumbers\destroyer.dm"
#include "code\modules\plumbing\plumbers\filter.dm"
#include "code\modules\plumbing\plumbers\pill_press.dm"
#include "code\modules\plumbing\plumbers\pumps.dm"
#include "code\modules\plumbing\plumbers\reaction_chamber.dm"
#include "code\modules\plumbing\plumbers\splitters.dm"
#include "code\modules\plumbing\plumbers\synthesizer.dm"
#include "code\modules\power\apc.dm"
#include "code\modules\power\cable.dm"
+11
View File
@@ -0,0 +1,11 @@
<ui-display title='Pill Press' button>
<ui-display title='Pill Size'>
<span> Current Pill Volume: </span> <ui-button action='change_pill_size'>{{data.pill_size}}</ui-button>
</ui-display>
<ui-display title='Cosmetic'>
<span> Pill Name: </span> <ui-button action='change_pill_name'>{{data.pill_name}}</ui-button> <br>
{{#each data.pill_styles}}
<ui-button state='{{id==data.pill_style ? "selected" : null}}' action='change_pill_style' params='{"id": "{{id}}"}'>{{{htmltag}}}</ui-button>
{{/each}}
</ui-display>
</ui-display>
+8
View File
@@ -0,0 +1,8 @@
<ui-display title='Splitter' button>
<ui-section>
<span>The splitter constantly switches between the port and the amount it sends, and only continues when it has succeeded. <br></span>
<span>The splitter outputs at a forced amount. Avoid putting multiple demanding machines on one output, as it strains it's effectiveness. <br></span>
<ui-button action='set_amount' params='{"target": "straight"}'>Straight {{data.straight}}</ui-button>
<ui-button action='set_amount' params='{"target": "side"}'>Side {{data.side}}</ui-button>
</ui-section>
</ui-display>
@@ -0,0 +1,9 @@
<ui-display title='Splitter' button>
<ui-section>
{{#each data.reagents: reagent}}
<span>{{reagent}} : {{data.reagents[reagent]}}</span>
<ui-button action='remove' params='reagent'>Remove</ui-button><br>
{{/each}}
<ui-button action='add'>Add</ui-button><br>
</ui-section>
</ui-display>