Merge remote-tracking branch 'origin/master' into TGUI-CHAT-TGUI-CHAT-TGUI-CHAT

This commit is contained in:
Letter N
2020-08-22 13:40:36 +08:00
147 changed files with 3447 additions and 803 deletions
@@ -2,6 +2,15 @@
//Large Objects//
/////////////////
/datum/crafting_recipe/plunger
name = "Plunger"
result = /obj/item/plunger
time = 1
reqs = list(/obj/item/stack/sheet/plastic = 1,
/obj/item/stack/sheet/mineral/wood = 1)
category = CAT_MISC
subcategory = CAT_TOOL
/datum/crafting_recipe/showercurtain
name = "Shower Curtains"
reqs = list(/obj/item/stack/sheet/cloth = 2,
@@ -337,7 +346,7 @@
result = /obj/item/toy/sword/cx
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
/datum/crafting_recipe/catgirlplushie
name = "Catgirl Plushie"
reqs = list(/obj/item/toy/plush/hairball = 3)
@@ -0,0 +1,215 @@
/datum/component/plumbing
///Index with "1" = /datum/ductnet/theductpointingnorth etc. "1" being the num2text from NORTH define
var/list/datum/ductnet/ducts = list()
///shortcut to our parents' reagent holder
var/datum/reagents/reagents
///TRUE if we wanna add proper pipe outless under our parent object. this is pretty good if i may so so myself
var/use_overlays = TRUE
///We can't just cut all of the parents' overlays, so we'll track them here
var/list/image/ducterlays
///directions in wich we act as a supplier
var/supply_connects
///direction in wich we act as a demander
var/demand_connects
///FALSE to pretty much just not exist in the plumbing world so we can be moved, TRUE to go plumbo mode
var/active = FALSE
///if TRUE connects will spin with the parent object visually and codually, so you can have it work in any direction. FALSE if you want it to be static
var/turn_connects = TRUE
/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE) //turn_connects for wheter or not we spin with the object to change our pipes
if(parent && !istype(parent, /atom/movable))
return COMPONENT_INCOMPATIBLE
var/atom/movable/AM = parent
if(!AM.reagents)
return COMPONENT_INCOMPATIBLE
reagents = AM.reagents
turn_connects = _turn_connects
RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED,COMSIG_PARENT_PREQDELETED), .proc/disable)
RegisterSignal(parent, list(COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH), .proc/toggle_active)
if(start)
enable()
if(use_overlays)
create_overlays()
/datum/component/plumbing/process()
if(!demand_connects || !reagents)
STOP_PROCESSING(SSfluids, src)
return
if(reagents.total_volume < reagents.maximum_volume)
for(var/D in GLOB.cardinals)
if(D & demand_connects)
send_request(D)
///Can we be added to the ductnet?
/datum/component/plumbing/proc/can_add(datum/ductnet/D, dir)
if(!active)
return
if(!dir || !D)
return FALSE
if(num2text(dir) in ducts)
return FALSE
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 = 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()
var/datum/ductnet/net
if(!ducts.Find(num2text(dir)))
return
net = ducts[num2text(dir)]
for(var/A in net.suppliers)
var/datum/component/plumbing/supplier = A
if(supplier.can_give(amount, reagent, net))
valid_suppliers += supplier
for(var/A in valid_suppliers)
var/datum/component/plumbing/give = A
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(amount <= 0)
return
if(reagent) //only asked for one type of reagent
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()
/datum/component/plumbing/proc/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
if(!reagents || !target || !target.reagents)
return FALSE
if(reagent)
reagents.trans_id_to(target.parent, reagent, amount)
else
reagents.trans_to(target.parent, amount)
///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize()
/datum/component/plumbing/proc/create_overlays()
var/atom/movable/AM = parent
for(var/image/I in ducterlays)
AM.overlays.Remove(I)
qdel(I)
ducterlays = list()
for(var/D in GLOB.cardinals)
var/color
var/direction
if(D & demand_connects)
color = "red" //red because red is mean and it takes
else if(D & supply_connects)
color = "blue" //blue is nice and gives
else
continue
var/image/I
if(turn_connects)
switch(D)
if(NORTH)
direction = "north"
if(SOUTH)
direction = "south"
if(EAST)
direction = "east"
if(WEST)
direction = "west"
I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]", layer = AM.layer - 1)
else
I = image('icons/obj/plumbing/plumbers.dmi', color, layer = AM.layer - 1) //color is not color as in the var, it's just the name
I.dir = D
AM.add_overlay(I)
ducterlays += I
///we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff
/datum/component/plumbing/proc/disable()
if(!active)
return
STOP_PROCESSING(SSfluids, src)
for(var/A in ducts)
var/datum/ductnet/D = ducts[A]
D.remove_plumber(src)
active = FALSE
for(var/D in GLOB.cardinals)
if(D & (demand_connects | supply_connects))
for(var/obj/machinery/duct/duct in get_step(parent, D))
duct.attempt_connect()
///settle wherever we are, and start behaving like a piece of plumbing
/datum/component/plumbing/proc/enable()
if(active)
return
update_dir()
active = TRUE
var/atom/movable/AM = parent
for(var/obj/machinery/duct/D in AM.loc) //Destroy any ducts under us. Ducts also self destruct if placed under a plumbing machine. machines disable when they get moved
if(D.anchored) //that should cover everything
D.disconnect_duct()
if(demand_connects)
START_PROCESSING(SSfluids, src)
for(var/D in GLOB.cardinals)
if(D & (demand_connects | supply_connects))
for(var/atom/movable/A in get_step(parent, D))
if(istype(A, /obj/machinery/duct))
var/obj/machinery/duct/duct = A
duct.attempt_connect()
else
var/datum/component/plumbing/P = A.GetComponent(/datum/component/plumbing)
if(P)
direct_connect(P, D)
/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move
/datum/component/plumbing/proc/toggle_active(obj/O, new_state)
if(new_state)
enable()
else
disable()
/** We update our connects only when we settle down by taking our current and original direction to find our new connects
* If someone wants it to fucking spin while connected to something go actually knock yourself out
*/
/datum/component/plumbing/proc/update_dir()
if(!turn_connects)
return
var/atom/movable/AM = parent
var/new_demand_connects
var/new_supply_connects
var/new_dir = AM.dir
var/angle = 180 - dir2angle(new_dir)
if(new_dir == SOUTH)
demand_connects = initial(demand_connects)
supply_connects = initial(supply_connects)
else
for(var/D in GLOB.cardinals)
if(D & initial(demand_connects))
new_demand_connects += turn(D, angle)
if(D & initial(supply_connects))
new_supply_connects += turn(D, angle)
demand_connects = new_demand_connects
supply_connects = new_supply_connects
///Give the direction of a pipe, and it'll return wich direction it originally was when it's object pointed SOUTH
/datum/component/plumbing/proc/get_original_direction(dir)
var/atom/movable/AM = parent
return turn(dir, dir2angle(AM.dir) - 180)
//special case in-case we want to connect directly with another machine without a duct
/datum/component/plumbing/proc/direct_connect(datum/component/plumbing/P, dir)
if(!P.active)
return
var/opposite_dir = turn(dir, 180)
if(P.demand_connects & opposite_dir && supply_connects & dir || P.supply_connects & opposite_dir && demand_connects & dir) //make sure we arent connecting two supplies or demands
var/datum/ductnet/net = new()
net.add_plumber(src, dir)
net.add_plumber(P, opposite_dir)
///has one pipe input that only takes, example is manual output pipe
/datum/component/plumbing/simple_demand
demand_connects = NORTH
///has one pipe output that only supplies. example is liquid pump and manual input pipe
/datum/component/plumbing/simple_supply
supply_connects = NORTH
///input and output, like a holding tank
/datum/component/plumbing/tank
demand_connects = WEST
supply_connects = EAST
@@ -0,0 +1,21 @@
/datum/component/plumbing/acclimator
demand_connects = WEST
supply_connects = EAST
var/obj/machinery/plumbing/acclimator/AC
/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE)
. = ..()
if(!istype(parent, /obj/machinery/plumbing/acclimator))
return COMPONENT_INCOMPATIBLE
AC = parent
/datum/component/plumbing/acclimator/can_give(amount, reagent)
. = ..()
if(. && AC.emptying)
return TRUE
return FALSE
///We're overriding process and not send_request, because all process does is do the requests, so we might aswell cut out the middle man and save some code from running
/datum/component/plumbing/acclimator/process()
if(AC.emptying)
return
. = ..()
+59
View File
@@ -0,0 +1,59 @@
///The magical plumbing component used by the chemical filters. The different supply connects behave differently depending on the filters set on the chemical filter
/datum/component/plumbing/filter
demand_connects = NORTH
supply_connects = SOUTH | EAST | WEST //SOUTH is straight, EAST is left and WEST is right. We look from the perspective of the insert
/datum/component/plumbing/filter/Initialize()
. = ..()
if(!istype(parent, /obj/machinery/plumbing/filter))
return COMPONENT_INCOMPATIBLE
/datum/component/plumbing/filter/can_give(amount, reagent, datum/ductnet/net)
. = ..()
if(.)
var/direction
for(var/A in ducts)
if(ducts[A] == net)
direction = get_original_direction(text2num(A)) //we need it relative to the direction, so filters don't change when we turn the filter
break
if(!direction)
return FALSE
if(reagent)
if(!can_give_in_direction(direction, reagent))
return FALSE
/datum/component/plumbing/filter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net)
if(!reagents || !target || !target.reagents)
return FALSE
var/direction
for(var/A in ducts)
if(ducts[A] == net)
direction = get_original_direction(text2num(A))
break
if(reagent)
reagents.trans_id_to(target.parent, reagent, amount)
else
for(var/A in reagents.reagent_list)
var/datum/reagent/R = A
if(!can_give_in_direction(direction, R.type))
continue
var/new_amount
if(R.volume < amount)
new_amount = amount - R.volume
reagents.trans_id_to(target.parent, R.type, amount)
amount = new_amount
if(amount <= 0)
break
///We check if the direction and reagent are valid to give. Needed for filters since different outputs have different behaviours
/datum/component/plumbing/filter/proc/can_give_in_direction(dir, reagent)
var/obj/machinery/plumbing/filter/F = parent
switch(dir)
if(SOUTH) //straight
if(!F.left.Find(reagent) && !F.right.Find(reagent))
return TRUE
if(WEST) //right
if(F.right.Find(reagent))
return TRUE
if(EAST) //left
if(F.left.Find(reagent))
return TRUE
@@ -0,0 +1,38 @@
/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, datum/ductnet/net)
. = ..()
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
RC.reagent_flags &= ~NO_REACT
reagents.handle_reactions()
RC.emptying = TRUE //If we move this up, it'll instantly get turned off since any reaction always sets the reagent_total to zero. Other option is make the reaction update
//everything for every chemical removed, wich isn't a good option either.
RC.on_reagent_change() //We need to check it now, because some reactions leave nothing left.
@@ -0,0 +1,45 @@
/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 = TRUE
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
. = ..()