[MIRROR] Hose Connector Component (#11045)

Co-authored-by: Will <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2025-06-15 10:24:10 -07:00
committed by GitHub
parent d65e68075b
commit c39a5b0e88
11 changed files with 448 additions and 388 deletions

View File

@@ -1,140 +0,0 @@
/obj/attackby(var/obj/item/O, var/mob/user)
. = ..()
if(locate(/obj/item/hose_connector) in src)
if(O.has_tool_quality(TOOL_WIRECUTTER))
var/list/available_sockets = list()
for(var/obj/item/hose_connector/HC in src)
if(HC.my_hose)
available_sockets |= HC
if(LAZYLEN(available_sockets))
if(available_sockets.len == 1)
var/obj/item/hose_connector/AC = available_sockets[1]
var/choice = tgui_alert(user, "Are you sure you want to disconnect [AC]?", "Confirm", list("Yes", "No"))
if(choice == "Yes" && Adjacent(user))
visible_message("[user] disconnects \the hose from \the [src].")
AC.my_hose.disconnect()
return
else
var/choice = tgui_input_list(user, "Select a target hose connector.", "Socket Disconnect", available_sockets)
if(choice)
var/obj/item/hose_connector/AC = choice
var/confirm = tgui_alert(user, "Are you sure you want to disconnect [AC]?", "Confirm", list("Yes", "No"))
if(confirm == "Yes" && Adjacent(user))
visible_message("[user] disconnects \the hose from \the [src].")
AC.my_hose.disconnect()
return
/obj/item/hose_connector
name = "hose connector"
desc = "A socket for a hose. It.. doesn't do anything on its own."
var/obj/carrier = null
var/flow_direction = HOSE_NEUTRAL
var/datum/hose/my_hose = null
/obj/item/hose_connector/Destroy()
if(my_hose)
my_hose.disconnect()
my_hose = null
if(carrier)
carrier = null
. = ..()
/obj/item/hose_connector/Initialize(mapload)
. = ..()
create_reagents(100)
if(!istype(loc, /turf))
name = "[flow_direction] hose connector ([loc])"
/obj/item/hose_connector/proc/valid_connection(var/obj/item/hose_connector/C)
if(istype(C))
if(C.my_hose)
return FALSE
if(C.flow_direction in (list(HOSE_INPUT, HOSE_OUTPUT) - flow_direction))
return TRUE
return FALSE
/obj/item/hose_connector/proc/disconnect()
my_hose = null
/obj/item/hose_connector/proc/connect(var/datum/hose/H = null)
if(istype(H))
my_hose = H
/obj/item/hose_connector/proc/setup_hoses(var/obj/item/hose_connector/target)
if(target)
var/datum/hose/H = new()
H.set_hose(src, target)
/obj/item/hose_connector/proc/get_pairing()
if(my_hose)
return my_hose.get_pairing(src)
return
/*
* Subtypes
*/
/obj/item/hose_connector/input
name = "hose input"
flow_direction = HOSE_INPUT
/obj/item/hose_connector/input/active
name = "active hose"
/obj/item/hose_connector/input/active/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/hose_connector/input/active/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
if(!isturf(loc))
carrier = loc
/obj/item/hose_connector/input/active/process()
if(carrier)
reagents.trans_to_obj(carrier, reagents.maximum_volume)
/obj/item/hose_connector/output
name = "hose output"
flow_direction = HOSE_OUTPUT
/obj/item/hose_connector/output/active
name = "active hose"
/obj/item/hose_connector/output/active/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/hose_connector/output/active/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
if(!isturf(loc))
carrier = loc
/obj/item/hose_connector/output/active/process()
if(carrier && my_hose)
carrier.reagents.trans_to_holder(reagents, reagents.maximum_volume)
else if(reagents.total_volume && carrier && !my_hose)
reagents.trans_to_obj(carrier, reagents.maximum_volume)

View File

@@ -1,113 +0,0 @@
GLOBAL_LIST_EMPTY(hoses)
/obj/effect/ebeam/hose
plane = OBJ_PLANE
layer = STAIRS_LAYER
/datum/hose
var/name = "hose"
var/obj/item/hose_connector/node1 = null
var/obj/item/hose_connector/node2 = null
var/hose_color = "#ffffff"
var/initial_distance = 7
var/datum/beam/hose = null
/datum/hose/proc/get_pairing(var/obj/item/hose_connector/target)
if(target)
if(target == node1)
return node2
else if(target == node2)
return node1
return
/datum/hose/proc/disconnect()
if(node1)
node1.disconnect()
node1 = null
if(node2)
node2.disconnect()
node2 = null
/datum/hose/proc/set_hose(var/obj/item/hose_connector/target1, var/obj/item/hose_connector/target2)
if(target1 && target2)
node1 = target1
node2 = target2
node1.connect(src)
node2.connect(src)
name = "[name] ([node1],[node2])"
initial_distance = get_dist(get_turf(node1), get_turf(node2))
GLOB.hoses |= src
START_PROCESSING(SSobj, src)
/datum/hose/process()
if(node1 && node2)
if(get_dist(get_turf(node1), get_turf(node2)) > 0)
hose = node1.loc.Beam(node2.loc, icon_state = "hose", beam_color = hose_color, maxdistance = world.view, beam_type = /obj/effect/ebeam/hose)
if(!hose || get_dist(get_turf(node1), get_turf(node2)) > initial_distance) // The hose didn't form. Something's fucky.
disconnect()
return
var/datum/reagents/reagent_node1 = node1.reagents
var/datum/reagents/reagent_node2 = node2.reagents
switch(node1.flow_direction) // Node 1 is the default 'master', interactions are considered in all current possible states in regards to it, however.
if(HOSE_INPUT)
if(node2.flow_direction == HOSE_NEUTRAL) // We're input, they're neutral. Take half of our volume.
reagent_node2.trans_to_holder(reagent_node1, reagent_node1.maximum_volume / 2)
else if(node2.flow_direction == HOSE_OUTPUT) // We're input, they're output. Take all of our volume.
reagent_node2.trans_to_holder(reagent_node1, reagent_node1.maximum_volume)
if(HOSE_OUTPUT) // We're output, give all of their maximum volume.
reagent_node1.trans_to_holder(reagent_node2, reagent_node2.maximum_volume)
if(HOSE_NEUTRAL)
switch(node2.flow_direction)
if(HOSE_INPUT) // We're neutral, they're input. Give them half of their volume.
reagent_node1.trans_to_holder(reagent_node2, reagent_node2.maximum_volume / 2)
if(HOSE_NEUTRAL) // We're neutral, they're neutral. Balance our values.
var/volume_difference_perc = (reagent_node1.total_volume / reagent_node1.maximum_volume) - (reagent_node2.total_volume / reagent_node2.maximum_volume)
var/volume_difference = 0
var/pulling = FALSE
if(volume_difference_perc > 0) // They are smaller, so they determine the transfer amount. Half of the difference will equalize.
volume_difference = reagent_node2.maximum_volume * volume_difference_perc / 2
else if(volume_difference_perc < 0) // We're smaller, so we determine the transfer amount. Half of the difference will equalize.
volume_difference_perc *= -1
pulling = TRUE
volume_difference = reagent_node1.maximum_volume * volume_difference_perc / 2
if(volume_difference)
if(pulling)
reagent_node2.trans_to_holder(reagent_node1, volume_difference)
else
reagent_node1.trans_to_holder(reagent_node2, volume_difference)
if(HOSE_OUTPUT)
reagent_node2.trans_to_holder(reagent_node1, reagent_node2.maximum_volume)
else
if(node1)
node1.disconnect()
node1 = null
if(node2)
node2.disconnect()
node2 = null
STOP_PROCESSING(SSobj, src)
GLOB.hoses -= src
qdel(src)

View File

@@ -1,93 +0,0 @@
/obj/item/stack/hose
name = "plastic tubing"
singular_name = "plastic tube"
desc = "A non-reusable plastic tube for moving reagents to and fro. It looks flimsy."
description_info = "This tubing may be used to join two hose sockets, if able.<br>\
Clicking on an object with a connector, such as a water tank, will display a list of possible sockets.<br>\
Neutral can link to all socket types, and Input/Output sockets can link to all but their own type.<br><br>\
" + span_warning("This hose does not stretch. The maximum distance you can move two objects from eachother\
without snapping the tube is determined by distance upon connection.")
icon = 'icons/obj/machines/reagent.dmi'
icon_state = "hose"
origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 1)
amount = 1
w_class = ITEMSIZE_SMALL
no_variants = TRUE
var/obj/item/hose_connector/remembered = null
/obj/item/stack/hose/Destroy()
remembered = null
. = ..()
/obj/item/stack/hose/CtrlClick(mob/user)
if(remembered)
to_chat(user, span_notice("You wind \the [src] back up."))
remembered = null
return
/obj/item/stack/hose/afterattack(var/atom/target, var/mob/living/user, proximity, params)
if(!proximity)
return
var/list/available_sockets = list()
for(var/obj/item/hose_connector/HC in target.contents)
if(!HC.my_hose)
if(remembered)
if(HC.flow_direction == HOSE_NEUTRAL || HC.flow_direction != remembered.flow_direction)
available_sockets |= HC
else
available_sockets |= HC
if(LAZYLEN(available_sockets))
if(available_sockets.len == 1)
var/obj/item/hose_connector/AC = available_sockets[1]
if(remembered && remembered.valid_connection(AC))
var/distancetonode = get_dist(remembered,AC)
if(distancetonode > world.view)
to_chat(user, span_notice("\The [src] would probably burst if it were this long."))
else if(distancetonode <= amount)
to_chat(user, span_notice("You join \the [remembered] to \the [AC]"))
remembered.setup_hoses(AC)
use(distancetonode)
remembered = null
else
to_chat(user, span_notice("You do not have enough tubing to connect the sockets."))
else
remembered = AC
to_chat(user, span_notice("You connect one end of tubing to \the [AC]."))
else
var/choice = tgui_input_list(user, "Select a target hose connector.", "Socket Selection", available_sockets)
if(choice)
var/obj/item/hose_connector/CC = choice
if(remembered)
if(remembered.valid_connection(CC))
var/distancetonode = get_dist(remembered, CC)
if(distancetonode > world.view)
to_chat(user, span_notice("\The [src] would probably burst if it were this long."))
else if(distancetonode <= amount)
to_chat(user, span_notice("You join \the [remembered] to \the [CC]"))
remembered.setup_hoses(CC)
use(distancetonode)
remembered = null
else
to_chat(user, span_notice("You do not have enough tubing to connect the sockets."))
else
remembered = CC
to_chat(user, span_notice("You connect one end of tubing to \the [CC]."))
return
else
..()

