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 all 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
40 changes: 33 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 Expand Up @@ -308,3 +316,21 @@
/datum/component/plumbing/tank
demand_connects = WEST
supply_connects = EAST

#define READY 2
///Baby component for the buffer plumbing machine
/datum/component/plumbing/buffer
demand_connects = WEST
supply_connects = EAST

/datum/component/plumbing/buffer/Initialize(start=TRUE, _turn_connects=TRUE, _ducting_layer, datum/reagents/custom_receiver)
if(!istype(parent, /obj/machinery/plumbing/buffer))
return COMPONENT_INCOMPATIBLE

return ..()

/datum/component/plumbing/buffer/can_give(amount, reagent, datum/ductnet/net)
var/obj/machinery/plumbing/buffer/buffer = parent
return (buffer.mode == READY) ? ..() : FALSE

#undef READY
49 changes: 29 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,24 @@
//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"

ducting_layer = SECOND_DUCT_LAYER

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

ducting_layer = SECOND_DUCT_LAYER

/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 ..()
3 changes: 2 additions & 1 deletion code/game/objects/items/RCD.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1012,9 +1012,10 @@ RLD
/obj/machinery/plumbing/tank = 20,
/obj/machinery/plumbing/synthesizer = 15,
/obj/machinery/plumbing/reaction_chamber = 15,
/obj/machinery/plumbing/acclimator = 10,
/obj/machinery/plumbing/buffer = 10,
/obj/machinery/plumbing/pill_press = 20,
//Above are the most common machinery which is shown on the first cycle. Keep new additions below THIS line
/obj/machinery/plumbing/acclimator = 10,
/obj/machinery/plumbing/bottler = 50,
/obj/machinery/plumbing/disposer = 10,
/obj/machinery/plumbing/fermenter = 30,
Expand Down
3 changes: 1 addition & 2 deletions code/game/objects/structures/lavaland/geyser.dm
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@
var/target_layer = DUCT_LAYER_DEFAULT

///Assoc list for possible layers
var/list/layers = list("First Layer" = FIRST_DUCT_LAYER, "Second Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT,
"Fourth Layer" = FOURTH_DUCT_LAYER, "Fifth Layer" = FIFTH_DUCT_LAYER)
var/list/layers = list("Alternate Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT)

/obj/item/plunger/attack_obj(obj/O, mob/living/user)
if(layer_mode)
Expand Down
11 changes: 5 additions & 6 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 Expand Up @@ -402,8 +402,7 @@ All the important duct code:
///Default layer of our duct
var/duct_layer = "Default Layer"
///Assoc index with all the available layers. yes five might be a bit much. Colors uses a global by the way
var/list/layers = list("First Layer" = FIRST_DUCT_LAYER, "Second Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT,
"Fourth Layer" = FOURTH_DUCT_LAYER, "Fifth Layer" = FIFTH_DUCT_LAYER)
var/list/layers = list("Alternate Layer" = SECOND_DUCT_LAYER, "Default Layer" = DUCT_LAYER_DEFAULT)

/obj/item/stack/ducts/examine(mob/user)
. = ..()
Expand Down
122 changes: 122 additions & 0 deletions code/modules/plumbing/plumbers/plumbing_buffer.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#define UNREADY 0
#define IDLE 1
#define READY 2

/obj/machinery/plumbing/buffer
name = "automatic buffer"
desc = "A chemical holding tank that waits for neighbouring automatic buffers to complete before allowing a withdrawal. Connect/reset by screwdrivering"
icon_state = "buffer"
buffer = 200

var/datum/buffer_net/buffer_net
var/activation_volume = 100
var/mode

/obj/machinery/plumbing/buffer/Initialize(mapload, bolt)
. = ..()

AddComponent(/datum/component/plumbing/buffer, bolt)

/obj/machinery/plumbing/buffer/create_reagents(max_vol, flags)
. = ..()
RegisterSignal(reagents, list(COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED), .proc/on_reagent_change)
RegisterSignal(reagents, COMSIG_PARENT_QDELETING, .proc/on_reagents_del)

/// Handles properly detaching signal hooks.
/obj/machinery/plumbing/buffer/proc/on_reagents_del(datum/reagents/reagents)
SIGNAL_HANDLER
UnregisterSignal(reagents, list(COMSIG_REAGENTS_ADD_REAGENT, COMSIG_REAGENTS_NEW_REAGENT, COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED, COMSIG_PARENT_QDELETING))
return NONE

/obj/machinery/plumbing/buffer/proc/on_reagent_change()
if(!buffer_net)
return
if(reagents.total_volume >= activation_volume && mode == UNREADY)
mode = IDLE
buffer_net.check_active()

else if(reagents.total_volume < activation_volume && mode != UNREADY)
mode = UNREADY
buffer_net.check_active()

/obj/machinery/plumbing/buffer/update_icon()
. = ..()
icon_state = initial(icon_state)
if(buffer_net)
switch(mode)
if(UNREADY)
icon_state += "_red"
if(IDLE)
icon_state += "_yellow"
if(READY)
icon_state += "_green"

/obj/machinery/plumbing/buffer/proc/attempt_connect()

for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
for(var/atom/movable/movable in T)
if(istype(movable, /obj/machinery/plumbing/buffer))
var/obj/machinery/plumbing/buffer/neighbour = movable
if(neighbour.buffer_net != buffer_net)
neighbour.buffer_net?.destruct()
//we could put this on a proc, but its so simple I dont think its worth the overhead
buffer_net.buffer_list += neighbour
neighbour.buffer_net = buffer_net
neighbour.attempt_connect() //technically this would runtime if you made about 200~ buffers

add_overlay(icon_state + "_alert")
addtimer(CALLBACK(src, /atom/.proc/cut_overlay, icon_state + "_alert"), 20)

/obj/machinery/plumbing/buffer/attack_hand_secondary(mob/user, modifiers)
. = ..()

var/new_volume = input(user, "Enter new activation threshold", "Beepityboop", activation_volume) as num|null
if(!new_volume)
return

activation_volume = round(clamp(new_volume, 0, buffer))
to_chat(user, "<span class='notice'>New activation threshold is now [activation_volume].</span>")

/obj/machinery/plumbing/buffer/attackby(obj/item/item, mob/user, params)
if(item.tool_behaviour == TOOL_SCREWDRIVER)
to_chat(user, "<span class='notice'>You reset the automatic buffer.</span>")

//reset the net
buffer_net?.destruct()
buffer_net = new()
LAZYADD(buffer_net.buffer_list, src)

attempt_connect()
else
return . = ..()

/obj/machinery/plumbing/buffer/doMove(destination)
. = ..()
buffer_net?.destruct()

/datum/buffer_net
var/list/obj/machinery/plumbing/buffer/buffer_list

/datum/buffer_net/proc/destruct()
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
buffer.buffer_net = null
buffer_list.Cut()
qdel(src)

/datum/buffer_net/proc/check_active()
var/ready = TRUE
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
if(buffer.mode == UNREADY)
ready = FALSE
break
for(var/obj/machinery/plumbing/buffer/buffer in buffer_list)
if(buffer.mode == READY && !ready)
buffer.mode = IDLE
else if(buffer.mode == IDLE && ready)
buffer.mode = READY
buffer.update_icon()

#undef UNREADY
#undef IDLE
#undef READY