diff --git a/code/__defines/misc_ch.dm b/code/__defines/misc_ch.dm
index dde3d325f4..759589f5d5 100644
--- a/code/__defines/misc_ch.dm
+++ b/code/__defines/misc_ch.dm
@@ -15,4 +15,10 @@
#define MAT_CARPET_PURPLE "purple carpet"
#define MAT_CARPET_ORANGE "orange carpet"
-#define PHASE_SHIELDED 16 // Prevents shadekin phasing in/out in this area
\ No newline at end of file
+#define PHASE_SHIELDED 16 // Prevents shadekin phasing in/out in this area
+
+#define RCD_FIRELOCK "Firelock" // Builds an emergency glass shutter
+#define RCD_WINDOOR "Windoor" // Build a window door
+#define RCD_FRAME "Frame" // Build a Machine or Computer frame
+#define RCD_WALLFRAME "WallFrame" // Build a selection of wall frames
+#define RCD_CONVEYOR "Conveyor" // Build direction conveyors
\ No newline at end of file
diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm
index fa568b8614..ac85972cef 100644
--- a/code/_onclick/hud/radial.dm
+++ b/code/_onclick/hud/radial.dm
@@ -261,6 +261,8 @@ GLOBAL_LIST_EMPTY(radial_menus)
current_user = M.client
//Blank
menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = LAYER_HUD_ABOVE)
+ menu_holder.plane = PLANE_PLAYER_HUD_ABOVE //CHOMPEdit - fixed plane
+ menu_holder.appearance_flags |= RESET_TRANSFORM //CHOMPEdit - fix radial scaling improperly based on mob size
menu_holder.appearance_flags |= KEEP_APART
menu_holder.vis_contents += elements + close_button
current_user.images += menu_holder
diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm
index 3af4562f09..42dcb9c6d0 100644
--- a/code/game/machinery/computer/camera.dm
+++ b/code/game/machinery/computer/camera.dm
@@ -134,8 +134,13 @@ GLOBAL_LIST_EMPTY(entertainment_screens)
if(isliving(usr) && Adjacent(usr) && !usr.incapacitated())
toggle()
visible_message("[usr] toggles [src] [enabled ? "on" : "off"].","You toggle [src] [enabled ? "on" : "off"].", runemessage = "click")
- else
+ //CHOMPEdit start - Changing click to only come into play when shift or alt clicking. These things are ANNOYING.
+ return
+ if(modifiers["shift"])
attack_hand(usr)
+ return
+ ..()
+ //CHOMPEdit end
/obj/machinery/computer/security/telescreen/entertainment/update_icon()
return // NUH
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index c26fee47ff..76e2d122be 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -13,10 +13,10 @@
power_channel = ENVIRON
explosion_resistance = 10
-
+
// Doors do their own stuff
bullet_vulnerability = 0
-
+
blocks_emissive = EMISSIVE_BLOCK_GENERIC // Not quite as nice as /tg/'s custom masks. We should make those sometime
var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
@@ -1004,7 +1004,7 @@ About the new airlock wires panel:
/* // CHOMPEDIT: disabling becaue alt-clicking to view a turf is pretty important.
/obj/machinery/door/airlock/AltClick(mob/user as mob)
-
+
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(!Adjacent(user))
return
@@ -1563,7 +1563,7 @@ About the new airlock wires panel:
src.lock()
return
-
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
switch(passed_mode)
if(RCD_DECONSTRUCT)
@@ -1583,3 +1583,4 @@ About the new airlock wires panel:
qdel(src)
return TRUE
return FALSE
+*/
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 08c2ba35d7..e89512d4da 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -31,7 +31,7 @@
var/make_rwalls = FALSE // If true, when building walls, they will be reinforced.
/* VOREStation Removal - Unused
/obj/item/weapon/rcd/Initialize()
-
+
src.spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -103,6 +103,10 @@
return FALSE
var/list/rcd_results = A.rcd_values(user, src, modes[mode_index])
+ //CHOMPEdit start
+ if(rcd_results == 1)
+ return FALSE
+ //CHOMPEdit end
if(!rcd_results)
to_chat(user, span("warning", "\The [src] blinks a red light as you point it towards \the [A], indicating \
that it won't work. Try changing the mode, or use it on something else."))
diff --git a/code/game/objects/items/weapons/RCD_vr.dm b/code/game/objects/items/weapons/RCD_vr.dm
index 48f380f1ae..7bd6a99c66 100644
--- a/code/game/objects/items/weapons/RCD_vr.dm
+++ b/code/game/objects/items/weapons/RCD_vr.dm
@@ -64,6 +64,7 @@
qdel(effects[A])
effects -= A
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
var/obj/item/weapon/rcd_ammo/cartridge = W
@@ -82,6 +83,7 @@
update_icon()
return TRUE
return ..()
+*/
/obj/item/weapon/rcd/proc/check_menu(mob/living/user)
if(!istype(user))
@@ -106,6 +108,7 @@
return TRUE
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/item/weapon/rcd/attack_self(mob/living/user)
..()
var/list/choices = list(
@@ -170,6 +173,7 @@
return
playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
to_chat(user, "You change RCD's mode to '[choice]'.")
+*/
//////////////////
/obj/item/weapon/rcd/electric/update_icon()
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index df9886cbb6..53aea7bc30 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -73,6 +73,8 @@
/obj/item/weapon/extinguisher/mini,
/obj/item/weapon/tape_roll,
/obj/item/device/integrated_electronics/wirer,
+ /obj/item/weapon/pipe_dispenser, //CHOMPAdd
+ /obj/item/weapon/holosign_creator/combifan, //CHOMPAdd
/obj/item/device/integrated_electronics/debugger, //Vorestation edit adding debugger to toolbelt can hold list
/obj/item/weapon/shovel/spade, //VOREStation edit. If it can hold minihoes and hatchers, why not the gardening spade?
/obj/item/stack/nanopaste, //VOREStation edit. Think of it as a tube of superglue. Belts hold that all the time.
@@ -479,6 +481,7 @@
/obj/item/taperoll,
/obj/item/weapon/reagent_containers/spray,
/obj/item/weapon/soap,
+ /obj/item/weapon/holosign_creator, //CHOMPAdd
/obj/item/device/lightreplacer //VOREStation edit
)
diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
index 0492608962..2a3fe1c8b1 100644
--- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm
@@ -81,6 +81,7 @@
/obj/item/weapon/storage/bag/trash,
/obj/item/weapon/storage/belt/janitor,
/obj/item/device/vac_attachment, //CHOMPAdd
+ /obj/item/weapon/holosign_creator, //CHOMPAdd
/obj/item/clothing/shoes/galoshes
)
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 b772ce52e3..ca45f2d754 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -37,6 +37,7 @@
/obj/item/clothing/head/beret/engineering/ce/white,
/obj/item/weapon/tank/emergency/oxygen/double, //VOREStation Edit: chief gets the good shit
/obj/item/weapon/reagent_containers/spray/windowsealant, //VOREStation Add,
+ /obj/item/weapon/rcd/advanced/loaded, //CHOMPAdd
/obj/item/weapon/pipe_dispenser) //YW Add
/obj/structure/closet/secure_closet/engineering_chief/Initialize()
@@ -138,6 +139,7 @@
/obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos,
/obj/item/clothing/shoes/boots/winter/atmos,
/obj/item/weapon/tank/emergency/oxygen/engi,
+ /obj/item/weapon/holosign_creator/combifan, //CHOMPAdd
/obj/item/weapon/storage/belt/utility/atmostech) //VOREStation edit. They don't get a toolbox to fill it from, so why not give a spare one that's full already?
/obj/structure/closet/secure_closet/atmos_personal/Initialize()
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index b18feb7f88..ee471b9f00 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -365,6 +365,7 @@
cover = 60
girder_material = "resin"
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/structure/girder/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
var/turf/simulated/T = get_turf(src)
if(!istype(T) || T.density)
@@ -413,6 +414,7 @@
to_chat(user, span("notice", "You deconstruct \the [src]."))
qdel(src)
return TRUE
+*/
/obj/structure/girder/bay
wall_type = /turf/simulated/wall/bay
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index c7e1e2efed..0f23bec24c 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -248,7 +248,7 @@
/obj/structure/grille/broken/rustic
icon_state = "grillerustic-b"
-
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/structure/grille/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
switch(passed_mode)
if(RCD_WINDOWGRILLE)
@@ -281,6 +281,7 @@
WD.anchored = TRUE
return TRUE
return FALSE
+*/
/obj/structure/grille/take_damage(var/damage)
health -= damage
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 35e7a339af..d953cc7dd9 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -686,6 +686,7 @@
return TRUE
. = ..()
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/obj/structure/window/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
switch(passed_mode)
if(RCD_DECONSTRUCT)
@@ -702,3 +703,4 @@
qdel(src)
return TRUE
return FALSE
+*/
\ No newline at end of file
diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm
index da2f4d3fbf..8e1dd1841e 100644
--- a/code/game/turfs/simulated/floor.dm
+++ b/code/game/turfs/simulated/floor.dm
@@ -112,6 +112,7 @@
/turf/simulated/floor/can_engrave()
return (!flooring || flooring.can_engrave)
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/turf/simulated/floor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
switch(passed_mode)
if(RCD_FLOORWALL)
@@ -179,10 +180,10 @@
to_chat(user, span("notice", "You deconstruct \the [src]."))
ChangeTurf(get_base_turf_by_area(src), preserve_outdoors = TRUE)
return TRUE
-
+*/
/turf/simulated/floor/AltClick(mob/user)
if(isliving(user))
var/mob/living/livingUser = user
if(try_graffiti(livingUser, livingUser.get_active_hand()))
return
- . = ..()
+ . = ..()
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 0c34354acc..a9cdb34ca8 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -309,6 +309,7 @@
/turf/simulated/wall/can_engrave()
return (material && material.hardness >= 10 && material.hardness <= 100)
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
/turf/simulated/wall/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
if(material.integrity > 1000) // Don't decon things like elevatorium.
return FALSE
@@ -332,6 +333,7 @@
ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE)
return TRUE
return FALSE
+*/
/turf/simulated/wall/AltClick(mob/user)
if(isliving(user))
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 15a8dd0c32..90c9cddfe9 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -44,7 +44,7 @@
//Lighting related
set_luminosity(!(dynamic_lighting))
-
+
if(opacity)
directional_opacity = ALL_CARDINALS
@@ -377,6 +377,7 @@
UNSETEMPTY(dangerous_objects) // This nulls the list var if it's empty.
// color = "#00FF00"
+/* CHOMPEdit - moved this block to modular_chomp\code\game\objects\items\weapons\rcd.dm
// This is all the way up here since its the common ancestor for things that need to get replaced with a floor when an RCD is used on them.
// More specialized turfs like walls should instead override this.
// The code for applying lattices/floor tiles onto lattices could also utilize something similar in the future.
@@ -401,7 +402,7 @@
ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE)
return TRUE
return FALSE
-
+*/
// We're about to be the A-side in a turf translation
/turf/proc/pre_translate_A(var/turf/B)
diff --git a/code/modules/mining/shelter_atoms_vr.dm b/code/modules/mining/shelter_atoms_vr.dm
index 433ab5f342..7159859672 100644
--- a/code/modules/mining/shelter_atoms_vr.dm
+++ b/code/modules/mining/shelter_atoms_vr.dm
@@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(unique_deployable)
template_id = "shelter_epsilon"
unique_id = "shelter_5"
is_ship = TRUE
-
+
/obj/item/device/survivalcapsule/popcabin
name = "pop-out cabin shelter capsule"
desc = "A cozy cabin; crammed into a survival capsule."
@@ -295,6 +295,15 @@ GLOBAL_LIST_EMPTY(unique_deployable)
var/buildstacktype = /obj/item/stack/material/steel
var/buildstackamount = 5
+//CHOMPAdd start - fans weren't updating atmos when destroyed or placed
+/obj/structure/fans/Destroy()
+ update_nearby_tiles()
+ return ..()
+
+/obj/structure/fans/Initialize(mapload)
+ .=..()
+ update_nearby_tiles()
+//CHOMPAdd end
/*
/obj/structure/fans/proc/deconstruct()
new buildstacktype(loc,buildstackamount)
diff --git a/icons/effects/effects_ch.dmi b/icons/effects/effects_ch.dmi
index 02beb51d3d..a87d305610 100644
Binary files a/icons/effects/effects_ch.dmi and b/icons/effects/effects_ch.dmi differ
diff --git a/modular_chomp/code/game/objects/items/holosign_creator.dm b/modular_chomp/code/game/objects/items/holosign_creator.dm
new file mode 100644
index 0000000000..77406bcc23
--- /dev/null
+++ b/modular_chomp/code/game/objects/items/holosign_creator.dm
@@ -0,0 +1,64 @@
+/obj/item/weapon/holosign_creator
+ name = "holographic sign projector"
+ desc = "A handy-dandy holographic projector that displays a janitorial sign."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "signmaker"
+ item_state = "electronic"
+ force = 0
+ w_class = 2
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 7
+ var/list/signs = list()
+ var/max_signs = 10
+ var/creation_time = 0 //time to create a holosign in deciseconds.
+ var/holosign_type = /obj/structure/holosign/wetsign
+ var/holocreator_busy = FALSE //to prevent placing multiple holo barriers at once
+
+/obj/item/weapon/holosign_creator/afterattack(atom/target, mob/user, clickchain_flags, list/params)
+ . = ..()
+ if(!check_allowed_items(target, 1))
+ return
+ var/turf/T = get_turf(target)
+ var/obj/structure/holosign/H = locate(holosign_type) in T
+ if(H)
+ to_chat(user, "You use [src] to deactivate [H].")
+ qdel(H)
+ else
+ if(!is_blocked_turf(T, TRUE)) //can't put holograms on a tile that has dense stuff
+ if(holocreator_busy)
+ to_chat(user, "[src] is busy creating a hologram.")
+ return
+ if(signs.len < max_signs)
+ playsound(src.loc, 'sound/machines/click.ogg', 20, 1)
+ if(creation_time)
+ holocreator_busy = TRUE
+ if(!do_after(user, creation_time, target = target))
+ holocreator_busy = FALSE
+ return
+ holocreator_busy = FALSE
+ if(signs.len >= max_signs)
+ return
+ if(is_blocked_turf(T, TRUE)) //don't try to sneak dense stuff on our tile during the wait.
+ return
+ H = new holosign_type(get_turf(target), src)
+ to_chat(user, "You create \a [H] with [src].")
+ else
+ to_chat(user, "[src] is projecting at max capacity!")
+
+/obj/item/weapon/holosign_creator/attack_self(mob/user)
+ . = ..()
+ if(.)
+ return
+ if(signs.len)
+ for(var/H in signs)
+ qdel(H)
+ to_chat(user, "You clear all active holograms.")
+
+/obj/item/weapon/holosign_creator/combifan
+ name = "ATMOS holo-combifan projector"
+ desc = "A holographic projector that creates holographic combi-fans that prevent changes in atmosphere and temperature conditions. Somehow."
+ icon_state = "signmaker_engi"
+ holosign_type = /obj/structure/holosign/barrier/combifan
+ creation_time = 0
+ max_signs = 3
\ No newline at end of file
diff --git a/modular_chomp/code/game/objects/items/weapons/RCD.dm b/modular_chomp/code/game/objects/items/weapons/RCD.dm
new file mode 100644
index 0000000000..ca02429546
--- /dev/null
+++ b/modular_chomp/code/game/objects/items/weapons/RCD.dm
@@ -0,0 +1,1375 @@
+/obj/item/weapon/rcd
+ allow_concurrent_building = 1
+ var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use
+ var/advanced_airlock_setting = 1 //Set to 1 if you want more paintjobs available
+ var/list/conf_access = null
+ var/use_one_access = 0 //If the airlock should require ALL or only ONE of the listed accesses.
+ var/girder_type = /obj/structure/girder
+ var/frame_type = /obj/structure/frame
+ var/wall_frame_type = /obj/machinery/alarm
+ var/window_dir = "FULL"
+ window_type = "rglass"
+ modes = list(RCD_FLOORWALL, RCD_AIRLOCK, RCD_WINDOWGRILLE, RCD_DECONSTRUCT, RCD_WINDOOR, RCD_FIRELOCK, RCD_FRAME, RCD_WALLFRAME, RCD_CONVEYOR)
+ var/static/image/radial_image_firelock = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "firelock")
+ var/static/image/radial_image_windoor = image(icon= 'modular_chomp/icons/mob/radial.dmi', icon_state = "windoor")
+ var/static/image/radial_image_frame = image(icon = 'icons/mob/radial.dmi', icon_state = "machine")
+ var/static/image/radial_image_wallframe = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wallframe")
+ var/static/image/radial_image_access = image(icon = 'icons/mob/radial.dmi', icon_state = "access")
+ var/static/image/radial_image_airlock_type = image(icon = 'icons/mob/radial.dmi', icon_state = "airlocktype")
+ var/static/image/radial_image_conveyor = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "conveyor")
+/*
+Material values
+plasteel = 12
+steel = 3.99
+tile = 0.99
+rod = 1.98
+glass = 3.99
+rglass = 6
+borosilicate = 9
+rborosilicate = 12
+*/
+
+/obj/item/weapon/rcd/attackby(obj/item/W, mob/user)
+ var/loaded = 0
+ if(istype(W, /obj/item/weapon/rcd_ammo))
+ var/obj/item/weapon/rcd_ammo/cartridge = W
+ var/can_store = min(max_stored_matter - stored_matter, cartridge.remaining)
+ if(can_store <= 0)
+ to_chat(user, span("warning", "There's either no space or \the [cartridge] is empty!"))
+ return FALSE
+ stored_matter += can_store
+ cartridge.remaining -= can_store
+ if(!cartridge.remaining)
+ to_chat(user, span("warning", "\The [cartridge] dissolves as it empties of compressed matter."))
+ user.drop_from_inventory(W)
+ qdel(W)
+ loaded = 1
+ return TRUE
+ if(istype(W,/obj/item/stack))
+ var/obj/item/stack/S = W
+ if(istype(S,/obj/item/stack/material/glass/phoronrglass))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*4, user)
+ else if(istype(S,/obj/item/stack/material/glass/phoronglass))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*3, user)
+ else if(istype(S,/obj/item/stack/material/glass/reinforced))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*2, user)
+ else if(istype(S,/obj/item/stack/material/plasteel))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*4, user)
+ else if(istype(S,/obj/item/stack/rods))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*0.66, user)
+ else if(istype(S,/obj/item/stack/tile/floor))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*0.33, user)
+ else if(istype(S,/obj/item/stack/material/steel))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*1.33, user)
+ else if(istype(S,/obj/item/stack/material/glass))
+ loaded = loadwithsheets(S, RCD_SHEETS_PER_MATTER_UNIT*1.33, user)
+ if(loaded)
+ playsound(src, 'sound/machines/click.ogg', 50, 1)
+ update_icon()
+ to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units."))
+ return ..()
+
+/obj/item/weapon/rcd/proc/loadwithsheets(obj/item/stack/S, value, mob/user)
+ var/maxsheets = round((max_stored_matter-stored_matter)/value) //calculate the max number of sheets that will fit in RCD
+ if(maxsheets > 0)
+ var/amount_to_use = min(S.amount, maxsheets)
+ S.use(amount_to_use)
+ stored_matter += value*amount_to_use
+ playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
+ to_chat(user, "You insert [amount_to_use] [S.name] sheets into [src]. ")
+ return 1
+ to_chat(user, "You can't insert any more [S.name] sheets into [src]!")
+ return 0
+
+/obj/item/weapon/rcd/attack_self(mob/living/user)
+ ..()
+ var/list/choices = list(
+ "Floors & Walls" = radial_image_floorwall,
+ "Airlock" = radial_image_airlock,
+ "Windoor" = radial_image_windoor,
+ "Firelock" = radial_image_firelock,
+ "Deconstruct" = radial_image_decon,
+ "Grilles & Windows" = radial_image_grillewind,
+ "Frames" = radial_image_frame,
+ "WallFrames" = radial_image_wallframe,
+ "Change Access" = radial_image_access,
+ "Change Airlock Type" = radial_image_airlock_type,
+ "Conveyors" = radial_image_conveyor
+ )
+ var/choice = show_radial_menu(user, user, choices, radius = 42, custom_check = CALLBACK(src, PROC_REF(check_menu), user), tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ switch(choice)
+ if("Floors & Walls")
+ var/list/wall_types = list(
+ "DEFAULT" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "default"),
+ "BAY" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "bay"),
+ "ERIS" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "eris")
+ )
+ var/selected_girder_type = show_radial_menu(user, src, wall_types, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ switch(selected_girder_type)
+ if("DEFAULT")
+ girder_type = /obj/structure/girder
+ if("BAY")
+ girder_type = /obj/structure/girder/bay
+ if("ERIS")
+ girder_type = /obj/structure/girder/eris
+ mode_index = modes.Find(RCD_FLOORWALL)
+ if("Airlock")
+ mode_index = modes.Find(RCD_AIRLOCK)
+ if("Windoor")
+ mode_index = modes.Find(RCD_WINDOOR)
+ if("Firelock")
+ mode_index = modes.Find(RCD_FIRELOCK)
+ if("Deconstruct")
+ mode_index = modes.Find(RCD_DECONSTRUCT)
+ if("Grilles & Windows")
+ mode_index = modes.Find(RCD_WINDOWGRILLE)
+ if("Frames")
+ mode_index = modes.Find(RCD_FRAME)
+ if("WallFrames")
+ var/list/wall_frame_types = list(
+ "Air Alarm" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wallframe"),
+ "Light Bulb" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "lightbulb"),
+ "Light Tube" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "lighttube"),
+ "Doorbell" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "doorbell"),
+ "Status Display" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "status"),
+ "Supply Requests Console" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "supply"),
+ "ATM" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "atm"),
+ "Newscaster" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "newscaster"),
+ "Wall Charger" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wallcharger"),
+ "Fire Alarm" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "firealarm"),
+ "Guest Pass Terminal" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "guestpass"),
+ "Intercom" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "intercom"),
+ "Keycard Authenticator" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "keycardauth"),
+ "Geiger Counter" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "geiger"),
+ "Electrochromic Window Button" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "windowtint"),
+ "ID Restoration Terminal" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "idrestore"),
+ "Timeclock Terminal" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "timeclock"),
+ "Station Map" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "stationmap"),
+ "AI Status Display" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "status"),
+ "Light Switch" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "lightswitch"),
+ "Entertainment Monitor" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "entertainment")
+ )
+ var/selected_wall_frame_type = show_radial_menu(user, src, wall_frame_types, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE, tooltips = TRUE)
+ if(!check_menu(user))
+ return
+ switch(selected_wall_frame_type)
+ if("Air Alarm")
+ wall_frame_type = /obj/machinery/alarm
+ if("Light Bulb")
+ wall_frame_type = /obj/machinery/light/small
+ if("Light Tube")
+ wall_frame_type = /obj/machinery/light
+ if("Doorbell")
+ wall_frame_type = /obj/machinery/doorbell_chime
+ if("Status Display")
+ wall_frame_type = /obj/machinery/status_display
+ if("Supply Requests Console")
+ wall_frame_type = /obj/machinery/requests_console
+ if("ATM")
+ wall_frame_type = /obj/machinery/atm
+ if("Newscaster")
+ wall_frame_type = /obj/machinery/newscaster
+ if("Wall Charger")
+ wall_frame_type = /obj/machinery/recharger/wallcharger
+ if("Fire Alarm")
+ wall_frame_type = /obj/machinery/firealarm
+ if("Guest Pass Terminal")
+ wall_frame_type = /obj/machinery/computer/guestpass
+ if("Intercom")
+ wall_frame_type = /obj/item/device/radio/intercom
+ if("Keycard Authenticator")
+ wall_frame_type = /obj/machinery/keycard_auth
+ if("Geiger Counter")
+ wall_frame_type = /obj/item/device/geiger/wall
+ if("Electrochromic Window Button")
+ wall_frame_type = /obj/machinery/button/windowtint
+ if("ID Restoration Terminal")
+ wall_frame_type = /obj/machinery/computer/id_restorer
+ if("Timeclock Terminal")
+ wall_frame_type = /obj/machinery/computer/timeclock
+ if("Station Map")
+ wall_frame_type = /obj/machinery/station_map
+ if("AI Status Display")
+ wall_frame_type = /obj/machinery/ai_status_display
+ if("Light Switch")
+ wall_frame_type = /obj/machinery/light_switch
+ if("Entertainment Monitor")
+ wall_frame_type = /obj/machinery/computer/security/telescreen/entertainment
+
+ mode_index = modes.Find(RCD_WALLFRAME)
+ if("Change Access")
+ change_airlock_access(user)
+ return
+ if("Change Airlock Type")
+ change_airlock_setting(user)
+ return
+ if("Conveyors")
+ mode_index = modes.Find(RCD_CONVEYOR)
+ else
+ return
+ playsound(src, 'sound/effects/pop.ogg', 50, FALSE)
+ to_chat(user, "You change RCD's mode to '[choice]'.")
+
+/obj/item/weapon/rcd/proc/get_airlock_image(airlock_type)
+ var/obj/machinery/door/airlock/proto = airlock_type
+ var/ic = initial(proto.icon)
+ var/mutable_appearance/MA = mutable_appearance(ic, "door_closed")
+ if(!initial(proto.glass))
+ MA.overlays += "fill_closed"
+ //Not scaling these down to button size because they look horrible then, instead just bumping up radius.
+ return MA
+
+/obj/item/weapon/rcd/proc/change_airlock_setting(mob/user)
+ if(!user)
+ return
+
+ var/list/solid_or_glass_choices = list(
+ "Solid" = get_airlock_image(/obj/machinery/door/airlock),
+ "Glass" = get_airlock_image(/obj/machinery/door/airlock/glass)
+ )
+
+ var/list/solid_choices = list(
+ "Standard" = get_airlock_image(/obj/machinery/door/airlock),
+ "Engineering" = get_airlock_image(/obj/machinery/door/airlock/engineering),
+ "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/atmos),
+ "Security" = get_airlock_image(/obj/machinery/door/airlock/security),
+ "Command" = get_airlock_image(/obj/machinery/door/airlock/command),
+ "Medical" = get_airlock_image(/obj/machinery/door/airlock/medical),
+ "Research" = get_airlock_image(/obj/machinery/door/airlock/research),
+ "Freezer" = get_airlock_image(/obj/machinery/door/airlock/freezer),
+ "Science" = get_airlock_image(/obj/machinery/door/airlock/science),
+ "Mining" = get_airlock_image(/obj/machinery/door/airlock/mining),
+ "Maintenance" = get_airlock_image(/obj/machinery/door/airlock/maintenance),
+ "External" = get_airlock_image(/obj/machinery/door/airlock/external),
+ "Airtight Hatch" = get_airlock_image(/obj/machinery/door/airlock/hatch),
+ "Maintenance Hatch" = get_airlock_image(/obj/machinery/door/airlock/maintenance_hatch)
+ )
+
+ var/list/glass_choices = list(
+ "Standard" = get_airlock_image(/obj/machinery/door/airlock/glass),
+ "Engineering" = get_airlock_image(/obj/machinery/door/airlock/glass_engineering),
+ "Atmospherics" = get_airlock_image(/obj/machinery/door/airlock/glass_atmos),
+ "Security" = get_airlock_image(/obj/machinery/door/airlock/glass_security),
+ "Command" = get_airlock_image(/obj/machinery/door/airlock/glass_command),
+ "Medical" = get_airlock_image(/obj/machinery/door/airlock/glass_medical),
+ "Research" = get_airlock_image(/obj/machinery/door/airlock/glass_research),
+ "Science" = get_airlock_image(/obj/machinery/door/airlock/glass_science),
+ "Mining" = get_airlock_image(/obj/machinery/door/airlock/glass_mining),
+ "External" = get_airlock_image(/obj/machinery/door/airlock/glass_external),
+ )
+
+ var/airlockcat = show_radial_menu(user, src, solid_or_glass_choices, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
+ if(!check_menu(user))
+ return
+ switch(airlockcat)
+ if("Solid")
+ if(advanced_airlock_setting == 1)
+ var/airlockpaint = show_radial_menu(user, src, solid_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
+ if(!check_menu(user))
+ return
+ switch(airlockpaint)
+ if("Standard")
+ 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("Freezer")
+ airlock_type = /obj/machinery/door/airlock/freezer
+ if("Science")
+ airlock_type = /obj/machinery/door/airlock/science
+ 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("Airtight Hatch")
+ airlock_type = /obj/machinery/door/airlock/hatch
+ if("Maintenance Hatch")
+ airlock_type = /obj/machinery/door/airlock/maintenance_hatch
+ airlock_glass = FALSE
+ else
+ airlock_type = /obj/machinery/door/airlock
+ airlock_glass = FALSE
+
+ if("Glass")
+ if(advanced_airlock_setting == 1)
+ var/airlockpaint = show_radial_menu(user, src , glass_choices, radius = 42, custom_check = CALLBACK(src, .proc/check_menu, user), require_near = TRUE)
+ if(!check_menu(user))
+ return
+ switch(airlockpaint)
+ if("Standard")
+ 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("Science")
+ airlock_type = /obj/machinery/door/airlock/glass_science
+ if("Mining")
+ airlock_type = /obj/machinery/door/airlock/glass_mining
+ if("External")
+ airlock_type = /obj/machinery/door/airlock/glass_external
+ airlock_glass = TRUE
+ else
+ airlock_type = /obj/machinery/door/airlock/glass
+ airlock_glass = TRUE
+ else
+ airlock_type = /obj/machinery/door/airlock
+ airlock_glass = FALSE
+
+/obj/item/weapon/rcd/verb/change_airlock_access(mob/user)
+
+ if (!ishuman(user) && !istype(user,/mob/living/silicon/robot))
+ return
+
+ var/t1 = ""
+
+
+ if(use_one_access)
+ t1 += "Restriction Type: At least one access required
"
+ else
+ t1 += "Restriction Type: All accesses required
"
+
+ t1 += "Remove All
"
+
+ var/accesses = ""
+ accesses += "
Access
"
+ accesses += ""
+ t1 += "[accesses]"
+
+ t1 += "Close
\n"
+
+ var/datum/browser/popup = new(user, "rcd_access", "Access Control", 900, 500, src)
+ popup.set_content(t1)
+ popup.open()
+
+/obj/item/weapon/rcd/Topic(href, href_list)
+ ..()
+ if (usr.stat || usr.restrained())
+ return
+ if (href_list["close"])
+ usr << browse(null, "window=rcd_access")
+ return
+
+ if (href_list["access"])
+ toggle_access(href_list["access"])
+ change_airlock_access(usr)
+
+/obj/item/weapon/rcd/proc/toggle_access(acc)
+ if (acc == "all")
+ conf_access = null
+ else if(acc == "one")
+ use_one_access = !use_one_access
+ else
+ var/req = text2num(acc)
+
+ if (conf_access == null)
+ conf_access = list()
+
+ if (!(req in conf_access))
+ conf_access += req
+ else
+ conf_access -= req
+ if (!conf_access.len)
+ conf_access = null
+
+
+
+//Storing all the RCD acts and values here for ease of navigation
+//////////////////////////////////////
+///////////////TURF///////////////////
+//////////////////////////////////////
+/turf/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(density || !can_build_into_floor)
+ return FALSE
+ if(passed_mode == RCD_FLOORWALL)
+ var/obj/structure/lattice/L = locate() in src
+ // A lattice costs one rod to make. A sheet can make two rods, meaning a lattice costs half of a sheet.
+ // A sheet also makes four floor tiles, meaning it costs 1/4th of a sheet to place a floor tile on a lattice.
+ // Therefore it should cost 3/4ths of a sheet if a lattice is not present, or 1/4th of a sheet if it does.
+ return list(
+ RCD_VALUE_MODE = RCD_FLOORWALL,
+ RCD_VALUE_DELAY = 0,
+ RCD_VALUE_COST = L ? RCD_SHEETS_PER_MATTER_UNIT * 0.25 : RCD_SHEETS_PER_MATTER_UNIT * 0.75
+ )
+ return FALSE
+
+/turf/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_FLOORWALL)
+ to_chat(user, span("notice", "You build a floor."))
+ ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE)
+ return TRUE
+ return FALSE
+
+//////////////////////////////////////
+///////////////FLOOR//////////////////
+//////////////////////////////////////
+/turf/simulated/floor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_FLOORWALL)
+ var/obj/structure/girder/G = locate() in src
+ if(G)
+ the_rcd.use_rcd(G, user)
+ return 1
+ // A wall costs four sheets to build (two for the grider and two for finishing it).
+ var/cost = RCD_SHEETS_PER_MATTER_UNIT * 2
+ return list(
+ RCD_VALUE_MODE = RCD_FLOORWALL,
+ RCD_VALUE_DELAY = 0.5 SECONDS,
+ RCD_VALUE_COST = cost
+ )
+ if(RCD_AIRLOCK)
+ // Airlock assemblies cost four sheets. Let's just add another for the electronics/wires/etc.
+ return list(
+ RCD_VALUE_MODE = RCD_AIRLOCK,
+ RCD_VALUE_DELAY = 5 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5
+ )
+ if(RCD_WINDOOR)
+ return list(
+ RCD_VALUE_MODE = RCD_WINDOOR,
+ RCD_VALUE_DELAY = 3 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 3
+ )
+ if(RCD_FIRELOCK)
+ return list(
+ RCD_VALUE_MODE = RCD_FIRELOCK,
+ RCD_VALUE_DELAY = 3 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5
+ )
+ if(RCD_WINDOWGRILLE)
+ var/obj/structure/grille/G = locate() in src
+ if(G)
+ the_rcd.use_rcd(G, user)
+ return 1
+ return list(
+ RCD_VALUE_MODE = RCD_WINDOWGRILLE,
+ RCD_VALUE_DELAY = 1 SECOND,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ if(RCD_DECONSTRUCT)
+ //12 floor deconstructions per full RCD
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 3 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 2.5
+ )
+ if(RCD_FRAME)
+ return list(
+ RCD_VALUE_MODE = RCD_FRAME,
+ RCD_VALUE_DELAY = 1.5 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 5
+ )
+ if(RCD_CONVEYOR)
+ return list(
+ RCD_VALUE_MODE = RCD_CONVEYOR,
+ RCD_VALUE_DELAY = 1.5 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 6
+ )
+ return FALSE
+
+
+/turf/simulated/floor/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_FLOORWALL)
+ to_chat(user, span("notice", "You build a girder."))
+ new the_rcd.girder_type(src)
+ return TRUE
+ if(RCD_AIRLOCK)
+ if(locate(/obj/machinery/door/airlock) in src)
+ return FALSE // No more airlock stacking.
+ to_chat(user, span("notice", "You build an airlock."))
+ var/obj/machinery/door/airlock/A = new the_rcd.airlock_type(src)
+ A.electronics = new/obj/item/weapon/airlock_electronics(A)
+ A.electronics.req_access = null
+ A.electronics.req_one_access = null
+ A.electronics.one_access = null
+ if(the_rcd.conf_access)
+ if(the_rcd.use_one_access)
+ A.electronics.one_access = the_rcd.use_one_access
+ A.electronics.req_one_access = the_rcd.conf_access.Copy()
+ A.req_one_access = the_rcd.conf_access.Copy()
+ else
+ A.electronics.conf_access = the_rcd.conf_access.Copy()
+ A.req_access = the_rcd.conf_access.Copy()
+ A.autoclose = TRUE
+ return TRUE
+ if(RCD_WINDOOR)
+ var/list/windoor_types = list(
+ "default" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "windoor"),
+ "secure" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "swindoor")
+ )
+ var/selected_windoor_type = show_radial_menu(user, src, windoor_types, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_windoor_type)
+ return FALSE
+ var/list/windoor_dirs = list(
+ "NORTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"windoorn":"swindoorn")),
+ "EAST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"windoore":"swindoore")),
+ "SOUTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"windoors":"swindoors")),
+ "WEST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"windoorw":"swindoorw"))
+ )
+ var/selected_windoor_dir = show_radial_menu(user, src, windoor_dirs, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_windoor_dir)
+ return FALSE
+ var/list/windoor_open_dirs = list(
+ "left" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"left":"leftsecure")),
+ "right" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = (selected_windoor_type=="default"?"right":"rightsecure"))
+ )
+ var/selected_windoor_open_dir = show_radial_menu(user, src, windoor_open_dirs, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_windoor_open_dir)
+ return FALSE
+ var/obj/machinery/door/window/A = new(src)
+ if(selected_windoor_type == "default")
+ selected_windoor_type = ""
+ A.icon_state = selected_windoor_open_dir+selected_windoor_type
+ A.base_state = selected_windoor_open_dir+selected_windoor_type
+ switch(selected_windoor_dir)
+ if("NORTH")
+ A.dir = NORTH
+ if("SOUTH")
+ A.dir = SOUTH
+ if("EAST")
+ A.dir = EAST
+ if("WEST")
+ A.dir = WEST
+ if(selected_windoor_type == "secure")
+ A.health = 300.0
+ A.maxhealth =300
+ A.electronics = new/obj/item/weapon/airlock_electronics(A)
+ A.electronics.req_access = null
+ A.electronics.req_one_access = null
+ A.electronics.one_access = null
+ if(the_rcd.conf_access)
+ if(the_rcd.use_one_access)
+ A.electronics.one_access = the_rcd.use_one_access
+ A.electronics.req_one_access = the_rcd.conf_access.Copy()
+ A.req_one_access = the_rcd.conf_access.Copy()
+ else
+ A.electronics.conf_access = the_rcd.conf_access.Copy()
+ A.req_access = the_rcd.conf_access.Copy()
+ A.autoclose = TRUE
+ return TRUE
+ if(RCD_FIRELOCK)
+ if(locate(/obj/machinery/door/firedoor/glass) in src)
+ return FALSE
+ to_chat(user, span("notice", "You build a firelock."))
+ new /obj/machinery/door/firedoor/glass(src)
+ return TRUE
+ if(RCD_WINDOWGRILLE)
+ if(locate(/obj/structure/grille) in src)
+ return FALSE
+ to_chat(user, span("notice", "You construct the grille."))
+ var/obj/structure/grille/G = new(src)
+ G.anchored = TRUE
+ return TRUE
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ ChangeTurf(get_base_turf_by_area(src), preserve_outdoors = TRUE)
+ return TRUE
+ if(RCD_FRAME)
+ var/list/frame_types = list(
+ "Machine" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"),
+ "Computer" = image(icon = 'icons/mob/radial.dmi', icon_state = "computer_dir")
+ )
+ var/selected_frame_type = show_radial_menu(user, src, frame_types, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_frame_type)
+ return FALSE
+ var/list/frame_dirs = list(
+ "NORTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "cnorth"),
+ "EAST" = image(icon = 'icons/mob/radial.dmi', icon_state = "ceast"),
+ "SOUTH" = image(icon = 'icons/mob/radial.dmi', icon_state = "csouth"),
+ "WEST" = image(icon = 'icons/mob/radial.dmi', icon_state = "cwest")
+ )
+ var/selected_frame_dir = show_radial_menu(user, src, frame_dirs, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_frame_dir)
+ return FALSE
+ var/obj/structure/frame
+ if(selected_frame_type == "Machine")
+ frame = new/obj/structure/frame(src)
+ else
+ frame = new/obj/structure/frame/computer(src)
+ switch(selected_frame_dir)
+ if("NORTH")
+ frame.dir = NORTH
+ if("SOUTH")
+ frame.dir = SOUTH
+ if("EAST")
+ frame.dir = EAST
+ if("WEST")
+ frame.dir = WEST
+ frame.anchored = 1
+ to_chat(user, span("notice", "You build a frame"))
+ return TRUE
+ if(RCD_CONVEYOR)
+ var/list/conveyor_dirs = list(
+ "NORTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "conveyorn"),
+ "EAST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "conveyore"),
+ "SOUTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "conveyors"),
+ "WEST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "conveyorw")
+ )
+ var/selected_conveyor_dir = show_radial_menu(user, src, conveyor_dirs, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_conveyor_dir)
+ return FALSE
+ var/obj/machinery/conveyor/C = new(src)
+ switch(selected_conveyor_dir)
+ if("NORTH")
+ C.set_dir(NORTH)
+ if("SOUTH")
+ C.set_dir(SOUTH)
+ if("EAST")
+ C.set_dir(EAST)
+ if("WEST")
+ C.set_dir(WEST)
+ to_chat(user, span("notice", "You build a conveyor"))
+ return TRUE
+
+//////////////////////////////////////
+//////////////WALL////////////////////
+//////////////////////////////////////
+/turf/simulated/wall/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ if(material.integrity > 1000) // Don't decon things like elevatorium.
+ return FALSE
+ if(reinf_material && !the_rcd.can_remove_rwalls) // Gotta do it the old fashioned way if your RCD can't.
+ return FALSE
+ var/delay_to_use = material.integrity / 3 // Steel has 150 integrity, so it'll take five seconds to down a regular wall.
+ if(reinf_material)
+ delay_to_use += reinf_material.integrity / 3
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = delay_to_use,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 2.5
+ )
+ if(RCD_WALLFRAME)
+ return list(
+ RCD_VALUE_MODE = RCD_WALLFRAME,
+ RCD_VALUE_DELAY = 1,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 3
+ )
+ return FALSE
+
+/turf/simulated/wall/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ ChangeTurf(/turf/simulated/floor/airless, preserve_outdoors = TRUE)
+ return TRUE
+ if(RCD_WALLFRAME)
+ if(!user || !x || !y || !user.x || !user.y) return
+ var/dx = user.x - x
+ var/dy = user.y - y
+ if(!dx && !dy) return
+
+ var/direction
+ if(abs(dx) < abs(dy))
+ if(dy > 0) direction = NORTH
+ else direction = SOUTH
+ else
+ if(dx > 0) direction = EAST
+ else direction = WEST
+ var/obj/O = new the_rcd.wall_frame_type(get_step(src,direction))
+ O.dir = direction
+ if(istype(O,/obj/machinery/light))
+ O.dir = reverse_dir[O.dir]
+ return TRUE
+ var/list/adjusts = list(
+ /obj/machinery/computer/security/telescreen/entertainment,
+ /obj/machinery/ai_status_display,
+ /obj/machinery/station_map,
+ /obj/machinery/recharger/wallcharger,
+ /obj/machinery/status_display
+ )
+ var/adjust_val = 0
+ for(var/A in adjusts)
+ if(istype(O,A))
+ adjust_val = 6
+ break
+ switch(direction)
+ if(NORTH)
+ O.pixel_x = 0
+ O.pixel_y = -26 - adjust_val
+ if(SOUTH)
+ O.pixel_x = 0
+ O.pixel_y = 26 + adjust_val
+ if(EAST)
+ O.pixel_x = -26 - adjust_val
+ O.pixel_y = 0
+ if(WEST)
+ O.pixel_x = 26 + adjust_val
+ O.pixel_y = 0
+ return TRUE
+ return FALSE
+
+//////////////////////////////////////
+//////////////GIRDER//////////////////
+//////////////////////////////////////
+/obj/structure/girder/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ var/turf/simulated/T = get_turf(src)
+ if(!istype(T) || T.density)
+ return FALSE
+
+ switch(passed_mode)
+ if(RCD_FLOORWALL)
+ // Finishing a wall costs two sheets.
+ var/cost = RCD_SHEETS_PER_MATTER_UNIT * 2
+ // Rwalls cost three to finish.
+ if(the_rcd.make_rwalls)
+ cost += RCD_SHEETS_PER_MATTER_UNIT * 1
+ return list(
+ RCD_VALUE_MODE = RCD_FLOORWALL,
+ RCD_VALUE_DELAY = 0.5 SECONDS,
+ RCD_VALUE_COST = cost
+ )
+ if(RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 0.5 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/structure/girder/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ var/turf/simulated/T = get_turf(src)
+ if(!istype(T) || T.density) // Should stop future bugs of people bringing girders to centcom and RCDing them, or somehow putting a girder on a durasteel wall and deconning it.
+ return FALSE
+
+ switch(passed_mode)
+ if(RCD_FLOORWALL)
+ to_chat(user, span("notice", "You finish a wall."))
+ // This is mostly the same as using on a floor. The girder's material is preserved, however.
+ T.ChangeTurf(wall_type)
+ var/turf/simulated/wall/new_T = get_turf(src) // Ref to the wall we just built.
+ // Apparently set_material(...) for walls requires refs to the material singletons and not strings.
+ // This is different from how other material objects with their own set_material(...) do it, but whatever.
+ var/datum/material/M = name_to_material[the_rcd.material_to_use]
+ new_T.set_material(M, the_rcd.make_rwalls ? M : null, girder_material)
+ new_T.add_hiddenprint(user)
+ qdel(src)
+ return TRUE
+
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+
+//////////////////////////////////////
+/////////////WINDOW///////////////////
+//////////////////////////////////////
+/obj/structure/window/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+
+/obj/structure/window/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+//////////////////////////////////////
+//////////////GRILLE//////////////////
+//////////////////////////////////////
+/obj/structure/grille/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_WINDOWGRILLE)
+ var/construct_cost = 4
+ if(destroyed)
+ construct_cost = 1
+ else
+ var/list/window_dirs = list(
+ "NORTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wnorth"),
+ "EAST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "weast"),
+ "SOUTH" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wsouth"),
+ "WEST" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wwest"),
+ "FULL" = image(icon = 'modular_chomp/icons/mob/radial.dmi', icon_state = "wfull"),
+ )
+ var/selected_window_dir = show_radial_menu(user, src, window_dirs, require_near = the_rcd.ranged?FALSE:TRUE, tooltips = TRUE)
+ if(!the_rcd.check_menu(user) || !selected_window_dir)
+ return FALSE
+ the_rcd.window_dir = selected_window_dir
+ if(selected_window_dir != "FULL")
+ construct_cost = 1
+ // A full tile window costs 4 glass sheets.
+ return list(
+ RCD_VALUE_MODE = RCD_WINDOWGRILLE,
+ RCD_VALUE_DELAY = 1 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * construct_cost
+ )
+ //Honestly shouldn't cost anything to deconstruct a grille
+ if(RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 0.5 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 0
+ )
+ return FALSE
+
+/obj/structure/grille/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ if(RCD_WINDOWGRILLE)
+ if(destroyed)
+ destroyed = 0
+ health = initial(health)
+ update_icon()
+ density = 1
+ to_chat(user, span("notice", "You repair \the [src]."))
+ return TRUE
+ var/temp_dir
+ switch(the_rcd.window_dir)
+ if("NORTH")
+ temp_dir = NORTH
+ if("SOUTH")
+ temp_dir = SOUTH
+ if("EAST")
+ temp_dir = EAST
+ if("WEST")
+ temp_dir = WEST
+ if("FULL")
+ temp_dir = 10
+ for(var/obj/structure/window/W in src.loc)
+ if(W && W.dir == temp_dir)
+ to_chat(user, span("warning", "There is already a window there."))
+ return FALSE
+
+ to_chat(user, span("notice", "You construct a window."))
+ var/window_to_spawn = /obj/structure/window/basic
+ switch(the_rcd.window_type)
+ if("glass")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/basic/full":"/obj/structure/window/basic")
+ if("rglass")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/reinforced/full":"/obj/structure/window/reinforced")
+ if("phoron")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/phoronbasic/full":"/obj/structure/window/phoronbasic")
+ if("rphoron")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/phoronreinforced/full":"/obj/structure/window/phoronreinforced")
+ if("titanium")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/titanium/full":"/obj/structure/window/titanium")
+ if("plastitanium")
+ window_to_spawn = (temp_dir==10?"/obj/structure/window/plastitanium/full":"/obj/structure/window/plastitanium")
+ var/obj/structure/window/WD = new window_to_spawn(loc)
+ WD.anchored = TRUE
+ WD.dir = temp_dir
+ return TRUE
+ return FALSE
+
+//////////////////////////////////////
+////////////AIRLOCK///////////////////
+//////////////////////////////////////
+/obj/machinery/door/airlock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ //6 deconstructs per full RCD
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 4 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 4
+ )
+ return FALSE
+
+/obj/machinery/door/airlock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ switch(passed_mode)
+ if(RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+//////////////////////////////////////
+/////////////FIRELOCK/////////////////
+//////////////////////////////////////
+/obj/machinery/door/firedoor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 3
+ )
+ return FALSE
+
+/obj/machinery/door/firedoor/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+//////////////////////////////////////
+////////////WALL FRAMES///////////////
+//////////////////////////////////////
+/obj/machinery/computer/security/telescreen/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/computer/security/telescreen/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/doorbell_chime/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/doorbell_chime/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/status_display/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/status_display/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/requests_console/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/requests_console/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/atm/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/atm/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/newscaster/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/newscaster/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/recharger/wallcharger/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/recharger/wallcharger/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/firealarm/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/firealarm/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/alarm/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/alarm/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/computer/guestpass/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/computer/guestpass/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/item/device/radio/intercom/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/item/device/radio/intercom/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/keycard_auth/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/keycard_auth/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/item/device/geiger/wall/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/item/device/geiger/wall/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/button/windowtint/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/button/windowtint/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/computer/id_restorer/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/computer/id_restorer/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/computer/timeclock/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/computer/timeclock/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/station_map/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/station_map/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/structure/trash_pile/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 8 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/structure/trash_pile/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/structure/loot_pile/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 8 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/structure/loot_pile/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/structure/frame/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/structure/frame/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/ai_status_display/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/ai_status_display/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/light/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/light/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/hologram/holopad/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/hologram/holopad/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/light_switch/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/light_switch/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/structure/table/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/structure/table/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/conveyor/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 2 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 1
+ )
+ return FALSE
+
+/obj/machinery/conveyor/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
+
+/obj/machinery/door/window/rcd_values(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ return list(
+ RCD_VALUE_MODE = RCD_DECONSTRUCT,
+ RCD_VALUE_DELAY = 3 SECONDS,
+ RCD_VALUE_COST = RCD_SHEETS_PER_MATTER_UNIT * 3
+ )
+ return FALSE
+
+/obj/machinery/door/window/rcd_act(mob/living/user, obj/item/weapon/rcd/the_rcd, passed_mode)
+ if(passed_mode == RCD_DECONSTRUCT)
+ to_chat(user, span("notice", "You deconstruct \the [src]."))
+ qdel(src)
+ return TRUE
+ return FALSE
\ No newline at end of file
diff --git a/modular_chomp/code/game/objects/structures/holosign.dm b/modular_chomp/code/game/objects/structures/holosign.dm
new file mode 100644
index 0000000000..3e0d261b49
--- /dev/null
+++ b/modular_chomp/code/game/objects/structures/holosign.dm
@@ -0,0 +1,70 @@
+/obj/structure/holosign
+ name = "holo sign"
+ icon = 'icons/effects/effects_ch.dmi'
+ anchored = TRUE
+ var/obj/item/weapon/holosign_creator/projector
+ var/health = 10
+ explosion_resistance = 1
+
+/obj/structure/holosign/Initialize(mapload, source_projector)
+ . = ..()
+ if(source_projector)
+ projector = source_projector
+ projector.signs += src
+/* if(overlays) // Fucking god damnit why do we have to have an entire different subsystem for this shit from other codebases.
+ overlays.add_overlay(src, icon, icon_state, ABOVE_MOB_LAYER, plane, dir, alpha, RESET_ALPHA) //you see mobs under it, but you hit them like they are above it
+ alpha = 0
+*/
+
+/obj/structure/holosign/Destroy()
+ if(projector)
+ projector.signs -= src
+ projector = null
+ return ..()
+
+/obj/structure/holosign/attack_hand(mob/user, list/params)
+ . = ..()
+ if(.)
+ return
+ user.setClickCooldown(user.get_attack_speed())
+ user.do_attack_animation(src)
+ take_damage(5)
+ playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
+
+/obj/structure/holosign/attackby(obj/item/W as obj, mob/user as mob)
+ user.setClickCooldown(user.get_attack_speed(W))
+ user.do_attack_animation(src)
+ playsound(loc, 'sound/weapons/egloves.ogg', 80, 1)
+ take_damage(W.force)
+
+/obj/structure/holosign/take_damage(var/damage)
+ health -= damage
+ spawn(1) healthcheck()
+ return 1
+
+/obj/structure/holosign/proc/healthcheck()
+ if(health <= 0)
+ qdel(src)
+
+/obj/structure/holosign/wetsign
+ name = "wet floor sign"
+ desc = "The words flicker as if they mean nothing."
+ icon_state = "holosign"
+
+/obj/structure/holosign/barrier/combifan
+ name = "holo combifan"
+ desc = "A holographic barrier resembling a blue-accented tiny fan. Though it does not prevent solid objects from passing through, gas and temperature changes are kept out."
+ icon_state = "holo_firelock"
+ anchored = TRUE
+ density = FALSE
+ layer = ABOVE_TURF_LAYER
+ can_atmos_pass = ATMOS_PASS_NO
+ alpha = 150
+
+/obj/structure/holosign/barrier/combifan/Destroy()
+ update_nearby_tiles()
+ return ..()
+
+/obj/structure/holosign/barrier/combifan/Initialize(mapload)
+ .=..()
+ update_nearby_tiles()
\ No newline at end of file
diff --git a/modular_chomp/icons/mob/radial.dmi b/modular_chomp/icons/mob/radial.dmi
new file mode 100644
index 0000000000..5e356c4b81
Binary files /dev/null and b/modular_chomp/icons/mob/radial.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 8afbfc6524..874f8915c9 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -4570,16 +4570,19 @@
#include "modular_chomp\code\game\machinery\colormate.dm"
#include "modular_chomp\code\game\machinery\petrification.dm"
#include "modular_chomp\code\game\objects\items.dm"
+#include "modular_chomp\code\game\objects\items\holosign_creator.dm"
#include "modular_chomp\code\game\objects\items\petrifier.dm"
#include "modular_chomp\code\game\objects\items\clockwork\ratvarian_spear.dm"
#include "modular_chomp\code\game\objects\items\devices\flipper.dm"
#include "modular_chomp\code\game\objects\items\devices\vacpack.dm"
#include "modular_chomp\code\game\objects\items\weapons\capture_crystal.dm"
#include "modular_chomp\code\game\objects\items\weapons\cigs_lighters.dm"
+#include "modular_chomp\code\game\objects\items\weapons\RCD.dm"
#include "modular_chomp\code\game\objects\items\weapons\storage\firstaid.dm"
#include "modular_chomp\code\game\objects\random\mapping.dm"
#include "modular_chomp\code\game\objects\structures\desert_planet_structures.dm"
#include "modular_chomp\code\game\objects\structures\gargoyle.dm"
+#include "modular_chomp\code\game\objects\structures\holosign.dm"
#include "modular_chomp\code\game\objects\structures\loot_pile.dm"
#include "modular_chomp\code\game\objects\structures\watercloset_ch.dm"
#include "modular_chomp\code\game\objects\structures\crate_lockers\largecrate.dm"