diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 973196b2a269d..81d386776e7fd 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -101,17 +101,26 @@ #define CAT_DRINK "Drinks" #define CAT_STRUCTURE "Structures" + // rcd buildtype defines -#define RCD_FLOORWALL 1 -#define RCD_AIRLOCK 2 -#define RCD_DECONSTRUCT 3 -#define RCD_WINDOWGRILLE 4 -#define RCD_LADDER 5 -#define RCD_MACHINE 8 -#define RCD_COMPUTER 16 - -#define RCD_UPGRADE_FRAMES (1<<0) +// these aren't even used as bitflags so who even knows why they are treated like them +#define RCD_FLOORWALL (1<<0) +#define RCD_AIRLOCK (1<<1) +#define RCD_DECONSTRUCT (1<<2) +#define RCD_WINDOWGRILLE (1<<3) +#define RCD_MACHINE (1<<4) +#define RCD_COMPUTER (1<<5) +#define RCD_FURNISHING (1<<6) +#define RCD_LADDER (1<<7) + +#define RCD_UPGRADE_FRAMES (1<<0) #define RCD_UPGRADE_SIMPLE_CIRCUITS (1<<1) -#define RCD_UPGRADE_SILO_LINK (1<<2) +#define RCD_UPGRADE_SILO_LINK (1<<2) +#define RCD_UPGRADE_FURNISHING (1<<3) + +#define RCD_WINDOW_FULLTILE "full tile" +#define RCD_WINDOW_DIRECTIONAL "directional" +#define RCD_WINDOW_NORMAL "glass" +#define RCD_WINDOW_REINFORCED "reinforced glass" #define RPD_UPGRADE_UNWRENCH (1<<0) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 5fbd9337b2583..6ca05f8a54558 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -203,7 +203,10 @@ /obj/machinery/door/airlock/proc/update_other_id() for(var/obj/machinery/door/airlock/Airlock in GLOB.airlocks) if(Airlock.closeOtherId == closeOtherId && Airlock != src) - close_others += Airlock + if(!(Airlock in close_others)) + close_others += Airlock + if(!(src in Airlock.close_others)) + Airlock.close_others += src /obj/machinery/door/airlock/proc/cyclelinkairlock() if (cyclelinkedairlock) @@ -721,6 +724,10 @@ /obj/machinery/door/airlock/examine(mob/user) . = ..() + if(closeOtherId) + . += "This airlock cycles on ID: [sanitize(closeOtherId)]." + if(obj_flags & EMAGGED) + . += "Its access panel is smoking slightly." if(charge && !panel_open && in_range(user, src)) . += "The maintenance panel seems haphazardly fastened." if(charge && panel_open) diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 222ae936a0dca..114bfa0b88c9c 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -8,6 +8,10 @@ var/one_access = 0 /// Unrestricted sides, or sides of the airlock that will open regardless of access var/unres_sides = 0 + ///what name are we passing to the finished airlock + var/passed_name + ///what string are we passing to the finished airlock as the cycle ID + var/passed_cycle_id /// A holder of the electronics, in case of them working as an integrated part var/holder @@ -51,6 +55,8 @@ data["accesses"] = accesses data["oneAccess"] = one_access data["unres_direction"] = unres_sides + data["passedName"] = passed_name + data["passedCycleId"] = passed_cycle_id return data /obj/item/electronics/airlock/ui_act(action, params) @@ -90,6 +96,14 @@ return accesses -= get_region_accesses(region) . = TRUE + if("passedName") + var/new_name = trim(sanitize("[params["passedName"]]"), 30) + passed_name = new_name + . = TRUE + if("passedCycleId") + var/new_cycle_id = trim(sanitize(params["passedCycleId"]), 30) + passed_cycle_id = new_cycle_id + . = TRUE /obj/item/electronics/airlock/ui_host() if(holder) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 39af859b4576a..9025b997b7dc6 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -193,8 +193,8 @@ return TRUE return ..() -/obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) - return get_dir(src, M) & unres_sides +/obj/machinery/door/proc/unrestricted_side(mob/opener) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) + return get_dir(src, opener) & unres_sides /obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) return diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 7321d5a7aa380..0fc90e773cef5 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -26,7 +26,7 @@ var/cable = 1 var/list/debris = list() -/obj/machinery/door/window/Initialize(mapload, set_dir) +/obj/machinery/door/window/Initialize(mapload, set_dir, unres_sides) . = ..() if(set_dir) setDir(set_dir) @@ -40,6 +40,19 @@ if(cable) debris += new /obj/item/stack/cable_coil(src, cable) + if(unres_sides) + //remove unres_sides from directions it can't be bumped from + switch(dir) + if(NORTH,SOUTH) + unres_sides &= ~EAST + unres_sides &= ~WEST + if(EAST,WEST) + unres_sides &= ~NORTH + unres_sides &= ~SOUTH + + src.unres_sides = unres_sides + update_icon() + var/static/list/loc_connections = list( COMSIG_ATOM_EXIT = PROC_REF(on_exit), ) @@ -47,6 +60,10 @@ AddElement(/datum/element/connect_loc, loc_connections) RegisterSignal(src, COMSIG_COMPONENT_NTNET_RECEIVE, PROC_REF(ntnet_receive)) +/obj/machinery/door/window/ComponentInitialize() + . = ..() + AddComponent(/datum/component/ntnet_interface) + /obj/machinery/door/window/Destroy() set_density(FALSE) air_update_turf(1) @@ -343,7 +360,7 @@ // Cutting WIRE_IDSCAN grants remote access... or it would, if we could hack windowdoors. return id_scan_hacked() || ..() -/obj/machinery/door/window/proc/ntnet_receive(datum/source, datum/netdata/data) +/obj/machinery/door/window/proc/ntnet_receive(datum/netdata/data) // Check if the airlock is powered. if(!hasPower()) return @@ -352,10 +369,13 @@ if(is_jammed(JAMMER_PROTECTION_WIRELESS)) return + // Check packet access level. + if(!check_access_ntnet(data)) + return // Handle received packet. - var/command = data.data["data"] - var/command_value = data.data["data_secondary"] + var/command = lowertext(data.data["data"]) + var/command_value = lowertext(data.data["data_secondary"]) switch(command) if("open") if(command_value == "on" && !density) @@ -371,6 +391,20 @@ if("touch") INVOKE_ASYNC(src, PROC_REF(open_and_close)) +/obj/machinery/door/window/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + switch(the_rcd.mode) + if(RCD_DECONSTRUCT) + return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 32) + return FALSE + +/obj/machinery/door/window/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, "You deconstruct the windoor.") + qdel(src) + return TRUE + return FALSE + /obj/machinery/door/window/brigdoor name = "secure door" icon_state = "leftsecure" diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 797319285d1f1..53f649551a18e 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -29,14 +29,13 @@ RLD var/datum/effect_system/spark_spread/spark_system var/matter = 0 var/max_matter = 100 - var/sheetmultiplier = 4 //Controls the amount of matter added for each glass/iron sheet, triple for plasteel - var/plasteelmultiplier = 3 //Plasteel is worth 3 times more than glass or iron - var/plasmarglassmultiplier = 2 //50% less plasma than in plasteel - var/rglassmultiplier = 1.5 //One iron sheet, half a glass sheet var/no_ammo_message = "The \'Low Ammo\' light on the device blinks yellow." var/has_ammobar = FALSE //controls whether or not does update_icon apply ammo indicator overlays var/ammo_sections = 10 //amount of divisions in the ammo indicator overlay/number of ammo indicator states - var/upgrade = FALSE + /// Bitflags for upgrades + var/upgrade = NONE + /// Bitflags for banned upgrades + var/banned_upgrades = NONE var/datum/component/remote_materials/silo_mats //remote connection to the silo var/silo_link = FALSE //switch to use internal or remote storage @@ -62,58 +61,66 @@ RLD return ..() /obj/item/construction/attackby(obj/item/W, mob/user, params) - if(iscyborg(user)) + if(istype(W, /obj/item/rcd_upgrade)) + install_upgrade(W, user) + return TRUE + if(insert_matter(W, user)) + return TRUE + return ..() + +/// Installs an upgrade into the RCD checking if it is already installed, or if it is a banned upgrade +/obj/item/construction/proc/install_upgrade(obj/item/rcd_upgrade/rcd_up, mob/user) + if(rcd_up.upgrade & upgrade) + to_chat(user, "[src] has already installed this upgrade!") + return + if(rcd_up.upgrade & banned_upgrades) + to_chat(user, "[src] can't install this upgrade!") return - var/loaded = 0 - if(istype(W, /obj/item/rcd_ammo)) - var/obj/item/rcd_ammo/R = W + upgrade |= rcd_up.upgrade + if((rcd_up.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats) + silo_mats = AddComponent(/datum/component/remote_materials, "RCD", FALSE, FALSE) + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) + qdel(rcd_up) + +/// Inserts matter into the RCD allowing it to build +/obj/item/construction/proc/insert_matter(obj/O, mob/user) + if(iscyborg(user)) + return FALSE + var/loaded = FALSE + if(istype(O, /obj/item/rcd_ammo)) + var/obj/item/rcd_ammo/R = O var/load = min(R.ammoamt, max_matter - matter) if(load <= 0) to_chat(user, "[src] can't hold any more matter-units!") - return + return FALSE R.ammoamt -= load if(R.ammoamt <= 0) qdel(R) matter += load - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - loaded = 1 - else if(istype(W, /obj/item/stack/sheet/iron) || istype(W, /obj/item/stack/sheet/glass)) - loaded = loadwithsheets(W, sheetmultiplier, user) - else if(istype(W, /obj/item/stack/sheet/plasteel)) - loaded = loadwithsheets(W, plasteelmultiplier*sheetmultiplier, user) //12 matter for 1 plasteel sheet - else if(istype(W, /obj/item/stack/sheet/plasmarglass)) - loaded = loadwithsheets(W, plasmarglassmultiplier*sheetmultiplier, user) //8 matter for one plasma rglass sheet - else if(istype(W, /obj/item/stack/sheet/rglass)) - loaded = loadwithsheets(W, rglassmultiplier*sheetmultiplier, user) //6 matter for one rglass sheet - else if(istype(W, /obj/item/stack/rods)) - loaded = loadwithsheets(W, sheetmultiplier * 0.5, user) // 2 matter for 1 rod, as 2 rods are produced from 1 iron - else if(istype(W, /obj/item/stack/tile/plasteel)) - loaded = loadwithsheets(W, sheetmultiplier * 0.25, user) // 1 matter for 1 floortile, as 4 tiles are produced from 1 iron + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) + loaded = TRUE + else if(istype(O, /obj/item/stack)) + loaded = loadwithsheets(O, user) if(loaded) to_chat(user, "[src] now holds [matter]/[max_matter] matter-units.") - else if(istype(W, /obj/item/rcd_upgrade)) - var/obj/item/rcd_upgrade/rcd_up = W - if(!(upgrade & rcd_up.upgrade)) - upgrade |= rcd_up.upgrade - if((rcd_up.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats) - silo_mats = AddComponent(/datum/component/remote_materials, "RCD", FALSE, FALSE) - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - qdel(W) - else - return ..() - update_icon() //ensures that ammo counters (if present) get updated + update_appearance() //ensures that ammo counters (if present) get updated + return loaded -/obj/item/construction/proc/loadwithsheets(obj/item/stack/sheet/S, value, mob/user) +/obj/item/construction/proc/loadwithsheets(obj/item/stack/loaded_stack, mob/user) + var/value = loaded_stack.matter_amount + if(value <= 0) + to_chat(user, "You can't insert [loaded_stack.name] into [src]!") + return FALSE var/maxsheets = round((max_matter-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) + var/amount_to_use = min(loaded_stack.amount, maxsheets) + loaded_stack.use(amount_to_use) 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 + playsound(src.loc, 'sound/machines/click.ogg', 50, TRUE) + to_chat(user, "You insert [amount_to_use] [loaded_stack.name] sheets into [src]. ") + return TRUE + to_chat(user, "You can't insert any more [loaded_stack.name] sheets into [src]!") + return FALSE /obj/item/construction/proc/activate() playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) @@ -201,6 +208,11 @@ RLD var/airlock_type = /obj/machinery/door/airlock var/airlock_glass = FALSE // So the floor's rcd_act knows how much ammo to use var/window_type = /obj/structure/window/fulltile + var/window_glass = RCD_WINDOW_NORMAL + var/window_size = RCD_WINDOW_FULLTILE + var/furnish_type = /obj/structure/chair + var/furnish_cost = 8 + var/furnish_delay = 10 var/advanced_airlock_setting = 1 //Set to 1 if you want more paintjobs available var/delay_mod = 1 var/canRturf = FALSE //Variable for R walls to deconstruct them @@ -211,33 +223,63 @@ RLD user.visible_message("[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide..") return BRUTELOSS -/obj/item/construction/rcd/verb/toggle_window_type_verb() - set name = "RCD : Toggle Window Type" +/obj/item/construction/rcd/verb/toggle_window_glass_verb() + set name = "RCD : Toggle Window Glass" set category = "Object" set src in view(1) if(!usr.canUseTopic(src, BE_CLOSE)) return - toggle_window_type(usr) + toggle_window_glass(usr) + +/obj/item/construction/rcd/verb/toggle_window_size_verb() + set name = "RCD : Toggle Window Size" + set category = "Object" + set src in view(1) -/obj/item/construction/rcd/proc/toggle_window_type(mob/user) - var/window_type_name - if (window_type == /obj/structure/window/fulltile) - window_type = /obj/structure/window/reinforced/fulltile - window_type_name = "reinforced glass" + if(!usr.canUseTopic(src, BE_CLOSE)) + return + + toggle_window_size(usr) + +/// Toggles the usage of reinforced or normal glass +/obj/item/construction/rcd/proc/toggle_window_glass(mob/user) + if (window_glass != RCD_WINDOW_REINFORCED) + set_window_type(user, RCD_WINDOW_REINFORCED, window_size) + return + set_window_type(user, RCD_WINDOW_NORMAL, window_size) + +/// Toggles the usage of directional or full tile windows +/obj/item/construction/rcd/proc/toggle_window_size(mob/user) + if (window_size != RCD_WINDOW_DIRECTIONAL) + set_window_type(user, window_glass, RCD_WINDOW_DIRECTIONAL) + return + set_window_type(user, window_glass, RCD_WINDOW_FULLTILE) + +/// Sets the window type to be created based on parameters +/obj/item/construction/rcd/proc/set_window_type(mob/user, glass, size) + window_glass = glass + window_size = size + if(window_glass == RCD_WINDOW_REINFORCED) + if(window_size == RCD_WINDOW_DIRECTIONAL) + window_type = /obj/structure/window/reinforced + else + window_type = /obj/structure/window/reinforced/fulltile else - window_type = /obj/structure/window/fulltile - window_type_name = "glass" + if(window_size == RCD_WINDOW_DIRECTIONAL) + window_type = /obj/structure/window + else + window_type = /obj/structure/window/fulltile - to_chat(user, "You change \the [src]'s window mode to [window_type_name].") + to_chat(user, "You change \the [src]'s window mode to [window_size] [window_glass] window.") /obj/item/construction/rcd/proc/toggle_silo_link(mob/user) if(silo_mats) silo_link = !silo_link to_chat(user, "You change \the [src]'s storage link state: [silo_link ? "ON" : "OFF"].") else - to_chat(user, "\the [src] dont have remote storage connection.") + to_chat(user, "\the [src] doesn't have remote storage connection.") /obj/item/construction/rcd/proc/get_airlock_image(airlock_type) var/obj/machinery/door/airlock/proto = airlock_type @@ -276,7 +318,9 @@ RLD var/list/solid_or_glass_choices = list( "Solid" = get_airlock_image(/obj/machinery/door/airlock), - "Glass" = get_airlock_image(/obj/machinery/door/airlock/glass) + "Glass" = get_airlock_image(/obj/machinery/door/airlock/glass), + "Windoor" = image(icon = 'icons/mob/radial.dmi', icon_state = "windoor"), + "Secure Windoor" = image(icon = 'icons/mob/radial.dmi', icon_state = "secure_windoor") ) var/list/solid_choices = list( @@ -403,10 +447,47 @@ RLD else airlock_type = /obj/machinery/door/airlock/glass airlock_glass = TRUE + if("Windoor") + airlock_type = /obj/machinery/door/window + airlock_glass = TRUE + if("Secure Windoor") + airlock_type = /obj/machinery/door/window/brigdoor + airlock_glass = TRUE else airlock_type = /obj/machinery/door/airlock airlock_glass = FALSE +/// Radial menu for choosing the object you want to be created with the furnishing mode +/obj/item/construction/rcd/proc/change_furnishing_type(mob/user) + if(!user) + return + var/static/list/choices = list( + "Chair" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair"), + "Stool" = image(icon = 'icons/mob/radial.dmi', icon_state = "stool"), + "Table" = image(icon = 'icons/mob/radial.dmi', icon_state = "table"), + "Glass Table" = image(icon = 'icons/mob/radial.dmi', icon_state = "glass_table") + ) + var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) + if(!check_menu(user)) + return + switch(choice) + if("Chair") + furnish_type = /obj/structure/chair + furnish_cost = 8 + furnish_delay = 10 + if("Stool") + furnish_type = /obj/structure/chair/stool + furnish_cost = 8 + furnish_delay = 10 + if("Table") + furnish_type = /obj/structure/table + furnish_cost = 16 + furnish_delay = 20 + if("Glass Table") + furnish_type = /obj/structure/table/glass + furnish_cost = 16 + furnish_delay = 20 + /obj/item/construction/rcd/proc/rcd_create(atom/A, mob/user) var/list/rcd_results = A.rcd_vals(user, src) if(!rcd_results) @@ -460,6 +541,10 @@ RLD choices += list( "Silo Link" = image(icon = 'icons/obj/mining.dmi', icon_state = "silo"), ) + if(upgrade & RCD_UPGRADE_FURNISHING) + choices += list( + "Furnishing" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair") + ) if(mode == RCD_AIRLOCK) choices += list( "Change Access" = image(icon = 'icons/mob/radial.dmi', icon_state = "access"), @@ -467,7 +552,12 @@ RLD ) else if(mode == RCD_WINDOWGRILLE) choices += list( - "Change Window Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype") + "Change Window Glass" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowtype"), + "Change Window Size" = image(icon = 'icons/mob/radial.dmi', icon_state = "windowsize") + ) + else if(mode == RCD_FURNISHING) + choices += list( + "Change Furnishing Type" = image(icon = 'icons/mob/radial.dmi', icon_state = "chair") ) var/choice = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) if(!check_menu(user)) @@ -483,6 +573,8 @@ RLD mode = RCD_WINDOWGRILLE if("Machine Frames") mode = RCD_MACHINE + if("Furnishing") + mode = RCD_FURNISHING if("Computer Frames") mode = RCD_COMPUTER change_computer_dir(user) @@ -495,15 +587,21 @@ RLD if("Change Airlock Type") change_airlock_setting(user) return - if("Change Window Type") - toggle_window_type(user) + if("Change Window Glass") + toggle_window_glass(user) + return + if("Change Window Size") + toggle_window_size(user) + return + if("Change Furnishing Type") + change_furnishing_type(user) return if("Silo Link") toggle_silo_link(user) return else return - playsound(src, 'sound/effects/pop.ogg', 50, 0) + playsound(src, 'sound/effects/pop.ogg', 50, FALSE) to_chat(user, "You change RCD's mode to '[choice]'.") /obj/item/construction/rcd/proc/target_check(atom/A, mob/user) // only returns true for stuff the device can actually work with @@ -543,6 +641,7 @@ RLD no_ammo_message = "Insufficient charge." desc = "A device used to rapidly build walls and floors." canRturf = TRUE + banned_upgrades = RCD_UPGRADE_SILO_LINK var/energyfactor = 72 @@ -804,14 +903,39 @@ RLD ///index, used in the attack self to get the type. stored here since it doesnt change var/list/choices = list() ///index, used in the attack self to get the type. stored here since it doesnt change + ///This list that holds all the plumbing design types the plumberer can construct. Its purpose is to make it easy to make new plumberer subtypes with a different selection of machines. + var/list/static/plumbing_design_types + var/list/name_to_type = list() /// var/list/machinery_data = list("cost" = list(), "delay" = list()) + +/obj/item/construction/plumbing/Initialize(mapload) + . = ..() + set_plumbing_designs() + + +///Set the list of designs this plumbing rcd can make +/obj/item/construction/plumbing/proc/set_plumbing_designs() + plumbing_design_types = list( + /obj/machinery/plumbing/input = 5, + /obj/machinery/plumbing/output = 5, + /obj/machinery/plumbing/tank = 20, + /obj/machinery/plumbing/synthesizer = 15, + /obj/machinery/plumbing/reaction_chamber = 15, + //Above are the most common machinery which is shown on the first cycle. Keep new additions below THIS line, unless they're probably gonna be needed alot + /obj/machinery/plumbing/acclimator = 10, + /obj/machinery/plumbing/disposer = 10, + /obj/machinery/plumbing/filter = 5, + /obj/machinery/plumbing/grinder_chemical = 30, + /obj/machinery/plumbing/splitter = 5 +) + /obj/item/construction/plumbing/attack_self(mob/user) ..() if(!choices.len) - for(var/A in subtypesof(/obj/machinery/plumbing)) + for(var/A in plumbing_design_types) var/obj/machinery/plumbing/M = A if(initial(M.rcd_constructable)) choices += list(initial(M.name) = image(icon = initial(M.icon), icon_state = initial(M.icon_state))) @@ -883,6 +1007,10 @@ RLD desc = "It contains direct silo connection RCD upgrade." upgrade = RCD_UPGRADE_SILO_LINK +/obj/item/rcd_upgrade/furnishing + desc = "It contains the design for chairs, stools, tables, and glass tables." + upgrade = RCD_UPGRADE_FURNISHING + #undef GLOW_MODE #undef LIGHT_MODE #undef REMOVE_MODE diff --git a/code/game/objects/items/debug_items.dm b/code/game/objects/items/debug_items.dm index cfba60c4257d2..e770be8e55f69 100644 --- a/code/game/objects/items/debug_items.dm +++ b/code/game/objects/items/debug_items.dm @@ -158,7 +158,7 @@ matter = INFINITY delay_mod = 0.1 ranged = TRUE - upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS + upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING canRturf = TRUE /obj/item/construction/rld/debug diff --git a/code/game/objects/items/stacks/rods/rods.dm b/code/game/objects/items/stacks/rods/rods.dm index 3376a344309fe..01fa00059e158 100644 --- a/code/game/objects/items/stacks/rods/rods.dm +++ b/code/game/objects/items/stacks/rods/rods.dm @@ -17,6 +17,7 @@ hitsound = 'sound/weapons/grenadelaunch.ogg' embedding = list() novariants = TRUE + matter_amount = 2 /obj/item/stack/rods/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to stuff \the [src] down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide!")//it looks like theyre ur mum diff --git a/code/game/objects/items/stacks/sheets/mineral/glass.dm b/code/game/objects/items/stacks/sheets/mineral/glass.dm index 7acb5fb24fc6d..e0ec416e94f6e 100644 --- a/code/game/objects/items/stacks/sheets/mineral/glass.dm +++ b/code/game/objects/items/stacks/sheets/mineral/glass.dm @@ -23,6 +23,7 @@ grind_results = list(/datum/reagent/silicon = 20) point_value = 1 tableVariant = /obj/structure/table/glass + matter_amount = 4 /obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -71,6 +72,7 @@ merge_type = /obj/item/stack/sheet/rglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) point_value = 4 + matter_amount = 6 /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -146,6 +148,7 @@ merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) point_value = 23 + matter_amount = 8 /obj/item/stack/sheet/plasmarglass/get_recipes() return GLOB.prglass_recipes diff --git a/code/game/objects/items/stacks/sheets/mineral/metals.dm b/code/game/objects/items/stacks/sheets/mineral/metals.dm index 7bc99b44cf8f6..2d6e0fd0a32cf 100644 --- a/code/game/objects/items/stacks/sheets/mineral/metals.dm +++ b/code/game/objects/items/stacks/sheets/mineral/metals.dm @@ -28,6 +28,7 @@ Metals Sheets grind_results = list(/datum/reagent/iron = 20) point_value = 2 tableVariant = /obj/structure/table + matter_amount = 4 /obj/item/stack/sheet/iron/ratvar_act() new /obj/item/stack/sheet/brass(loc, amount) @@ -61,6 +62,7 @@ Metals Sheets grind_results = list(/datum/reagent/iron = 20, /datum/reagent/toxin/plasma = 20) point_value = 23 tableVariant = /obj/structure/table/reinforced + matter_amount = 12 /obj/item/stack/sheet/plasteel/get_recipes() return GLOB.plasteel_recipes diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 177985ea11379..cffc364633b4e 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -38,6 +38,8 @@ var/novariants = TRUE ///Stores table variant to be built from this stack var/obj/structure/table/tableVariant + /// Amount of matter for RCD + var/matter_amount = 0 //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index a1fbf740b261b..cbf735da25f65 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -497,6 +497,7 @@ mineralType = "iron" armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70, STAMINA = 0) resistance_flags = FIRE_PROOF + matter_amount = 1 /obj/item/stack/tile/plasteel/cyborg desc = "The ground you walk on." //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 3adb0b8c64364..c9d44b53a3419 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -274,8 +274,13 @@ door.req_access = electronics.accesses if(created_name) door.name = created_name + else if(electronics.passed_name) + door.name = sanitize(electronics.passed_name) else door.name = base_name + if(electronics.passed_cycle_id) + door.closeOtherId = electronics.passed_cycle_id + door.update_other_id() door.previous_airlock = previous_assembly electronics.forceMove(door) door.update_icon() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index c1784d4cbf8ae..62411eaa38e91 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -53,10 +53,9 @@ if(RCD_DECONSTRUCT) return list("mode" = RCD_DECONSTRUCT, "delay" = 20, "cost" = 5) if(RCD_WINDOWGRILLE) - if(the_rcd.window_type == /obj/structure/window/reinforced/fulltile) + if(the_rcd.window_glass == RCD_WINDOW_REINFORCED) return list("mode" = RCD_WINDOWGRILLE, "delay" = 40, "cost" = 12) - else - return list("mode" = RCD_WINDOWGRILLE, "delay" = 20, "cost" = 8) + return list("mode" = RCD_WINDOWGRILLE, "delay" = 20, "cost" = 8) return FALSE /obj/structure/grille/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) @@ -69,17 +68,17 @@ if(RCD_WINDOWGRILLE) if(!isturf(loc)) return FALSE - var/turf/T = loc + var/turf/local_turf = loc if(!ispath(the_rcd.window_type, /obj/structure/window)) CRASH("Invalid window path type in RCD: [the_rcd.window_type]") var/obj/structure/window/window_path = the_rcd.window_type - if(!valid_window_location(T, user.dir, is_fulltile = initial(window_path.fulltile))) + if(!valid_window_location(local_turf, user.dir, is_fulltile = initial(window_path.fulltile))) to_chat(user, "Already a window in this direction!.") return FALSE to_chat(user, "You construct the window.") log_attack("[key_name(user)] has constructed a window at [loc_name(src)] using [format_text(initial(the_rcd.name))]") - var/obj/structure/window/WD = new the_rcd.window_type(T, user.dir) + var/obj/structure/window/WD = new the_rcd.window_type(local_turf, user.dir) WD.setAnchored(TRUE) return TRUE return FALSE diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 764c96ec104a0..81178075b39a2 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -248,6 +248,19 @@ new framestack(T, framestackamount) qdel(src) +/obj/structure/table/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + switch(the_rcd.mode) + if(RCD_DECONSTRUCT) + return list("mode" = RCD_DECONSTRUCT, "delay" = 24, "cost" = 16) + return FALSE + +/obj/structure/table/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_DECONSTRUCT) + to_chat(user, "You deconstruct the table.") + qdel(src) + return TRUE + return FALSE /* * Glass tables diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index fc31a345300e7..942a0514a1ad7 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -203,6 +203,8 @@ return list("mode" = RCD_MACHINE, "delay" = 20, "cost" = 25) if(RCD_COMPUTER) return list("mode" = RCD_COMPUTER, "delay" = 20, "cost" = 25) + if(RCD_FURNISHING) + return list("mode" = RCD_FURNISHING, "delay" = the_rcd.furnish_delay, "cost" = the_rcd.furnish_cost) return FALSE /turf/open/floor/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) @@ -217,28 +219,47 @@ return TRUE if(RCD_LADDER) to_chat(user, "You build a ladder.") - var/obj/structure/ladder/L = new(src) - L.anchored = TRUE + var/obj/structure/ladder/Ladder = new(src) + Ladder.anchored = TRUE return TRUE if(RCD_AIRLOCK) - if(locate(/obj/machinery/door/airlock) in src) + if(locate(/obj/machinery/door) in src) return FALSE + if(ispath(the_rcd.airlock_type, /obj/machinery/door/window)) + to_chat(user, "You build a windoor.") + var/obj/machinery/door/window/new_window = new the_rcd.airlock_type(src, user.dir, the_rcd.airlock_electronics?.unres_sides) + if(the_rcd.airlock_electronics) + new_window.name = the_rcd.airlock_electronics.passed_name || initial(new_window.name) + if(the_rcd.airlock_electronics.one_access) + new_window.req_one_access = the_rcd.airlock_electronics.accesses.Copy() + else + new_window.req_access = the_rcd.airlock_electronics.accesses.Copy() + new_window.autoclose = TRUE + new_window.update_icon() + return TRUE to_chat(user, "You build an airlock.") log_attack("[key_name(user)] has constructed an airlock at [loc_name(src)] using [format_text(initial(the_rcd.name))]") - var/obj/machinery/door/airlock/A = new the_rcd.airlock_type(src) - A.electronics = new /obj/item/electronics/airlock(A) + var/obj/machinery/door/airlock/new_airlock = new the_rcd.airlock_type(src) + new_airlock.electronics = new /obj/item/electronics/airlock(new_airlock) if(the_rcd.airlock_electronics) - A.electronics.accesses = the_rcd.airlock_electronics.accesses.Copy() - A.electronics.one_access = the_rcd.airlock_electronics.one_access - A.electronics.unres_sides = the_rcd.airlock_electronics.unres_sides - if(A.electronics.one_access) - A.req_one_access = A.electronics.accesses + new_airlock.electronics.accesses = the_rcd.airlock_electronics.accesses.Copy() + new_airlock.electronics.one_access = the_rcd.airlock_electronics.one_access + new_airlock.electronics.unres_sides = the_rcd.airlock_electronics.unres_sides + new_airlock.electronics.passed_name = the_rcd.airlock_electronics.passed_name + new_airlock.electronics.passed_cycle_id = the_rcd.airlock_electronics.passed_cycle_id + if(new_airlock.electronics.one_access) + new_airlock.req_one_access = new_airlock.electronics.accesses else - A.req_access = A.electronics.accesses - if(A.electronics.unres_sides) - A.unres_sides = A.electronics.unres_sides - A.autoclose = TRUE - A.update_icon() + new_airlock.req_access = new_airlock.electronics.accesses + if(new_airlock.electronics.unres_sides) + new_airlock.unres_sides = new_airlock.electronics.unres_sides + if(new_airlock.electronics.passed_name) + new_airlock.name = new_airlock.electronics.passed_name + if(new_airlock.electronics.passed_cycle_id) + new_airlock.closeOtherId = new_airlock.electronics.passed_cycle_id + new_airlock.update_other_id() + new_airlock.autoclose = TRUE + new_airlock.update_icon() return TRUE if(RCD_DECONSTRUCT) var/previous_turf = initial(name) @@ -252,24 +273,30 @@ return FALSE to_chat(user, "You construct the grille.") log_attack("[key_name(user)] has constructed a grille at [loc_name(src)] using [format_text(initial(the_rcd.name))]") - var/obj/structure/grille/G = new(src) - G.anchored = TRUE + var/obj/structure/grille/new_grille = new(src) + new_grille.anchored = TRUE return TRUE if(RCD_MACHINE) if(locate(/obj/structure/frame/machine) in src) return FALSE - var/obj/structure/frame/machine/M = new(src) - M.state = 2 - M.icon_state = "box_1" - M.anchored = TRUE + var/obj/structure/frame/machine/new_machine = new(src) + new_machine.state = 2 + new_machine.icon_state = "box_1" + new_machine.anchored = TRUE return TRUE if(RCD_COMPUTER) if(locate(/obj/structure/frame/computer) in src) return FALSE - var/obj/structure/frame/computer/C = new(src) - C.anchored = TRUE - C.state = 1 - C.setDir(the_rcd.computer_dir) + var/obj/structure/frame/computer/new_computer = new(src) + new_computer.anchored = TRUE + new_computer.state = 1 + new_computer.setDir(the_rcd.computer_dir) + return TRUE + if(RCD_FURNISHING) + if(locate(the_rcd.furnish_type) in src) + return FALSE + var/atom/new_furnish = new the_rcd.furnish_type(src) + new_furnish.setDir(user.dir) return TRUE return FALSE diff --git a/code/modules/mining/aux_base_camera.dm b/code/modules/mining/aux_base_camera.dm index c5de462d03f9c..186904ea06743 100644 --- a/code/modules/mining/aux_base_camera.dm +++ b/code/modules/mining/aux_base_camera.dm @@ -210,13 +210,13 @@ /datum/action/innate/aux_base/window_type - name = "Select Window Type" + name = "Select Window Glass" button_icon_state = "window_select" /datum/action/innate/aux_base/window_type/Activate() if(..()) return - B.RCD.toggle_window_type() + B.RCD.toggle_window_glass() /datum/action/innate/aux_base/place_fan name = "Place Tiny Fan" diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index d1bfe256eac84..d0493343f4b5b 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -93,6 +93,16 @@ category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/rcd_upgrade/furnishing + name = "RCD furnishing upgrade" + desc = "Adds the ability to furnish areas using the RCD." + id = "rcd_upgrade_furnishing" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 5000, /datum/material/glass = 2500, /datum/material/silver = 1500, /datum/material/titanium = 2000) + build_path = /obj/item/rcd_upgrade/furnishing + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/rcd_upgrade/silo_link name = "Advanced RCD silo link upgrade" desc = "Upgrades the RCD to be able to pull materials from the ore silo. The RCD must be linked to the silo using a multitool before it will function." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index a06697ad9488b..ce4d036d2df97 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1575,8 +1575,9 @@ description = "Unlocks new designs that improve rapid devices." design_ids = list( "rcd_upgrade_frames", + "rcd_upgrade_furnishing", "rcd_upgrade_simple_circuits", - "rpd_upgrade_unwrench", + "rpd_upgrade_unwrench" ) prereq_ids = list("adv_engi") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/icons/mob/radial.dmi b/icons/mob/radial.dmi index d0c94f15ad86c..cd9bfad2001c3 100644 Binary files a/icons/mob/radial.dmi and b/icons/mob/radial.dmi differ diff --git a/tgui/packages/tgui/interfaces/AirlockElectronics.js b/tgui/packages/tgui/interfaces/AirlockElectronics.js index 8eb0de72828d0..04125188360f4 100644 --- a/tgui/packages/tgui/interfaces/AirlockElectronics.js +++ b/tgui/packages/tgui/interfaces/AirlockElectronics.js @@ -1,11 +1,11 @@ import { useBackend } from '../backend'; -import { Button, LabeledList, Section } from '../components'; +import { Button, LabeledList, Input, Section } from '../components'; import { Window } from '../layouts'; import { AccessList } from './common/AccessList'; export const AirlockElectronics = (props, context) => { const { act, data } = useBackend(context); - const { oneAccess, unres_direction } = data; + const { oneAccess, unres_direction, passedName, passedCycleId } = data; const regions = data.regions || []; const accesses = data.accesses || []; return ( @@ -62,6 +62,30 @@ export const AirlockElectronics = (props, context) => { } /> + + + act('passedName', { + passedName: value, + }) + } + /> + + + + act('passedCycleId', { + passedCycleId: value, + }) + } + /> +