mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-09 16:12:17 +00:00
Co-authored-by: Will <7099514+Willburd@users.noreply.github.com> Co-authored-by: Cameron Lennox <killer65311@gmail.com>
302 lines
8.7 KiB
Plaintext
302 lines
8.7 KiB
Plaintext
/*CONTENTS
|
|
Buildable pipes
|
|
Buildable meters
|
|
*/
|
|
|
|
/obj/item/pipe
|
|
name = "pipe"
|
|
desc = "A pipe."
|
|
var/pipe_type
|
|
var/pipename
|
|
force = 7
|
|
throwforce = 7
|
|
icon = 'icons/obj/pipe-item.dmi'
|
|
icon_state = "simple"
|
|
item_state = "buildpipe"
|
|
w_class = ITEMSIZE_NORMAL
|
|
level = 2
|
|
var/piping_layer = PIPING_LAYER_DEFAULT
|
|
var/dispenser_class // Tells the dispenser what orientations we support, so RPD can show previews.
|
|
|
|
// One subtype for each way components connect to neighbors
|
|
/obj/item/pipe/directional
|
|
dispenser_class = PIPE_DIRECTIONAL
|
|
/obj/item/pipe/binary
|
|
dispenser_class = PIPE_STRAIGHT
|
|
/obj/item/pipe/binary/bendable
|
|
dispenser_class = PIPE_BENDABLE
|
|
/obj/item/pipe/trinary
|
|
dispenser_class = PIPE_TRINARY
|
|
/obj/item/pipe/trinary/flippable
|
|
dispenser_class = PIPE_TRIN_M
|
|
var/mirrored = FALSE
|
|
/obj/item/pipe/quaternary
|
|
dispenser_class = PIPE_ONEDIR
|
|
|
|
/**
|
|
* Call constructor with:
|
|
* @param loc Location
|
|
* @pipe_type
|
|
*/
|
|
/obj/item/pipe/Initialize(mapload, var/_pipe_type, var/_dir, var/obj/machinery/atmospherics/make_from)
|
|
if(make_from)
|
|
make_from_existing(make_from)
|
|
else
|
|
pipe_type = _pipe_type
|
|
set_dir(_dir)
|
|
|
|
update()
|
|
pixel_x += rand(-5, 5)
|
|
pixel_y += rand(-5, 5)
|
|
AddElement(/datum/element/rotatable)
|
|
. = ..()
|
|
|
|
/obj/item/pipe/proc/make_from_existing(obj/machinery/atmospherics/make_from)
|
|
set_dir(make_from.dir)
|
|
pipename = make_from.name
|
|
if(make_from.req_access)
|
|
src.req_access = make_from.req_access
|
|
if(make_from.req_one_access)
|
|
src.req_one_access = make_from.req_one_access
|
|
color = make_from.pipe_color
|
|
pipe_type = make_from.type
|
|
|
|
/obj/item/pipe/trinary/flippable/make_from_existing(obj/machinery/atmospherics/trinary/make_from)
|
|
..()
|
|
if(make_from.mirrored)
|
|
do_a_flip()
|
|
|
|
/obj/item/pipe/dropped(mob/user)
|
|
if(loc)
|
|
setPipingLayer(piping_layer)
|
|
return ..()
|
|
|
|
/obj/item/pipe/proc/setPipingLayer(new_layer = PIPING_LAYER_DEFAULT)
|
|
var/obj/machinery/atmospherics/fakeA = pipe_type
|
|
if(initial(fakeA.pipe_flags) & (PIPING_ALL_LAYER|PIPING_DEFAULT_LAYER_ONLY))
|
|
new_layer = PIPING_LAYER_DEFAULT
|
|
piping_layer = new_layer
|
|
// Do it the Polaris way
|
|
switch(piping_layer)
|
|
if(PIPING_LAYER_SCRUBBER)
|
|
color = PIPE_COLOR_RED
|
|
name = "[initial(fakeA.name)] scrubber fitting"
|
|
if(PIPING_LAYER_SUPPLY)
|
|
color = PIPE_COLOR_BLUE
|
|
name = "[initial(fakeA.name)] supply fitting"
|
|
if(PIPING_LAYER_FUEL)
|
|
color = PIPE_COLOR_YELLOW
|
|
name = "[initial(fakeA.name)] fuel fitting"
|
|
if(PIPING_LAYER_AUX)
|
|
color = PIPE_COLOR_CYAN
|
|
name = "[initial(fakeA.name)] aux fitting"
|
|
// Or if we were to do it the TG way...
|
|
// pixel_x = PIPE_PIXEL_OFFSET_X(piping_layer)
|
|
// pixel_y = PIPE_PIXEL_OFFSET_Y(piping_layer)
|
|
// layer = initial(layer) + PIPE_LAYER_OFFSET(piping_layer)
|
|
|
|
/obj/item/pipe/proc/update()
|
|
var/obj/machinery/atmospherics/fakeA = pipe_type
|
|
name = "[initial(fakeA.name)] fitting"
|
|
icon_state = initial(fakeA.pipe_state)
|
|
|
|
/obj/item/pipe/verb/flip()
|
|
set category = "Object"
|
|
set name = "Flip Pipe"
|
|
set src in view(1)
|
|
|
|
if ( usr.stat || usr.restrained() || !usr.canmove )
|
|
return
|
|
|
|
do_a_flip()
|
|
|
|
/obj/item/pipe/proc/do_a_flip()
|
|
set_dir(turn(dir, -180))
|
|
fixdir()
|
|
|
|
/obj/item/pipe/trinary/flippable/do_a_flip()
|
|
// set_dir(turn(dir, flipped ? 45 : -45))
|
|
// TG has a magic icon set with the flipped versions in the diagonals.
|
|
// We may switch to this later, but for now gotta do some magic.
|
|
mirrored = !mirrored
|
|
var/obj/machinery/atmospherics/fakeA = pipe_type
|
|
icon_state = "[initial(fakeA.pipe_state)][mirrored ? "m" : ""]"
|
|
|
|
/obj/item/pipe/handle_rotation_verbs(angle)
|
|
. = ..()
|
|
if(.)
|
|
fixdir()
|
|
|
|
// Don't let pulling a pipe straighten it out.
|
|
/obj/item/pipe/binary/bendable/Move()
|
|
var/old_bent = !IS_CARDINAL(dir)
|
|
. = ..()
|
|
if(old_bent && IS_CARDINAL(dir))
|
|
set_dir(turn(src.dir, -45))
|
|
|
|
//Helper to clean up dir
|
|
/obj/item/pipe/proc/fixdir()
|
|
return
|
|
|
|
/obj/item/pipe/binary/fixdir()
|
|
if(dir == SOUTH)
|
|
set_dir(NORTH)
|
|
else if(dir == WEST)
|
|
set_dir(EAST)
|
|
|
|
/obj/item/pipe/trinary/flippable/fixdir()
|
|
if(dir in GLOB.cornerdirs)
|
|
set_dir(turn(dir, 45))
|
|
|
|
/obj/item/pipe/attack_self(mob/user)
|
|
set_dir(turn(dir,-90))
|
|
fixdir()
|
|
|
|
//called when a turf is attacked with a pipe item
|
|
/obj/item/pipe/afterattack(turf/simulated/floor/target, mob/user, proximity)
|
|
if(!proximity) return
|
|
if(istype(target) && user.canUnEquip(src))
|
|
user.drop_from_inventory(src, target)
|
|
else
|
|
return ..()
|
|
|
|
/obj/item/pipe/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
|
if(W.has_tool_quality(TOOL_WRENCH))
|
|
return wrench_act(user, W)
|
|
return ..()
|
|
|
|
/obj/item/pipe/proc/wrench_act(var/mob/living/user, var/obj/item/tool/wrench/W)
|
|
if(!isturf(loc))
|
|
return TRUE
|
|
|
|
add_fingerprint(user)
|
|
fixdir()
|
|
|
|
var/obj/machinery/atmospherics/fakeA = pipe_type
|
|
var/flags = initial(fakeA.pipe_flags)
|
|
for(var/obj/machinery/atmospherics/M in loc)
|
|
if((M.pipe_flags & flags & PIPING_ONE_PER_TURF)) //Only one dense/requires density object per tile, eg connectors/cryo/heater/coolers.
|
|
to_chat(user, span_warning("Something is hogging the tile!"))
|
|
return TRUE
|
|
if((M.piping_layer != piping_layer) && !((M.pipe_flags | flags) & PIPING_ALL_LAYER)) // Pipes on different layers can't block each other unless they are ALL_LAYER
|
|
continue
|
|
if(M.get_init_dirs() & SSmachines.get_init_dirs(pipe_type, dir)) // matches at least one direction on either type of pipe
|
|
to_chat(user, span_warning("There is already a pipe at that location!"))
|
|
return TRUE
|
|
// no conflicts found
|
|
|
|
var/obj/machinery/atmospherics/A = new pipe_type(loc)
|
|
build_pipe(A)
|
|
// TODO - Evaluate and remove the "need at least one thing to connect to" thing ~Leshana
|
|
// With how the pipe code works, at least one end needs to be connected to something, otherwise the game deletes the segment.
|
|
if (QDELETED(A))
|
|
to_chat(user, span_warning("There's nothing to connect this pipe section to!"))
|
|
return TRUE
|
|
transfer_fingerprints_to(A)
|
|
|
|
playsound(src, W.usesound, 50, 1)
|
|
user.visible_message( \
|
|
"[user] fastens \the [src].", \
|
|
span_notice("You fasten \the [src]."), \
|
|
span_warningplain("You hear ratcheting."))
|
|
|
|
qdel(src)
|
|
|
|
/obj/item/pipe/proc/build_pipe(obj/machinery/atmospherics/A)
|
|
A.set_dir(dir)
|
|
A.init_dir()
|
|
if(pipename)
|
|
A.name = pipename
|
|
if(req_access)
|
|
A.req_access = req_access
|
|
if(req_one_access)
|
|
A.req_one_access = req_one_access
|
|
A.on_construction(color, piping_layer)
|
|
|
|
/obj/item/pipe/trinary/flippable/build_pipe(obj/machinery/atmospherics/trinary/T)
|
|
T.mirrored = mirrored
|
|
. = ..()
|
|
|
|
// Lookup the initialize_directions for a given atmos machinery instance facing dir.
|
|
// TODO - Right now this determines the answer by instantiating an instance and checking!
|
|
// There has to be a better way... ~Leshana
|
|
/datum/controller/subsystem/machines/proc/get_init_dirs(type, dir)
|
|
var/static/list/pipe_init_dirs_cache = list()
|
|
if(!pipe_init_dirs_cache[type])
|
|
pipe_init_dirs_cache[type] = list()
|
|
|
|
if(!pipe_init_dirs_cache[type]["[dir]"])
|
|
var/obj/machinery/atmospherics/temp = new type(null, dir)
|
|
pipe_init_dirs_cache[type]["[dir]"] = temp.get_init_dirs()
|
|
qdel(temp)
|
|
|
|
return pipe_init_dirs_cache[type]["[dir]"]
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// Meters are special - not like any other pipes or components
|
|
//
|
|
|
|
/obj/item/pipe_meter
|
|
name = "meter"
|
|
desc = "A meter that can be laid on pipes."
|
|
icon = 'icons/obj/pipe-item.dmi'
|
|
icon_state = "meter"
|
|
item_state = "buildpipe"
|
|
w_class = ITEMSIZE_LARGE
|
|
var/piping_layer = PIPING_LAYER_DEFAULT
|
|
|
|
/obj/item/pipe_meter/attackby(var/obj/item/W as obj, var/mob/user as mob)
|
|
if(W.has_tool_quality(TOOL_WRENCH))
|
|
return wrench_act(user, W)
|
|
return ..()
|
|
|
|
/obj/item/pipe_meter/proc/wrench_act(var/mob/living/user, var/obj/item/tool/wrench/W)
|
|
var/obj/machinery/atmospherics/pipe/pipe
|
|
for(var/obj/machinery/atmospherics/pipe/P in loc)
|
|
if(P.piping_layer == piping_layer)
|
|
pipe = P
|
|
break
|
|
if(!pipe)
|
|
to_chat(user, span_warning("You need to fasten it to a pipe!"))
|
|
return TRUE
|
|
new /obj/machinery/meter(loc, piping_layer)
|
|
playsound(src, W.usesound, 50, 1)
|
|
to_chat(user, span_notice("You fasten the meter to the pipe."))
|
|
qdel(src)
|
|
|
|
/obj/item/pipe_meter/dropped(mob/user)
|
|
. = ..()
|
|
if(loc)
|
|
setAttachLayer(piping_layer)
|
|
|
|
/obj/item/pipe_meter/proc/setAttachLayer(new_layer = PIPING_LAYER_DEFAULT)
|
|
piping_layer = new_layer
|
|
|
|
/obj/item/pipe_gsensor
|
|
name = "gas sensor"
|
|
desc = "A sensor that can be hooked to a computer."
|
|
icon = 'icons/obj/stationobjs.dmi'
|
|
icon_state = "gsensor0"
|
|
item_state = "buildpipe"
|
|
w_class = ITEMSIZE_LARGE
|
|
var/label = null
|
|
var/id_tag
|
|
var/output = 3
|
|
|
|
/obj/item/pipe_gsensor/attackby(obj/item/W, mob/user)
|
|
if(W.has_tool_quality(TOOL_WRENCH))
|
|
return wrench_act(user, W)
|
|
return ..()
|
|
|
|
/obj/item/pipe_gsensor/proc/wrench_act(mob/living/user, obj/item/tool/wrench/W)
|
|
var/obj/machinery/air_sensor/air_sensor = new /obj/machinery/air_sensor(loc)
|
|
air_sensor.id_tag = id_tag
|
|
air_sensor.output = output
|
|
playsound(src, W.usesound, 50, 1)
|
|
to_chat(user, span_notice("You fasten the meter to the pipe."))
|
|
qdel(src)
|