View File

@@ -11,9 +11,6 @@
var/has_sockets = TRUE
var/obj/item/hose_connector/input/active/InputSocket
var/obj/item/hose_connector/output/active/OutputSocket
var/amount_per_transfer_from_this = 10
var/possible_transfer_amounts = list(10,25,50,100)
@@ -22,12 +19,6 @@
/obj/structure/reagent_dispensers/attackby(obj/item/W as obj, mob/user as mob)
return
/obj/structure/reagent_dispensers/Destroy()
QDEL_NULL(InputSocket)
QDEL_NULL(OutputSocket)
. = ..()
/obj/structure/reagent_dispensers/Initialize(mapload)
var/datum/reagents/R = new/datum/reagents(5000)
reagents = R
@@ -36,10 +27,8 @@
src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
if(has_sockets)
InputSocket = new(src)
InputSocket.carrier = src
OutputSocket = new(src)
OutputSocket.carrier = src
AddComponent(/datum/component/hose_connector/input)
AddComponent(/datum/component/hose_connector/output)
. = ..()
@@ -158,12 +147,12 @@
//Helium3
/obj/structure/reagent_dispensers/he3
name = "/improper He3 tank"
name = "He3 tank"
desc = "A Helium3 tank."
icon_state = "he3"
amount_per_transfer_from_this = 10
/obj/structure/reagent_dispenser/he3/Initialize(mapload)
/obj/structure/reagent_dispensers/he3/Initialize(mapload)
. = ..()
reagents.add_reagent(REAGENT_ID_HELIUM3,1000)

