Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworks plumbing reaction chamber, purity support #57071

Merged
merged 8 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 15 additions & 7 deletions code/datums/components/plumbing/_plumbing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,30 @@
var/recipient_reagents_holder
///How do we apply the new reagents to the receiver? Generally doesn't matter, but some stuff, like people, does care if its injected or whatevs
var/methods
///What color is our demand connect? Also it's not auto-colored so you'll have to make new sprites if its anything other than red, blue, yellow or green
var/demand_color = "red"
///What color is our supply connect? Also, refrain from pointlessly using non-standard colors unless it's really funny or something
var/supply_color = "blue"

///turn_connects is for wheter or not we spin with the object to change our pipes
/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE, _ducting_layer)
/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE, _ducting_layer, datum/reagents/custom_receiver)
if(!ismovable(parent))
return COMPONENT_INCOMPATIBLE

if(_ducting_layer)
ducting_layer = ducting_layer

var/atom/movable/AM = parent
if(!AM.reagents)
if(!AM.reagents && !custom_receiver)
return COMPONENT_INCOMPATIBLE

reagents = AM.reagents
turn_connects = _turn_connects

recipient_reagents_holder = AM.reagents
if(custom_receiver)
recipient_reagents_holder = custom_receiver
else
recipient_reagents_holder = AM.reagents

RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED,COMSIG_PARENT_PREQDELETED), .proc/disable)
RegisterSignal(parent, list(COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH), .proc/toggle_active)
Expand Down Expand Up @@ -145,9 +153,9 @@
var/color
var/direction
if(D & initial(demand_connects))
color = "red" //red because red is mean and it takes
color = demand_color
else if(D & initial(supply_connects))
color = "blue" //blue is nice and gives
color = supply_color
else
continue

Expand All @@ -164,10 +172,10 @@
direction = "west"

if(turn_connects)
I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]", layer = AM.layer - 1)
I = image('icons/obj/plumbing/connects.dmi', "[direction]-[color]", layer = AM.layer - 1)

else
I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]-s", layer = AM.layer - 1) //color is not color as in the var, it's just the name of the icon_state
I = image('icons/obj/plumbing/connects.dmi', "[direction]-[color]-s", layer = AM.layer - 1) //color is not color as in the var, it's just the name of the icon_state
I.dir = D

I.pixel_x = duct_x
Expand Down
45 changes: 25 additions & 20 deletions code/datums/components/plumbing/reaction_chamber.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/datum/component/plumbing/reaction_chamber
demand_connects = WEST
supply_connects = EAST
demand_connects = NORTH
supply_connects = SOUTH

/datum/component/plumbing/reaction_chamber/Initialize(start=TRUE, _turn_connects=TRUE)
. = ..()
Expand All @@ -10,25 +10,18 @@
/datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net)
. = ..()
var/obj/machinery/plumbing/reaction_chamber/RC = parent
if(!. || !RC.emptying)
if(!. || !RC.emptying || reagents.is_reacting == TRUE)
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))
if(RC.emptying)
return

process_request(amount = min(MACHINE_REAGENT_TRANSFER, RC.target_volume - reagents.total_volume), dir = dir)

if(RC.target_volume > round(reagents.total_volume, CHEMICAL_VOLUME_ROUNDING)) //not enough yet
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
reagents.handle_reactions()
Expand All @@ -37,8 +30,20 @@
//everything for every chemical removed, wich isn't a good option either.
RC.on_reagent_change(reagents) //We need to check it now, because some reactions leave nothing left.

///Special connect that we currently use for reaction chambers. Being used so we can keep certain inputs seperate, like into a special internal acid container
/datum/component/plumbing/acidic_input
demand_connects = WEST
demand_color = "yellow"

/datum/component/plumbing/acidic_input/send_request(dir)
process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = /datum/reagent/reaction_agent/acidic_buffer, dir = dir)

///Special connect that we currently use for reaction chambers. Being used so we can keep certain inputs seperate, like into a special internal base container
/datum/component/plumbing/alkaline_input
demand_connects = EAST
demand_color = "green"

/datum/component/plumbing/alkaline_input/send_request(dir)
process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = /datum/reagent/reaction_agent/basic_buffer, dir = dir)


/datum/component/plumbing/reaction_chamber/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
if(reagents.is_reacting == TRUE) //Let the thing react in peace
return
return ..()
8 changes: 4 additions & 4 deletions code/modules/plumbing/ducts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ All the important duct code:
if(istype(AM, /obj/machinery/duct))
return connect_duct(AM, direction, ignore_color)

var/plumber = AM.GetComponent(/datum/component/plumbing)
if(!plumber)
return
return connect_plumber(plumber, direction)
for(var/plumber in AM.GetComponents(/datum/component/plumbing))
if(!plumber) //apparently yes it will be null hahahaasahsdvashufv
return
. += connect_plumber(plumber, direction) //so that if one is true, all is true. beautiful.

///connect to a duct
/obj/machinery/duct/proc/connect_duct(obj/machinery/duct/D, direction, ignore_color)
Expand Down
50 changes: 31 additions & 19 deletions code/modules/plumbing/plumbers/reaction_chamber.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,34 @@
buffer = 200
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/fuel/oil = 50)
*/
var/list/required_reagents = list()
///At what volume do we start reacting?
var/target_volume = 200
///If above this pH, we start dumping buffer into it
var/acidic_limit = 9
///If below this pH, we start dumping buffer into it
var/alkaline_limit = 5
///our reagent goal has been reached, so now we lock our inputs and start emptying
var/emptying = FALSE

