From ccb9ceb8112d8718bc437c65985a682273efc57c Mon Sep 17 00:00:00 2001
From: PJB3005
Date: Sat, 15 Aug 2015 18:18:51 +0200
Subject: [PATCH] RCD Rework.
RCDs now work on a system of schematics, with an RPD style UI.
RPD, RCD, RSF and tile painters all implemented into this new system.
---
code/ATMOSPHERICS/components/unary/cap.dm | 2 +-
code/ATMOSPHERICS/components/unary/tank.dm | 2 +-
code/ATMOSPHERICS/he_pipes.dm | 2 +
code/ATMOSPHERICS/pipes.dm | 76 ++-
.../gamemodes/malfunction/Malf_Modules.dm | 2 +-
code/game/gamemodes/steal_items.dm | 4 +-
code/game/machinery/autolathe.dm | 8 +-
code/game/objects/items/weapons/RCD.dm | 289 ---------
code/game/objects/items/weapons/RPD.dm | 609 ------------------
code/game/objects/items/weapons/RSF.dm | 135 ----
.../objects/items/weapons/tile_painter.dm | 490 --------------
.../closets/secure/engineering.dm | 2 +-
.../structures/crates_lockers/crates.dm | 2 +-
code/global.dm | 2 +-
code/modules/RCD/RCD.dm | 231 +++++++
code/modules/RCD/RPD.dm | 64 ++
code/modules/RCD/RSF.dm | 39 ++
code/modules/RCD/engie.dm | 45 ++
code/modules/RCD/schematic.dm | 83 +++
code/modules/RCD/schematics/engi.dm | 394 +++++++++++
code/modules/RCD/schematics/pipe.dm | 572 ++++++++++++++++
code/modules/RCD/schematics/service.dm | 46 ++
code/modules/RCD/schematics/test.dm | 6 +
code/modules/RCD/schematics/tile.dm | 609 ++++++++++++++++++
code/modules/RCD/tile painter.dm | 15 +
code/modules/clothing/spacesuits/alien.dm | 2 +-
code/modules/clothing/spacesuits/ert.dm | 2 +-
code/modules/clothing/spacesuits/rig.dm | 6 +-
code/modules/flufftext/Hallucination.dm | 2 +-
code/modules/html_interface/RCD/RCD.css | 28 +
code/modules/html_interface/RCD/RCD.dm | 21 +
.../RCD/html_interface_no_bootstrap.html | 15 +
code/modules/html_interface/html_interface.dm | 5 +-
code/modules/maps/spawners/spawners.dm | 6 +-
.../mob/living/silicon/mommi/mommi_modules.dm | 4 +-
.../mob/living/silicon/robot/robot_modules.dm | 8 +-
code/setup.dm | 6 +
html/changelogs/PJB3005-RCD.yml | 9 +
icons/obj/RCD.dmi | Bin 0 -> 928 bytes
icons/obj/items.dmi | Bin 89167 -> 88243 bytes
maps/defficiency.dmm | 6 +-
maps/metaclub.dmm | 14 +-
maps/taxistation.dmm | 6 +-
maps/tgstation.dmm | 12 +-
vgstation13.dme | 16 +-
45 files changed, 2293 insertions(+), 1604 deletions(-)
delete mode 100644 code/game/objects/items/weapons/RCD.dm
delete mode 100644 code/game/objects/items/weapons/RPD.dm
delete mode 100644 code/game/objects/items/weapons/RSF.dm
delete mode 100644 code/game/objects/items/weapons/tile_painter.dm
create mode 100644 code/modules/RCD/RCD.dm
create mode 100644 code/modules/RCD/RPD.dm
create mode 100644 code/modules/RCD/RSF.dm
create mode 100644 code/modules/RCD/engie.dm
create mode 100644 code/modules/RCD/schematic.dm
create mode 100644 code/modules/RCD/schematics/engi.dm
create mode 100644 code/modules/RCD/schematics/pipe.dm
create mode 100644 code/modules/RCD/schematics/service.dm
create mode 100644 code/modules/RCD/schematics/test.dm
create mode 100644 code/modules/RCD/schematics/tile.dm
create mode 100644 code/modules/RCD/tile painter.dm
create mode 100644 code/modules/html_interface/RCD/RCD.css
create mode 100644 code/modules/html_interface/RCD/RCD.dm
create mode 100644 code/modules/html_interface/RCD/html_interface_no_bootstrap.html
create mode 100644 html/changelogs/PJB3005-RCD.yml
create mode 100644 icons/obj/RCD.dmi
diff --git a/code/ATMOSPHERICS/components/unary/cap.dm b/code/ATMOSPHERICS/components/unary/cap.dm
index 1cf8e3d7aab..be5face4e10 100644
--- a/code/ATMOSPHERICS/components/unary/cap.dm
+++ b/code/ATMOSPHERICS/components/unary/cap.dm
@@ -98,7 +98,7 @@
/obj/machinery/atmospherics/unary/cap/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- if(istype(W, /obj/item/weapon/pipe_dispenser) || istype(W, /obj/item/device/pipe_painter))
+ if(istype(W, /obj/item/device/rcd/rpd) || istype(W, /obj/item/device/pipe_painter))
return // Coloring pipes.
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/red))
diff --git a/code/ATMOSPHERICS/components/unary/tank.dm b/code/ATMOSPHERICS/components/unary/tank.dm
index ea994ad4921..36ccdd589d6 100644
--- a/code/ATMOSPHERICS/components/unary/tank.dm
+++ b/code/ATMOSPHERICS/components/unary/tank.dm
@@ -95,7 +95,7 @@
/obj/machinery/atmospherics/unary/tank/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- if(istype(W, /obj/item/weapon/pipe_dispenser) || istype(W, /obj/item/device/pipe_painter))
+ if(istype(W, /obj/item/device/rcd/rpd) || istype(W, /obj/item/device/pipe_painter))
return // Coloring pipes.
if (istype(W, /obj/item/device/analyzer) && get_dist(user, src) <= 1)
user.visible_message("[user] has used [W] on \icon[icon] [src]", "You use \the [W] on \icon[icon] [src]")
diff --git a/code/ATMOSPHERICS/he_pipes.dm b/code/ATMOSPHERICS/he_pipes.dm
index 019f1016808..e52d5e8e9bc 100644
--- a/code/ATMOSPHERICS/he_pipes.dm
+++ b/code/ATMOSPHERICS/he_pipes.dm
@@ -16,6 +16,8 @@
burst_type = /obj/machinery/atmospherics/unary/vent/burstpipe/heat_exchanging
+ available_colors = null //Overrides the available colors list from the parent.
+
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/getNodeType(var/node_id)
return PIPE_TYPE_HE
diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm
index 11ff514acb3..30503968324 100644
--- a/code/ATMOSPHERICS/pipes.dm
+++ b/code/ATMOSPHERICS/pipes.dm
@@ -24,13 +24,13 @@
var/baseicon=""
available_colors = list(
- "grey"=PIPE_COLOR_GREY,
- "red"=PIPE_COLOR_RED,
- "blue"=PIPE_COLOR_BLUE,
- "cyan"=PIPE_COLOR_CYAN,
- "green"=PIPE_COLOR_GREEN,
- "yellow"=PIPE_COLOR_YELLOW,
- "purple"=PIPE_COLOR_PURPLE
+ "grey" = PIPE_COLOR_GREY,
+ "red" = PIPE_COLOR_RED,
+ "blue" = PIPE_COLOR_BLUE,
+ "cyan" = PIPE_COLOR_CYAN,
+ "green" = PIPE_COLOR_GREEN,
+ "yellow" = PIPE_COLOR_YELLOW,
+ "purple" = PIPE_COLOR_PURPLE
)
/obj/machinery/atmospherics/pipe/singularity_pull(/obj/machinery/singularity/S, size)
@@ -404,7 +404,7 @@
level = 1
alpha=128
/obj/machinery/atmospherics/pipe/simple/insulated
- name = "Insulated pipe"
+ name = "\improper Insulated pipe"
//icon = 'icons/obj/atmospherics/red_pipe.dmi'
icon = 'icons/obj/atmospherics/insulated.dmi'
minimum_temperature_difference = 10000
@@ -415,8 +415,12 @@
alert_pressure = 900000
available_colors = list(
- "red"=IPIPE_COLOR_RED,
- "blue"=IPIPE_COLOR_BLUE
+ "red" = IPIPE_COLOR_RED,
+ "blue" = IPIPE_COLOR_BLUE,
+ "cyan" = PIPE_COLOR_CYAN,
+ "green" = PIPE_COLOR_GREEN,
+ "yellow" = PIPE_COLOR_YELLOW,
+ "purple" = PIPE_COLOR_PURPLE
)
_color = "red"
/obj/machinery/atmospherics/pipe/simple/insulated/visible
@@ -592,35 +596,35 @@
update_icon()
/obj/machinery/atmospherics/pipe/manifold/scrubbers
- name = "Scrubbers pipe"
+ name = "\improper Scrubbers pipe"
_color = "red"
color=PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold/supply
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "blue"
color=PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold/supplymain
- name = "Main air supply pipe"
+ name = "\improper Main air supply pipe"
_color = "purple"
color=PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold/general
- name = "Gas pipe"
+ name = "\improper Gas pipe"
_color = "gray"
color=PIPE_COLOR_GREY
/obj/machinery/atmospherics/pipe/manifold/yellow
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "yellow"
color=PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold/cyan
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "cyan"
color=PIPE_COLOR_CYAN
/obj/machinery/atmospherics/pipe/manifold/filtering
- name = "Air filtering pipe"
+ name = "\improper Air filtering pipe"
_color = "green"
color=PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold/insulated
- name = "Insulated pipe"
+ name = "\improper Insulated pipe"
//icon = 'icons/obj/atmospherics/red_pipe.dmi'
icon = 'icons/obj/atmospherics/insulated.dmi'
icon_state = "manifold"
@@ -628,10 +632,16 @@
_color = "red"
color=IPIPE_COLOR_RED
level = 2
+
available_colors = list(
- "red"=IPIPE_COLOR_RED,
- "blue"=IPIPE_COLOR_BLUE
+ "red" = IPIPE_COLOR_RED,
+ "blue" = IPIPE_COLOR_BLUE,
+ "cyan" = PIPE_COLOR_CYAN,
+ "green" = PIPE_COLOR_GREEN,
+ "yellow" = PIPE_COLOR_YELLOW,
+ "purple" = PIPE_COLOR_PURPLE
)
+
/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible
level = 2
/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden
@@ -838,40 +848,46 @@
update_icon()
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers
- name = "Scrubbers pipe"
+ name = "\improper Scrubbers pipe"
_color = "red"
color=PIPE_COLOR_RED
/obj/machinery/atmospherics/pipe/manifold4w/supply
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "blue"
color=PIPE_COLOR_BLUE
/obj/machinery/atmospherics/pipe/manifold4w/supplymain
- name = "Main air supply pipe"
+ name = "\improper Main air supply pipe"
_color = "purple"
color=PIPE_COLOR_PURPLE
/obj/machinery/atmospherics/pipe/manifold4w/general
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "gray"
color=PIPE_COLOR_GREY
/obj/machinery/atmospherics/pipe/manifold4w/yellow
- name = "Air supply pipe"
+ name = "\improper Air supply pipe"
_color = "yellow"
color=PIPE_COLOR_YELLOW
/obj/machinery/atmospherics/pipe/manifold4w/filtering
- name = "Air filtering pipe"
+ name = "\improper Air filtering pipe"
_color = "green"
color=PIPE_COLOR_GREEN
/obj/machinery/atmospherics/pipe/manifold4w/insulated
icon = 'icons/obj/atmospherics/insulated.dmi'
- name = "Insulated pipe"
+ name = "\improper Insulated pipe"
_color = "red"
alert_pressure = 900*ONE_ATMOSPHERE
color=IPIPE_COLOR_RED
level = 2
+
available_colors = list(
- "red"=IPIPE_COLOR_RED,
- "blue"=IPIPE_COLOR_BLUE
+ "red" = IPIPE_COLOR_RED,
+ "blue" = IPIPE_COLOR_BLUE,
+ "cyan" = PIPE_COLOR_CYAN,
+ "green" = PIPE_COLOR_GREEN,
+ "yellow" = PIPE_COLOR_YELLOW,
+ "purple" = PIPE_COLOR_PURPLE
)
+
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible
level = 2
/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden
@@ -916,7 +932,7 @@
/obj/machinery/atmospherics/pipe/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
- if(istype(W, /obj/item/weapon/pipe_dispenser) || istype(W, /obj/item/device/pipe_painter))
+ if(istype(W, /obj/item/device/rcd/rpd) || istype(W, /obj/item/device/pipe_painter))
return // Coloring pipes.
if(istype(W, /obj/item/weapon/reagent_containers/glass/paint/red))
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 04f01581c80..f68d02eb80f 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -86,7 +86,7 @@ rcd light flash thingy on matter drain
for(var/datum/AI_Module/large/disable_rcd/rcdmod in current_modules)
if(rcdmod.uses > 0)
rcdmod.uses --
- for(var/obj/item/weapon/rcd/rcd in world)
+ for(var/obj/item/device/rcd/matter/engineering/rcd in world)
rcd.disabled = 1
for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
rcd.disabled = 1
diff --git a/code/game/gamemodes/steal_items.dm b/code/game/gamemodes/steal_items.dm
index 968d533ee33..626efd29f8b 100644
--- a/code/game/gamemodes/steal_items.dm
+++ b/code/game/gamemodes/steal_items.dm
@@ -72,12 +72,12 @@
/datum/theft_objective/traitor/rcd
name = "an RCD"
- typepath = /obj/item/weapon/rcd
+ typepath = /obj/item/device/rcd/matter/engineering
protected_jobs = list("Chief Engineer")
/datum/theft_objective/traitor/rpd
name = "an RPD"
- typepath = /obj/item/weapon/pipe_dispenser
+ typepath = /obj/item/device/rcd/rpd
protected_jobs = list("Chief Engineer", "Atmospherics Technician")
/datum/theft_objective/traitor/jetpack
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index f390fd2e64c..605b1949313 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -92,7 +92,7 @@
new /obj/item/clothing/head/welding(), \
new /obj/item/device/taperecorder(), \
new /obj/item/weapon/chisel(), \
- new /obj/item/weapon/tile_painter(), \
+ new /obj/item/device/rcd/tile_painter(), \
),
"Misc_Other"=list(
new /obj/item/weapon/rcd_ammo(), \
@@ -107,9 +107,9 @@
"Hidden_Items" = list(
new /obj/item/weapon/flamethrower/full(), \
new /obj/item/ammo_storage/box/flare(), \
- new /obj/item/weapon/rcd(), \
- new /obj/item/weapon/pipe_dispenser(),\
- new /obj/item/weapon/rsf(), \
+ new /obj/item/device/rcd/matter/engineering(), \
+ new /obj/item/device/rcd/rpd(),\
+ new /obj/item/device/rcd/matter/rsf(), \
new /obj/item/device/radio/electropack(), \
new /obj/item/weapon/weldingtool/largetank(), \
new /obj/item/weapon/handcuffs(), \
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
deleted file mode 100644
index e7b66053156..00000000000
--- a/code/game/objects/items/weapons/RCD.dm
+++ /dev/null
@@ -1,289 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/*
-CONTAINS:
-RCD
-*/
-/obj/item/weapon/rcd
- name = "rapid-construction-device (RCD)"
- desc = "A device used to rapidly build walls/floor."
- icon = 'icons/obj/items.dmi'
- icon_state = "rcd"
- opacity = 0
- density = 0
- anchored = 0.0
- flags = FPRINT
- siemens_coefficient = 1
- force = 10.0
- throwforce = 10.0
- throw_speed = 1
- throw_range = 5
- w_class = 3.0
- starting_materials = list(MAT_IRON = 50000)
- w_type = RECYK_ELECTRONIC
- melt_temperature = MELTPOINT_STEEL // Lots of metal
- origin_tech = "engineering=4;materials=2"
- var/datum/effect/effect/system/spark_spread/spark_system
- var/matter = 0
- var/max_matter = 30
- var/working = 0
- var/mode = 1
- var/canRwall = 0
- var/disabled = 0
- var/airlock_type = /obj/machinery/door/airlock
- var/floor_cost = 1
- var/wall_cost = 3
- var/airlock_cost = 3
- var/decon_cost = 5
-
-/obj/item/weapon/rcd/verb/change_airlock_setting()
- set name = "Change Airlock Setting"
- set category = "Object"
- set src in usr
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/rcd/verb/change_airlock_setting() called tick#: [world.time]")
-
- var airlockcat = input(usr, "Select the type of the airlock.") in list("Solid", "Glass")
- switch(airlockcat)
- if("Solid")
- var airlockpaint = input(usr, "Select the paintjob of the airlock.") in list("Default", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining", "Maintenance", "External", "High Security")
- switch(airlockpaint)
- if("Default")
- airlock_type = /obj/machinery/door/airlock
- if("Engineering")
- airlock_type = /obj/machinery/door/airlock/engineering
- if("Atmospherics")
- airlock_type = /obj/machinery/door/airlock/atmos
- if("Security")
- airlock_type = /obj/machinery/door/airlock/security
- if("Command")
- airlock_type = /obj/machinery/door/airlock/command
- if("Medical")
- airlock_type = /obj/machinery/door/airlock/medical
- if("Research")
- airlock_type = /obj/machinery/door/airlock/research
- if("Mining")
- airlock_type = /obj/machinery/door/airlock/mining
- if("Maintenance")
- airlock_type = /obj/machinery/door/airlock/maintenance
- if("External")
- airlock_type = /obj/machinery/door/airlock/external
- if("High Security")
- airlock_type = /obj/machinery/door/airlock/highsecurity
-
- if("Glass")
- var airlockpaint = input(usr, "Select the paintjob of the airlock.") in list("Default", "Engineering", "Atmospherics", "Security", "Command", "Medical", "Research", "Mining")
- switch(airlockpaint)
- if("Default")
- airlock_type = /obj/machinery/door/airlock/glass
- if("Engineering")
- airlock_type = /obj/machinery/door/airlock/glass_engineering
- if("Atmospherics")
- airlock_type = /obj/machinery/door/airlock/glass_atmos
- if("Security")
- airlock_type = /obj/machinery/door/airlock/glass_security
- if("Command")
- airlock_type = /obj/machinery/door/airlock/glass_command
- if("Medical")
- airlock_type = /obj/machinery/door/airlock/glass_medical
- if("Research")
- airlock_type = /obj/machinery/door/airlock/glass_research
- if("Mining")
- airlock_type = /obj/machinery/door/airlock/glass_mining
- else
- airlock_type = /obj/machinery/door/airlock
-
-/obj/item/weapon/rcd/suicide_act(mob/user)
- viewers(user) << "[user] is using the deconstruct function on the [src.name] on \himself! It looks like \he's trying to commit suicide!"
- return (user.death(1))
-
-/obj/item/weapon/rcd/New()
- ..()
- src.spark_system = new /datum/effect/effect/system/spark_spread
- spark_system.set_up(5, 0, src)
- spark_system.attach(src)
- return
-
-/obj/item/weapon/rcd/examine(mob/user)
- ..()
- if(istype(src, /obj/item/weapon/rcd/borg))
- user << "It's been set to draw power from a power cell."
- else
- user << "It currently holds [matter]/[max_matter] matter-units."
-
-/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
- ..()
- if(istype(W, /obj/item/weapon/rcd_ammo))
- if((matter + 10) > max_matter)
- user << "The RCD can't hold any more matter-units."
- return
- qdel(W)
- matter += 10
- playsound(get_turf(src), 'sound/machines/click.ogg', 20, 1)
- user << "The RCD now holds [matter]/[max_matter] matter-units."
- return
- if(isscrewdriver(W))
- user << "You unscrew the access panel and release the cartridge chamber."
- while(matter>=10)
- new /obj/item/weapon/rcd_ammo(user.loc)
- matter -= 10
- return
-
-
-/obj/item/weapon/rcd/attack_self(mob/user)
- //Change the mode
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- switch(mode)
- if(1)
- mode = 2
- user << "Changed mode to 'Airlock'"
- if(prob(20))
- src.spark_system.start()
- return
- if(2)
- mode = 3
- user << "Changed mode to 'Deconstruct'"
- if(prob(20))
- src.spark_system.start()
- return
- if(3)
- mode = 1
- user << "Changed mode to 'Floor & Walls'"
- if(prob(20))
- src.spark_system.start()
- return
-
-/obj/item/weapon/rcd/proc/activate()
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/rcd/proc/activate() called tick#: [world.time]")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
-
-
-/obj/item/weapon/rcd/afterattack(atom/A, mob/user)
- if(disabled && !isrobot(user))
- return 0
- if(get_dist(user,A)>1)
- return 0
- if(istype(A,/area/shuttle)||istype(A,/turf/space/transit))
- return 0
- if(!(istype(A, /turf) || istype(A, /obj/machinery/door/airlock)))
- return 0
-
- switch(mode)
- if(1)
- if(istype(A, /turf/space))
- if(useResource(floor_cost, user))
- user << "Building Floor..."
- activate()
- A:ChangeTurf(/turf/simulated/floor/plating/airless)
- return 1
- return 0
-
- if(istype(A, /turf/simulated/floor))
- if(checkResource(wall_cost, user))
- user << "Building Wall ..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- if(!useResource(wall_cost, user)) return 0
- activate()
- A:ChangeTurf(/turf/simulated/wall)
- return 1
- return 0
-
- if(2)
- if(checkResource(airlock_cost, user))
- user << "Building Airlock..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 50))
- if(!useResource(airlock_cost, user)) return 0
- if(locate(/obj/machinery/door/airlock) in A) return 0
- activate()
- var/obj/machinery/door/airlock/T = new airlock_type( A )
- T.autoclose = 1
- return 1
- return 0
- return 0
-
- if(3)
- if(istype(A, /turf/simulated/wall))
- if(istype(A, /turf/simulated/wall/r_wall) && !canRwall)
- return 0
- if(checkResource(decon_cost, user))
- user << "Deconstructing Wall..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 40))
- if(!useResource(decon_cost, user)) return 0
- activate()
- A:ChangeTurf(/turf/simulated/floor/plating)
- return 1
- return 0
-
- if(istype(A, /turf/simulated/floor))
- if(checkResource(decon_cost, user))
- user << "Deconstructing Floor..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 50))
- if(!useResource(decon_cost, user)) return 0
- activate()
- A:ChangeTurf(get_base_turf(A.z))
- return 1
- return 0
-
- if(istype(A, /obj/machinery/door/airlock))
- if(checkResource((decon_cost * 2), user))
- user << "Deconstructing Airlock..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 50))
- if(!useResource((decon_cost * 2), user)) return 0
- activate()
- del(A)
- return 1
- return 0
- return 0
- else
- user << "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin."
- return 0
-
-/obj/item/weapon/rcd/proc/useResource(var/amount, var/mob/user)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/rcd/proc/useResource() called tick#: [world.time]")
- if(matter < amount)
- return 0
- matter -= amount
- return 1
-
-/obj/item/weapon/rcd/proc/checkResource(var/amount, var/mob/user)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/rcd/proc/checkResource() called tick#: [world.time]")
- return matter >= amount
-/obj/item/weapon/rcd/borg/useResource(var/amount, var/mob/user)
- if(!isrobot(user))
- return 0
- return user:cell:use(amount * 30)
-
-/obj/item/weapon/rcd/borg/checkResource(var/amount, var/mob/user)
- if(!isrobot(user))
- return 0
- return user:cell:charge >= (amount * 30)
-
-/obj/item/weapon/rcd/borg/New()
- ..()
- canRwall = 1
-
-/obj/item/weapon/rcd_ammo
- name = "compressed matter cartridge"
- desc = "Highly compressed matter in a cartridge form, used in various fabricators."
- icon = 'icons/obj/ammo.dmi'
- icon_state = "rcd"
- item_state = "rcdammo"
- opacity = 0
- density = 0
- anchored = 0.0
- origin_tech = "materials=2"
- w_class = 2.0
- starting_materials = list(MAT_IRON = 30000, MAT_GLASS = 15000)
- w_type = RECYK_ELECTRONIC
-
-/obj/item/weapon/rcd_ammo/attackby(var/obj/O, mob/user)
- if(istype(O, /obj/item/device/material_synth) && !istype(O, /obj/item/device/material_synth/robot))
- return O.attackby(src, user)
- else if(istype(O, /obj/item/weapon/rcd) && !istype(O, /obj/item/weapon/rcd/borg))
- return O.attackby(src, user)
- else if(istype(O, /obj/item/weapon/rsf) && !istype(O, /obj/item/weapon/rsf/cyborg))
- return O.attackby(src, user)
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm
deleted file mode 100644
index ef703a8716a..00000000000
--- a/code/game/objects/items/weapons/RPD.dm
+++ /dev/null
@@ -1,609 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-/*
-CONTAINS:
-RPD
-*/
-#define PIPE_BINARY 0
-#define PIPE_BENT 1
-#define PIPE_TRINARY 2
-#define PIPE_TRIN_M 3
-#define PIPE_UNARY 4
-
-/datum/pipe_info
- var/id=-1
- var/dir=SOUTH
- var/dirtype=PIPE_BINARY
- var/icon = 'icons/obj/pipe-item.dmi'
- var/icon_state=""
- var/selected=0
-
-/datum/pipe_info/New(var/pid,var/direction,var/dt)
- src.id=pid
- src.icon_state=pipeID2State[pid+1]
- src.dir=direction
- src.dirtype=dt
-
-/datum/pipe_info/proc/Render(var/dispenser,var/label)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/pipe_info/proc/Render() called tick#: [world.time]")
- return "[label]"
-
-/datum/pipe_info/meter
- icon = 'icons/obj/pipes.dmi'
- icon_state = "meterX"
-
-/datum/pipe_info/meter/New()
- return
-
-/datum/pipe_info/meter/Render(var/dispenser,var/label)
- return "[label]" //hardcoding is no
-
-/datum/pipe_info/gsensor
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "gsensor1"
-
-/datum/pipe_info/gsensor/New()
- return
-
-/datum/pipe_info/gsensor/Render(var/dispenser,var/label)
- return "[label]" //hardcoding is no
-
-var/global/list/disposalpipeID2State=list(
- "pipe-s",
- "pipe-c",
- "pipe-j1",
- "pipe-y",
- "pipe-t",
- "disposal",
- "outlet",
- "intake",
- "pipe-j1s",
- "pipe-j1s",
-)
-
-/datum/pipe_info/disposal
- icon = 'icons/obj/pipes/disposal.dmi'
- icon_state = "meterX"
-
-/datum/pipe_info/disposal/New(var/pid,var/dt)
- src.id=pid
- src.icon_state=disposalpipeID2State[pid+1]
- src.dir=2
- src.dirtype=dt
- if(pid<6 || pid>8)
- icon_state = "con[icon_state]"
-
-/datum/pipe_info/disposal/Render(var/dispenser,var/label)
- return "[label]" //avoid hardcoding.
-
-//find these defines in code\ATMOSPHERICS\\\pipe\consruction.dm
-var/global/list/RPD_recipes=list(
- "Regular Pipes" = list(
- "Pipe" = new /datum/pipe_info(PIPE_SIMPLE_STRAIGHT, 1, PIPE_BINARY),
- "Bent Pipe" = new /datum/pipe_info(PIPE_SIMPLE_BENT, 5, PIPE_BENT),
- "Manifold" = new /datum/pipe_info(PIPE_MANIFOLD, 1, PIPE_TRINARY),
- "Manual Valve" = new /datum/pipe_info(PIPE_MVALVE, 1, PIPE_BINARY),
- "Digital Valve" = new /datum/pipe_info(PIPE_DVALVE, 1, PIPE_BINARY),
- "Pipe Cap" = new /datum/pipe_info(PIPE_CAP, 1, PIPE_UNARY),
- "4-Way Manifold" = new /datum/pipe_info(PIPE_MANIFOLD4W, 1, PIPE_BINARY),
- "Manual T-Valve" = new /datum/pipe_info(PIPE_MTVALVE, 2, PIPE_TRIN_M),
- "Digital T-Valve" = new /datum/pipe_info(PIPE_DTVALVE, 2, PIPE_TRIN_M),
- ),
- "Devices"=list(
- "Connector" = new /datum/pipe_info(PIPE_CONNECTOR, 1, PIPE_UNARY),
- "Unary Vent" = new /datum/pipe_info(PIPE_UVENT, 1, PIPE_UNARY),
- "Passive Vent" = new /datum/pipe_info(PIPE_PASV_VENT, 1, PIPE_UNARY),
- "Gas Pump" = new /datum/pipe_info(PIPE_PUMP, 1, PIPE_UNARY),
- "Passive Gate" = new /datum/pipe_info(PIPE_PASSIVE_GATE, 1, PIPE_UNARY),
- "Volume Pump" = new /datum/pipe_info(PIPE_VOLUME_PUMP, 1, PIPE_UNARY),
- "Scrubber" = new /datum/pipe_info(PIPE_SCRUBBER, 1, PIPE_UNARY),
- "Meter" = new /datum/pipe_info/meter(),
- "Gas Sensor" = new /datum/pipe_info/gsensor(),
- "Gas Filter" = new /datum/pipe_info(PIPE_GAS_FILTER, 1, PIPE_TRIN_M),
- "Gas Mixer" = new /datum/pipe_info(PIPE_GAS_MIXER, 1, PIPE_TRIN_M),
- "Thermal Plate" = new /datum/pipe_info(PIPE_THERMAL_PLATE, 1, PIPE_UNARY),
- "Injector" = new /datum/pipe_info(PIPE_INJECTOR, 1, PIPE_UNARY),
- "Dual-Port Vent" = new /datum/pipe_info(PIPE_DP_VENT, 1, PIPE_UNARY),
- ),
- "Heat Exchange" = list(
- "Pipe" = new /datum/pipe_info(PIPE_HE_STRAIGHT, 1, PIPE_BINARY),
- "Bent Pipe" = new /datum/pipe_info(PIPE_HE_BENT, 5, PIPE_BENT),
- "Junction" = new /datum/pipe_info(PIPE_JUNCTION, 1, PIPE_UNARY),
- "Heat Exchanger" = new /datum/pipe_info(PIPE_HEAT_EXCHANGE, 1, PIPE_UNARY),
- ),
- "Insulated Pipes" = list(
- "Pipe" = new /datum/pipe_info(PIPE_INSULATED_STRAIGHT,1, PIPE_BINARY),
- "Bent Pipe" = new /datum/pipe_info(PIPE_INSULATED_BENT, 5, PIPE_BENT),
- "Manifold" = new /datum/pipe_info(PIPE_INSUL_MANIFOLD, 1, PIPE_TRINARY),
- "4-Way Manifold" = new /datum/pipe_info(PIPE_INSUL_MANIFOLD4W, 1, PIPE_BINARY),
- ),
- "Disposal Pipes" = list(
- "Pipe" = new /datum/pipe_info/disposal(DISP_PIPE_STRAIGHT, PIPE_UNARY),
- "Bent Pipe" = new /datum/pipe_info/disposal(DISP_PIPE_BENT, PIPE_BENT),
- "Junction" = new /datum/pipe_info/disposal(DISP_JUNCTION, PIPE_TRINARY),
- "Y-Junction" = new /datum/pipe_info/disposal(DISP_YJUNCTION, PIPE_TRINARY),
- "Trunk" = new /datum/pipe_info/disposal(DISP_END_TRUNK, PIPE_UNARY),
- "Bin" = new /datum/pipe_info/disposal(DISP_END_BIN, PIPE_BINARY),
- "Outlet" = new /datum/pipe_info/disposal(DISP_END_OUTLET, PIPE_UNARY),
- "Chute" = new /datum/pipe_info/disposal(DISP_END_CHUTE, PIPE_UNARY),
- "Sorting Junction" = new /datum/pipe_info/disposal(DISP_SORT_JUNCTION, PIPE_TRINARY),
- "Wrapped Sorting Junction" = new /datum/pipe_info/disposal(DISP_SORT_WRAP_JUNCTION, PIPE_TRINARY),
- )
-)
-/obj/item/weapon/pipe_dispenser
- name = "Rapid Piping Device (RPD)"
- desc = "A device used to rapidly pipe things."
- icon = 'icons/obj/items.dmi'
- icon_state = "rpd"
- opacity = 0
- density = 0
- anchored = 0.0
- flags = FPRINT
- siemens_coefficient = 1
- force = 10.0
- throwforce = 10.0
- throw_speed = 1
- throw_range = 5
- w_class = 3.0
- starting_materials = list(MAT_IRON = 75000, MAT_GLASS = 37500)
- w_type = RECYK_ELECTRONIC
- melt_temperature = MELTPOINT_STEEL
- origin_tech = "engineering=4;materials=2"
- var/datum/effect/effect/system/spark_spread/spark_system
- var/working = 0
- var/p_type = 0
- var/p_conntype = 0
- var/p_dir = 1
- var/p_class = 0
- var/p_disposal = 0
- var/list/paint_colors = list(
- "grey" = "#cccccc",
- "red" = "#800000",
- "blue" = "#000080",
- "cyan" = "#1C94C4",
- "green" = "#00CC00",
- "yellow" = "#FFCC00",
- "purple" = "purple"
- )
- var/paint_color="grey"
-
-/obj/item/weapon/pipe_dispenser/New()
- . = ..()
- spark_system = new /datum/effect/effect/system/spark_spread
- spark_system.set_up(5, 0, src)
- spark_system.attach(src)
-
-/obj/item/weapon/pipe_dispenser/attack_self(mob/user as mob)
- show_menu(user)
-
-/obj/item/weapon/pipe_dispenser/proc/render_dir_img(var/_dir,var/pic,var/title)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/pipe_dispenser/proc/render_dir_img() called tick#: [world.time]")
- var/selected=""
- if(_dir == p_dir)
- selected=" class=\"selected\""
- return "
"
-
-/obj/item/weapon/pipe_dispenser/proc/show_menu(mob/user as mob)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/pipe_dispenser/proc/show_menu() called tick#: [world.time]")
- if(!user || !src) return 0
- var/dat = {"Type
-Utilities:
-"}
- var/icon/preview=null
- for(var/category in RPD_recipes)
- dat += "[category]:"
- var/list/cat=RPD_recipes[category]
- for(var/label in cat)
- var/datum/pipe_info/I = cat[label]
- var/found=0
- if(I.id == p_type)
- if(p_class==0 && I.type==/datum/pipe_info)
- found=1
- else if(p_class==2 && I.type==/datum/pipe_info/disposal)
- found=1
- if(found)
- preview=new /icon(I.icon,I.icon_state)
- dat += I.Render(src,label)
- dat += "
"
-
- var/color_css=""
- var/color_picker=""
- for(var/color_name in paint_colors)
- var/color=paint_colors[color_name]
- color_css += {"
- a.color.[color_name] {
- color: [color];
- }
- a.color.[color_name]:hover {
- border:1px solid [color];
- }
- a.color.[color_name].selected {
- background-color: [color];
- }
- "}
- var/selected=""
- if(color_name==paint_color)
- selected = " selected"
- color_picker += {"•"}
-
- var/dirsel="Direction
"
- switch(p_conntype)
- if(-1)
- if(p_class==-2)
- dirsel = "Direction
[color_picker]"
-
- if(PIPE_BINARY) // Straight, N-S, W-E
- if(preview)
- user << browse_rsc(new /icon(preview, dir=NORTH), "vertical.png")
- user << browse_rsc(new /icon(preview, dir=EAST), "horizontal.png")
-
- dirsel += ""
- dirsel += render_dir_img(1,"vertical.png","Vertical")
- dirsel += render_dir_img(4,"horizontal.png","Horizontal")
- dirsel += "
"
- else
- dirsel+={"
-
- ↕
- ↔
-
- "}
- if(PIPE_BENT) // Bent, N-W, N-E etc
- if(preview)
- user << browse_rsc(new /icon(preview, dir=NORTHWEST), "nw.png")
- user << browse_rsc(new /icon(preview, dir=NORTHEAST), "ne.png")
- user << browse_rsc(new /icon(preview, dir=SOUTHWEST), "sw.png")
- user << browse_rsc(new /icon(preview, dir=SOUTHEAST), "se.png")
-
- dirsel += ""
- dirsel += render_dir_img(9,"nw.png","West to North")
- dirsel += render_dir_img(5,"ne.png","North to East")
- dirsel += "
"
- dirsel += render_dir_img(10,"sw.png","South to West")
- dirsel += render_dir_img(6,"se.png","East to South")
- dirsel += "
"
- else
- dirsel+={"
-
- ╝
- ╚
-
- ╗
- ╔
-
- "}
- if(PIPE_TRINARY) // Manifold
- if(preview)
- user << browse_rsc(new /icon(preview, dir=NORTH), "s.png")
- user << browse_rsc(new /icon(preview, dir=EAST), "w.png")
- user << browse_rsc(new /icon(preview, dir=SOUTH), "n.png")
- user << browse_rsc(new /icon(preview, dir=WEST), "e.png")
-
- dirsel += ""
- dirsel += render_dir_img(1,"s.png","West South East")
- dirsel += render_dir_img(4,"w.png","North West South")
- dirsel += "
"
- dirsel += render_dir_img(2,"n.png","East North West")
- dirsel += render_dir_img(8,"e.png","South East North")
- dirsel += "
"
- else
- dirsel+={"
-
- ╦
- ╣
-
- ╩
- ╠
-
- "}
- if(PIPE_TRIN_M) // Mirrored ones
- if(preview)
- user << browse_rsc(new /icon(preview, dir=NORTH), "s.png")
- user << browse_rsc(new /icon(preview, dir=EAST), "w.png")
- user << browse_rsc(new /icon(preview, dir=SOUTH), "n.png")
- user << browse_rsc(new /icon(preview, dir=WEST), "e.png")
- user << browse_rsc(new /icon(preview, dir=SOUTHEAST), "sm.png") //each mirror icon is 45 anticlockwise from it's real direction
- user << browse_rsc(new /icon(preview, dir=NORTHEAST), "wm.png")
- user << browse_rsc(new /icon(preview, dir=NORTHWEST), "nm.png")
- user << browse_rsc(new /icon(preview, dir=SOUTHWEST), "em.png")
-
- dirsel += ""
- dirsel += render_dir_img(1,"s.png","West South East")
- dirsel += render_dir_img(4,"w.png","North West South")
- dirsel += "
"
- dirsel += render_dir_img(2,"n.png","East North West")
- dirsel += render_dir_img(8,"e.png","South East North")
- dirsel += "
"
- dirsel += render_dir_img(6,"sm.png","West South East")
- dirsel += render_dir_img(5,"wm.png","North West South")
- dirsel += "
"
- dirsel += render_dir_img(9,"nm.png","East North West")
- dirsel += render_dir_img(10,"em.png","South East North")
- dirsel += "
"
- else
- dirsel+={"
-
- ╦
- ╣
-
- ╩
- ╠
-
- ╦
- ╣
-
- ╩
- ╠
-
- "}
- if(PIPE_UNARY) // Unary
- if(preview)
- user << browse_rsc(new /icon(preview, dir=NORTH), "n.png")
- user << browse_rsc(new /icon(preview, dir=EAST), "e.png")
- user << browse_rsc(new /icon(preview, dir=SOUTH), "s.png")
- user << browse_rsc(new /icon(preview, dir=WEST), "w.png")
-
- dirsel += ""
- dirsel += render_dir_img(NORTH,"n.png","North")
- dirsel += render_dir_img(EAST, "e.png","East")
- dirsel += render_dir_img(SOUTH,"s.png","South")
- dirsel += render_dir_img(WEST, "w.png","West")
- dirsel += "
"
- else
- dirsel+={"
-
- ↑
- →
- ↓
- ←
-
- "}
-
- dat = {"
-
-
- [name]
-
-
-
-[dirsel][dat]
-
-
-"}
- user << browse(dat, "window=pipedispenser")
- onclose(user, "pipedispenser")
- return
-
-/obj/item/weapon/pipe_dispenser/Topic(href, href_list)
- if(usr.stat || usr.restrained())
- usr << browse(null, "window=pipedispenser")
- return
- usr.set_machine(src)
- src.add_fingerprint(usr)
- if(!src.Adjacent(usr))
- usr.unset_machine(usr)
- return
- if(href_list["setdir"])
- p_dir= text2num(href_list["setdir"])
- show_menu(usr)
-
- if(href_list["eatpipes"])
- p_class = -1
- p_conntype=-1
- p_dir=1
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["paintpipes"])
- p_class = -2
- p_conntype=-1
- p_dir=1
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["set_color"])
- paint_color=href_list["set_color"]
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["makepipe"])
- p_type = text2num(href_list["makepipe"])
- p_dir = text2num(href_list["dir"])
- p_conntype = text2num(href_list["type"])
- p_class = 0
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["makemeter"])
- p_class = 1
- p_conntype=-1
- p_dir=1
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["makegsensor"])
- p_class = 3
- p_conntype=-1
- p_dir=1
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
- if(href_list["dmake"])
- p_type = text2num(href_list["dmake"])
- p_conntype = text2num(href_list["type"])
- p_dir = 1
- p_class = 2
- src.spark_system.start()
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- show_menu(usr)
-
-
-/obj/item/weapon/pipe_dispenser/afterattack(atom/A, mob/user)
- if(!in_range(A,user))
- return
- if(loc != user)
- return
- if(!isrobot(user) && !ishuman(user))
- return 0
- if(istype(A,/area/shuttle)||istype(A,/turf/space/transit))
- return 0
- if(istype(A, /obj/structure/lattice) || istype(A,/obj/structure/catwalk))
- A = get_turf(A)
-
- switch(p_class)
- if(-2) // Paint pipes
- if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/unary/tank) || istype(A,/obj/machinery/atmospherics/unary/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated))
- // Avoid spewing errors about invalid mode -2 when clicking on stuff that aren't pipes.
- user << "\The [src]'s error light flickers. Perhaps you need to only use it on pipes and pipe meters?"
- return 0
- var/obj/machinery/atmospherics/pipe/P = A
- if(!(paint_color in P.available_colors))
- user << "This [P] can't be painted [paint_color]. Available colors: [english_list(P.available_colors)]"
- return 0
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- P._color = paint_color
- user.visible_message("[user] paints \the [P] [paint_color].","You paint \the [P] [paint_color].")
- P.update_icon()
- return 1
- if(-1) // Eating pipes
- // Must click on an actual pipe or meter.
- if(istype(A,/obj/item/pipe) || istype(A,/obj/item/pipe_meter) || istype(A,/obj/structure/disposalconstruct) || istype(A,/obj/item/pipe_gsensor))
- user << "Destroying Pipe..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 5))
- if(A)
- activate()
- if(istype(A, /obj/item/pipe))
- returnToPool(A)
- else
- qdel(A)
- return 1
- return 0
-
- // Avoid spewing errors about invalid mode -1 when clicking on stuff that aren't pipes.
- user << "The [src]'s error light flickers. Perhaps you need to only use it on pipes and pipe meters?"
- return 0
- if(0)
- if(!(istype(A, /turf)))
- user << "The [src]'s error light flickers."
- return 0
- user << "Building Pipes ..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- activate()
- var/obj/item/pipe/P = getFromPool(/obj/item/pipe, A)
- P.New(A,pipe_type=p_type,dir=p_dir) //new (A, pipe_type=p_type, dir=p_dir)
- P.update()
- P.add_fingerprint(usr)
- return 1
- return 0
-
- if(1)
- if(!(istype(A, /turf)))
- user << "The [src]'s error light flickers."
- return 0
- user << "Building Meter..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- activate()
- new /obj/item/pipe_meter(A)
- return 1
- return 0
-
- if(2)
- if(!(istype(A, /turf)))
- user << "The [src]'s error light flickers."
- return 0
- user << "Building Pipes..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- activate()
- var/obj/structure/disposalconstruct/C = new (A)
- // This may still produce runtimes, but I checked and /obj/structure/disposalconstruct
- // DOES have a dir property, inherited from /obj/structure. - N3X
- C.dir=p_dir
- switch(p_type)
- if(0)
- C.ptype = 0
- if(1)
- C.ptype = 1
- if(2)
- C.ptype = 2
- if(3)
- C.ptype = 4
- if(4)
- C.ptype = 5
- if(5)
- C.ptype = 6
- C.density = 1
- if(6)
- C.ptype = 7
- C.density = 1
- if(7)
- C.ptype = 8
- C.density = 1
- if(8)
- C.ptype = 9
- if(9)
- C.ptype = 11
- C.add_fingerprint(usr)
- C.update()
- return 1
- return 0
- if(3)
- if(!(istype(A, /turf)))
- user << "The [src]'s error light flickers."
- return 0
- user << "Building Sensor..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- activate()
- new /obj/item/pipe_gsensor(A)
- return 1
- return 0
- else
- ..()
- return 0
-
-
-/obj/item/weapon/pipe_dispenser/proc/activate()
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/pipe_dispenser/proc/activate() called tick#: [world.time]")
- playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1)
-
diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm
deleted file mode 100644
index e64c09e85dc..00000000000
--- a/code/game/objects/items/weapons/RSF.dm
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-CONTAINS:
-RSF
-
-*/
-/obj/item/weapon/rsf
- name = "\improper Rapid-Service-Fabricator"
- desc = "A device used to rapidly deploy service items."
- icon = 'icons/obj/items.dmi'
- icon_state = "rsf"
- opacity = 0
- density = 0
- anchored = 0.0
- starting_materials = list(MAT_IRON = 40000)
- var/matter = 0
- var/max_matter = 40
- var/matter_respawn = 0
- var/mode = 1
- var/list/modes
- w_class = 3.0
-
-/obj/item/weapon/rsf/New()
- ..()
- modes = list(
- "glass",
- "paper",
- "flask",
- "dice",
- "deck of cards",
- "candle",
- "cardboard sheet",
- )
- return
-
-/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob)
- ..()
- if (istype(W, /obj/item/weapon/rcd_ammo))
- if (matter >= max_matter)
- user << "The RSF can't hold any more matter."
- return
- if ((matter+20) >= max_matter)
- qdel(W)
- matter = max_matter
- playsound(get_turf(src), 'sound/machines/click.ogg', 20, 1)
- user << "The RSF now holds [matter]/[max_matter] fabrication-units."
- return
- qdel(W)
- matter += 20
- playsound(get_turf(src), 'sound/machines/click.ogg', 20, 1)
- user << "The RSF now holds [matter]/[max_matter] fabrication-units."
- return
-
-/obj/item/weapon/rsf/attack_self(mob/user as mob)
- playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
- mode++
- if(mode>modes.len) mode = 1
- user << "Now dispensing [modes[mode]]!"
-
-/obj/item/weapon/rsf/examine(mob/user)
- ..()
- if(istype(src, /obj/item/weapon/rsf/cyborg))
- user << "It's been set to draw power from a power cell."
- else
- user << "It currently holds [matter]/[max_matter] fabrication-units."
-
-/obj/item/weapon/rsf/proc/pay(var/mob/user, var/amount) //spend matter or energy
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/rsf/proc/pay() called tick#: [world.time]")
- if(isrobot(user)) //if the user is a robot, take power from its cell
- var/mob/living/silicon/robot/R = user
- if(R.cell)
- return R.cell.use(amount * 50)
- return 0
-
- if(amount <= matter)
- matter -= amount
- user << "The RSF now holds [matter]/[max_matter] fabrication-units."
- return 1
- return 0
-
-/obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob)
- if(!A.Adjacent(user))
- return
- if (!(istype(A, /obj/structure/table) || istype(A, /turf/simulated/floor))) //Must click on a table or floor to spawn stuff
- return
-
- switch(modes[mode])
- if("dosh")
- if(pay(user,4))
- user << "Dispensing Dosh..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/spacecash/c10(get_turf(A))
- return
- if("glass")
- if(pay(user,1))
- user << "Dispensing Glass..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/reagent_containers/food/drinks/drinkingglass(get_turf(A))
- if("flask")
- if(pay(user,1))
- user << "Dispensing Flask..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/reagent_containers/food/drinks/flask/barflask(get_turf(A))
- if("paper")
- if(pay(user,1))
- user << "Dispensing Paper..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/paper(get_turf(A))
- if("candle")
- if(pay(user,1))
- user << "Dispensing a Candle..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/candle(get_turf(A))
- if("dice")
- if(pay(user,1))
- user << "Dispensing Dice Pack..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/weapon/storage/pill_bottle/dice(get_turf(A))
- if("deck of cards")
- if(pay(user,1))
- user << "Dispensing a Deck of Cards..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/toy/cards(get_turf(A))
- if("cardboard sheet")
- if(pay(user,1))
- user << "Dispensing a Cardboard Sheet..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
- new /obj/item/stack/sheet/cardboard(get_turf(A))
-
-/obj/item/weapon/rsf/cyborg/New()
- ..()
- modes |= "dosh" //cyborg rsfs get money
- desc = "A device used to rapidly deploy service items."
-
-/obj/item/weapon/rsf/cyborg/process()
- return //Borg RSF doesn't need matter
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/tile_painter.dm b/code/game/objects/items/weapons/tile_painter.dm
deleted file mode 100644
index f46af576afc..00000000000
--- a/code/game/objects/items/weapons/tile_painter.dm
+++ /dev/null
@@ -1,490 +0,0 @@
-#define PAINT_FLOOR 1
-#define PAINT_PLATING 2
-#define PAINT_REINFORCED 3
-#define PAINT_ALL 0
-
-#define DIR_ONE 1 //for those tiles with only one direction
-#define DIR_ORTHO 2 //orthogonal (south, west, north, east)
-#define DIR_ALL 3 //all the directions
-
-
-/datum/paint_info
- var/dir = SOUTH
- var/icon/icon = 'icons/turf/floors.dmi'
- var/icon_state = "floor"
- var/ftype as num //the floor type required for this paint job
- var/adirs //available dirs for this floor type
-
-/datum/paint_info/New(var/padir, var/picon)
- src.adirs = padir
- src.dir = SOUTH
- src.icon_state = picon
- src.ftype = PAINT_FLOOR
-
-/datum/paint_info/New(var/padir, var/picon, var/ptype)
- if(ptype == null) ptype = PAINT_FLOOR //DM really can't resolve this?
- src.dir = SOUTH
- src.icon_state = picon
- src.ftype = ptype
- src.adirs = padir
-
-/datum/paint_info/proc/validate(var/turf/simulated/floor/test)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/paint_info/proc/validate() called tick#: [world.time]")
- //This is used to give the user a hint that he's a massive retard for using a floor painter on the carpet
- switch(ftype)
- if(PAINT_FLOOR) //why is it named plasteel anyway?
- if(!(istype(test.floor_tile,/obj/item/stack/tile/plasteel)))
- return 0 //if it's carpet, wood or some other stuff, we aren't going to paint that
- if(istype(test, /turf/simulated/floor/engine))
- return 0 //reinforced floor has plasteel in floor_tile too
- //but that isn't a regular floor
- if(PAINT_PLATING)
- if(!istype(test,/turf/simulated/floor/plating))
- return 0
- if(PAINT_REINFORCED)
- if(!istype(test,/turf/simulated/floor/engine))
- return 0
- return 1
-
-/datum/paint_info/proc/apply(var/turf/simulated/floor/T, var/pname, var/pdesc)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/paint_info/proc/apply() called tick#: [world.time]")
- //warning("[type]: Running /datum/paint_info/proc/apply.")
- T.icon_state = icon_state
- T.icon_regular_floor = icon_state //required to 'save' the new floor type so if someone crowbars it and puts it back it won't revert to the original state
- T.dir = dir
- T.desc = pdesc //so if you paint over a plaque with a floor the tile loses its description
- if(pname != "")
- T.name = pname
- T.ClearDecals()
-
-/datum/paint_info/decal
- icon = 'icons/effects/warning_stripes.dmi'
- ftype = PAINT_ALL
-
-/datum/paint_info/decal/apply(var/turf/simulated/floor/T, var/pname, var/pdesc)
- T.AddDecal(image(icon, icon_state = icon_state, dir = dir))
-
-
-//The list of all available floor design groups
-
-var/global/list/paint_variants = list(
- "Decals" = list(
- // Stripes
- new /datum/paint_info/decal(DIR_ALL, "warning"),
- new /datum/paint_info/decal(DIR_ONE, "all"),
-
- // Loading areas (TODO: colorable)
- new /datum/paint_info/decal(DIR_ORTHO, "warning_corner"),
- new /datum/paint_info/decal(DIR_ONE, "unloading"),
- new /datum/paint_info/decal(DIR_ONE, "bot"),
- new /datum/paint_info/decal(DIR_ORTHO, "loading_area"),
- new /datum/paint_info/decal(DIR_ONE, "no"),
-
- // Atmos lettering
- new /datum/paint_info/decal(DIR_ORTHO, "oxygen"),
- new /datum/paint_info/decal(DIR_ORTHO, "nitrogen"),
- new /datum/paint_info/decal(DIR_ORTHO, "carbon_dioxide"),
- new /datum/paint_info/decal(DIR_ORTHO, "nitrous_oxide"),
- new /datum/paint_info/decal(DIR_ORTHO, "air"),
- new /datum/paint_info/decal(DIR_ORTHO, "plasma"),
- new /datum/paint_info/decal(DIR_ORTHO, "zoo"),
-
- // Numbers
- new /datum/paint_info/decal(DIR_ORTHO, "1"),
- new /datum/paint_info/decal(DIR_ORTHO, "2"),
- new /datum/paint_info/decal(DIR_ORTHO, "3"),
- new /datum/paint_info/decal(DIR_ORTHO, "4"),
- new /datum/paint_info/decal(DIR_ORTHO, "5"),
- new /datum/paint_info/decal(DIR_ORTHO, "6"),
- new /datum/paint_info/decal(DIR_ORTHO, "7"),
- new /datum/paint_info/decal(DIR_ORTHO, "8"),
- new /datum/paint_info/decal(DIR_ORTHO, "9"),
- new /datum/paint_info/decal(DIR_ORTHO, "0"),
- ),
- "Gray" = list(new /datum/paint_info(DIR_ONE,"floor"),
- new /datum/paint_info(DIR_ALL,"black"),
- new /datum/paint_info(DIR_ORTHO,"blackcorner")),
-
- "Neutral" = list(new /datum/paint_info(DIR_ALL,"neutral"),
- new /datum/paint_info(DIR_ORTHO,"neutralcorner"),
- new /datum/paint_info(DIR_ONE,"neutralfull")),
-
- "White" = list(new /datum/paint_info(DIR_ONE,"white"),
- new /datum/paint_info(DIR_ALL,"whitehall"),
- new /datum/paint_info(DIR_ORTHO,"whitecorner")),
-
- "Red" = list(new /datum/paint_info(DIR_ONE,"redfull"),
- new /datum/paint_info(DIR_ALL,"red"),
- new /datum/paint_info(DIR_ORTHO,"redcorner")),
-
- "Green" = list(new /datum/paint_info(DIR_ONE,"greenfull"),
- new /datum/paint_info(DIR_ALL,"green"),
- new /datum/paint_info(DIR_ORTHO,"greencorner")),
-
- "Blue" = list(new /datum/paint_info(DIR_ONE,"bluefull"),
- new /datum/paint_info(DIR_ALL,"blue"),
- new /datum/paint_info(DIR_ORTHO,"bluecorner")),
-
- "Yellow" = list(new /datum/paint_info(DIR_ONE,"yellowfull"),
- new /datum/paint_info(DIR_ALL,"yellow"),
- new /datum/paint_info(DIR_ORTHO,"yellowcorner")),
-
- "Purple" = list(new /datum/paint_info(DIR_ONE,"purplefull"),
- new /datum/paint_info(DIR_ALL,"purple"),
- new /datum/paint_info(DIR_ORTHO,"purplecorner")),
-
- "Orange" = list(new /datum/paint_info(DIR_ONE,"orangefull"),
- new /datum/paint_info(DIR_ALL,"orange"),
- new /datum/paint_info(DIR_ORTHO,"orangecorner")),
-
- "Brown" = list(new /datum/paint_info(DIR_ONE,"dark brown full"),
- new /datum/paint_info(DIR_ALL,"brown"),
- new /datum/paint_info(DIR_ORTHO,"browncorner")),
-
- "Red and yellow" = list(new /datum/paint_info(DIR_ONE,"redyellowfull"),
- new /datum/paint_info(DIR_ALL,"redyellow")),
-
- "Red and blue" = list(new /datum/paint_info(DIR_ONE,"redbluefull"),
- new /datum/paint_info(DIR_ALL,"redblue")),
-
- "Red and green" = list(new /datum/paint_info(DIR_ONE,"redgreenfull"),
- new /datum/paint_info(DIR_ALL,"redgreen")),
-
- "Green and yellow" = list(new /datum/paint_info(DIR_ONE,"greenyellowfull"),
- new /datum/paint_info(DIR_ALL,"greenyellow")),
-
- "Green and blue" = list(new /datum/paint_info(DIR_ONE,"greenbluefull"),
- new /datum/paint_info(DIR_ALL,"greenblue")),
-
- "Blue and yellow" = list(new /datum/paint_info(DIR_ONE,"blueyellowfull"),
- new /datum/paint_info(DIR_ALL,"blueyellow")),
-
- "White red" = list(new /datum/paint_info(DIR_ONE,"whiteredfull"),
- new /datum/paint_info(DIR_ALL,"whitered"),
- new /datum/paint_info(DIR_ORTHO,"whiteredcorner")),
-
- "White green" = list(new /datum/paint_info(DIR_ONE,"whitegreenfull"),
- new /datum/paint_info(DIR_ALL,"whitegreen"),
- new /datum/paint_info(DIR_ORTHO,"whitegreencorner")),
-
- "White blue" = list(new /datum/paint_info(DIR_ONE,"whitebluefull"),
- new /datum/paint_info(DIR_ALL,"whiteblue"),
- new /datum/paint_info(DIR_ORTHO,"whitebluecorner"),
- new /datum/paint_info(DIR_ONE,"cmo")),
-
- "White yellow" = list(new /datum/paint_info(DIR_ONE,"whiteyellowfull"),
- new /datum/paint_info(DIR_ALL,"whiteyellow"),
- new /datum/paint_info(DIR_ORTHO,"whiteyellowcorner")),
-
- "White purple" = list(new /datum/paint_info(DIR_ONE,"whitepurplefull"),
- new /datum/paint_info(DIR_ALL,"whitepurple"),
- new /datum/paint_info(DIR_ORTHO,"whitepurplecorner")),
-
- "Arrival" = list(new /datum/paint_info(DIR_ALL,"arrival")),
-
- "Escape" = list(new /datum/paint_info(DIR_ALL,"escape")),
-
- "Dark" = list(new /datum/paint_info(DIR_ONE,"dark"),
- new /datum/paint_info(DIR_ALL,"dark floor stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark floor corner")),
-
- "Dark red" = list(new /datum/paint_info(DIR_ONE,"dark red full"),
- new /datum/paint_info(DIR_ALL,"dark red stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark red corner")),
-
- "Dark blue" = list(new /datum/paint_info(DIR_ONE,"dark blue full"),
- new /datum/paint_info(DIR_ALL,"dark blue stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark blue corner")),
-
- "Dark green" = list(new /datum/paint_info(DIR_ONE,"dark green full"),
- new /datum/paint_info(DIR_ALL,"dark green stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark green corner")),
-
- "Dark purple" = list(new /datum/paint_info(DIR_ONE,"dark purple full"),
- new /datum/paint_info(DIR_ALL,"dark purple stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark purple corner")),
-
- "Dark yellow" = list(new /datum/paint_info(DIR_ONE,"dark yellow full"),
- new /datum/paint_info(DIR_ALL,"dark yellow stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark yellow corner")),
-
- "Dark orange" = list(new /datum/paint_info(DIR_ONE,"dark orange full"),
- new /datum/paint_info(DIR_ALL,"dark orange stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark orange corner")),
-
- "Dark orange" = list(new /datum/paint_info(DIR_ONE,"dark orange full"),
- new /datum/paint_info(DIR_ALL,"dark orange stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark orange corner")),
-
- "Dark vault" = list(new /datum/paint_info(DIR_ONE,"dark vault full"),
- new /datum/paint_info(DIR_ALL,"dark vault stripe"),
- new /datum/paint_info(DIR_ORTHO,"dark vault corner"),
- new /datum/paint_info(DIR_ORTHO,"dark-markings")),
-
- "Markings" = list(new /datum/paint_info(DIR_ONE,"delivery"),
- new /datum/paint_info(DIR_ONE,"bot"),
- new /datum/paint_info(DIR_ONE,"whitedelivery"),
- new /datum/paint_info(DIR_ONE,"whitebot"),
- new /datum/paint_info(DIR_ONE,"enginedelivery", PAINT_REINFORCED),
- new /datum/paint_info(DIR_ONE,"enginebot", PAINT_REINFORCED),
- new /datum/paint_info(DIR_ONE,"plaque")),
-
- "Loading area" = list(new /datum/paint_info(DIR_ORTHO,"loadingarea"),
- new /datum/paint_info(DIR_ORTHO,"engineloadingarea", PAINT_REINFORCED),
- new /datum/paint_info(DIR_ORTHO,"dark loading")),
-
- "Warning" = list(new /datum/paint_info(DIR_ALL,"warning"),
- new /datum/paint_info(DIR_ORTHO,"warningcorner")),
-
- "White warning" = list(new /datum/paint_info(DIR_ALL,"warnwhite"),
- new /datum/paint_info(DIR_ORTHO,"warnwhitecorner")),
-
- "Reinforced warning" = list(new /datum/paint_info(DIR_ALL,"enginewarn", PAINT_REINFORCED),
- new /datum/paint_info(DIR_ORTHO,"enginewarncorner", PAINT_REINFORCED)),
-
- "Plating warning" = list(new /datum/paint_info(DIR_ALL,"warnplate", PAINT_PLATING),
- new /datum/paint_info(DIR_ORTHO,"warnplatecorner", PAINT_PLATING)),
-
- "Chapel" = list(new /datum/paint_info(DIR_ALL,"chapel")),
-
- "SS13 logo" = list(new /datum/paint_info(DIR_ONE,"L1"),
- new /datum/paint_info(DIR_ONE,"L3"),
- new /datum/paint_info(DIR_ONE,"L5"),
- new /datum/paint_info(DIR_ONE,"L7"),
- new /datum/paint_info(DIR_ONE,"L9"),
- new /datum/paint_info(DIR_ONE,"L11"),
- new /datum/paint_info(DIR_ONE,"L13"),
- new /datum/paint_info(DIR_ONE,"L15"),
- new /datum/paint_info(DIR_ONE,"L2"),
- new /datum/paint_info(DIR_ONE,"L4"),
- new /datum/paint_info(DIR_ONE,"L6"),
- new /datum/paint_info(DIR_ONE,"L8"),
- new /datum/paint_info(DIR_ONE,"L10"),
- new /datum/paint_info(DIR_ONE,"L12"),
- new /datum/paint_info(DIR_ONE,"L14"),
- new /datum/paint_info(DIR_ONE,"L16")),
-
- "Derelict logo" = list(new /datum/paint_info(DIR_ONE,"derelict9"),
- new /datum/paint_info(DIR_ONE,"derelict10"),
- new /datum/paint_info(DIR_ONE,"derelict11"),
- new /datum/paint_info(DIR_ONE,"derelict12"),
- new /datum/paint_info(DIR_ONE,"derelict13"),
- new /datum/paint_info(DIR_ONE,"derelict14"),
- new /datum/paint_info(DIR_ONE,"derelict15"),
- new /datum/paint_info(DIR_ONE,"derelict16"),
- new /datum/paint_info(DIR_ONE,"derelict1"),
- new /datum/paint_info(DIR_ONE,"derelict2"),
- new /datum/paint_info(DIR_ONE,"derelict3"),
- new /datum/paint_info(DIR_ONE,"derelict4"),
- new /datum/paint_info(DIR_ONE,"derelict5"),
- new /datum/paint_info(DIR_ONE,"derelict6"),
- new /datum/paint_info(DIR_ONE,"derelict7"),
- new /datum/paint_info(DIR_ONE,"derelict8")),
-
- "Other" = list(new /datum/paint_info(DIR_ONE,"dark"),
- new /datum/paint_info(DIR_ONE,"bar"),
- new /datum/paint_info(DIR_ONE,"cafeteria"),
- new /datum/paint_info(DIR_ONE,"checker"),
- new /datum/paint_info(DIR_ONE,"barber"),
- new /datum/paint_info(DIR_ONE,"grimy"),
- new /datum/paint_info(DIR_ONE,"hydrofloor"),
- new /datum/paint_info(DIR_ONE,"showroomfloor"),
- new /datum/paint_info(DIR_ONE,"freezerfloor"),
- new /datum/paint_info(DIR_ONE,"bcircuit"),
- new /datum/paint_info(DIR_ONE,"gcircuit"),
- new /datum/paint_info(DIR_ONE,"solarpanel"))
-)
-
-/obj/item/weapon/tile_painter
- name = "tile painter"
- desc = "A device used to paint floors in various colors and fashions."
- icon = 'icons/obj/items.dmi'
- icon_state = "rpd" //placeholder art, someone please sprite it
- opacity = 0
- density = 0
- anchored = 0.0
- flags = FPRINT
- siemens_coefficient = 1
- force = 10.0
- throwforce = 10.0
- throw_speed = 1
- throw_range = 5
- w_class = 3.0
- starting_materials = list(MAT_IRON = 15000, MAT_GLASS = 7500)
- w_type = RECYK_ELECTRONIC
- melt_temperature = MELTPOINT_STEEL
- origin_tech = "engineering=2;materials=1"
- var/working = 0
- var/datum/paint_info/selected
- var/category = ""
-
-/obj/item/weapon/tile_painter/New()
- selected = new /datum/paint_info(SOUTH,"floor")
- ..()
-
-/obj/item/weapon/tile_painter/Destroy() //do I even have to do that
- selected = null
- ..() // FUCKING DUMB
-
-/obj/item/weapon/tile_painter/attack_self(mob/user as mob)
- show_menu(user)
-
-/obj/item/weapon/tile_painter/proc/render_tile(var/icon/basestate, var/mob/user, var/datum/paint_info/I, var/cdir=SOUTH)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/tile_painter/proc/render_tile() called tick#: [world.time]")
- // Send user the image
- user << browse_rsc(new /icon(basestate, dir=cdir), "[I.icon_state][cdir].png")
- // Determine if we're actually selecting this
- var/is_selected = selected.icon==I.icon && selected.icon_state == I.icon_state && selected.dir==cdir
- var/class=""
- if(is_selected)
- class=" class=\"selected\""
-
- // Make HTML.
- return "
"
-
-/obj/item/weapon/tile_painter/proc/populate_selection(mob/user as mob, var/datum/paint_info/I)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/tile_painter/proc/populate_selection() called tick#: [world.time]")
- var/data = ""
- var/icon/basestate = new /icon(I.icon, I.icon_state)
- switch(I.adirs)
- if(DIR_ONE)
- data += render_tile(basestate,user,I)
- if(DIR_ORTHO)
- for(var/d in cardinal) // cardinal is N,S,E,W (see global.dm)
- data += render_tile(basestate,user,I,d)
- if(DIR_ALL)
- for(var/d in alldirs) // All 2D directions
- data += render_tile(basestate,user,I,d)
-
- return data
-
-/obj/item/weapon/tile_painter/proc/show_menu(mob/user as mob)
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/tile_painter/proc/show_menu() called tick#: [world.time]")
- if(!user || !src) return 0
-
- var/data = {"Tile Painter
- "}
-
- if(category == "")
-
- data += "List of available tile groups:
"
- data += ""
-
- for(var/iterator in paint_variants)
- data += "[iterator] (view)
"
-
- data += "
"
-
- else
-
- var/list/tiles = paint_variants[category]
- data += "[category]
"
- data += ""
- for(var/i = 1; i <= tiles.len; i++)
- if((category == "SS13 logo" || category == "Derelict logo") && i == 9)
- data += "
"
- var/datum/paint_info/I = tiles[i]
- data += populate_selection(user, I)
-
- data += "
Back"
- data += "
"
-
- var/menu = {"
-
-
- Tile Painter
-
-
- [data]
-
-
-"}
- user << browse(menu, "window=tilepainter")
- onclose(user, "tilepainter")
- return
-
-/obj/item/weapon/tile_painter/Topic(href, href_list)
- if(usr.stat || usr.restrained())
- usr << browse(null, "window=tilepainter")
- return
- usr.set_machine(src)
- src.add_fingerprint(usr)
-
- if(href_list["select"])
- if(href_list["select"] == "null") category = ""
- else category = href_list["select"]
- show_menu(usr)
-
- //if we got this, that means we got set_state as well
- if(href_list["set_dir"])
- selected = locate(href_list["set_type"])
- selected.dir = text2num(href_list["set_dir"])
-
-/obj/item/weapon/tile_painter/afterattack(atom/A, mob/user)
- if(!in_range(A,user))
- return
- if(loc != user)
- return
- if(!isrobot(user) && !ishuman(user))
- return 0
- if(istype(A,/area/shuttle)||istype(A,/turf/space/transit))
- return 0
- if(!(istype(A, /turf/simulated/floor)))
- return 0
-
- var/turf/simulated/floor/test = get_turf(A) //it should be the simulated floor type
- //world.log << "[src]: selected=[selected.type]"
- if(!selected.validate(test))
- user << "An error indicator on [src] flicks on for a moment. Perhaps you're using it on the wrong floor type?"
- return 0
-
- var/pdesc = ""
- var/pname = ""
- switch(selected.ftype)
- if(PAINT_FLOOR) pname = "floor" //restoring the name of our new tile, usually if you place a floor tile on a plating it's still called "plating" for now
- if(PAINT_REINFORCED) pname = "reinforced floor" //also getting rid of the plaque if it's there
- if(PAINT_PLATING) pname = "plating"
-
- if(selected.icon_state == "plaque") //some juice
- pdesc = input(user,"What do you want to be described on this plaque?", "Plaque description")
- pname = "Commemorative Plaque"
-
- user << "Painting floor..."
- playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
- if(do_after(user,A, 20))
- activate()
- var/turf/simulated/floor/T = get_turf(A)
- selected.apply(T,pname,pdesc)
- return 1
- return 0
-
-/obj/item/weapon/tile_painter/proc/activate()
- //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/obj/item/weapon/tile_painter/proc/activate() called tick#: [world.time]")
- playsound(get_turf(src), 'sound/effects/extinguish.ogg', 50, 1) //pssshtt
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 5a91652eaaf..d9c7fc0e4e5 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -150,7 +150,7 @@
new /obj/item/weapon/wrench/socket(src)
new /obj/item/weapon/gun/projectile/flare(src) //yay for emergency lighting
new /obj/item/ammo_storage/box/flare(src)
- new /obj/item/weapon/pipe_dispenser(src)
+ new /obj/item/device/rcd/rpd(src)
new /obj/item/device/analyzer(src)
return
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 29af30f6d24..a3cd6239600 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -342,7 +342,7 @@
new /obj/item/weapon/rcd_ammo(src)
new /obj/item/weapon/rcd_ammo(src)
new /obj/item/weapon/rcd_ammo(src)
- new /obj/item/weapon/rcd(src)
+ new /obj/item/device/rcd/matter/engineering(src)
/obj/structure/closet/crate/radiation/New()
..()
diff --git a/code/global.dm b/code/global.dm
index 69ba5674e49..f15858a7f5e 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -205,9 +205,9 @@ var/list/blobstart = list()
var/list/ninjastart = list()
// list/traitors = list() //traitor list
var/list/cardinal = list( NORTH, SOUTH, EAST, WEST )
+var/list/diagonal = list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
var/list/alldirs = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
-
var/global/universal_cult_chat = 0 //if set to 1, even human cultists can use cultchat
var/datum/station_state/start_state = null
diff --git a/code/modules/RCD/RCD.dm b/code/modules/RCD/RCD.dm
new file mode 100644
index 00000000000..a362074e04f
--- /dev/null
+++ b/code/modules/RCD/RCD.dm
@@ -0,0 +1,231 @@
+//Main class for the modular RCD system.
+/obj/item/device/rcd
+ name = "\improper Rapid-Construction-Device (RCD)"
+ desc = "Used to rapidly construct things, or deconstruct them, for that matter."
+
+ icon = 'icons/obj/RCD.dmi'
+ icon_state = "rcd"
+
+ flags = FPRINT
+ siemens_coefficient = 1
+ w_class = 3
+ siemens_coefficient = 1
+ force = 10
+ throwforce = 10
+ throw_speed = 1
+ throw_range = 5
+ starting_materials = list(MAT_IRON = 50000)
+ w_type = RECYK_ELECTRONIC
+ melt_temperature = MELTPOINT_STEEL // Lots of metal
+ origin_tech = "engineering=4;materials=2"
+
+ var/datum/rcd_schematic/selected
+ var/list/schematics = list(/datum/rcd_schematic/test) //list of schematics, in definitions of RCD subtypes, no organization is needed, in New() these get organized.
+ var/sparky = 1 //Make sparks. LOTS OF SPARKS.
+
+ var/busy = 0
+
+ var/datum/html_interface/rcd/interface
+ var/datum/effect/effect/system/spark_spread/spark_system
+
+/obj/item/device/rcd/New()
+ . = ..()
+
+ interface = new(src, sanitize(name)) //interface gets created BEFORE the schematics get created, so they can modify the HEAD content (RPD pipe colour picker).
+
+ init_schematics()
+
+ rebuild_ui()
+
+ spark_system = new
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+
+//create and organize the schematics
+/obj/item/device/rcd/proc/init_schematics()
+ var/list/old_schematics = schematics
+ schematics = list()
+
+ for(var/path in old_schematics)
+ var/datum/rcd_schematic/C = new path(src)
+ if(!schematics[C.category])
+ schematics[C.category] = list()
+
+ schematics[C.category] += C
+
+/obj/item/device/rcd/Destroy()
+ for(var/cat in schematics)
+ for(var/datum/rcd_schematic/C in schematics[cat])
+ C.master = null
+
+ schematics = null
+
+ del(interface)
+ del(spark_system)
+
+ . = ..()
+
+/obj/item/device/rcd/attack_self(var/mob/user)
+ interface.show(user)
+
+/obj/item/device/rcd/proc/rebuild_ui()
+ var/dat = ""
+
+ dat += {"
+ Selected:
+ Options
+
+
+ Available schematics
+ "}
+ for(var/cat in schematics)
+ dat += "[cat]:"
+ var/list/L = schematics[cat]
+ for(var/i = 1 to L.len) //So we have the indexes.
+ var/datum/rcd_schematic/C = L[i]
+ dat += "- [C.name]
"
+
+ dat += "
"
+
+ interface.updateLayout(dat)
+
+ if(selected)
+ interface.updateContent("schematic_options", selected.get_HTML())
+ interface.updateContent("selectedname", selected.name)
+
+/obj/item/device/rcd/Topic(var/href, var/list/href_list)
+ . = ..()
+ if(.)
+ return
+
+ if(href_list["cat"] && href_list["index"] && !busy) //Change selected schematic.
+ var/list/L = schematics[href_list["cat"]]
+ if(!L)
+ return 1
+
+ var/datum/rcd_schematic/C = L[Clamp(text2num(href_list["index"]), 1, L.len)]
+ if(!istype(C))
+ return 1
+
+ if(!(selected ? selected.deselect(usr, C) : 1 && C.select(usr, selected)))
+ return 1
+
+ spark()
+
+ selected = C
+ update_options_menu()
+ interface.updateContent("selectedname", selected.name)
+
+ return 1
+
+ else if(selected) //The href didn't get handled by us so we pass it down to the selected schematic.
+ return selected.Topic(href, href_list)
+
+/obj/item/device/rcd/afterattack(var/atom/A, var/mob/user)
+ if(!selected)
+ return 1
+
+ if(selected.flags ^ (RCD_SELF_SANE | RCD_RANGE) && !(user.Adjacent(A) && A.Adjacent(user))) //If RCD_SELF_SANE and RCD_RANGE are disabled we use adjacency.
+ return 1
+
+ if(selected.flags & RCD_RANGE && selected.flags ^ RCD_SELF_SANE && get_dist(A, user) > 1) //RCD_RANGE is used AND we're NOT SELF_SANE, use range(1)
+ return 1
+
+ if(selected.flags & RCD_GET_TURF) //Get the turf because RCD_GET_TURF is on.
+ A = get_turf(A)
+
+ if(selected.flags ^ RCD_SELF_SANE && get_energy() < selected.energy_cost) //Handle energy amounts, but only if not SELF_SANE.
+ return 1
+
+ busy = 1 //Busy to prevent switching schematic while it's in use.
+ var/t = selected.attack(A, user)
+ if(!t) //No errors
+ if(selected.flags ^ RCD_SELF_COST) //Handle energy costs unless the schematic does it itself.
+ use_energy(selected.energy_cost, user)
+ else
+ if(istext(t))
+ user << "\the [src]'s error light flickers: [t]"
+ else
+ user << "\the [src]'s error light flickers."
+
+ busy = 0
+
+ return 1
+
+/obj/item/device/rcd/proc/spark()
+ if(sparky)
+ spark_system.start()
+
+/obj/item/device/rcd/proc/get_energy()
+ return INFINITY
+
+/obj/item/device/rcd/proc/use_energy(var/amount, var/mob/user)
+ return
+
+/obj/item/device/rcd/proc/update_options_menu()
+ if(selected)
+ interface.updateContent("schematic_options", selected.get_HTML())
+ else
+ interface.updateContent("schematic_options", " ")
+
+/obj/item/device/rcd/borg
+ var/cell_power_per_energy = 30
+
+/obj/item/device/rcd/borg/use_energy(var/amount, var/mob/user)
+ if(!isrobot(user))
+ return
+
+ var/mob/living/silicon/robot/R = user
+
+ if(!R.cell)
+ return
+
+ R.cell.use(amount * cell_power_per_energy)
+
+/obj/item/device/rcd/borg/get_energy(var/amount, var/mob/user)
+ if(!isrobot(user))
+ return 0
+
+ var/mob/living/silicon/robot/R = user
+
+ if(!R.cell)
+ return
+
+ return R.cell.charge * cell_power_per_energy
+
+//Matter based RCDs.
+/obj/item/device/rcd/matter
+ var/matter = 0
+ var/max_matter = 30
+
+/obj/item/device/rcd/matter/examine(var/mob/user)
+ ..()
+ user << "It currently holds [matter]/[max_matter] matter-units."
+
+/obj/item/device/rcd/matter/attackby(var/obj/item/weapon/W, var/mob/user)
+ ..()
+ if(istype(W, /obj/item/weapon/rcd_ammo))
+ if((matter + 10) > max_matter)
+ user << "\the [src] can't hold any more matter-units."
+ return 1
+
+ qdel(W)
+ matter += 10
+ playsound(get_turf(src), 'sound/machines/click.ogg', 20, 1)
+ user << "\the [src] now holds [matter]/[max_matter] matter-units."
+ return 1
+
+ if(isscrewdriver(W))
+ user << "You unscrew the access panel and release the cartridge chamber."
+ while(matter >= 10)
+ new /obj/item/weapon/rcd_ammo(user.loc)
+ matter -= 10
+
+ return 1
+
+/obj/item/device/rcd/matter/use_energy(var/amount, var/mob/user)
+ matter -= amount
+ user << "\the [src] currently holds [matter]/[max_matter] matter-units."
+
+/obj/item/device/rcd/matter/get_energy()
+ return matter
diff --git a/code/modules/RCD/RPD.dm b/code/modules/RCD/RPD.dm
new file mode 100644
index 00000000000..50727d3e8f6
--- /dev/null
+++ b/code/modules/RCD/RPD.dm
@@ -0,0 +1,64 @@
+/obj/item/device/rcd/rpd
+ name = "Rapid Piping Device (RPD)"
+ desc = "A device used to rapidly pipe things."
+ icon_state = "rpd"
+
+ starting_materials = list(MAT_IRON = 75000, MAT_GLASS = 37500)
+
+ schematics = list(
+
+ /* Utilities */
+ /datum/rcd_schematic/decon_pipes,
+ /datum/rcd_schematic/paint_pipes,
+
+ /* Regular pipes */
+ /datum/rcd_schematic/pipe,
+ /datum/rcd_schematic/pipe/bent,
+ /datum/rcd_schematic/pipe/manifold,
+ /datum/rcd_schematic/pipe/valve,
+ /datum/rcd_schematic/pipe/dvalve,
+ /datum/rcd_schematic/pipe/cap,
+ /datum/rcd_schematic/pipe/manifold_4w,
+ /datum/rcd_schematic/pipe/mtvalve,
+ /datum/rcd_schematic/pipe/dtvalve,
+
+ /* Devices */
+ /datum/rcd_schematic/pipe/connector,
+ /datum/rcd_schematic/pipe/unary_vent,
+ /datum/rcd_schematic/pipe/passive_vent,
+ /datum/rcd_schematic/pipe/pump,
+ /datum/rcd_schematic/pipe/passive_gate,
+ /datum/rcd_schematic/pipe/volume_pump,
+ /datum/rcd_schematic/pipe/scrubber,
+ /datum/rcd_schematic/pmeter,
+ /datum/rcd_schematic/gsensor,
+ /datum/rcd_schematic/pipe/filter,
+ /datum/rcd_schematic/pipe/mixer,
+ /datum/rcd_schematic/pipe/thermal_plate,
+ /datum/rcd_schematic/pipe/injector,
+ /datum/rcd_schematic/pipe/dp_vent,
+
+ /* H/E Pipes */
+ /datum/rcd_schematic/pipe/he,
+ /datum/rcd_schematic/pipe/he_bent,
+ /datum/rcd_schematic/pipe/juntion,
+ /datum/rcd_schematic/pipe/heat_exchanger,
+
+ /* Insulated Pipes */
+ /datum/rcd_schematic/pipe/insulated,
+ /datum/rcd_schematic/pipe/insulated_bent,
+ /datum/rcd_schematic/pipe/insulated_manifold,
+ /datum/rcd_schematic/pipe/insulated_4w_manifold,
+
+ /* Disposal Pipes */
+ /datum/rcd_schematic/pipe/disposal,
+ /datum/rcd_schematic/pipe/disposal/bent,
+ /datum/rcd_schematic/pipe/disposal/junction,
+ /datum/rcd_schematic/pipe/disposal/y_junction,
+ /datum/rcd_schematic/pipe/disposal/trunk,
+ /datum/rcd_schematic/pipe/disposal/bin,
+ /datum/rcd_schematic/pipe/disposal/outlet,
+ /datum/rcd_schematic/pipe/disposal/chute,
+ /datum/rcd_schematic/pipe/disposal/sort,
+ /datum/rcd_schematic/pipe/disposal/sort_wrap
+ )
diff --git a/code/modules/RCD/RSF.dm b/code/modules/RCD/RSF.dm
new file mode 100644
index 00000000000..f51b115145a
--- /dev/null
+++ b/code/modules/RCD/RSF.dm
@@ -0,0 +1,39 @@
+//Yes, subtype of engineering. (compressed matter handling.)
+/obj/item/device/rcd/matter/rsf
+ name = "\improper Rapid-Service-Fabricator"
+ desc = "A device used to rapidly deploy service items."
+
+ icon_state = "rsf"
+
+ starting_materials = list(MAT_IRON = 40000)
+
+ max_matter = 40
+
+ schematics = list(
+ /datum/rcd_schematic/rsf/glass,
+ /datum/rcd_schematic/rsf/flask,
+ /datum/rcd_schematic/rsf/paper,
+ /datum/rcd_schematic/rsf/candle,
+ /datum/rcd_schematic/rsf/dice,
+ /datum/rcd_schematic/rsf/cards,
+ /datum/rcd_schematic/rsf/cardboard
+ )
+
+/obj/item/device/rcd/borg/rsf
+ name = "\improper Rapid-Service-Fabricator"
+ desc = "A device used to rapidly deploy service items."
+
+ icon_state = "rsf"
+
+ cell_power_per_energy = 50
+
+ schematics = list(
+ /datum/rcd_schematic/rsf/dosh,
+ /datum/rcd_schematic/rsf/glass,
+ /datum/rcd_schematic/rsf/flask,
+ /datum/rcd_schematic/rsf/paper,
+ /datum/rcd_schematic/rsf/candle,
+ /datum/rcd_schematic/rsf/dice,
+ /datum/rcd_schematic/rsf/cards,
+ /datum/rcd_schematic/rsf/cardboard
+ )
diff --git a/code/modules/RCD/engie.dm b/code/modules/RCD/engie.dm
new file mode 100644
index 00000000000..7b8d295ba65
--- /dev/null
+++ b/code/modules/RCD/engie.dm
@@ -0,0 +1,45 @@
+/obj/item/device/rcd/matter/engineering
+ schematics = list(
+ /datum/rcd_schematic/decon,
+ /datum/rcd_schematic/con_floors,
+ /datum/rcd_schematic/con_walls,
+ /datum/rcd_schematic/con_airlock
+ )
+
+ var/disabled = 0
+
+/obj/item/device/rcd/matter/engineering/afterattack(var/atom/A, var/mob/user)
+ if(disabled)
+ return
+
+ return ..()
+
+/obj/item/device/rcd/matter/engineering/suicide_act(var/mob/user)
+ visible_message("[user] is using the deconstruct function on \the [src] on \himself! It looks like \he's trying to commit suicide!")
+ return (user.death(1))
+
+/obj/item/device/rcd/borg/engineering
+ schematics = list(
+ /datum/rcd_schematic/decon,
+ /datum/rcd_schematic/con_floors,
+ /datum/rcd_schematic/con_walls,
+ /datum/rcd_schematic/con_airlock/no_access
+ )
+
+/obj/item/weapon/rcd_ammo
+ name = "compressed matter cartridge"
+ desc = "Highly compressed matter in a cartridge form, used in various fabricators."
+ icon = 'icons/obj/ammo.dmi'
+ icon_state = "rcd"
+ item_state = "rcdammo"
+ opacity = 0
+ density = 0
+ anchored = 0.0
+ origin_tech = "materials=2"
+ w_class = 2.0
+ starting_materials = list(MAT_IRON = 30000, MAT_GLASS = 15000)
+ w_type = RECYK_ELECTRONIC
+
+/obj/item/weapon/rcd_ammo/attackby(var/obj/O, mob/user)
+ if(is_type_in_list(O, list(/obj/item/device/rcd/matter/engineering, /obj/item/device/rcd/matter/rsf)) || (istype(O, /obj/item/device/material_synth) && !istype(O, /obj/item/device/material_synth/robot)))
+ return O.attackby(src, user)
diff --git a/code/modules/RCD/schematic.dm b/code/modules/RCD/schematic.dm
new file mode 100644
index 00000000000..ed30adfd241
--- /dev/null
+++ b/code/modules/RCD/schematic.dm
@@ -0,0 +1,83 @@
+/datum/rcd_schematic
+ var/name = "whomp" //Obvious.
+ var/category = "" //More obvious. Yes you need a category.
+ var/energy_cost = 0 //Energy cost of this schematic.
+ var/flags = 0 //Bitflags.
+
+ var/obj/item/device/rcd/master //Okay all of the vars here are obvious...
+
+/datum/rcd_schematic/New(var/obj/item/device/rcd/n_master)
+ master = n_master
+ . = ..()
+
+
+/*
+Called when the RCD this thing belongs to attacks an atom.
+params:
+ - var/atom/A: The atom being attacked.
+ - var/mob/user: The mob using the RCD.
+
+return value:
+ - !0: Non-descriptive error.
+ - string: Error with reason.
+ - 0: No errors.
+*/
+
+/datum/rcd_schematic/proc/attack(var/atom/A, var/mob/user)
+ return 0
+
+
+/*
+Called when the RCD's schematic changes away from this one.
+params:
+ - var/mob/user: The user, duh...
+ - var/datum/rcd_schematic/old_schematic: The new schematic.
+
+return value:
+ - !0: Switch allowed.
+ - 0: Switch not allowed
+*/
+
+/datum/rcd_schematic/proc/deselect(var/mob/user, var/datum/rcd_schematic/new_schematic)
+ return 1
+
+
+/*
+Called when the RCD's schematic changes to this one
+Note: this is called AFTER deselect().
+params:
+ - var/mob/user: The user, duh...
+ - var/datum/rcd_schematic/old_schematic: The schematic before this one.
+
+return value:
+ - !0: Switch allowed.
+ - 0: Switch not allowed
+*/
+
+/datum/rcd_schematic/proc/select(var/mob/user, var/datum/rcd_schematic/old_schematic)
+ return 1
+
+
+/*
+Called to get the HTML for things like the direction menu on an RPD.
+Note:
+ - Do not do hrefs to the src, any hrefs should direct at the HTML interface, Topic() calls are passed down if not used by the RCD itself.
+ - Always return something here ("" is not enough), else there will be a Jscript error for clients.
+
+params:
+ - I don't need to explain this.
+*/
+
+/datum/rcd_schematic/proc/get_HTML()
+ return " "
+
+/*
+Called when a client logs in and the required resources need to be sent to the cache.
+Use client << browse_rsc() to sent the files.
+
+params:
+ - var/client/client: client to send to.
+*/
+
+/datum/rcd_schematic/proc/send_icons(var/client/client)
+ return
\ No newline at end of file
diff --git a/code/modules/RCD/schematics/engi.dm b/code/modules/RCD/schematics/engi.dm
new file mode 100644
index 00000000000..8222b92f624
--- /dev/null
+++ b/code/modules/RCD/schematics/engi.dm
@@ -0,0 +1,394 @@
+/datum/rcd_schematic/decon
+ name = "Deconstruct"
+ category = "Construction"
+ energy_cost = 5
+
+ var/can_r_wall = 0
+
+/datum/rcd_schematic/decon/attack(var/atom/A, var/mob/user)
+ if(istype(A, /turf/simulated/wall))
+ var/turf/simulated/wall/T = A
+ if(istype(T, /turf/simulated/wall/r_wall) && !can_r_wall)
+ return "it cannot deconstruct reinforced walls!"
+
+ user << "Deconstructing \the [T]..."
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+
+ if(do_after(user, T, 40))
+ if(master.get_energy() < energy_cost)
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ T.ChangeTurf(/turf/simulated/floor/plating)
+ return 0
+
+ else if(istype(A, /turf/simulated/floor))
+ var/turf/simulated/floor/T = A
+ user << "Deconstructing \the [T]..."
+ if(do_after(user, T, 50))
+ if(master.get_energy() < energy_cost)
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ T.ChangeTurf(get_base_turf(T.z))
+ return 0
+
+ else if(istype(A, /obj/machinery/door/airlock))
+ var/obj/machinery/door/airlock/D = A
+ user << "Deconstructing \the [D]..."
+ if(do_after(user, D, 50))
+ if(master.get_energy() < energy_cost)
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ qdel(D)
+ return 0
+
+ return 1
+
+/datum/rcd_schematic/con_floors
+ name = "Build floors"
+ category = "Construction"
+ energy_cost = 1
+
+/datum/rcd_schematic/con_floors/attack(var/atom/A, var/mob/user)
+ if(!(istype(A, /turf/space) && !istype(A, /turf/space/transit)))
+ return "it can only create floors on space!"
+
+ var/turf/space/S = A
+
+ user << "Building floor..."
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ S.ChangeTurf(/turf/simulated/floor/plating/airless)
+ return 0
+
+/datum/rcd_schematic/con_walls
+ name = "Build walls"
+ category = "Construction"
+ energy_cost = 3
+
+/datum/rcd_schematic/con_walls/attack(var/atom/A, var/mob/user)
+ if(!istype(A, /turf/simulated/floor))
+ return 1
+
+ var/turf/simulated/floor/T = A
+ user << "Building wall"
+ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1)
+ if(do_after(user, A, 20))
+ if(master.get_energy() < energy_cost)
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ T.ChangeTurf(/turf/simulated/wall)
+ return 0
+
+ return 1
+
+/datum/rcd_schematic/con_airlock
+ name = "Build airlock"
+ category = "Construction"
+ energy_cost = 3
+
+ var/allow_access = 1
+ var/selected_name = "Airlock"
+ var/list/selected_access = list() //Selected access levels.
+ var/one_access = 0
+
+ var/list/schematics = list()
+ var/datum/airlock_schematic/selected
+
+/datum/rcd_schematic/con_airlock/no_access
+ allow_access = 0
+
+/datum/rcd_schematic/con_airlock/New()
+ . = ..()
+
+ for(var/path in typesof(/datum/airlock_schematic))
+ schematics += new path
+
+ selected = schematics[1]
+
+/datum/rcd_schematic/con_airlock/deselect()
+ . = ..()
+ selected = schematics[1] //Reset the selection.
+
+/datum/rcd_schematic/con_airlock/send_icons(var/client/client)
+ for(var/datum/airlock_schematic/C in schematics)
+ C.send_icon(client)
+
+/datum/rcd_schematic/con_airlock/get_HTML()
+ . = ""
+ for(var/i = 1 to schematics.len)
+ var/datum/airlock_schematic/C = schematics[i]
+ var/selected_text = ""
+ if(selected == C)
+ selected_text = " class='selected'"
+
+ . += "
"
+
+ if(!(i % 5))
+ . += "
"
+
+ . += {"
+
+
+ "}
+
+ if(allow_access)
+ . += {"
+
+
+
+ Show access controls
+
+
+ "
+
+ . += "
"
+
+/datum/rcd_schematic/con_airlock/Topic(var/href, var/href_list)
+ if(href_list["set_selected"])
+ var/idx = Clamp(text2num(href_list["set_selected"]), 1, schematics.len)
+ var/datum/airlock_schematic/C = schematics[idx]
+
+ selected = C
+ selected_name = C.name //Reset the name.
+
+ master.update_options_menu()
+ return 1
+
+ if(href_list["new_name"])
+ selected_name = copytext(sanitize(href_list["new_name"]), 1, MAX_NAME_LEN)
+
+ master.update_options_menu()
+ return 1
+
+ if(href_list["oneAccess"] && allow_access)
+ one_access = text2num(href_list["oneAccess"])
+
+ //Along with oneAccess, the hrefs for access levels get called, as such we process them here before we return 1
+ selected_access.Cut()
+ var/list/access_levels = get_all_accesses()
+
+ for(var/href_key in href_list - list("oneAccess", "src")) //This should loop through all the access levels that are on.
+ var/access = text2num(href_key)
+ if(!(access in access_levels)) //Only check valid access levels.
+ continue
+
+ selected_access |= access
+
+ master.update_options_menu()
+ return 1
+
+/datum/rcd_schematic/con_airlock/attack(var/atom/A, var/mob/user)
+ if(!istype(A, /turf))
+ return 1
+
+ if(locate(/obj/machinery/door/airlock) in A)
+ return "there is already an airlock on this spot!"
+
+ user << "Building airlock..."
+
+ if(!do_after(user, A, 50))
+ return 1
+
+ if(master.get_energy() < energy_cost)
+ return 1
+
+ if(locate(/obj/machinery/door/airlock) in A)
+ return "there is already an airlock on this spot!"
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+
+ var/obj/machinery/door/airlock/D = new selected.airlock_type(A)
+ if(capitalize(selected_name) == selected_name) //The name inputted is capitalized, so we add \improper.
+ D.name = "\improper [selected_name]"
+ else
+ D.name = selected_name
+
+ if(allow_access)
+ if(one_access)
+ D.req_one_access = selected_access.Copy()
+ else
+ D.req_access = selected_access.Copy()
+
+ D.autoclose = 1
+
+//Schematics for schematics, I know, but it's OOP!
+/datum/airlock_schematic
+ var/name = "airlock" //Name of the airlock for the tooltip.
+ var/airlock_type = /obj/machinery/door/airlock //Type of the airlock.
+ var/img = "rcd_airlock.png" //Icon to send to the client AND to use for the preview.
+ var/icon = 'icons/obj/doors/Doorint.dmi' //Icon file to pull the icon from to send to the client.
+
+/datum/airlock_schematic/proc/send_icon(var/client/client)
+ client << browse_rsc(new /icon(icon, "door_closed"), img)
+
+//ALL THE AIRLOCK TYPES.
+/datum/airlock_schematic/engie
+ name = "\improper Engineering Airlock"
+ airlock_type = /obj/machinery/door/airlock/engineering
+ img = "rcd_airlock_eng.png"
+ icon = 'icons/obj/doors/Dooreng.dmi'
+
+/datum/airlock_schematic/atmos
+ name = "\improper Atmospherics Airlock"
+ airlock_type = /obj/machinery/door/airlock/atmos
+ img = "rcd_airlock_atmos.png"
+ icon = 'icons/obj/doors/Dooratmo.dmi'
+
+/datum/airlock_schematic/sec
+ name = "\improper Security Airlock"
+ airlock_type = /obj/machinery/door/airlock/security
+ img = "rcd_airlock_sec.png"
+ icon = 'icons/obj/doors/Doorsec.dmi'
+
+/datum/airlock_schematic/command
+ name = "\improper Command Airlock"
+ airlock_type = /obj/machinery/door/airlock/command
+ img = "rcd_airlock_command.png"
+ icon = 'icons/obj/doors/Doorcom.dmi'
+
+/datum/airlock_schematic/med
+ name = "\improper Medical Airlock"
+ airlock_type = /obj/machinery/door/airlock/medical
+ img = "rcd_airlock_med.png"
+ icon = 'icons/obj/doors/Doormed.dmi'
+
+/datum/airlock_schematic/sci
+ name = "\improper Research Airlock"
+ airlock_type = /obj/machinery/door/airlock/research
+ img = "rcd_airlock_sci.png"
+ icon = 'icons/obj/doors/doorresearch.dmi'
+
+/datum/airlock_schematic/mining
+ name = "\improper Mining Airlock"
+ airlock_type = /obj/machinery/door/airlock/mining
+ img = "rcd_airlock_mining.png"
+ icon = 'icons/obj/doors/Doormining.dmi'
+
+/datum/airlock_schematic/maint
+ name = "\improper Maintenance Access"
+ airlock_type = /obj/machinery/door/airlock/maintenance
+ img = "rcd_airlock_maint.png"
+ icon = 'icons/obj/doors/Doormaint.dmi'
+
+/datum/airlock_schematic/ext
+ name = "\improper External Airlock"
+ airlock_type = /obj/machinery/door/airlock/external
+ img = "rcd_airlock_ext.png"
+ icon = 'icons/obj/doors/Doorext.dmi'
+
+/datum/airlock_schematic/high_sec
+ name = "\improper High-Tech Security Airlock"
+ airlock_type = /obj/machinery/door/airlock/highsecurity
+ img = "rcd_airlock_high-sec.png"
+ icon = 'icons/obj/doors/hightechsecurity.dmi'
+
+
+/datum/airlock_schematic/glass
+ name = "\improper Glass Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass
+ img = "rcd_airlock_glass.png"
+ icon = 'icons/obj/doors/Doorglass.dmi'
+
+/datum/airlock_schematic/glass_eng
+ name = "\improper Glass Engineering Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_engineering
+ img = "rcd_airlock_glass_eng.png"
+ icon = 'icons/obj/doors/Doorengglass.dmi'
+
+/datum/airlock_schematic/glass_atmos
+ name = "\improper Glass Atmospherics Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_atmos
+ img = "rcd_airlock_glass_atmos.png"
+ icon = 'icons/obj/doors/Dooratmoglass.dmi'
+
+/datum/airlock_schematic/glass_sec
+ name = "\improper Glass Security Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_security
+ img = "rcd_airlock_glass_sec.png"
+ icon = 'icons/obj/doors/Doorsecglass.dmi'
+
+/datum/airlock_schematic/glass_command
+ name = "\improper Glass Command Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_command
+ img = "rcd_airlock_glass_com.png"
+ icon = 'icons/obj/doors/Doorcomglass.dmi'
+
+/datum/airlock_schematic/glass_med
+ name = "\improper Glass Medical Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_medical
+ img = "rcd_airlock_glass_med.png"
+ icon = 'icons/obj/doors/doormedglass.dmi'
+
+/datum/airlock_schematic/glass_sci
+ name = "\improper Glass Research Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_research
+ img = "rcd_airlock_glass_sci.png"
+ icon = 'icons/obj/doors/doorresearchglass.dmi'
+
+/datum/airlock_schematic/glass_mining
+ name = "\improper Glass Mining Airlock"
+ airlock_type = /obj/machinery/door/airlock/glass_mining
+ img = "rcd_airlock_glass_mining.png"
+ icon = 'icons/obj/doors/Doorminingglass.dmi'
diff --git a/code/modules/RCD/schematics/pipe.dm b/code/modules/RCD/schematics/pipe.dm
new file mode 100644
index 00000000000..308267af47b
--- /dev/null
+++ b/code/modules/RCD/schematics/pipe.dm
@@ -0,0 +1,572 @@
+#define PIPE_BINARY 0
+#define PIPE_BENT 1
+#define PIPE_TRINARY 2
+#define PIPE_TRIN_M 3
+#define PIPE_UNARY 4
+
+//UTILITIES.
+
+/datum/rcd_schematic/decon_pipes
+ name = "Eat pipes"
+ category = "Utilities"
+ flags = RCD_RANGE
+
+/datum/rcd_schematic/decon_pipes/attack(var/atom/A, var/mob/user)
+ if(!istype(A, /atom/movable))
+ return 1
+
+ var/atom/movable/AM = A
+
+ if(!is_type_in_list(AM, list(/obj/item/pipe, /obj/item/pipe_meter, /obj/item/pipe_gsensor, /obj/structure/disposalconstruct)))
+ return 1
+
+ user << "Destroying Pipe..."
+ playsound(get_turf(master), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, AM, 5))
+ return 1
+
+ if(!AM)
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+
+ if(istype(AM, /obj/item/pipe))
+ returnToPool(A)
+ else
+ qdel(AM)
+
+/datum/rcd_schematic/paint_pipes
+ name = "Paint pipes"
+ category = "Utilities"
+ flags = RCD_RANGE
+
+ var/list/available_colors = list(
+ "grey" = "#CCCCCC",
+ "red" = "#800000",
+ "blue" = "#000080",
+ "cyan" = "#1C94C4",
+ "green" = "#00CC00",
+ "yellow" = "#FFCC00",
+ "purple" = "purple"
+ )
+
+ var/selected_color = "grey"
+
+/datum/rcd_schematic/paint_pipes/New(var/obj/item/device/rcd/n_master)
+ . = ..()
+
+ if(!master || !master.interface)
+ return
+
+ //Add the colour CSS defines to the master's interface's HEAD.
+ var/color_css
+
+ for(var/color_name in available_colors)
+ var/color = available_colors[color_name]
+ color_css += {"
+ a.color.[color_name] {
+ color: [color];
+ }
+ a.color.[color_name]:hover {
+ border:1px solid [color];
+ }
+ a.color.[color_name].selected {
+ background-color: [color];
+ }
+ "}
+
+ master.interface.head += ""
+
+/datum/rcd_schematic/paint_pipes/deselect(var/mob/user, var/datum/rcd_schematic/new_schematic)
+ . = ..()
+
+ selected_color = available_colors[1]
+
+/datum/rcd_schematic/paint_pipes/get_HTML()
+ for(var/color_name in available_colors)
+ var/selected = ""
+ if(color_name == selected_color)
+ selected = " selected"
+
+ . += "•"
+
+/datum/rcd_schematic/paint_pipes/attack(var/atom/A, var/mob/user)
+ if(!istype(A, /obj/machinery/atmospherics))
+ return 1
+
+ var/obj/machinery/atmospherics/O = A
+
+ if(!O.available_colors || !O.available_colors.len)
+ return "you cannot paint this!"
+
+ if(!(selected_color in O.available_colors))
+ return "the color '[selected_color]' is not available for \a [O]"
+
+ playsound(get_turf(master), 'sound/machines/click.ogg', 50, 1)
+ O._color = selected_color
+
+ user.visible_message("[user] paints \the [O] [selected_color].","You paint \the [O] [selected_color].")
+ O.update_icon()
+
+/datum/rcd_schematic/paint_pipes/Topic(var/href, var/list/href_list)
+ if(href_list["set_color"])
+ if(href_list["set_color"] in available_colors)
+ selected_color = href_list["set_color"]
+
+ master.update_options_menu()
+
+ return 1
+
+//METERS AND SENSORS.
+
+/datum/rcd_schematic/gsensor
+ name = "Gas sensor"
+ category = "Devices"
+ flags = RCD_RANGE | RCD_GET_TURF
+
+/datum/rcd_schematic/gsensor/attack(var/atom/A, var/mob/user)
+ if(!isturf(A))
+ return
+
+ user << "Building gas sensor..."
+ playsound(get_turf(master), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, A, 20))
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ new /obj/item/pipe_gsensor(A)
+
+/datum/rcd_schematic/pmeter
+ name = "Pipe meter"
+ category = "Devices"
+ flags = RCD_RANGE | RCD_GET_TURF
+
+/datum/rcd_schematic/pmeter/attack(var/atom/A, var/mob/user)
+ if(!isturf(A))
+ return
+
+ user << "Building pipe meter..."
+ playsound(get_turf(master), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, A, 20))
+ return 1
+
+ playsound(get_turf(master), 'sound/items/Deconstruct.ogg', 50, 1)
+ new /obj/item/pipe_meter(A)
+
+//ACTUAL PIPES.
+
+/datum/rcd_schematic/pipe
+ name = "Pipe"
+ category = "Regular pipes"
+ flags = RCD_RANGE | RCD_GET_TURF
+
+ var/pipe_id = PIPE_SIMPLE_STRAIGHT
+ var/pipe_type = PIPE_BINARY
+ var/selected_dir = NORTH
+
+/datum/rcd_schematic/pipe/send_icons(var/client/client)
+ var/list/dir_list //We get the dirs to loop through and send images to the client for.
+ switch(pipe_type)
+ if(PIPE_UNARY, PIPE_TRINARY)
+ dir_list = cardinal
+
+ if(PIPE_BINARY)
+ dir_list = list(NORTH, EAST)
+
+ if(PIPE_BENT)
+ dir_list = diagonal
+
+ if(PIPE_TRIN_M)
+ dir_list = alldirs
+
+ else
+ dir_list = list()
+
+ for(var/dir in dir_list)
+ send_icon(client, dir)
+
+/datum/rcd_schematic/pipe/proc/send_icon(var/client/client, var/dir)
+ client << browse_rsc(new/icon('icons/obj/pipe-item.dmi', pipeID2State[pipe_id + 1], dir), "RPD_[pipe_id]_[dir].png")
+
+/datum/rcd_schematic/pipe/get_HTML()
+ . += ""
+
+ switch(pipe_type)
+ if(PIPE_BINARY)
+ . += render_dir_image(NORTH, "Vertical")
+ . += render_dir_image(EAST, "Horizontal")
+
+ if(PIPE_UNARY)
+ . += render_dir_image(NORTH, "North")
+ . += render_dir_image(EAST, "East")
+ . += render_dir_image(SOUTH, "South")
+ . += render_dir_image(WEST, "West")
+
+ if(PIPE_BENT)
+ . += render_dir_image(9, "West to North")
+ . += render_dir_image(5, "North to East")
+ . += "
"
+ . += render_dir_image(10, "South to West")
+ . += render_dir_image(6, "East to South")
+
+ if(PIPE_TRINARY)
+ . += render_dir_image(NORTH, "West South East")
+ . += render_dir_image(EAST, "North West South")
+ . += "
"
+ . += render_dir_image(SOUTH, "East North West")
+ . += render_dir_image(WEST, "South East North")
+
+ if(PIPE_TRIN_M)
+ . += render_dir_image(NORTH, "West South East")
+ . += render_dir_image(EAST, "North West South")
+ . += "
"
+ . += render_dir_image(SOUTH, "East North West")
+ . += render_dir_image(WEST, "South East North")
+ . += "
"
+ . += render_dir_image(6, "West South East")
+ . += render_dir_image(5, "North West South")
+ . += "
"
+ . += render_dir_image(9, "East North West")
+ . += render_dir_image(10, "South East North")
+
+ . += "
"
+
+/datum/rcd_schematic/pipe/proc/render_dir_image(var/dir, var/title)
+ var/selected = ""
+ if(selected_dir == dir)
+ selected = " class='selected'"
+
+ return "
"
+
+/datum/rcd_schematic/pipe/Topic(var/href, var/href_list)
+ if(href_list["set_dir"])
+ var/dir = text2num(href_list["set_dir"])
+ if(!(dir in alldirs) || selected_dir == dir)
+ return 1
+
+ selected_dir = dir
+ master.update_options_menu()
+
+ return 1
+
+/datum/rcd_schematic/pipe/attack(var/atom/A, var/mob/user)
+ user << "Building Pipes ..."
+ playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, A, 20))
+ return 1
+
+ playsound(get_turf(user), 'sound/items/Deconstruct.ogg', 50, 1)
+
+ var/obj/item/pipe/P = getFromPool(/obj/item/pipe, A, pipe_id, selected_dir)
+ P.update()
+ P.add_fingerprint(user)
+
+//Disposal piping.
+/datum/rcd_schematic/pipe/disposal
+ category = "Disposal Pipes"
+
+ pipe_id = DISP_PIPE_STRAIGHT
+ var/actual_id = 0 //This is needed because disposals construction code is a shit.
+
+/datum/rcd_schematic/pipe/disposal/send_icon(var/client/client, var/dir)
+ client << browse_rsc(new/icon('icons/obj/pipes/disposal.dmi', disposalpipeID2State[pipe_id + 1], dir), "RPD_D_[pipe_id]_[dir].png")
+
+/datum/rcd_schematic/pipe/disposal/render_dir_image(var/dir, var/title)
+ var/selected = ""
+ if(selected_dir == dir)
+ selected = " class='selected'"
+
+ return "
"
+
+/datum/rcd_schematic/pipe/disposal/attack(var/atom/A, var/mob/user)
+ user << "Building Pipes ..."
+ playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, A, 20))
+ return 1
+
+ playsound(get_turf(user), 'sound/items/Deconstruct.ogg', 50, 1)
+
+ var/obj/structure/disposalconstruct/C = new/obj/structure/disposalconstruct(A)
+ C.dir = selected_dir
+ C.ptype = actual_id
+ C.update()
+
+ C.add_fingerprint(user)
+
+var/global/list/disposalpipeID2State=list(
+ "pipe-s",
+ "pipe-c",
+ "pipe-j1",
+ "pipe-y",
+ "pipe-t",
+ "disposal",
+ "outlet",
+ "intake",
+ "pipe-j1s",
+ "pipe-j1s",
+)
+
+//PIPE DEFINES START HERE.
+
+//REGULAR PIPES.
+//Straight is the base class, so not included.
+
+/datum/rcd_schematic/pipe/bent
+ name = "Bent Pipe"
+
+ pipe_id = PIPE_SIMPLE_BENT
+ pipe_type = PIPE_BENT
+
+/datum/rcd_schematic/pipe/manifold
+ name = "Manifold"
+
+ pipe_id = PIPE_MANIFOLD
+ pipe_type = PIPE_TRINARY
+
+/datum/rcd_schematic/pipe/valve
+ name = "Manual Valve"
+
+ pipe_id = PIPE_MVALVE
+ pipe_type = PIPE_BINARY
+
+/datum/rcd_schematic/pipe/dvalve
+ name = "Digital Valve"
+
+ pipe_id = PIPE_DVALVE
+ pipe_type = PIPE_BINARY
+
+/datum/rcd_schematic/pipe/cap
+ name = "Pipe Cap"
+
+ pipe_id = PIPE_CAP
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/manifold_4w
+ name = "4-Way Manifold"
+
+ pipe_id = PIPE_MANIFOLD4W
+ pipe_type = PIPE_BINARY
+
+/datum/rcd_schematic/pipe/mtvalve
+ name = "Manual T-Valve"
+
+ pipe_id = PIPE_MTVALVE
+ pipe_type = PIPE_TRIN_M
+
+/datum/rcd_schematic/pipe/dtvalve
+ name = "Digital T-Valve"
+
+ pipe_id = PIPE_DTVALVE
+ pipe_type = PIPE_TRIN_M
+
+//DEVICES.
+
+/datum/rcd_schematic/pipe/connector
+ name = "Connecter"
+ category = "Devices"
+
+ pipe_id = PIPE_CONNECTOR
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/unary_vent
+ name = "Unary Vent"
+ category = "Devices"
+
+ pipe_id = PIPE_UVENT
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/passive_vent
+ name = "Passive Vent"
+ category = "Devices"
+
+ pipe_id = PIPE_PASV_VENT
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/pump
+ name = "Gas Pump"
+ category = "Devices"
+
+ pipe_id = PIPE_PUMP
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/passive_gate
+ name = "Passive gate"
+ category = "Devices"
+
+ pipe_id = PIPE_PASSIVE_GATE
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/volume_pump
+ name = "Volume Pump"
+ category = "Devices"
+
+ pipe_id = PIPE_VOLUME_PUMP
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/scrubber
+ name = "Scrubber"
+ category = "Devices"
+
+ pipe_id = PIPE_SCRUBBER
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/filter
+ name = "Gas Filter"
+ category = "Devices"
+
+ pipe_id = PIPE_GAS_FILTER
+ pipe_type = PIPE_TRIN_M
+
+/datum/rcd_schematic/pipe/mixer
+ name = "Gas Mixer"
+ category = "Devices"
+
+ pipe_id = PIPE_GAS_MIXER
+ pipe_type = PIPE_TRIN_M
+
+/datum/rcd_schematic/pipe/thermal_plate
+ name = "Thermal Plate"
+ category = "Devices"
+
+ pipe_id = PIPE_THERMAL_PLATE
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/injector
+ name = "Injector"
+ category = "Devices"
+
+ pipe_id = PIPE_INJECTOR
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/dp_vent
+ name = "Dual-Port Vent"
+ category = "Devices"
+
+ pipe_id = PIPE_DP_VENT
+ pipe_type = PIPE_UNARY
+
+//H/E Pipes.
+
+/datum/rcd_schematic/pipe/he
+ name = "Pipe"
+ category = "Heat Exchange"
+
+ pipe_id = PIPE_HE_STRAIGHT
+ pipe_type = PIPE_BINARY
+
+/datum/rcd_schematic/pipe/he_bent
+ name = "Bent Pipe"
+ category = "Heat Exchange"
+
+ pipe_id = PIPE_HE_BENT
+ pipe_type = PIPE_BENT
+
+/datum/rcd_schematic/pipe/juntion
+ name = "Junction"
+ category = "Heat Exchange"
+
+ pipe_id = PIPE_JUNCTION
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/heat_exchanger
+ name = "Heat Exchanger"
+ category = "Heat Exchange"
+
+ pipe_id = PIPE_HEAT_EXCHANGE
+ pipe_type = PIPE_UNARY
+
+//INSULATED PIPES.
+
+/datum/rcd_schematic/pipe/insulated
+ name = "Pipe"
+ category = "Insulated Pipes"
+
+ pipe_id = PIPE_INSULATED_STRAIGHT
+ pipe_type = PIPE_BINARY
+
+/datum/rcd_schematic/pipe/insulated_bent
+ name = "Bent Pipe"
+ category = "Insulated Pipes"
+
+ pipe_id = PIPE_INSULATED_BENT
+ pipe_type = PIPE_BENT
+
+/datum/rcd_schematic/pipe/insulated_manifold
+ name = "Manifold"
+ category = "Insulated Pipes"
+
+ pipe_id = PIPE_INSUL_MANIFOLD
+ pipe_type = PIPE_TRINARY
+
+/datum/rcd_schematic/pipe/insulated_4w_manifold
+ name = "4-Way Manifold"
+ category = "Insulated Pipes"
+
+ pipe_id = PIPE_INSUL_MANIFOLD4W
+ pipe_type = PIPE_BINARY
+
+//DISPOSAL PIPES
+//Again basic straight is handled in the parent.
+
+/datum/rcd_schematic/pipe/disposal/bent
+ name = "Bent Pipe"
+
+ pipe_id = DISP_PIPE_BENT
+ actual_id = 1
+ pipe_type = PIPE_UNARY //Yes this makes no sense but BLAME FUCKING DISPOSALS CODE.
+
+/datum/rcd_schematic/pipe/disposal/junction
+ name = "Junction"
+
+ pipe_id = DISP_JUNCTION
+ actual_id = 2
+ pipe_type = PIPE_TRINARY
+
+/datum/rcd_schematic/pipe/disposal/y_junction
+ name = "Y-Junction"
+
+ pipe_id = DISP_YJUNCTION
+ actual_id = 4
+ pipe_type = PIPE_TRINARY
+
+/datum/rcd_schematic/pipe/disposal/trunk
+ name = "Trunk"
+
+ pipe_id = DISP_END_TRUNK
+ actual_id = 5
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/disposal/bin
+ name = "Bin"
+
+ pipe_id = DISP_END_BIN
+ actual_id = 6
+ pipe_type = -1 //Will disable the icon.
+
+/datum/rcd_schematic/pipe/disposal/outlet
+ name = "Outlet"
+
+ pipe_id = DISP_END_OUTLET
+ actual_id = 7
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/disposal/chute
+ name = "Chute"
+
+ pipe_id = DISP_END_CHUTE
+ actual_id = 8
+ pipe_type = PIPE_UNARY
+
+/datum/rcd_schematic/pipe/disposal/sort
+ name = "Sorting Junction"
+
+ pipe_id = DISP_SORT_JUNCTION
+ actual_id = 9
+ pipe_type = PIPE_TRINARY
+
+/datum/rcd_schematic/pipe/disposal/sort_wrap
+ name = "Wrapped Sorting Junction"
+
+ pipe_id = DISP_SORT_WRAP_JUNCTION
+ actual_id = 11
+ pipe_type = PIPE_TRINARY
diff --git a/code/modules/RCD/schematics/service.dm b/code/modules/RCD/schematics/service.dm
new file mode 100644
index 00000000000..c109df56260
--- /dev/null
+++ b/code/modules/RCD/schematics/service.dm
@@ -0,0 +1,46 @@
+//RSF schematics.
+/datum/rcd_schematic/rsf
+ energy_cost = 1
+ var/spawn_type
+ category = "Service"
+
+/datum/rcd_schematic/rsf/attack(var/atom/A, var/mob/user)
+ if(!is_type_in_list(A, list(/obj/structure/table, /turf/simulated/floor)))
+ return 1
+
+ user << "Dispensing [lowertext(name)]"
+ playsound(get_turf(src), 'sound/machines/click.ogg', 10, 1)
+ new spawn_type(get_turf(A))
+
+/datum/rcd_schematic/rsf/dosh
+ name = "Dosh"
+ spawn_type = /obj/item/weapon/spacecash/c10
+ energy_cost = 4
+
+/datum/rcd_schematic/rsf/glass
+ name = "Glass"
+ spawn_type = /obj/item/weapon/reagent_containers/food/drinks/drinkingglass
+
+/datum/rcd_schematic/rsf/flask
+ name = "Flask"
+ spawn_type = /obj/item/weapon/reagent_containers/food/drinks/flask/barflask
+
+/datum/rcd_schematic/rsf/paper
+ name = "Paper"
+ spawn_type = /obj/item/weapon/paper
+
+/datum/rcd_schematic/rsf/candle
+ name = "Candle"
+ spawn_type = /obj/item/candle
+
+/datum/rcd_schematic/rsf/dice
+ name = "Dice"
+ spawn_type = /obj/item/weapon/storage/pill_bottle/dice
+
+/datum/rcd_schematic/rsf/cards
+ name = "Deck of cards"
+ spawn_type = /obj/item/toy/cards
+
+/datum/rcd_schematic/rsf/cardboard
+ name = "Cardboard Sheet..."
+ spawn_type = /obj/item/stack/sheet/cardboard
diff --git a/code/modules/RCD/schematics/test.dm b/code/modules/RCD/schematics/test.dm
new file mode 100644
index 00000000000..bc7f5c07636
--- /dev/null
+++ b/code/modules/RCD/schematics/test.dm
@@ -0,0 +1,6 @@
+/datum/rcd_schematic/test
+ category = "test"
+
+/datum/rcd_schematic/test/attack(var/atom/A, var/mob/user)
+ user << "WHOMP"
+ A.color = "#FFFF00"
diff --git a/code/modules/RCD/schematics/tile.dm b/code/modules/RCD/schematics/tile.dm
new file mode 100644
index 00000000000..0886508cf8f
--- /dev/null
+++ b/code/modules/RCD/schematics/tile.dm
@@ -0,0 +1,609 @@
+#define PAINT_ALL 0
+#define PAINT_FLOOR 1
+#define PAINT_PLATING 2
+#define PAINT_REINFORCED 3
+
+#define DIR_ONE 1 //For those tiles with only one direction.
+#define DIR_ORTHO 2 //Orthogonal (south, west, north, east).
+#define DIR_ALL 3 //All the directions.
+
+#define PAINT_ASK_DESC = 1
+s
+/datum/rcd_schematic/tile
+ name = "Decals"
+ category = "Painting"
+
+ flags = RCD_GET_TURF
+
+ var/datum/paint_info/selected
+ var/selected_dir = 2
+
+/datum/rcd_schematic/tile/send_icons(var/client/client)
+ var/list/our_list = get_our_list()
+ if(!our_list)
+ return
+
+ for(var/datum/paint_info/P in our_list)
+ for(var/ndir in get_dir_list_by_dir_type(P.adirs))
+ client << browse_rsc(new/icon(P.icon, P.icon_state, ndir), "[P.file_name][P.icon_state]_[ndir].png")
+
+/datum/rcd_schematic/tile/proc/get_dir_list_by_dir_type(var/adir)
+ switch(adir)
+ if(DIR_ONE)
+ return list(SOUTH)
+
+ if(DIR_ORTHO)
+ return cardinal
+
+ if(DIR_ALL)
+ return alldirs
+
+/datum/rcd_schematic/tile/get_HTML()
+ . += ""
+
+ var/list/our_list = get_our_list()
+ for(var/datum/paint_info/P in our_list)
+ for(var/dir in get_dir_list_by_dir_type(P.adirs))
+ var/selected = ""
+ if(selected == P && dir == selected_dir)
+ selected = " class='selected'"
+
+ . += "
"
+
+ . += "
"
+
+/datum/rcd_schematic/tile/Topic(var/href, var/href_list)
+ if(href_list["select_paint"])
+ var/list/our_list = get_our_list()
+ var/idx = Clamp(round(text2num(href_list["select_paint"])), 1, our_list.len)
+
+ selected = our_list[idx]
+ if(!(selected_dir in get_dir_list_by_dir_type(selected.adirs)))
+ selected_dir = 2
+
+ master.update_options_menu()
+ . = 1
+
+ if(href_list["set_dir"])
+ var/dir = text2num(href_list["set_dir"])
+ if(!(dir in get_dir_list_by_dir_type(selected.adirs)))
+ return 1
+
+ selected_dir = dir
+
+/datum/rcd_schematic/tile/attack(var/atom/A, var/mob/user)
+ if(!selected)
+ return 1
+
+ if(!selected.validate(A))
+ return "maybe you're using it on the wrong floor type?"
+
+ var/nname = ""
+
+ switch(selected.ftype)
+ if(PAINT_FLOOR) nname = "floor" //restoring the name of our new tile, usually if you place a floor tile on a plating it's still called "plating" for now
+ if(PAINT_REINFORCED) nname = "reinforced floor" //also getting rid of the plaque if it's there
+ if(PAINT_PLATING) nname = "plating"
+
+ user << "Painting floor..."
+ playsound(get_turf(master), 'sound/machines/click.ogg', 50, 1)
+ if(!do_after(user, A, 20))
+ return 1
+
+ playsound(get_turf(master), 'sound/effects/extinguish.ogg', 25, 1)
+
+ selected.apply(A, nname, dir = selected_dir)
+
+//Gets the list of paint info datums.
+/datum/rcd_schematic/tile/proc/get_our_list()
+ return paint_variants[name]
+
+/datum/paint_info
+ var/icon/icon = 'icons/turf/floors.dmi'
+ var/icon_state = "floor"
+ var/ftype = PAINT_FLOOR //The floor type required for this paint job.
+ var/adirs = DIR_ONE //Available dirs for this floor type.
+ var/file_name = "tile_painter_" //The file data gets added after this, used to seperate the decals and floor types.
+ var/flags = 0
+
+/datum/paint_info/New(var/padir, var/picon, var/ptype, var/nflags = 0)
+ if(ptype)
+ ftype = ptype
+
+ if(padir)
+ adirs = padir
+
+ if(picon)
+ icon_state = picon
+
+ flags = nflags
+
+//This is used to give the user a hint that he's a massive retard for using a floor painter on the carpet
+/datum/paint_info/proc/validate(var/turf/simulated/floor/test)
+ switch(ftype)
+ if(PAINT_FLOOR) //why is it named plasteel anyway?
+ if(!(istype(test.floor_tile,/obj/item/stack/tile/plasteel)))
+ return 0 //if it's carpet, wood or some other stuff, we aren't going to paint that
+ if(istype(test, /turf/simulated/floor/engine))
+ return 0 //reinforced floor has plasteel in floor_tile too
+ //but that isn't a regular floor
+ if(PAINT_PLATING)
+ if(!istype(test,/turf/simulated/floor/plating))
+ return 0
+
+ if(PAINT_REINFORCED)
+ if(!istype(test,/turf/simulated/floor/engine))
+ return 0
+
+ return 1
+
+/datum/paint_info/proc/apply(var/turf/simulated/floor/T, var/pname, var/pdesc, var/dir)
+ T.icon_state = icon_state
+ T.icon_regular_floor = icon_state //required to 'save' the new floor type so if someone crowbars it and puts it back it won't revert to the original state
+ T.dir = dir
+ T.desc = pdesc //so if you paint over a plaque with a floor the tile loses its description
+ if(pname)
+ T.name = pname
+
+ T.ClearDecals()
+
+/datum/paint_info/decal
+ icon = 'icons/effects/warning_stripes.dmi'
+ ftype = PAINT_ALL
+ file_name = "tile_painter_d_"
+
+/datum/paint_info/decal/apply(var/turf/simulated/floor/T, var/pname, var/pdesc, var/dir)
+ T.AddDecal(image(icon, icon_state = icon_state, dir = dir))
+
+//The list of all available floor design groups.
+
+/datum/rcd_schematic/tile/gray
+ name = "Gray"
+
+/datum/rcd_schematic/tile/neutral
+ name = "Neutral"
+
+/datum/rcd_schematic/tile/white
+ name = "White"
+
+/datum/rcd_schematic/tile/red
+ name = "Red"
+
+/datum/rcd_schematic/tile/green
+ name = "Green"
+
+/datum/rcd_schematic/tile/blue
+ name = "Blue"
+
+/datum/rcd_schematic/tile/yellow
+ name = "Yellow"
+
+/datum/rcd_schematic/tile/purple
+ name = "Purple"
+
+/datum/rcd_schematic/tile/orange
+ name = "Orange"
+
+/datum/rcd_schematic/tile/brown
+ name = "Brown"
+
+/datum/rcd_schematic/tile/red_yellow
+ name = "Red and yellow"
+
+/datum/rcd_schematic/tile/red_blue
+ name = "Red and blue"
+
+/datum/rcd_schematic/tile/red_green
+ name = "Red and green"
+
+/datum/rcd_schematic/tile/green_yellow
+ name = "Green and yellow"
+
+/datum/rcd_schematic/tile/green_blue
+ name = "Green and blue"
+
+/datum/rcd_schematic/tile/blue_yellow
+ name = "Blue and yellow"
+
+/datum/rcd_schematic/tile/white_red
+ name = "White red"
+
+/datum/rcd_schematic/tile/white_green
+ name = "White green"
+
+/datum/rcd_schematic/tile/white_blue
+ name = "White blue"
+
+/datum/rcd_schematic/tile/white_yellow
+ name = "White yellow"
+
+/datum/rcd_schematic/tile/white_purple
+ name = "White purple"
+
+/datum/rcd_schematic/tile/arrival
+ name = "Arrival"
+
+/datum/rcd_schematic/tile/escape
+ name = "Escape"
+
+/datum/rcd_schematic/tile/dark
+ name = "Dark"
+
+/datum/rcd_schematic/tile/dark_red
+ name = "Dark red"
+
+/datum/rcd_schematic/tile/dark_blue
+ name = "Dark blue"
+
+/datum/rcd_schematic/tile/dark_green
+ name = "Dark green"
+
+/datum/rcd_schematic/tile/dark_purple
+ name = "Dark purple"
+
+/datum/rcd_schematic/tile/dark_yellow
+ name = "Dark yellow"
+
+/datum/rcd_schematic/tile/dark_orange
+ name = "Dark orange"
+
+/datum/rcd_schematic/tile/dark_vault
+ name = "Dark vault"
+
+/datum/rcd_schematic/tile/markings
+ name = "Markings"
+
+/datum/rcd_schematic/tile/loading
+ name = "Loading area"
+
+/datum/rcd_schematic/tile/warning
+ name = "Warning"
+
+/datum/rcd_schematic/tile/warning_white
+ name = "White warning"
+
+/datum/rcd_schematic/tile/warning_reinforced
+ name = "Reinforced warning"
+
+/datum/rcd_schematic/tile/warning_plating
+ name = "Plating warning"
+
+/datum/rcd_schematic/tile/chapel
+ name = "Chapel"
+
+/datum/rcd_schematic/tile/ss13_logo
+ name = "SS13 logo"
+
+/datum/rcd_schematic/tile/derelict_logo
+ name = "Derelict logo"
+
+/datum/rcd_schematic/tile/other
+ name = "Other"
+
+//Ririchiyo's potatobox grid.
+/datum/rcd_schematic/tile/all
+ name = "All"
+
+//We override this so we DON'T send files twice, sending is handled in the specific ones.
+/datum/rcd_schematic/tile/all/send_icons(var/client/client)
+ return
+
+//We get EVERY paint info datum.
+/datum/rcd_schematic/tile/all/get_our_list()
+ . = list()
+ for(var/key in paint_variants)
+ for(var/datum/paint_info/P in paint_variants[key])
+ . += P
+
+
+var/global/list/paint_variants = list(
+ "Decals" = list(
+ // Stripes
+ new /datum/paint_info/decal(DIR_ALL, "warning"),
+ new /datum/paint_info/decal(DIR_ONE, "all"),
+
+ // Loading areas (TODO: colourable)
+ new /datum/paint_info/decal(DIR_ORTHO, "warning_corner"),
+ new /datum/paint_info/decal(DIR_ONE, "unloading"),
+ new /datum/paint_info/decal(DIR_ONE, "bot"),
+ new /datum/paint_info/decal(DIR_ORTHO, "loading_area"),
+ new /datum/paint_info/decal(DIR_ONE, "no"),
+
+ // Atmos lettering
+ new /datum/paint_info/decal(DIR_ORTHO, "oxygen"),
+ new /datum/paint_info/decal(DIR_ORTHO, "nitrogen"),
+ new /datum/paint_info/decal(DIR_ORTHO, "carbon_dioxide"),
+ new /datum/paint_info/decal(DIR_ORTHO, "nitrous_oxide"),
+ new /datum/paint_info/decal(DIR_ORTHO, "air"),
+ new /datum/paint_info/decal(DIR_ORTHO, "plasma"),
+ new /datum/paint_info/decal(DIR_ORTHO, "zoo"),
+
+ // Numbers
+ new /datum/paint_info/decal(DIR_ORTHO, "1"),
+ new /datum/paint_info/decal(DIR_ORTHO, "2"),
+ new /datum/paint_info/decal(DIR_ORTHO, "3"),
+ new /datum/paint_info/decal(DIR_ORTHO, "4"),
+ new /datum/paint_info/decal(DIR_ORTHO, "5"),
+ new /datum/paint_info/decal(DIR_ORTHO, "6"),
+ new /datum/paint_info/decal(DIR_ORTHO, "7"),
+ new /datum/paint_info/decal(DIR_ORTHO, "8"),
+ new /datum/paint_info/decal(DIR_ORTHO, "9"),
+ new /datum/paint_info/decal(DIR_ORTHO, "0"),
+
+ // Path markers
+ new /datum/paint_info/decal(DIR_ORTHO, "1"),
+ new /datum/paint_info/decal(DIR_ORTHO, "1"),
+ new /datum/paint_info/decal(DIR_ORTHO, "1"),
+ new /datum/paint_info/decal(DIR_ORTHO, "1"),
+ ),
+ "Gray" = list(
+ new /datum/paint_info(DIR_ONE, "floor"),
+ new /datum/paint_info(DIR_ALL, "black"),
+ new /datum/paint_info(DIR_ORTHO, "blackcorner")
+ ),
+
+ "Neutral" = list(
+ new /datum/paint_info(DIR_ALL, "neutral"),
+ new /datum/paint_info(DIR_ORTHO, "neutralcorner"),
+ new /datum/paint_info(DIR_ONE, "neutralfull")
+ ),
+
+ "White" = list(
+ new /datum/paint_info(DIR_ONE, "white"),
+ new /datum/paint_info(DIR_ALL, "whitehall"),
+ new /datum/paint_info(DIR_ORTHO, "whitecorner")
+ ),
+
+ "Red" = list(
+ new /datum/paint_info(DIR_ONE, "redfull"),
+ new /datum/paint_info(DIR_ALL, "red"),
+ new /datum/paint_info(DIR_ORTHO, "redcorner")
+ ),
+
+ "Green" = list(
+ new /datum/paint_info(DIR_ONE, "greenfull"),
+ new /datum/paint_info(DIR_ALL, "green"),
+ new /datum/paint_info(DIR_ORTHO, "greencorner")
+ ),
+
+ "Blue" = list(
+ new /datum/paint_info(DIR_ONE, "bluefull"),
+ new /datum/paint_info(DIR_ALL, "blue"),
+ new /datum/paint_info(DIR_ORTHO, "bluecorner")
+ ),
+
+ "Yellow" = list(
+ new /datum/paint_info(DIR_ONE, "yellowfull"),
+ new /datum/paint_info(DIR_ALL, "yellow"),
+ new /datum/paint_info(DIR_ORTHO, "yellowcorner")
+ ),
+
+ "Purple" = list(
+ new /datum/paint_info(DIR_ONE, "purplefull"),
+ new /datum/paint_info(DIR_ALL, "purple"),
+ new /datum/paint_info(DIR_ORTHO, "purplecorner")
+ ),
+
+ "Orange" = list(
+ new /datum/paint_info(DIR_ONE, "orangefull"),
+ new /datum/paint_info(DIR_ALL, "orange"),
+ new /datum/paint_info(DIR_ORTHO, "orangecorner")
+ ),
+
+ "Brown" = list(
+ new /datum/paint_info(DIR_ONE, "dark brown full"),
+ new /datum/paint_info(DIR_ALL, "brown"),
+ new /datum/paint_info(DIR_ORTHO, "browncorner")
+ ),
+
+ "Red and yellow" = list(
+ new /datum/paint_info(DIR_ONE, "redyellowfull"),
+ new /datum/paint_info(DIR_ALL, "redyellow")
+ ),
+
+ "Red and blue" = list(
+ new /datum/paint_info(DIR_ONE, "redbluefull"),
+ new /datum/paint_info(DIR_ALL, "redblue")
+ ),
+
+ "Red and green" = list(
+ new /datum/paint_info(DIR_ONE, "redgreenfull"),
+ new /datum/paint_info(DIR_ALL, "redgreen")
+ ),
+
+ "Green and yellow" = list(
+ new /datum/paint_info(DIR_ONE, "greenyellowfull"),
+ new /datum/paint_info(DIR_ALL, "greenyellow")
+ ),
+
+ "Green and blue" = list(
+ new /datum/paint_info(DIR_ONE, "greenbluefull"),
+ new /datum/paint_info(DIR_ALL, "greenblue")
+ ),
+
+ "Blue and yellow" = list(
+ new /datum/paint_info(DIR_ONE, "blueyellowfull"),
+ new /datum/paint_info(DIR_ALL, "blueyellow")
+ ),
+
+ "White red" = list(
+ new /datum/paint_info(DIR_ONE, "whiteredfull"),
+ new /datum/paint_info(DIR_ALL, "whitered"),
+ new /datum/paint_info(DIR_ORTHO, "whiteredcorner")
+ ),
+
+ "White green" = list(
+ new /datum/paint_info(DIR_ONE, "whitegreenfull"),
+ new /datum/paint_info(DIR_ALL, "whitegreen"),
+ new /datum/paint_info(DIR_ORTHO, "whitegreencorner")
+ ),
+
+ "White blue" = list(
+ new /datum/paint_info(DIR_ONE, "whitebluefull"),
+ new /datum/paint_info(DIR_ALL, "whiteblue"),
+ new /datum/paint_info(DIR_ORTHO, "whitebluecorner"),
+ new /datum/paint_info(DIR_ONE, "cmo")
+ ),
+
+ "White yellow" = list(
+ new /datum/paint_info(DIR_ONE, "whiteyellowfull"),
+ new /datum/paint_info(DIR_ALL, "whiteyellow"),
+ new /datum/paint_info(DIR_ORTHO, "whiteyellowcorner")
+ ),
+
+ "White purple" = list(
+ new /datum/paint_info(DIR_ONE, "whitepurplefull"),
+ new /datum/paint_info(DIR_ALL, "whitepurple"),
+ new /datum/paint_info(DIR_ORTHO, "whitepurplecorner")
+ ),
+
+ "Arrival" = list(
+ new /datum/paint_info(DIR_ALL, "arrival")
+ ),
+
+ "Escape" = list(
+ new /datum/paint_info(DIR_ALL, "escape")
+ ),
+
+ "Dark" = list(
+ new /datum/paint_info(DIR_ONE, "dark"),
+ new /datum/paint_info(DIR_ALL, "dark floor stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark floor corner")
+ ),
+
+ "Dark red" = list(
+ new /datum/paint_info(DIR_ONE, "dark red full"),
+ new /datum/paint_info(DIR_ALL, "dark red stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark red corner")
+ ),
+
+ "Dark blue" = list(
+ new /datum/paint_info(DIR_ONE, "dark blue full"),
+ new /datum/paint_info(DIR_ALL, "dark blue stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark blue corner")
+ ),
+
+ "Dark green" = list(
+ new /datum/paint_info(DIR_ONE, "dark green full"),
+ new /datum/paint_info(DIR_ALL, "dark green stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark green corner")
+ ),
+
+ "Dark purple" = list(
+ new /datum/paint_info(DIR_ONE, "dark purple full"),
+ new /datum/paint_info(DIR_ALL, "dark purple stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark purple corner")
+ ),
+
+ "Dark yellow" = list(
+ new /datum/paint_info(DIR_ONE, "dark yellow full"),
+ new /datum/paint_info(DIR_ALL, "dark yellow stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark yellow corner")
+ ),
+
+ "Dark orange" = list(
+ new /datum/paint_info(DIR_ONE, "dark orange full"),
+ new /datum/paint_info(DIR_ALL, "dark orange stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark orange corner")
+ ),
+
+ "Dark vault" = list(
+ new /datum/paint_info(DIR_ONE, "dark vault full"),
+ new /datum/paint_info(DIR_ALL, "dark vault stripe"),
+ new /datum/paint_info(DIR_ORTHO, "dark vault corner"),
+ new /datum/paint_info(DIR_ORTHO, "dark-markings")
+ ),
+
+ "Markings" = list(
+ new /datum/paint_info(DIR_ONE, "delivery"),
+ new /datum/paint_info(DIR_ONE, "bot"),
+ new /datum/paint_info(DIR_ONE, "whitedelivery"),
+ new /datum/paint_info(DIR_ONE, "whitebot"),
+ new /datum/paint_info(DIR_ONE, "enginedelivery", PAINT_REINFORCED),
+ new /datum/paint_info(DIR_ONE, "enginebot", PAINT_REINFORCED),
+ new /datum/paint_info(DIR_ONE, "plaque")
+ ),
+
+ "Loading area" = list(
+ new /datum/paint_info(DIR_ORTHO, "loadingarea"),
+ new /datum/paint_info(DIR_ORTHO, "engineloadingarea", PAINT_REINFORCED),
+ new /datum/paint_info(DIR_ORTHO, "dark loading")
+ ),
+
+ "Warning" = list(
+ new /datum/paint_info(DIR_ALL, "warning"),
+ new /datum/paint_info(DIR_ORTHO, "warningcorner")
+ ),
+
+ "White warning" = list(
+ new /datum/paint_info(DIR_ALL, "warnwhite"),
+ new /datum/paint_info(DIR_ORTHO, "warnwhitecorner")
+ ),
+
+ "Reinforced warning" = list(
+ new /datum/paint_info(DIR_ALL, "enginewarn", PAINT_REINFORCED),
+ new /datum/paint_info(DIR_ORTHO, "enginewarncorner", PAINT_REINFORCED)
+ ),
+
+ "Plating warning" = list(
+ new /datum/paint_info(DIR_ALL, "warnplate", PAINT_PLATING),
+ new /datum/paint_info(DIR_ORTHO, "warnplatecorner", PAINT_PLATING)
+ ),
+
+ "Chapel" = list(
+ new /datum/paint_info(DIR_ALL, "chapel")
+ ),
+
+ "SS13 logo" = list(
+ new /datum/paint_info(DIR_ONE, "L1"),
+ new /datum/paint_info(DIR_ONE, "L3"),
+ new /datum/paint_info(DIR_ONE, "L5"),
+ new /datum/paint_info(DIR_ONE, "L7"),
+ new /datum/paint_info(DIR_ONE, "L9"),
+ new /datum/paint_info(DIR_ONE, "L11"),
+ new /datum/paint_info(DIR_ONE, "L13"),
+ new /datum/paint_info(DIR_ONE, "L15"),
+ new /datum/paint_info(DIR_ONE, "L2"),
+ new /datum/paint_info(DIR_ONE, "L4"),
+ new /datum/paint_info(DIR_ONE, "L6"),
+ new /datum/paint_info(DIR_ONE, "L8"),
+ new /datum/paint_info(DIR_ONE, "L10"),
+ new /datum/paint_info(DIR_ONE, "L12"),
+ new /datum/paint_info(DIR_ONE, "L14"),
+ new /datum/paint_info(DIR_ONE, "L16")
+ ),
+
+ "Derelict logo" = list(
+ new /datum/paint_info(DIR_ONE, "derelict9"),
+ new /datum/paint_info(DIR_ONE, "derelict10"),
+ new /datum/paint_info(DIR_ONE, "derelict11"),
+ new /datum/paint_info(DIR_ONE, "derelict12"),
+ new /datum/paint_info(DIR_ONE, "derelict13"),
+ new /datum/paint_info(DIR_ONE, "derelict14"),
+ new /datum/paint_info(DIR_ONE, "derelict15"),
+ new /datum/paint_info(DIR_ONE, "derelict16"),
+ new /datum/paint_info(DIR_ONE, "derelict1"),
+ new /datum/paint_info(DIR_ONE, "derelict2"),
+ new /datum/paint_info(DIR_ONE, "derelict3"),
+ new /datum/paint_info(DIR_ONE, "derelict4"),
+ new /datum/paint_info(DIR_ONE, "derelict5"),
+ new /datum/paint_info(DIR_ONE, "derelict6"),
+ new /datum/paint_info(DIR_ONE, "derelict7"),
+ new /datum/paint_info(DIR_ONE, "derelict8")
+ ),
+
+ "Other" = list(
+ new /datum/paint_info(DIR_ONE, "dark"),
+ new /datum/paint_info(DIR_ONE, "bar"),
+ new /datum/paint_info(DIR_ONE, "cafeteria"),
+ new /datum/paint_info(DIR_ONE, "checker"),
+ new /datum/paint_info(DIR_ONE, "barber"),
+ new /datum/paint_info(DIR_ONE, "grimy"),
+ new /datum/paint_info(DIR_ONE, "hydrofloor"),
+ new /datum/paint_info(DIR_ONE, "showroomfloor"),
+ new /datum/paint_info(DIR_ONE, "freezerfloor"),
+ new /datum/paint_info(DIR_ONE, "bcircuit"),
+ new /datum/paint_info(DIR_ONE, "gcircuit"),
+ new /datum/paint_info(DIR_ONE, "solarpanel")
+ )
+)
diff --git a/code/modules/RCD/tile painter.dm b/code/modules/RCD/tile painter.dm
new file mode 100644
index 00000000000..7e6bcdc3ac7
--- /dev/null
+++ b/code/modules/RCD/tile painter.dm
@@ -0,0 +1,15 @@
+/obj/item/device/rcd/tile_painter
+ name = "tile painter"
+ desc = "A device used to paint floors in various colours and fashions."
+
+ icon_state = "rpd" //placeholder art, someone please sprite it
+
+ starting_materials = list(MAT_IRON = 75000, MAT_GLASS = 37500)
+
+ origin_tech = "engineering=2;materials=1"
+
+ sparky = 0
+
+/obj/item/device/rcd/tile_painter/New()
+ schematics = typesof(/datum/rcd_schematic/tile) //For some stupid reason typesof() isn't constant.
+ . = ..()
diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm
index 2e84b6f772b..e36bcf6a8f3 100644
--- a/code/modules/clothing/spacesuits/alien.dm
+++ b/code/modules/clothing/spacesuits/alien.dm
@@ -14,7 +14,7 @@
/obj/item/clothing/suit/space/unathi
armor = list(melee = 40, bullet = 30, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 50)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/device/rcd)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
species_restricted = list("Unathi")
diff --git a/code/modules/clothing/spacesuits/ert.dm b/code/modules/clothing/spacesuits/ert.dm
index 169c2063c67..5653df4b72a 100644
--- a/code/modules/clothing/spacesuits/ert.dm
+++ b/code/modules/clothing/spacesuits/ert.dm
@@ -38,7 +38,7 @@
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 60)
flags = FPRINT | PLASMAGUARD
pressure_resistance = 200 * ONE_ATMOSPHERE
- allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/weapon/rcd, /obj/item/weapon/crowbar, \
+ allowed = list(/obj/item/device/flashlight, /obj/item/weapon/tank, /obj/item/device/t_scanner, /obj/item/device/rcd, /obj/item/weapon/crowbar, \
/obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool, /obj/item/weapon/wirecutters, /obj/item/weapon/wrench, /obj/item/device/multitool, \
/obj/item/device/radio, /obj/item/device/analyzer, /obj/item/weapon/gun/energy/laser, /obj/item/weapon/gun/energy/pulse_rifle, \
/obj/item/weapon/gun/energy/taser, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/gun)
diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm
index 921325afd27..48d8b7d837f 100644
--- a/code/modules/clothing/spacesuits/rig.dm
+++ b/code/modules/clothing/spacesuits/rig.dm
@@ -83,7 +83,7 @@
slowdown = 1
species_restricted = list("exclude","Vox")
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd, /obj/item/weapon/wrench/socket)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/device/rcd, /obj/item/weapon/wrench/socket)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
pressure_resistance = 200 * ONE_ATMOSPHERE
@@ -294,7 +294,7 @@
item_state = "atmos_gold_hardsuit"
slowdown = 2
armor = list(melee = 30, bullet = 5, laser = 40,energy = 5, bomb = 35, bio = 100, rad = 60)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/backpack/satchel_norm,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd, /obj/item/weapon/extinguisher, /obj/item/weapon/)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/backpack/satchel_norm,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/device/rcd, /obj/item/weapon/extinguisher, /obj/item/weapon/)
//ADMINBUS RIGS. SOVIET + NAZI
/obj/item/clothing/head/helmet/space/rig/nazi
@@ -436,4 +436,4 @@
icon_state = "rig0-t51b"
item_state = "rig0-t51b"
armor = list(melee = 35, bullet = 35, laser = 40, energy = 40, bomb = 80, bio = 100, rad = 100)
- _color="t51b"
+ _color="t51b"
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 947118c67fe..6465f5fe275 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -393,7 +393,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/item/device/radio/headset/syndicate, /obj/item/weapon/plastique,\
/obj/item/device/powersink, /obj/item/weapon/storage/box/syndie_kit,\
/obj/item/toy/syndicateballoon, /obj/item/weapon/gun/energy/laser/captain,\
- /obj/item/weapon/hand_tele, /obj/item/weapon/rcd, /obj/item/weapon/tank/jetpack,\
+ /obj/item/weapon/hand_tele, /obj/item/device/rcd, /obj/item/weapon/tank/jetpack,\
/obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\
/obj/item/clothing/shoes/magboots, /obj/item/blueprints, /obj/item/weapon/disk/nuclear,\
/obj/item/clothing/suit/space/nasavoid, /obj/item/weapon/tank)
diff --git a/code/modules/html_interface/RCD/RCD.css b/code/modules/html_interface/RCD/RCD.css
new file mode 100644
index 00000000000..045ec0cad97
--- /dev/null
+++ b/code/modules/html_interface/RCD/RCD.css
@@ -0,0 +1,28 @@
+/*Made by N3X15*/
+
+html {
+ font-family:sans-serif;
+ font-size:small;
+}
+a{
+ color:#0066cc;
+ text-decoration:none;
+}
+
+a img {
+ border:1px solid #0066cc;
+ background:#dfdfdf;
+}
+
+a.color {
+ padding: 5px 10px;
+ font-size: large;
+ font-weight: bold;
+ border:1px solid white;
+}
+
+a.selected img,
+a:hover {
+ background: #0066cc;
+ color: #ffffff;
+}
diff --git a/code/modules/html_interface/RCD/RCD.dm b/code/modules/html_interface/RCD/RCD.dm
new file mode 100644
index 00000000000..ceedd82d136
--- /dev/null
+++ b/code/modules/html_interface/RCD/RCD.dm
@@ -0,0 +1,21 @@
+/*
+ RCD UI style.
+ N3X15 wrote the stylesheet (originally RPD stylesheet)
+ Made into a htmli datum by PJB3005
+*/
+
+/datum/html_interface/rcd
+ default_html_file = 'html_interface_no_bootstrap.html'
+
+/datum/html_interface/rcd/New()
+ . = ..()
+ head += ""
+
+/datum/html_interface/rcd/sendResources(var/client/client)
+ . = ..()
+ client << browse_rsc('RCD.css')
+
+ //Send the icons.
+ for(var/path in typesof(/datum/rcd_schematic) - /datum/rcd_schematic)
+ var/datum/rcd_schematic/C = new path()
+ C.send_icons(client)
diff --git a/code/modules/html_interface/RCD/html_interface_no_bootstrap.html b/code/modules/html_interface/RCD/html_interface_no_bootstrap.html
new file mode 100644
index 00000000000..5ddb00eef6a
--- /dev/null
+++ b/code/modules/html_interface/RCD/html_interface_no_bootstrap.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/modules/html_interface/html_interface.dm b/code/modules/html_interface/html_interface.dm
index e28fe0fb356..9baafb7cf27 100644
--- a/code/modules/html_interface/html_interface.dm
+++ b/code/modules/html_interface/html_interface.dm
@@ -105,6 +105,9 @@ mob/verb/test()
// The initial height of the browser control, used when the window is first shown to a client.
var/height
+ // File which the HTML is copied from onto the browser window on the client.
+ var/default_html_file = 'html_interface.html'
+
/datum/html_interface/New(atom/ref, title, width = 700, height = 480, head = "")
html_interfaces.Add(src)
@@ -232,7 +235,7 @@ mob/verb/test()
else
src.createWindow(hclient)
hclient.is_loaded = FALSE
- hclient.client << output(replacetextEx(replacetextEx(file2text('html_interface.html'), "\[hsrc\]", "\ref[src]"), "", "[head]"), "browser_\ref[src].browser")
+ hclient.client << output(replacetextEx(replacetextEx(file2text(default_html_file), "\[hsrc\]", "\ref[src]"), "", "[head]"), "browser_\ref[src].browser")
winshow(hclient.client, "browser_\ref[src]", TRUE)
if(oldwindow && winexists(hclient.client, "browser_\ref[oldwindow]"))
winshow(hclient.client, "browser_\ref[oldwindow]", FALSE)
diff --git a/code/modules/maps/spawners/spawners.dm b/code/modules/maps/spawners/spawners.dm
index f6b641332db..107d00c2b9d 100644
--- a/code/modules/maps/spawners/spawners.dm
+++ b/code/modules/maps/spawners/spawners.dm
@@ -666,10 +666,10 @@
/obj/item/weapon/grenade/chem_grenade/antiweed,
/obj/item/weapon/hatchet,
/obj/item/weapon/pickaxe/jackhammer,
- /obj/item/weapon/pipe_dispenser,
- /obj/item/weapon/rcd,
+ /obj/item/device/rcd/rpd,
+ /obj/item/device/rcd,
/obj/item/weapon/rcd_ammo,
- /obj/item/weapon/rsf,
+ /obj/item/device/rcd/matter/rsf,
/obj/item/weapon/weldingtool/hugetank,
/obj/item/weapon/tank/plasma,
/obj/item/gun_part/silencer,
diff --git a/code/modules/mob/living/silicon/mommi/mommi_modules.dm b/code/modules/mob/living/silicon/mommi/mommi_modules.dm
index 8740fe94dd1..7dae0cce50c 100644
--- a/code/modules/mob/living/silicon/mommi/mommi_modules.dm
+++ b/code/modules/mob/living/silicon/mommi/mommi_modules.dm
@@ -23,8 +23,8 @@
src.modules += new /obj/item/device/analyzer(src)
src.modules += new /obj/item/weapon/extinguisher(src) // Aurx sed so
src.modules += new /obj/item/weapon/extinguisher/foam(src)
- src.modules += new /obj/item/weapon/pipe_dispenser(src)
- src.modules += new /obj/item/weapon/tile_painter(src)
+ src.modules += new /obj/item/device/rcd/rpd(src)
+ src.modules += new /obj/item/device/rcd/tile_painter(src)
src.modules += new /obj/item/blueprints/mommiprints(src)
src.modules += new /obj/item/device/material_synth/robot/mommi(src)
sensor_augs = list("Mesons", "Disable")
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 52360aa746d..0efd123ae09 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -189,8 +189,8 @@
/obj/item/weapon/robot_module/engineering/New()
..()
src.emag = new /obj/item/borg/stun(src)
- src.modules += new /obj/item/weapon/rcd/borg(src)
- src.modules += new /obj/item/weapon/pipe_dispenser(src) //What could possibly go wrong?
+ src.modules += new /obj/item/device/rcd/borg/engineering(src)
+ src.modules += new /obj/item/device/rcd/rpd(src) //What could possibly go wrong?
src.modules += new /obj/item/weapon/extinguisher(src)
src.modules += new /obj/item/weapon/extinguisher/foam(src)
src.modules += new /obj/item/weapon/weldingtool/largetank(src)
@@ -203,7 +203,7 @@
src.modules += new /obj/item/device/analyzer(src)
src.modules += new /obj/item/taperoll/atmos(src)
src.modules += new /obj/item/taperoll/engineering(src)
- src.modules += new /obj/item/weapon/tile_painter(src)
+ src.modules += new /obj/item/device/rcd/tile_painter(src)
src.modules += new /obj/item/device/material_synth/robot(src)
sensor_augs = list("Mesons", "Disable")
@@ -315,7 +315,7 @@
src.modules += new /obj/item/weapon/reagent_containers/food/condiment/enzyme(src)
src.modules += new /obj/item/weapon/pen/robopen(src)
- src.modules += new /obj/item/weapon/rsf/cyborg(src)
+ src.modules += new /obj/item/device/rcd/borg/rsf(src)
src.modules += new /obj/item/weapon/reagent_containers/robodropper(src)
diff --git a/code/setup.dm b/code/setup.dm
index f3c750daf2d..43362410c0a 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -1213,6 +1213,12 @@ var/proccalls = 1
#define COREFIRERESIST 1
#define HIGHRESCAMS 2
+//RCD schematic bitflags.
+#define RCD_SELF_SANE 1 //Check proximity ourselves.
+#define RCD_GET_TURF 2 //If used on objs/mobs, get the turf instead.
+#define RCD_RANGE 4 //Use range() instead of adjacency. (old RPD behaviour.) (overriden by RCD_SELF_SANE)
+#define RCD_SELF_COST 8 //Handle energy usage ourselves. (energy availability still checked).
+
//Mob sizes
#define SIZE_TINY 1 //Mice, lizards, borers, kittens - mostly things that can fit into a man's palm
#define SIZE_SMALL 2 //Monkeys, dionae, cats, dogs
diff --git a/html/changelogs/PJB3005-RCD.yml b/html/changelogs/PJB3005-RCD.yml
new file mode 100644
index 00000000000..924f469f550
--- /dev/null
+++ b/html/changelogs/PJB3005-RCD.yml
@@ -0,0 +1,9 @@
+author: PJB3005
+delete-after: true
+changes:
+ - tweak: Rewrites RCD/RPD/RSF/tile painter code into one to be more moduler & simpler.
+ - tweak: RCD, RSF & tile painter now have an RPD-like UI.
+ - tweak: Setting airlock colour on the RCD is now done through the UI instead of a verb.
+ - tweak: UIs of the RPD and tile painter are now MASSIVELY more responsive.
+ - tweak: The RCD can now make airlocks with custom names and access levels (latter is disabled for engie borgs).
+ - tweak: You can paint ALL insulated pipes now! (colours other than white available)
\ No newline at end of file
diff --git a/icons/obj/RCD.dmi b/icons/obj/RCD.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..47d4d60b25ea0e0820569cfe58937568891269da
GIT binary patch
literal 928
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≥k}5!f0)
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