View File

@@ -17,7 +17,6 @@
active_power_usage = 200 * CELLRATE
var/obj/item/cell/cell = null
var/obj/item/hose_connector/output/Output = null
var/reagents_per_cycle = 5 // severe nerf to unupgraded speed
var/on = 0
var/unlocked = 0
@@ -29,16 +28,11 @@
default_apply_parts()
cell = default_use_hicell()
Output = new(src)
AddComponent(/datum/component/hose_connector/output)
RefreshParts()
update_icon()
/obj/machinery/pump/Destroy()
QDEL_NULL(cell)
QDEL_NULL(Output)
. = ..()
/obj/machinery/pump/RefreshParts()
var/obj/item/stock_parts/manipulator/SM = locate() in component_parts
active_power_usage = initial(active_power_usage) / SM.rating
@@ -94,11 +88,8 @@
T.pump_reagents(reagents, reagents_per_cycle)
update_icon()
if(Output.get_pairing())
reagents.trans_to_holder(Output.reagents, Output.reagents.maximum_volume)
if(prob(5))
visible_message(span_notice("\The [src] gurgles as it pumps fluid."))
var/datum/component/hose_connector/HC = GetComponent(/datum/component/hose_connector)
HC.force_pump()
// Sets the power state, if possible.
// Returns TRUE/FALSE on power state changing

View File

@@ -228,12 +228,20 @@
var/icon/hose_overlay
var/obj/item/hose_connector/input/active/InputSocket
/obj/item/reagent_containers/spray/chemsprayer/hosed/Initialize(mapload)
. = ..()
AddComponent(/datum/component/recursive_move)
AddComponent(/datum/component/hose_connector/input)
RegisterSignal(src, COMSIG_OBSERVER_MOVED, /obj/item/reagent_containers/spray/chemsprayer/hosed/proc/update_hose)
InputSocket = new(src)
/obj/item/reagent_containers/spray/chemsprayer/hosed/Destroy()
UnregisterSignal(src, COMSIG_OBSERVER_MOVED)
. = ..()
/obj/item/reagent_containers/spray/chemsprayer/hosed/proc/update_hose(atom/source, atom/oldloc, direction, forced, list/old_locs, momentum_change)
SIGNAL_HANDLER
var/datum/component/hose_connector/HC = GetComponent(/datum/component/hose_connector)
HC.update_hose_beam()
/obj/item/reagent_containers/spray/chemsprayer/hosed/update_icon()
..()
@@ -243,7 +251,8 @@
if(!hose_overlay)
hose_overlay = new/icon(icon, "[icon_state]+hose")
if(InputSocket.get_pairing())
var/datum/component/hose_connector/HC = GetComponent(/datum/component/hose_connector)
if(HC.get_pairing())
add_overlay(hose_overlay)
/obj/item/reagent_containers/spray/chemsprayer/hosed/AltClick(mob/living/carbon/user)