///towards which temperature do we build (except during draining)?
var/target_temperature = 300
///cool/heat power
var/heater_coefficient = 0.05 //same lvl as acclimator
///Beaker that holds the acidic buffer. I don't want to deal with snowflaking so it's just a seperate thing. It's a small (50u) beaker
var/obj/item/reagent_containers/glass/beaker/acidic_beaker
///beaker that holds the alkaline buffer.
var/obj/item/reagent_containers/glass/beaker/alkaline_beaker

/obj/machinery/plumbing/reaction_chamber/Initialize(mapload, bolt)
. = ..()
AddComponent(/datum/component/plumbing/reaction_chamber, bolt)

acidic_beaker = new (src)
alkaline_beaker = new (src)

AddComponent(/datum/component/plumbing/acidic_input, bolt, custom_receiver = acidic_beaker)
AddComponent(/datum/component/plumbing/alkaline_input, bolt, custom_receiver = alkaline_beaker)

/obj/machinery/plumbing/reaction_chamber/create_reagents(max_vol, flags)
. = ..()
RegisterSignal(reagents, list(COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED), .proc/on_reagent_change)
Expand All @@ -43,6 +55,11 @@
return NONE

/obj/machinery/plumbing/reaction_chamber/process(delta_time)
if(!reagents.is_reacting && reagents.ph < alkaline_limit)
alkaline_beaker.reagents.trans_to(reagents, 1 * delta_time)
if(!reagents.is_reacting && reagents.ph > acidic_limit)
acidic_beaker.reagents.trans_to(reagents, 1 * delta_time)

if(!emptying) //suspend heating/cooling during emptying phase
reagents.adjust_thermal_energy((target_temperature - reagents.chem_temp) * heater_coefficient * delta_time * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater
reagents.handle_reactions()
Expand All @@ -62,17 +79,15 @@

/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
data["temperature"] = round(reagents.chem_temp, 0.1)
data["ph"] = round(reagents.ph, 0.01)
data["targetTemp"] = target_temperature
data["isReacting"] = reagents.is_reacting
data["reagentQuantity"] = target_volume
data["reagentAcidic"] = acidic_limit
data["reagentAlkaline"] = alkaline_limit
return data

/obj/machinery/plumbing/reaction_chamber/ui_act(action, params)
Expand All @@ -81,20 +96,17 @@
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(params["chem"])
if(input_reagent && !required_reagents.Find(input_reagent))
var/input_amount = text2num(params["amount"])
if(input_amount)
required_reagents[input_reagent] = input_amount
if("temperature")
var/target = params["target"]
if(text2num(target) != null)
target = text2num(target)
. = TRUE
if(.)
target_temperature = clamp(target, 0, 1000)
if("volume")
target_volume = round(text2num(params["target"]))
if("acidic")
acidic_limit = round(text2num(params["target"]))
if("alkaline")
alkaline_limit = round(text2num(params["target"]))

29 changes: 17 additions & 12 deletions code/modules/reagents/chemistry/holder.dm
Original file line number Diff line number Diff line change
Expand Up @@ -519,33 +519,38 @@
var/list/cached_reagents = reagent_list
if (!target)
return
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))

var/datum/reagents/holder
if(istype(target, /datum/reagents))
holder = target
else if(target.reagents && total_volume > 0 && get_reagent_amount(reagent))
holder = target.reagents
else
return
if(amount < 0)
return

var/cached_amount = amount
var/datum/reagents/R = target.reagents
if(src.get_reagent_amount(reagent)<amount)
amount = src.get_reagent_amount(reagent)
if(get_reagent_amount(reagent) < amount)
amount = get_reagent_amount(reagent)

amount = min(round(amount, CHEMICAL_VOLUME_ROUNDING), R.maximum_volume-R.total_volume)
amount = min(round(amount, CHEMICAL_VOLUME_ROUNDING), holder.maximum_volume - holder.total_volume)
var/trans_data = null
for (var/CR in cached_reagents)
var/datum/reagent/current_reagent = CR
for (var/looping_through_reagents in cached_reagents)
var/datum/reagent/current_reagent = looping_through_reagents
if(current_reagent.type == reagent)
if(preserve_data)
trans_data = current_reagent.data
if(current_reagent.intercept_reagents_transfer(R, cached_amount))//Use input amount instead.
if(current_reagent.intercept_reagents_transfer(holder, cached_amount))//Use input amount instead.
break
force_stop_reagent_reacting(current_reagent)
R.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, current_reagent.ph, no_react = TRUE)
holder.add_reagent(current_reagent.type, amount, trans_data, chem_temp, current_reagent.purity, current_reagent.ph, no_react = TRUE)
remove_reagent(current_reagent.type, amount, 1)
break

src.update_total()
R.update_total()
R.handle_reactions()
update_total()
holder.update_total()
holder.handle_reactions()
return amount

/// Copies the reagents to the target object
Expand Down
Binary file added icons/obj/plumbing/connects.dmi
Binary file not shown.
Binary file modified icons/obj/plumbing/plumbers.dmi
Binary file not shown.