diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index b14fd514b85..802abe2c349 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -290,6 +290,7 @@ /// Icon filter that creates gaussian blur #define GAUSSIAN_BLUR(filter_size) filter(type="blur", size=filter_size) +// Colors related to items used in construction #define CABLE_COLOR_BLUE "blue" #define CABLE_HEX_COLOR_BLUE COLOR_STRONG_BLUE #define CABLE_COLOR_BROWN "brown" @@ -308,6 +309,9 @@ #define CABLE_HEX_COLOR_WHITE COLOR_WHITE #define CABLE_COLOR_YELLOW "yellow" #define CABLE_HEX_COLOR_YELLOW COLOR_YELLOW +//windows affected by Nar'Sie turn this color. +#define NARSIE_WINDOW_COLOUR "#7D1919" + #define COLOR_CARP_PURPLE "#aba2ff" #define COLOR_CARP_PINK "#da77a8" diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm deleted file mode 100644 index 4e37baadffb..00000000000 --- a/code/__DEFINES/construction.dm +++ /dev/null @@ -1,227 +0,0 @@ -/*ALL DEFINES RELATED TO CONSTRUCTION, CONSTRUCTING THINGS, OR CONSTRUCTED OBJECTS GO HERE*/ - -//Defines for construction states - -//girder construction states -#define GIRDER_NORMAL 0 -#define GIRDER_REINF_STRUTS 1 -#define GIRDER_REINF 2 -#define GIRDER_DISPLACED 3 -#define GIRDER_DISASSEMBLED 4 -#define GIRDER_TRAM 5 - -//rwall construction states -#define INTACT 0 -#define SUPPORT_LINES 1 -#define COVER 2 -#define CUT_COVER 3 -#define ANCHOR_BOLTS 4 -#define SUPPORT_RODS 5 -#define SHEATH 6 - -//window construction states -#define WINDOW_OUT_OF_FRAME 0 -#define WINDOW_IN_FRAME 1 -#define WINDOW_SCREWED_TO_FRAME 2 - -//reinforced window construction states -#define RWINDOW_FRAME_BOLTED 3 -#define RWINDOW_BARS_CUT 4 -#define RWINDOW_POPPED 5 -#define RWINDOW_BOLTS_OUT 6 -#define RWINDOW_BOLTS_HEATED 7 -#define RWINDOW_SECURE 8 - -//airlock assembly construction states -#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0 -#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1 -#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2 - -//blast door (de)construction states -#define BLASTDOOR_NEEDS_WIRES 0 -#define BLASTDOOR_NEEDS_ELECTRONICS 1 -#define BLASTDOOR_FINISHED 2 - -//default_unfasten_wrench() return defines -#define CANT_UNFASTEN 0 -#define FAILED_UNFASTEN 1 -#define SUCCESSFUL_UNFASTEN 2 - -//ai core defines -#define EMPTY_CORE 0 -#define CIRCUIT_CORE 1 -#define SCREWED_CORE 2 -#define CABLED_CORE 3 -#define GLASS_CORE 4 -#define AI_READY_CORE 5 - -//Construction defines for the pinion airlock -#define GEAR_SECURE 1 -#define GEAR_LOOSE 2 - -//floodlights because apparently we use defines now -#define FLOODLIGHT_NEEDS_WIRES 0 -#define FLOODLIGHT_NEEDS_LIGHTS 1 -#define FLOODLIGHT_NEEDS_SECURING 2 - -// Stationary gas tanks -#define TANK_FRAME 0 -#define TANK_PLATING_UNSECURED 1 - -//other construction-related things - -//windows affected by Nar'Sie turn this color. -#define NARSIE_WINDOW_COLOUR "#7D1919" - -// Defines related to the custom materials used on objects. -///The amount of materials you get from a sheet of mineral like iron/diamond/glass etc. 100 Units. -#define SHEET_MATERIAL_AMOUNT 100 -///The amount of materials you get from half a sheet. Used in standard object quantities. 50 units. -#define HALF_SHEET_MATERIAL_AMOUNT (SHEET_MATERIAL_AMOUNT/2) -///The amount of materials used in the smallest of objects, like pens and screwdrivers. 10 units. -#define SMALL_MATERIAL_AMOUNT (HALF_SHEET_MATERIAL_AMOUNT/5) -///The amount of material that goes into a coin, which determines the value of the coin. -#define COIN_MATERIAL_AMOUNT (HALF_SHEET_MATERIAL_AMOUNT * 0.4) - -//The maximum size of a stack object. -#define MAX_STACK_SIZE 50 -//maximum amount of cable in a coil -#define MAXCOIL 30 - -//food/drink crafting defines -//When adding new defines, please make sure to also add them to the encompassing list -#define CAT_FOOD "Foods" -#define CAT_BREAD "Breads" -#define CAT_BURGER "Burgers" -#define CAT_CAKE "Cakes" -#define CAT_EGG "Egg-Based Food" -#define CAT_LIZARD "Lizard Food" -#define CAT_MEAT "Meats" -#define CAT_SEAFOOD "Seafood" -#define CAT_MARTIAN "Martian Food" -#define CAT_MISCFOOD "Misc. Food" -#define CAT_MEXICAN "Mexican Food" -#define CAT_MOTH "Mothic Food" -#define CAT_PASTRY "Pastries" -#define CAT_PIE "Pies" -#define CAT_PIZZA "Pizzas" -#define CAT_SALAD "Salads" -#define CAT_SANDWICH "Sandwiches" -#define CAT_SOUP "Soups" -#define CAT_SPAGHETTI "Spaghettis" -#define CAT_ICE "Frozen" -#define CAT_DRINK "Drinks" - -GLOBAL_LIST_INIT(crafting_category_food, list( - CAT_FOOD, - CAT_BREAD, - CAT_BURGER, - CAT_CAKE, - CAT_EGG, - CAT_LIZARD, - CAT_MEAT, - CAT_SEAFOOD, - CAT_MARTIAN, - CAT_MISCFOOD, - CAT_MEXICAN, - CAT_MOTH, - CAT_PASTRY, - CAT_PIE, - CAT_PIZZA, - CAT_SALAD, - CAT_SANDWICH, - CAT_SOUP, - CAT_SPAGHETTI, - CAT_ICE, - CAT_DRINK, -)) - -//crafting defines -//When adding new defines, please make sure to also add them to the encompassing list -#define CAT_WEAPON_RANGED "Weapons Ranged" -#define CAT_WEAPON_MELEE "Weapons Melee" -#define CAT_WEAPON_AMMO "Weapon Ammo" -#define CAT_ROBOT "Robotics" -#define CAT_MISC "Misc" -#define CAT_CLOTHING "Clothing" -#define CAT_CHEMISTRY "Chemistry" -#define CAT_ATMOSPHERIC "Atmospherics" -#define CAT_STRUCTURE "Structures" -#define CAT_TILES "Tiles" -#define CAT_WINDOWS "Windows" -#define CAT_DOORS "Doors" -#define CAT_FURNITURE "Furniture" -#define CAT_EQUIPMENT "Equipment" -#define CAT_CONTAINERS "Containers" -#define CAT_ENTERTAINMENT "Entertainment" -#define CAT_TOOLS "Tools" -#define CAT_CULT "Blood Cult" - -GLOBAL_LIST_INIT(crafting_category, list( - CAT_WEAPON_RANGED, - CAT_WEAPON_MELEE, - CAT_WEAPON_AMMO, - CAT_ROBOT, - CAT_MISC, - CAT_CLOTHING, - CAT_CHEMISTRY, - CAT_ATMOSPHERIC, - CAT_STRUCTURE, - CAT_TILES, - CAT_WINDOWS, - CAT_DOORS, - CAT_FURNITURE, - CAT_EQUIPMENT, - CAT_CONTAINERS, - CAT_ENTERTAINMENT, - CAT_TOOLS, - CAT_CULT, -)) - -//rcd modes -#define RCD_FLOORWALL 0 -#define RCD_AIRLOCK 1 -#define RCD_DECONSTRUCT 2 -#define RCD_WINDOWGRILLE 3 -#define RCD_MACHINE 4 -#define RCD_COMPUTER 5 -#define RCD_FURNISHING 6 -#define RCD_CATWALK 7 -#define RCD_FLOODLIGHT 8 -#define RCD_WALLFRAME 9 -#define RCD_REFLECTOR 10 -#define RCD_GIRDER 11 - - -#define RCD_UPGRADE_FRAMES (1<<0) -#define RCD_UPGRADE_SIMPLE_CIRCUITS (1<<1) -#define RCD_UPGRADE_SILO_LINK (1<<2) -#define RCD_UPGRADE_FURNISHING (1<<3) -#define RCD_UPGRADE_ANTI_INTERRUPT (1<<4) -#define RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN (1<<5) - -#define RPD_UPGRADE_UNWRENCH (1<<0) - -#define RCD_WINDOW_FULLTILE "full tile" -#define RCD_WINDOW_DIRECTIONAL "directional" -#define RCD_WINDOW_NORMAL "glass" -#define RCD_WINDOW_REINFORCED "reinforced glass" - -#define RCD_MEMORY_WALL 1 -#define RCD_MEMORY_WINDOWGRILLE 2 - -// How much faster to use the RCD when on a tile with memory -#define RCD_MEMORY_SPEED_BUFF 5 - -/// How much less resources the RCD uses when reconstructing -#define RCD_MEMORY_COST_BUFF 8 - -/// If set to TRUE in rcd_vals, will bypass the cooldown on slowing down frequent use -#define RCD_RESULT_BYPASS_FREQUENT_USE_COOLDOWN "bypass_frequent_use_cooldown" - -// Defines for the construction component -#define FORWARD 1 -#define BACKWARD -1 - -#define ITEM_DELETE "delete" -#define ITEM_MOVE_INSIDE "move_inside" diff --git a/code/__DEFINES/construction/actions.dm b/code/__DEFINES/construction/actions.dm new file mode 100644 index 00000000000..9fe4fd157e3 --- /dev/null +++ b/code/__DEFINES/construction/actions.dm @@ -0,0 +1,11 @@ +//default_unfasten_wrench() return defines +#define CANT_UNFASTEN 0 +#define FAILED_UNFASTEN 1 +#define SUCCESSFUL_UNFASTEN 2 + +// Defines for the construction component +#define FORWARD 1 +#define BACKWARD -1 + +#define ITEM_DELETE "delete" +#define ITEM_MOVE_INSIDE "move_inside" diff --git a/code/__DEFINES/materials.dm b/code/__DEFINES/construction/material.dm similarity index 72% rename from code/__DEFINES/materials.dm rename to code/__DEFINES/construction/material.dm index 5fc5cc08ea2..dad575c58c3 100644 --- a/code/__DEFINES/materials.dm +++ b/code/__DEFINES/construction/material.dm @@ -1,31 +1,43 @@ +//Defines for amount of material retrived from sheets & other items +/// The amount of materials you get from a sheet of mineral like iron/diamond/glass etc. 100 Units. +#define SHEET_MATERIAL_AMOUNT 100 +/// The amount of materials you get from half a sheet. Used in standard object quantities. 50 units. +#define HALF_SHEET_MATERIAL_AMOUNT (SHEET_MATERIAL_AMOUNT / 2) +/// The amount of materials used in the smallest of objects, like pens and screwdrivers. 10 units. +#define SMALL_MATERIAL_AMOUNT (HALF_SHEET_MATERIAL_AMOUNT / 5) +/// The amount of material that goes into a coin, which determines the value of the coin. +#define COIN_MATERIAL_AMOUNT (HALF_SHEET_MATERIAL_AMOUNT * 0.4) + +//Cable related values +/// The maximum size of a stack object. +#define MAX_STACK_SIZE 50 +/// Maximum amount of cable in a coil +#define MAXCOIL 30 + +//Category of materials /// Is the material from an ore? currently unused but exists atm for categorizations sake #define MAT_CATEGORY_ORE "ore capable" - /// Hard materials, such as iron or silver #define MAT_CATEGORY_RIGID "rigid material" - /// Materials that can be used to craft items #define MAT_CATEGORY_ITEM_MATERIAL "item material" - -///Use this flag on TRUE if you want the basic recipes +/// Use this flag on TRUE if you want the basic recipes #define MAT_CATEGORY_BASE_RECIPES "basic recipes" +///Flags for map loaded materials /// Used to make a material initialize at roundstart. #define MATERIAL_INIT_MAPLOAD (1<<0) /// Used to make a material type able to be instantiated on demand after roundstart. #define MATERIAL_INIT_BESPOKE (1<<1) -/// Makes sure only integer values are used when consuming, removing & checking for mats -#define OPTIMAL_COST(cost)(max(1, round(cost))) - //Material Container Flags. ///If the container shows the amount of contained materials on examine. #define MATCONTAINER_EXAMINE (1<<0) ///If the container cannot have materials inserted through attackby(). #define MATCONTAINER_NO_INSERT (1<<1) -///if the user can insert mats into the container despite the intent. +///If the user can insert mats into the container despite the intent. #define MATCONTAINER_ANY_INTENT (1<<2) -///if the user won't receive a warning when attacking the container with an unallowed item. +///If the user won't receive a warning when attacking the container with an unallowed item. #define MATCONTAINER_SILENT (1<<3) // The following flags are for decomposing alloys. Should be expanded upon and diversified once someone gets around to reworking recycling. @@ -59,14 +71,12 @@ /// Applies the material greyscale color to the atom's greyscale color. #define MATERIAL_GREYSCALE (1<<4) -/// Wrapper for fetching material references. Exists exclusively so that people don't need to wrap everything in a list every time. -#define GET_MATERIAL_REF(arguments...) SSmaterials._GetMaterialRef(list(##arguments)) - -#define MATERIAL_SOURCE(mat) "[mat.name]_material" - -///Special return values of [/datum/component/material_container/insert_item] +//Special return values of [/datum/component/material_container/insert_item] +/// No material was found inside them item #define MATERIAL_INSERT_ITEM_NO_MATS -1 +/// The container does not have the space for the item #define MATERIAL_INSERT_ITEM_NO_SPACE -2 +/// The item material type was not accepted or other reasons #define MATERIAL_INSERT_ITEM_FAILURE 0 diff --git a/code/__DEFINES/construction/rcd.dm b/code/__DEFINES/construction/rcd.dm new file mode 100644 index 00000000000..e8c9ae55f32 --- /dev/null +++ b/code/__DEFINES/construction/rcd.dm @@ -0,0 +1,50 @@ +//rcd constants for the design list +/// The mode of operation to design an specific type of rcd design +#define RCD_DESIGN_MODE "rcd_design_mode" + /// For changing turfs + #define RCD_TURF (1 << 0) + /// Full tile windows + #define RCD_WINDOWGRILLE (1 << 1) + /// Windoors & Airlocks + #define RCD_AIRLOCK (1 << 2) + /// Literarly anything that is spawned on top of a turf such as tables, machines etc + #define RCD_STRUCTURE (1 << 3) + /// For wallmounts like air alarms, fire alarms & apc + #define RCD_WALLFRAME (1 << 4) + /// For deconstructing an structure + #define RCD_DECONSTRUCT (1 << 5) +/// The typepath of the structure the rcd is trying to build +#define RCD_DESIGN_PATH "rcd_design_path" + +/// Time taken for an rcd hologram to disappear +#define RCD_HOLOGRAM_FADE_TIME (15 SECONDS) + +//All available upgrades +/// Upgrade for building machines +#define RCD_UPGRADE_FRAMES (1 << 0) +/// Upgrade for installing circuitboards in air alarms, fire alarms, apc & cells in them +#define RCD_UPGRADE_SIMPLE_CIRCUITS (1 << 1) +/// Upgrade for drawing iron from ore silo +#define RCD_UPGRADE_SILO_LINK (1 << 2) +/// Upgrade for building furnishing items +#define RCD_UPGRADE_FURNISHING (1 << 3) +/// Upgrade to stop construction effect from getting attacked +#define RCD_UPGRADE_ANTI_INTERRUPT (1 << 4) +/// Upgrade to disable delay multiplier when building multiple structures +#define RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN (1 << 5) +/// All upgrades packed in 1 flag +#define RCD_ALL_UPGRADES (RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_SILO_LINK | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN) +/// Upgrades for the Rapid Pipe Dispenser to unwrench pipes +#define RPD_UPGRADE_UNWRENCH (1 << 0) + +//Memory constants for faster construction speeds +/// The memory constant for a wall +#define RCD_MEMORY_WALL 1 +/// The memory constant for full tile windows +#define RCD_MEMORY_WINDOWGRILLE 2 +// How much faster to use the RCD when on a tile with memory +#define RCD_MEMORY_SPEED_BUFF 5 +/// How much less resources the RCD uses when reconstructing +#define RCD_MEMORY_COST_BUFF 8 +/// If set to TRUE in rcd_vals, will bypass the cooldown on slowing down frequent use +#define RCD_RESULT_BYPASS_FREQUENT_USE_COOLDOWN "bypass_frequent_use_cooldown" diff --git a/code/__DEFINES/construction/structures.dm b/code/__DEFINES/construction/structures.dm new file mode 100644 index 00000000000..cda5b920a42 --- /dev/null +++ b/code/__DEFINES/construction/structures.dm @@ -0,0 +1,62 @@ +//Defines for construction states + +//ai core defines +#define EMPTY_CORE 0 +#define CIRCUIT_CORE 1 +#define SCREWED_CORE 2 +#define CABLED_CORE 3 +#define GLASS_CORE 4 +#define AI_READY_CORE 5 + +//girder construction states +#define GIRDER_NORMAL 0 +#define GIRDER_REINF_STRUTS 1 +#define GIRDER_REINF 2 +#define GIRDER_DISPLACED 3 +#define GIRDER_DISASSEMBLED 4 +#define GIRDER_TRAM 5 + +//rwall construction states +#define INTACT 0 +#define SUPPORT_LINES 1 +#define COVER 2 +#define CUT_COVER 3 +#define ANCHOR_BOLTS 4 +#define SUPPORT_RODS 5 +#define SHEATH 6 + +//window construction states +#define WINDOW_OUT_OF_FRAME 0 +#define WINDOW_IN_FRAME 1 +#define WINDOW_SCREWED_TO_FRAME 2 + +//reinforced window construction states +#define RWINDOW_FRAME_BOLTED 3 +#define RWINDOW_BARS_CUT 4 +#define RWINDOW_POPPED 5 +#define RWINDOW_BOLTS_OUT 6 +#define RWINDOW_BOLTS_HEATED 7 +#define RWINDOW_SECURE 8 + +//airlock assembly construction states +#define AIRLOCK_ASSEMBLY_NEEDS_WIRES 0 +#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1 +#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2 + +//blast door (de)construction states +#define BLASTDOOR_NEEDS_WIRES 0 +#define BLASTDOOR_NEEDS_ELECTRONICS 1 +#define BLASTDOOR_FINISHED 2 + +//floodlights because apparently we use defines now +#define FLOODLIGHT_NEEDS_WIRES 0 +#define FLOODLIGHT_NEEDS_LIGHTS 1 +#define FLOODLIGHT_NEEDS_SECURING 2 + +//Construction defines for the pinion airlock +#define GEAR_SECURE 1 +#define GEAR_LOOSE 2 + +// Stationary gas tanks +#define TANK_FRAME 0 +#define TANK_PLATING_UNSECURED 1 diff --git a/code/__DEFINES/crafting.dm b/code/__DEFINES/crafting.dm index 75e82816786..647278aa3ec 100644 --- a/code/__DEFINES/crafting.dm +++ b/code/__DEFINES/crafting.dm @@ -6,3 +6,48 @@ #define CRAFTING_MACHINERY_USE 0 ///If the structure is only "used" i.e. it checks to see if it's nearby and allows crafting, but doesn't delete it #define CRAFTING_STRUCTURE_USE 0 + +//food/drink crafting defines +//When adding new defines, please make sure to also add them to the encompassing list +#define CAT_FOOD "Foods" +#define CAT_BREAD "Breads" +#define CAT_BURGER "Burgers" +#define CAT_CAKE "Cakes" +#define CAT_EGG "Egg-Based Food" +#define CAT_LIZARD "Lizard Food" +#define CAT_MEAT "Meats" +#define CAT_SEAFOOD "Seafood" +#define CAT_MARTIAN "Martian Food" +#define CAT_MISCFOOD "Misc. Food" +#define CAT_MEXICAN "Mexican Food" +#define CAT_MOTH "Mothic Food" +#define CAT_PASTRY "Pastries" +#define CAT_PIE "Pies" +#define CAT_PIZZA "Pizzas" +#define CAT_SALAD "Salads" +#define CAT_SANDWICH "Sandwiches" +#define CAT_SOUP "Soups" +#define CAT_SPAGHETTI "Spaghettis" +#define CAT_ICE "Frozen" +#define CAT_DRINK "Drinks" + +//crafting defines +//When adding new defines, please make sure to also add them to the encompassing list +#define CAT_WEAPON_RANGED "Weapons Ranged" +#define CAT_WEAPON_MELEE "Weapons Melee" +#define CAT_WEAPON_AMMO "Weapon Ammo" +#define CAT_ROBOT "Robotics" +#define CAT_MISC "Misc" +#define CAT_CLOTHING "Clothing" +#define CAT_CHEMISTRY "Chemistry" +#define CAT_ATMOSPHERIC "Atmospherics" +#define CAT_STRUCTURE "Structures" +#define CAT_TILES "Tiles" +#define CAT_WINDOWS "Windows" +#define CAT_DOORS "Doors" +#define CAT_FURNITURE "Furniture" +#define CAT_EQUIPMENT "Equipment" +#define CAT_CONTAINERS "Containers" +#define CAT_ENTERTAINMENT "Entertainment" +#define CAT_TOOLS "Tools" +#define CAT_CULT "Blood Cult" diff --git a/code/__HELPERS/construction.dm b/code/__HELPERS/construction.dm index 9d21362a87a..9cc7d112532 100644 --- a/code/__HELPERS/construction.dm +++ b/code/__HELPERS/construction.dm @@ -1,5 +1,18 @@ -/// Produces a new RCD result from the given one if it can be calculated that -/// the RCD should speed up with the remembered form. +/// Makes sure only integer values are used when consuming, removing & checking for mats +#define OPTIMAL_COST(cost)(max(1, round(cost))) + +/// Wrapper for fetching material references. Exists exclusively so that people don't need to wrap everything in a list every time. +#define GET_MATERIAL_REF(arguments...) SSmaterials._GetMaterialRef(list(##arguments)) + +// Wrapper to convert material name into its source name +#define MATERIAL_SOURCE(mat) "[mat.name]_material" + + +/** + * Produces a new RCD result from the given one if it can be calculated that + * the RCD should speed up with the remembered form. + * + */ /proc/rcd_result_with_memory(list/defaults, turf/place, expected_memory) if (place?.rcd_memory == expected_memory) return defaults + list( diff --git a/code/_globalvars/lists/crafting.dm b/code/_globalvars/lists/crafting.dm new file mode 100644 index 00000000000..48b2b61a42b --- /dev/null +++ b/code/_globalvars/lists/crafting.dm @@ -0,0 +1,44 @@ +GLOBAL_LIST_INIT(crafting_category_food, list( + CAT_FOOD, + CAT_BREAD, + CAT_BURGER, + CAT_CAKE, + CAT_EGG, + CAT_LIZARD, + CAT_MEAT, + CAT_SEAFOOD, + CAT_MARTIAN, + CAT_MISCFOOD, + CAT_MEXICAN, + CAT_MOTH, + CAT_PASTRY, + CAT_PIE, + CAT_PIZZA, + CAT_SALAD, + CAT_SANDWICH, + CAT_SOUP, + CAT_SPAGHETTI, + CAT_ICE, + CAT_DRINK, +)) + +GLOBAL_LIST_INIT(crafting_category, list( + CAT_WEAPON_RANGED, + CAT_WEAPON_MELEE, + CAT_WEAPON_AMMO, + CAT_ROBOT, + CAT_MISC, + CAT_CLOTHING, + CAT_CHEMISTRY, + CAT_ATMOSPHERIC, + CAT_STRUCTURE, + CAT_TILES, + CAT_WINDOWS, + CAT_DOORS, + CAT_FURNITURE, + CAT_EQUIPMENT, + CAT_CONTAINERS, + CAT_ENTERTAINMENT, + CAT_TOOLS, + CAT_CULT, +)) diff --git a/code/_globalvars/lists/rcd.dm b/code/_globalvars/lists/rcd.dm new file mode 100644 index 00000000000..86f546df223 --- /dev/null +++ b/code/_globalvars/lists/rcd.dm @@ -0,0 +1,90 @@ +///all stuff used by RCD for construction +GLOBAL_LIST_INIT(rcd_designs, list( + //1ST ROOT CATEGORY + "Construction" = list( //Stuff you use to make & decorate areas + //Walls & Windows + "Structures" = list( + list(RCD_DESIGN_MODE = RCD_TURF, RCD_DESIGN_PATH = /turf/open/floor/plating/rcd), + list(RCD_DESIGN_MODE = RCD_WINDOWGRILLE, RCD_DESIGN_PATH = /obj/structure/window), + list(RCD_DESIGN_MODE = RCD_WINDOWGRILLE, RCD_DESIGN_PATH = /obj/structure/window/reinforced), + list(RCD_DESIGN_MODE = RCD_WINDOWGRILLE, RCD_DESIGN_PATH = /obj/structure/window/fulltile), + list(RCD_DESIGN_MODE = RCD_WINDOWGRILLE, RCD_DESIGN_PATH = /obj/structure/window/reinforced/fulltile), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/reflector/wrenched), + list(RCD_DESIGN_MODE = RCD_TURF, RCD_DESIGN_PATH = /obj/structure/lattice/catwalk), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/girder), + ), + + //Computers & Machine Frames + "Machines" = list( + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/frame/machine/secured), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/frame/computer/rcd/north), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/frame/computer/rcd/south), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/frame/computer/rcd/east), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/frame/computer/rcd/west), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/floodlight_frame/completed), + list(RCD_DESIGN_MODE = RCD_WALLFRAME, RCD_DESIGN_PATH = /obj/item/wallframe/apc), + list(RCD_DESIGN_MODE = RCD_WALLFRAME, RCD_DESIGN_PATH = /obj/item/wallframe/airalarm), + list(RCD_DESIGN_MODE = RCD_WALLFRAME, RCD_DESIGN_PATH = /obj/item/wallframe/firealarm), + ), + + //Interior Design[construction_mode = RCD_FURNISHING is implied] + "Furniture" = list( + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/chair), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/chair/stool), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/chair/stool/bar), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/table), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/table/glass), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/rack), + list(RCD_DESIGN_MODE = RCD_STRUCTURE, RCD_DESIGN_PATH = /obj/structure/bed), + ), + ), + + //2ND ROOT CATEGORY[construction_mode = RCD_AIRLOCK is implied,"icon=closed"] + "Airlocks" = list( //used to seal/close areas + //Window Doors[airlock_glass = TRUE is implied] + "Windoors" = list( + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/window), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/window/brigdoor), + ), + + //Glass Airlocks[airlock_glass = TRUE is implied,do fill_closed overlay] + "Glass Airlocks" = list( + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/public/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/engineering/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/atmos/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/security/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/command/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/medical/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/research/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/virology/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/mining/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/external/glass), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance/external/glass), + ), + + //Solid Airlocks[airlock_glass = FALSE is implied,no fill_closed overlay] + "Solid Airlocks" = list( + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/public), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/engineering), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/atmos), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/security), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/command), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/medical), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/research), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/freezer), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/virology), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/mining), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/external), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance/external), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/hatch), + list(RCD_DESIGN_MODE = RCD_AIRLOCK, RCD_DESIGN_PATH = /obj/machinery/door/airlock/maintenance_hatch), + ), + ), + + //3RD CATEGORY Airlock access,empty list cause airlock_electronics UI will be displayed when this tab is selected + "Airlock Access" = list() +)) diff --git a/code/_globalvars/rcd.dm b/code/_globalvars/rcd.dm new file mode 100644 index 00000000000..9e674273bf9 --- /dev/null +++ b/code/_globalvars/rcd.dm @@ -0,0 +1,13 @@ +GLOBAL_VAR_INIT(icon_holographic_wall, init_holographic_wall()) +GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) + +/proc/init_holographic_wall() + return icon('icons/turf/walls/wall.dmi', "wall-0") + +/proc/init_holographic_window() + var/icon/grille_icon = icon('icons/obj/structures.dmi', "grille") + var/icon/window_icon = icon('icons/obj/smooth_structures/window.dmi', "window-0") + + grille_icon.Blend(window_icon, ICON_OVERLAY) + + return grille_icon diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 2ded8d992ad..edca877d905 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1032,8 +1032,8 @@ * * Default behaviour is to send [COMSIG_ATOM_RCD_ACT] and return FALSE */ -/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode) +/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, rcd_data["[RCD_DESIGN_MODE]"]) return FALSE /** diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 5230dbe9e09..a252e124723 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -234,3 +234,37 @@ if(state >= 3) new /obj/item/stack/cable_coil(drop_location(), 5) ..() + +/// Helpers for rcd +/obj/structure/frame/computer/rcd + icon = 'icons/hud/radial.dmi' + icon_state = "cnorth" + +/obj/structure/frame/computer/rcd/Initialize(mapload) + name = "computer frame" + icon = 'icons/obj/assemblies/stock_parts.dmi' + icon_state = "0" + + . = ..() + + set_anchored(TRUE) + +/obj/structure/frame/computer/rcd/north + dir = NORTH + name = "Computer North" + icon_state = "cnorth" + +/obj/structure/frame/computer/rcd/south + dir = SOUTH + name = "Computer South" + icon_state = "csouth" + +/obj/structure/frame/computer/rcd/east + dir = EAST + name = "Computer East" + icon_state = "ceast" + +/obj/structure/frame/computer/rcd/west + dir = WEST + name = "Computer West" + icon_state = "cwest" diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 3bf44a9aa9e..228f849b4ae 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -428,3 +428,12 @@ new physical_object_type(drop_location()) else stack_trace("Invalid component [component] was found in constructable frame") + +/obj/structure/frame/machine/secured + state = 2 + icon_state = "box_1" + +/obj/structure/frame/machine/secured/Initialize(mapload) + . = ..() + + set_anchored(TRUE) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index a1fa73b1f8b..33ad787116c 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1563,13 +1563,12 @@ if(security_level != AIRLOCK_SECURITY_NONE) to_chat(user, span_notice("[src]'s reinforcement needs to be removed first.")) return FALSE - return list("mode" = RCD_DECONSTRUCT, "delay" = 5 SECONDS, "cost" = 32) + return list("delay" = 5 SECONDS, "cost" = 32) return FALSE -/obj/machinery/door/airlock/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) +/obj/machinery/door/airlock/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) if(RCD_DECONSTRUCT) - to_chat(user, span_notice("You deconstruct the airlock.")) qdel(src) return TRUE return FALSE @@ -1806,24 +1805,29 @@ // Station Airlocks Regular /obj/machinery/door/airlock/command + name = "command airlock" icon = 'icons/obj/doors/airlocks/station/command.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_com normal_integrity = 450 /obj/machinery/door/airlock/security + name = "security airlock" icon = 'icons/obj/doors/airlocks/station/security.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_sec normal_integrity = 450 /obj/machinery/door/airlock/engineering + name = "engineering airlock" icon = 'icons/obj/doors/airlocks/station/engineering.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_eng /obj/machinery/door/airlock/medical + name = "medical airlock" icon = 'icons/obj/doors/airlocks/station/medical.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_med /obj/machinery/door/airlock/hydroponics //Hydroponics front doors! + name = "hydroponics airlock" icon = 'icons/obj/doors/airlocks/station/hydroponics.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_hydro @@ -1849,6 +1853,7 @@ assemblytype = /obj/structure/door_assembly/door_assembly_atmo /obj/machinery/door/airlock/research + name = "research airlock" icon = 'icons/obj/doors/airlocks/station/research.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_research @@ -1858,16 +1863,19 @@ assemblytype = /obj/structure/door_assembly/door_assembly_fre /obj/machinery/door/airlock/science + name = "science airlock" icon = 'icons/obj/doors/airlocks/station/science.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_science /obj/machinery/door/airlock/virology + name = "virology airlock" icon = 'icons/obj/doors/airlocks/station/virology.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_viro // Station Airlocks Glass /obj/machinery/door/airlock/glass + name = "glass airlock" opacity = FALSE glass = TRUE @@ -1885,11 +1893,13 @@ id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR /obj/machinery/door/airlock/command/glass + name = "command glass airlock" opacity = FALSE glass = TRUE normal_integrity = 400 /obj/machinery/door/airlock/engineering/glass + name = "engineering glass airlock" opacity = FALSE glass = TRUE @@ -1897,19 +1907,23 @@ critical_machine = TRUE //stops greytide virus from opening & bolting doors in critical positions, such as the SM chamber. /obj/machinery/door/airlock/security/glass + name = "security glass airlock" opacity = FALSE glass = TRUE normal_integrity = 400 /obj/machinery/door/airlock/medical/glass + name = "medical glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/hydroponics/glass //Uses same icon as medical/glass, maybe update it with its own unique icon one day? + name = "hydroponics glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/research/glass + name = "research glass airlock" opacity = FALSE glass = TRUE @@ -1926,10 +1940,12 @@ id_tag = INCINERATOR_ORDMIX_AIRLOCK_EXTERIOR /obj/machinery/door/airlock/mining/glass + name = "mining glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/atmos/glass + name = "atmospheric glass airlock" opacity = FALSE glass = TRUE @@ -1937,18 +1953,22 @@ critical_machine = TRUE //stops greytide virus from opening & bolting doors in critical positions, such as the SM chamber. /obj/machinery/door/airlock/science/glass + name = "science glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/virology/glass + name = "virology glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/maintenance/glass + name = "maintainence glass airlock" opacity = FALSE glass = TRUE /obj/machinery/door/airlock/maintenance/external/glass + name = "maintainence external glass airlock" opacity = FALSE glass = TRUE normal_integrity = 200 @@ -2108,11 +2128,13 @@ // Public Airlocks /obj/machinery/door/airlock/public + name = "public airlock" icon = 'icons/obj/doors/airlocks/public/glass.dmi' overlays_file = 'icons/obj/doors/airlocks/public/overlays.dmi' assemblytype = /obj/structure/door_assembly/door_assembly_public /obj/machinery/door/airlock/public/glass + name = "public glass airlock" opacity = FALSE glass = TRUE @@ -2183,6 +2205,7 @@ /obj/machinery/door/airlock/external/ruin /obj/machinery/door/airlock/external/glass + name = "external glass airlock" opacity = FALSE glass = TRUE diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b8568863600..d7254e7f6b1 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -889,21 +889,19 @@ /obj/structure/firelock_frame/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if(the_rcd.mode == RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 5 SECONDS, "cost" = 16) + return list("delay" = 5 SECONDS, "cost" = 16) else if((constructionStep == CONSTRUCTION_NO_CIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) - return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 2 SECONDS, "cost" = 1) + return list("delay" = 2 SECONDS, "cost" = 1) return FALSE -/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) +/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) if(RCD_UPGRADE_SIMPLE_CIRCUITS) - user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \ - span_notice("You adapt a firelock circuit and slot it into the assembly.")) + user.balloon_alert(user, "circuit installed") constructionStep = CONSTRUCTION_PANEL_OPEN update_appearance() return TRUE if(RCD_DECONSTRUCT) - to_chat(user, span_notice("You deconstruct [src].")) qdel(src) return TRUE return FALSE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 35044d5a81a..30b4e04c4cc 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -441,15 +441,13 @@ /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" = 5 SECONDS, "cost" = 32) + return list("delay" = 5 SECONDS, "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, span_notice("You deconstruct the windoor.")) - qdel(src) - return TRUE +/obj/machinery/door/window/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT) + qdel(src) + return TRUE return FALSE /obj/machinery/door/window/brigdoor diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 82c5ce56a16..ad822a7171a 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -413,14 +413,13 @@ /obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if((buildstage == FIRE_ALARM_BUILD_NO_CIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) - return list("mode" = RCD_WALLFRAME, "delay" = 2 SECONDS, "cost" = 1) + return list("delay" = 2 SECONDS, "cost" = 1) return FALSE -/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) +/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) if(RCD_WALLFRAME) - user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \ - span_notice("You adapt a fire alarm circuit and slot it into the assembly.")) + balloon_alert(user, "circuit installed") buildstage = FIRE_ALARM_BUILD_NO_WIRES update_appearance() return TRUE diff --git a/code/game/objects/effects/rcd.dm b/code/game/objects/effects/rcd.dm new file mode 100644 index 00000000000..17ea3e44a10 --- /dev/null +++ b/code/game/objects/effects/rcd.dm @@ -0,0 +1,43 @@ +/// How many tiles within player radius does it perform a rcd scan in +#define RCD_DESTRUCTIVE_SCAN_RANGE 10 + +/** + * Global proc that generates RCD hologram in a range. + * + * Arguments: + * * source - The atom the scans originate from + * * scan_range - The range of turfs we grab from the source + * * fade_time - The time for RCD holograms to fade + */ +/proc/rcd_scan(atom/source, scan_range = RCD_DESTRUCTIVE_SCAN_RANGE, fade_time = RCD_HOLOGRAM_FADE_TIME) + playsound(source, 'sound/items/rcdscan.ogg', 50, vary = TRUE, pressure_affected = FALSE) + + var/turf/source_turf = get_turf(source) + for(var/turf/open/surrounding_turf as anything in RANGE_TURFS(scan_range, source_turf)) + var/rcd_memory = surrounding_turf.rcd_memory + if(!rcd_memory) + continue + + var/skip_to_next_turf = FALSE + + for(var/atom/content_of_turf as anything in surrounding_turf.contents) + if (content_of_turf.density) + skip_to_next_turf = TRUE + break + + if(skip_to_next_turf) + continue + + var/hologram_icon + switch(rcd_memory) + if(RCD_MEMORY_WALL) + hologram_icon = GLOB.icon_holographic_wall + if(RCD_MEMORY_WINDOWGRILLE) + hologram_icon = GLOB.icon_holographic_window + + var/obj/effect/rcd_hologram/hologram = new(surrounding_turf) + hologram.icon = hologram_icon + hologram.makeHologram() + animate(hologram, alpha = 0, time = fade_time, easing = CIRCULAR_EASING | EASE_IN) + +#undef RCD_DESTRUCTIVE_SCAN_RANGE diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index 33994c91774..e2a391a2278 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -1,27 +1,9 @@ -#define RCD_DESTRUCTIVE_SCAN_RANGE 10 -#define RCD_HOLOGRAM_FADE_TIME (15 SECONDS) -#define RCD_DESTRUCTIVE_SCAN_COOLDOWN (RCD_HOLOGRAM_FADE_TIME + 1 SECONDS) - -///each define maps to a variable used for construction in the RCD -#define CONSTRUCTION_MODE "construction_mode" -#define WINDOW_TYPE "window_type" -#define COMPUTER_DIR "computer_dir" -#define WALLFRAME_TYPE "wallframe_type" -#define FURNISH_TYPE "furnish_type" -#define AIRLOCK_TYPE "airlock_type" - -///flags to be sent to UI -#define TITLE "title" -#define ICON "icon" - -///flags for creating icons shared by an entire category -#define CATEGORY_ICON_STATE "category_icon_state" -#define CATEGORY_ICON_SUFFIX "category_icon_suffix" -#define TITLE_ICON "ICON=TITLE" - -///multiplier applied on construction & deconstruction time when building multiple structures +/// Multiplier applied on construction & deconstruction time when building multiple structures #define FREQUENT_USE_DEBUFF_MULTIPLIER 3 +/// Delay before another rcd scan can be performed in the UI +#define RCD_DESTRUCTIVE_SCAN_COOLDOWN (RCD_HOLOGRAM_FADE_TIME + 1 SECONDS) + //RAPID CONSTRUCTION DEVICE /obj/item/construction/rcd @@ -38,124 +20,23 @@ has_ammobar = TRUE actions_types = list(/datum/action/item_action/rcd_scan) - ///all stuff used by RCD for construction - var/static/list/root_categories = list( - //1ST ROOT CATEGORY - "Construction" = list( //Stuff you use to make & decorate areas - //Walls & Windows - "Structures" = list( - list(CONSTRUCTION_MODE = RCD_FLOORWALL, ICON = "wallfloor", TITLE = "Wall/Floor"), - list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window, ICON = "windowsize", TITLE = "Directional Window"), - list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/reinforced, ICON = "windowtype", TITLE = "Directional Reinforced Window"), - list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/fulltile, ICON = "window0", TITLE = "Full Tile Window"), - list(CONSTRUCTION_MODE = RCD_WINDOWGRILLE, WINDOW_TYPE = /obj/structure/window/reinforced/fulltile, ICON = "rwindow0", TITLE = "Full Tile Reinforced Window"), - list(CONSTRUCTION_MODE = RCD_CATWALK, ICON = "catwalk-0", TITLE = "Catwalk"), - list(CONSTRUCTION_MODE = RCD_REFLECTOR, ICON = "reflector_base", TITLE = "Reflector"), - list(CONSTRUCTION_MODE = RCD_GIRDER, ICON = "girder", TITLE = "Girder"), - ), - - //Computers & Machine Frames - "Machines" = list( - list(CONSTRUCTION_MODE = RCD_MACHINE, ICON = "box_1", TITLE = "Machine Frame"), - list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = NORTH, ICON = "cnorth", TITLE = "Computer North"), - list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = SOUTH, ICON = "csouth", TITLE = "Computer South"), - list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = EAST, ICON = "ceast", TITLE = "Computer East"), - list(CONSTRUCTION_MODE = RCD_COMPUTER, COMPUTER_DIR = WEST, ICON = "cwest", TITLE = "Computer West"), - list(CONSTRUCTION_MODE = RCD_FLOODLIGHT, ICON = "floodlight_c1", TITLE = "FloodLight Frame"), - list(CONSTRUCTION_MODE = RCD_WALLFRAME, WALLFRAME_TYPE = /obj/item/wallframe/apc, ICON = "apc", TITLE = "APC WallFrame"), - list(CONSTRUCTION_MODE = RCD_WALLFRAME, WALLFRAME_TYPE = /obj/item/wallframe/airalarm, ICON = "alarm_bitem", TITLE = "AirAlarm WallFrame"), - list(CONSTRUCTION_MODE = RCD_WALLFRAME, WALLFRAME_TYPE = /obj/item/wallframe/firealarm, ICON = "fire_bitem", TITLE = "FireAlarm WallFrame"), - ), - - //Interior Design[construction_mode = RCD_FURNISHING is implied] - "Furniture" = list( - list(FURNISH_TYPE = /obj/structure/chair, ICON = "chair", TITLE = "Chair"), - list(FURNISH_TYPE = /obj/structure/chair/stool, ICON = "stool", TITLE = "Stool"), - list(FURNISH_TYPE = /obj/structure/chair/stool/bar, ICON = "bar", TITLE = "Bar Stool"), - list(FURNISH_TYPE = /obj/structure/table, ICON = "table",TITLE = "Table"), - list(FURNISH_TYPE = /obj/structure/table/glass, ICON = "glass_table", TITLE = "Glass Table"), - list(FURNISH_TYPE = /obj/structure/rack, ICON = "rack", TITLE = "Rack"), - list(FURNISH_TYPE = /obj/structure/bed, ICON = "bed", TITLE = "Bed"), - list(FURNISH_TYPE = /obj/machinery/microwave/engineering, ICON = "engi_mw_complete", TITLE = "Wireless Microwave"), - ), - ), - - //2ND ROOT CATEGORY[construction_mode = RCD_AIRLOCK is implied,"icon=closed"] - "Airlocks" = list( //used to seal/close areas - //Window Doors[airlock_glass = TRUE is implied] - "Windoors" = list( - list(AIRLOCK_TYPE = /obj/machinery/door/window, ICON = "windoor", TITLE = "Windoor"), - list(AIRLOCK_TYPE = /obj/machinery/door/window/brigdoor, ICON = "secure_windoor", TITLE = "Secure Windoor"), - ), - - //Glass Airlocks[airlock_glass = TRUE is implied,do fill_closed overlay] - "Glass Airlocks" = list( - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/glass, TITLE = "Standard", CATEGORY_ICON_STATE = TITLE_ICON, CATEGORY_ICON_SUFFIX = "Glass"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/public/glass, TITLE = "Public"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/engineering/glass, TITLE = "Engineering"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/atmos/glass, TITLE = "Atmospherics"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/security/glass, TITLE = "Security"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/command/glass, TITLE = "Command"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/medical/glass, TITLE = "Medical"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/research/glass, TITLE = "Research"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/virology/glass, TITLE = "Virology"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/mining/glass, TITLE = "Mining"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/glass, TITLE = "Maintenance"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/external/glass, TITLE = "External"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/external/glass, TITLE = "External Maintenance"), - ), - - //Solid Airlocks[airlock_glass = FALSE is implied,no fill_closed overlay] - "Solid Airlocks" = list( - list(AIRLOCK_TYPE = /obj/machinery/door/airlock, TITLE = "Standard", CATEGORY_ICON_STATE = TITLE_ICON), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/public, TITLE = "Public"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/engineering, TITLE = "Engineering"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/atmos, TITLE = "Atmospherics"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/security, TITLE = "Security"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/command, TITLE = "Command"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/medical, TITLE = "Medical"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/research, TITLE = "Research"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/freezer, TITLE = "Freezer"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/virology, TITLE = "Virology"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/mining, TITLE = "Mining"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance, TITLE = "Maintenance"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/external, TITLE = "External"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance/external, TITLE = "External Maintenance"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/hatch, TITLE = "Airtight Hatch"), - list(AIRLOCK_TYPE = /obj/machinery/door/airlock/maintenance_hatch, TITLE = "Maintenance Hatch"), - ), - ), - - //3RD CATEGORY Airlock access,empty list cause airlock_electronics UI will be displayed when this tab is selected - "Airlock Access" = list() - ) - - /// name of currently selected design - var/design_title = "Wall/Floor" - /// category of currently selected design - var/design_category = "Structures" /// main category of currently selected design[Structures, Airlocks, Airlock Access] - var/root_category = "Construction" + var/root_category + /// category of currently selected design + var/design_category + /// name of currently selected design + var/design_title + /// type of structure being built, used to decide what variables are used to build what structure + var/mode + /// temporary holder of mode, used to restore mode original value after rcd deconstruction act + var/construction_mode + /// The path of the structure the rcd is currently creating + var/atom/movable/rcd_design_path + /// owner of this rcd. It can either be an construction console or an player var/owner - /// type of structure being built, used to decide what variables are used to build what structure - var/mode = RCD_FLOORWALL - /// temporary holder of mode, used to restore mode original value after rcd deconstruction act - var/construction_mode = RCD_FLOORWALL /// used by arcd, can this rcd work from a range var/ranged = FALSE - /// direction which computer frames are constructed in - var/computer_dir = NORTH - /// type of airlock/windoor being built[mode = RCD_AIRLOCK] - var/airlock_type = /obj/machinery/door/airlock - /// are we building glass/solid airlocks - var/airlock_glass = FALSE - /// are we building normal/reinforced directional/fulltile windows - var/obj/structure/window/window_type = /obj/structure/window/fulltile - /// type of wallmount airalarm,firealarm,apc we are trying to build - var/obj/item/wallframe/wallframe_type = /obj/item/wallframe/apc - /// type of furniture tables,chairs etc we are trying to build - var/furnish_type = /obj/structure/chair /// delay multiplier for all construction types var/delay_mod = 1 /// variable for R walls to deconstruct them @@ -168,19 +49,35 @@ ///number of active rcd effects in use e.g. when building multiple walls at once this value increases var/current_active_effects = 0 -GLOBAL_VAR_INIT(icon_holographic_wall, init_holographic_wall()) -GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) +/obj/effect/rcd_hologram + name = "hologram" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/proc/init_holographic_wall() - return icon('icons/turf/walls/wall.dmi', "wall-0") +/obj/effect/rcd_hologram/Initialize(mapload) + . = ..() + QDEL_IN(src, RCD_HOLOGRAM_FADE_TIME) -/proc/init_holographic_window() - var/icon/grille_icon = icon('icons/obj/structures.dmi', "grille") - var/icon/window_icon = icon('icons/obj/smooth_structures/window.dmi', "window-0") +/obj/item/construction/rcd/Initialize(mapload) + . = ..() + airlock_electronics = new(src) + airlock_electronics.name = "Access Control" + airlock_electronics.holder = src - grille_icon.Blend(window_icon, ICON_OVERLAY) + root_category = GLOB.rcd_designs[1] + design_category = GLOB.rcd_designs[root_category][1] + var/list/design = GLOB.rcd_designs[root_category][design_category][1] - return grille_icon + rcd_design_path = design["[RCD_DESIGN_PATH]"] + design_title = initial(rcd_design_path.name) + mode = design["[RCD_DESIGN_MODE]"] + construction_mode = mode + + GLOB.rcd_list += src + +/obj/item/construction/rcd/Destroy() + QDEL_NULL(airlock_electronics) + GLOB.rcd_list -= src + . = ..() /obj/item/construction/rcd/ui_action_click(mob/user, actiontype) if (!COOLDOWN_FINISHED(src, destructive_scan_cooldown)) @@ -190,57 +87,6 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) COOLDOWN_START(src, destructive_scan_cooldown, RCD_DESTRUCTIVE_SCAN_COOLDOWN) rcd_scan(src) -/** - * Global proc that generates RCD hologram in a range. - * - * Arguments: - * * source - The atom the scans originate from - * * scan_range - The range of turfs we grab from the source - * * fade_time - The time for RCD holograms to fade - */ -/proc/rcd_scan(atom/source, scan_range = RCD_DESTRUCTIVE_SCAN_RANGE, fade_time = RCD_HOLOGRAM_FADE_TIME) - playsound(source, 'sound/items/rcdscan.ogg', 50, vary = TRUE, pressure_affected = FALSE) - - var/turf/source_turf = get_turf(source) - for(var/turf/open/surrounding_turf in RANGE_TURFS(scan_range, source_turf)) - var/rcd_memory = surrounding_turf.rcd_memory - if(!rcd_memory) - continue - - var/skip_to_next_turf = FALSE - - for(var/atom/content_of_turf as anything in surrounding_turf.contents) - if (content_of_turf.density) - skip_to_next_turf = TRUE - break - - if(skip_to_next_turf) - continue - - var/hologram_icon - switch(rcd_memory) - if(RCD_MEMORY_WALL) - hologram_icon = GLOB.icon_holographic_wall - if(RCD_MEMORY_WINDOWGRILLE) - hologram_icon = GLOB.icon_holographic_window - - var/obj/effect/rcd_hologram/hologram = new(surrounding_turf) - hologram.icon = hologram_icon - hologram.makeHologram() - animate(hologram, alpha = 0, time = fade_time, easing = CIRCULAR_EASING | EASE_IN) - -/obj/effect/rcd_hologram - name = "hologram" - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/effect/rcd_hologram/Initialize(mapload) - . = ..() - QDEL_IN(src, RCD_HOLOGRAM_FADE_TIME) - -#undef RCD_DESTRUCTIVE_SCAN_COOLDOWN -#undef RCD_DESTRUCTIVE_SCAN_RANGE -#undef RCD_HOLOGRAM_FADE_TIME - /obj/item/construction/rcd/suicide_act(mob/living/user) var/turf/T = get_turf(user) @@ -248,15 +94,15 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS - mode = RCD_FLOORWALL + mode = RCD_TURF user.visible_message(span_suicide("[user] sets the RCD to 'Wall' and points it down [user.p_their()] throat! It looks like [user.p_theyre()] trying to commit suicide!")) if(checkResource(16, user)) // It takes 16 resources to construct a wall - var/success = T.rcd_act(user, src, RCD_FLOORWALL) + var/success = T.rcd_act(user, src, list("[RCD_DESIGN_MODE]" = RCD_TURF, "[RCD_DESIGN_PATH]" = /turf/open/floor/plating/rcd)) T = get_turf(user) // If the RCD placed a floor instead of a wall, having a wall without plating under it is cursed // There isn't an easy programmatical way to check if rcd_act will place a floor or a wall, so just repeat using it for free if(success && isopenturf(T)) - T.rcd_act(user, src, RCD_FLOORWALL) + T.rcd_act(user, src, list("[RCD_DESIGN_MODE]" = RCD_TURF, "[RCD_DESIGN_PATH]" = /turf/open/floor/plating/rcd)) useResource(16, user) activate() playsound(loc, 'sound/machines/click.ogg', 50, 1) @@ -275,15 +121,18 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) * * [mob][user]- the user */ /obj/item/construction/rcd/proc/can_place(atom/target, list/rcd_results, mob/user) + var/rcd_mode = rcd_results["[RCD_DESIGN_MODE]"] + var/atom/movable/rcd_structure = rcd_results["[RCD_DESIGN_PATH]"] /** *For anything that does not go an a wall we have to make sure that turf is clear for us to put the structure on it *If we are just trying to destory something then this check is not nessassary - *RCD_WALLFRAME is also returned as the mode when upgrading apc, airalarm, firealarm using simple circuits upgrade + *RCD_WALLFRAME is also returned as the rcd_mode when upgrading apc, airalarm, firealarm using simple circuits upgrade */ - if(rcd_results["mode"] != RCD_WALLFRAME && rcd_results["mode"] != RCD_DECONSTRUCT) + if(rcd_mode != RCD_WALLFRAME && rcd_mode != RCD_DECONSTRUCT) var/turf/target_turf = get_turf(target) //if we are trying to build a window we check for specific edge cases - if(rcd_results["mode"] == RCD_WINDOWGRILLE) + if(rcd_mode == RCD_WINDOWGRILLE) + var/obj/structure/window/window_type = rcd_structure var/is_full_tile = initial(window_type.fulltile) var/list/structures_to_ignore @@ -305,7 +154,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) * if we are trying to create plating on turf which is not a proper floor then dont check for objects on top of the turf just allow that turf to be converted into plating. e.g. create plating beneath a player or underneath a machine frame/any dense object * if we are trying to finish a wall girder then let it finish then make sure no one/nothing is stuck in the girder */ - else if(rcd_results["mode"] == RCD_FLOORWALL && (!istype(target_turf, /turf/open/floor) || istype(target, /obj/structure/girder))) + else if(rcd_mode == RCD_TURF && rcd_structure == /turf/open/floor/plating/rcd && (!istype(target_turf, /turf/open/floor) || istype(target, /obj/structure/girder))) //if a player builds a wallgirder on top of himself manually with iron sheets he can't finish the wall if he is still on the girder. Exclude the girder itself when checking for other dense objects on the turf if(istype(target, /obj/structure/girder) && target_turf.is_blocked_turf(exclude_mobs = FALSE, source_atom = null, ignore_atoms = list(target))) playsound(loc, 'sound/machines/click.ogg', 50, TRUE) @@ -316,27 +165,29 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) else //structures which are small enough to fit on turfs containing directional windows. var/static/list/small_structures = list( - RCD_AIRLOCK, - RCD_COMPUTER, - RCD_FLOODLIGHT, - RCD_FURNISHING, - RCD_MACHINE, - RCD_REFLECTOR, - RCD_WINDOWGRILLE, + /obj/machinery/door, + /obj/structure/frame/computer/rcd, + /obj/structure/floodlight_frame/completed, + /obj/structure/chair, + /obj/structure/table, + /obj/structure/rack, + /obj/structure/bed, + /obj/structure/frame/machine/secured, + /obj/structure/reflector, ) //edge cases for what we can/can't ignore var/ignore_mobs = FALSE var/list/ignored_types - if(rcd_results["mode"] in small_structures) + if(rcd_mode == RCD_WINDOWGRILLE || is_path_in_list(rcd_structure, small_structures)) ignored_types = list(/obj/structure/window) //if we are trying to create grills/windoors we can go ahead and further ignore other windoors on the turf - if(rcd_results["mode"] == RCD_WINDOWGRILLE || (rcd_results["mode"] == RCD_AIRLOCK && ispath(airlock_type, /obj/machinery/door/window))) + if(rcd_mode == RCD_WINDOWGRILLE || (rcd_mode == RCD_AIRLOCK && ispath(rcd_structure, /obj/machinery/door/window))) //only ignore mobs if we are trying to create windoors and not grills. We dont want to drop a grill on top of somebody - ignore_mobs = rcd_results["mode"] == RCD_AIRLOCK + ignore_mobs = rcd_mode == RCD_AIRLOCK ignored_types += /obj/machinery/door/window //if we are trying to create full airlock doors then we do the regular checks and make sure we have the full space for them. i.e. dont ignore anything dense on the turf - else if(rcd_results["mode"] == RCD_AIRLOCK) + else if(rcd_mode == RCD_AIRLOCK) ignored_types = list() //check if the structure can fit on this turf @@ -359,6 +210,8 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) var/list/rcd_results = target.rcd_vals(user, src) if(!rcd_results) return FALSE + rcd_results["[RCD_DESIGN_MODE]"] = mode + rcd_results["[RCD_DESIGN_PATH]"] = rcd_design_path var/delay = rcd_results["delay"] * delay_mod if ( @@ -382,7 +235,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) * * rcd_results- list of params which contains the cost & build mode to create the structure */ /obj/item/construction/rcd/proc/_rcd_create_effect(atom/target, mob/user, delay, list/rcd_results) - var/obj/effect/constructing_effect/rcd_effect = new(get_turf(target), delay, src.mode, upgrade) + var/obj/effect/constructing_effect/rcd_effect = new(get_turf(target), delay, rcd_results["[RCD_DESIGN_MODE]"], upgrade) //resource & structure placement sanity checks before & after delay along with beam effects if(!checkResource(rcd_results["cost"], user) || !can_place(target, rcd_results, user)) @@ -390,7 +243,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) return FALSE var/beam if(ranged) - beam = user.Beam(target,icon_state="rped_upgrade", time = delay) + beam = user.Beam(target, icon_state = "rped_upgrade", time = delay) if(!do_after(user, delay, target = target)) qdel(rcd_effect) if(!isnull(beam)) @@ -406,25 +259,13 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) qdel(rcd_effect) return FALSE activate() - if(!target.rcd_act(user, src, rcd_results["mode"])) + if(!target.rcd_act(user, src, rcd_results)) qdel(rcd_effect) return FALSE playsound(loc, 'sound/machines/click.ogg', 50, TRUE) rcd_effect.end_animation() return TRUE -/obj/item/construction/rcd/Initialize(mapload) - . = ..() - airlock_electronics = new(src) - airlock_electronics.name = "Access Control" - airlock_electronics.holder = src - GLOB.rcd_list += src - -/obj/item/construction/rcd/Destroy() - QDEL_NULL(airlock_electronics) - GLOB.rcd_list -= src - . = ..() - /obj/item/construction/rcd/ui_assets(mob/user) return list( get_asset_datum(/datum/asset/spritesheet/rcd), @@ -440,27 +281,20 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) ui.open() /obj/item/construction/rcd/ui_static_data(mob/user) - return airlock_electronics.ui_static_data(user) - -/obj/item/construction/rcd/ui_data(mob/user) var/list/data = ..() - //main categories - data["selected_root"] = root_category + var/list/electronics_data = airlock_electronics.ui_static_data(user) + for(var/key in electronics_data) + data[key] = electronics_data[key] + data["root_categories"] = list() - for(var/category in root_categories) + for(var/category in GLOB.rcd_designs) data["root_categories"] += category - //create the category list - data["selected_category"] = design_category - data["selected_design"] = design_title data["categories"] = list() - - var/category_icon_state - var/category_icon_suffix - for(var/sub_category as anything in root_categories[root_category]) - var/list/target_category = root_categories[root_category][sub_category] - if(target_category.len == 0) + for(var/sub_category as anything in GLOB.rcd_designs[root_category]) + var/list/target_category = GLOB.rcd_designs[root_category][sub_category] + if(!length(target_category)) continue //skip category if upgrades were not installed for these @@ -468,35 +302,26 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) continue if(sub_category == "Furniture" && !(upgrade & RCD_UPGRADE_FURNISHING)) continue - category_icon_state = "" - category_icon_suffix = "" var/list/designs = list() //initialize all designs under this category - for(var/i in 1 to target_category.len) - var/list/design = target_category[i] + for(var/list/design as anything in target_category) + var/atom/movable/design_path = design[RCD_DESIGN_PATH] - //check for special icon flags - if(design[CATEGORY_ICON_STATE] != null) - category_icon_state = design[CATEGORY_ICON_STATE] - if(design[CATEGORY_ICON_SUFFIX] != null) - category_icon_suffix = design[CATEGORY_ICON_SUFFIX] + var/design_name = initial(design_path.name) - //get icon or create it from pre defined flags - var/icon_state - if(design[ICON] != null) - icon_state = design[ICON] - else - icon_state = category_icon_state - if(icon_state == TITLE_ICON) - icon_state = design[TITLE] - icon_state = "[icon_state][category_icon_suffix]" - - //sanitize them so you dont go insane when icon names contain spaces in them - icon_state = sanitize_css_class_name(icon_state) - - designs += list(list(TITLE = design[TITLE], ICON = icon_state)) + designs += list(list("title" = design_name, "icon" = sanitize_css_class_name(design_name))) data["categories"] += list(list("cat_name" = sub_category, "designs" = designs)) + return data + +/obj/item/construction/rcd/ui_data(mob/user) + var/list/data = ..() + + //main categories + data["selected_root"] = root_category + data["selected_category"] = design_category + data["selected_design"] = design_title + //merge airlock_electronics ui data with this var/list/airlock_data = airlock_electronics.ui_data(user) for(var/key in airlock_data) @@ -504,22 +329,19 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) return data -/obj/item/construction/rcd/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) - return +/obj/item/construction/rcd/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state) switch(action) if("root_category") var/new_root = params["root_category"] - if(root_categories[new_root] != null) //is a valid category + if(GLOB.rcd_designs[new_root] != null) //is a valid category root_category = new_root if("design") + //read and validate params from UI var/category_name = params["category"] var/index = params["index"] - - var/list/root = root_categories[root_category] + var/list/root = GLOB.rcd_designs[root_category] if(root == null) //not a valid root return TRUE var/list/category = root[category_name] @@ -537,31 +359,15 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) if(category == "Furniture" && !(upgrade & RCD_UPGRADE_FURNISHING)) return TRUE + //use UI params to set variables var/list/design = category[index] if(design == null) //not a valid design return TRUE - design_category = category_name - design_title = design["title"] - - if(category_name == "Structures") - construction_mode = design[CONSTRUCTION_MODE] - if(design[WINDOW_TYPE] != null) - window_type = design[WINDOW_TYPE] - else if(category_name == "Machines") - construction_mode = design[CONSTRUCTION_MODE] - if(design[COMPUTER_DIR] != null) - computer_dir = design[COMPUTER_DIR] - if(design[WALLFRAME_TYPE] != null) - wallframe_type = design[WALLFRAME_TYPE] - else if(category_name == "Furniture") - construction_mode = RCD_FURNISHING - furnish_type = design[FURNISH_TYPE] - - if(root_category == "Airlocks") - construction_mode = RCD_AIRLOCK - airlock_glass = (category_name != "Solid Airlocks") - airlock_type = design[AIRLOCK_TYPE] + mode = design["[RCD_DESIGN_MODE]"] + construction_mode = mode + rcd_design_path = design["[RCD_DESIGN_PATH]"] + design_title = initial(rcd_design_path.name) else airlock_electronics.do_action(action, params) @@ -659,16 +465,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) matter = 160 /obj/item/construction/rcd/loaded/upgraded - upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN - -/obj/item/construction/rcd/combat - name = "industrial RCD" - icon_state = "ircd" - inhand_icon_state = "ircd" - max_matter = 500 - matter = 500 - canRturf = TRUE - upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN + upgrade = RCD_ALL_UPGRADES /obj/item/construction/rcd/ce name = "professional RCD" @@ -683,21 +480,37 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) 0.0, 0.0, 0.0, 0.0, ) +/obj/item/construction/rcd/combat + name = "industrial RCD" + icon_state = "ircd" + inhand_icon_state = "ircd" + max_matter = 500 + matter = 500 + canRturf = TRUE + upgrade = RCD_ALL_UPGRADES + +/obj/item/construction/rcd/combat/admin + name = "admin RCD" + max_matter = INFINITY + matter = INFINITY + upgrade = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK + +// Ranged RCD +/obj/item/construction/rcd/arcd + name = "advanced rapid-construction-device (ARCD)" + desc = "A prototype RCD with ranged capability and infinite capacity." + max_matter = INFINITY + matter = INFINITY + canRturf = TRUE + delay_mod = 0.6 + ranged = TRUE + icon_state = "arcd" + inhand_icon_state = "oldrcd" + has_ammobar = FALSE + upgrade = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK + #undef FREQUENT_USE_DEBUFF_MULTIPLIER - -#undef CONSTRUCTION_MODE -#undef WINDOW_TYPE -#undef COMPUTER_DIR -#undef WALLFRAME_TYPE -#undef FURNISH_TYPE -#undef AIRLOCK_TYPE - -#undef TITLE -#undef ICON - -#undef CATEGORY_ICON_STATE -#undef CATEGORY_ICON_SUFFIX -#undef TITLE_ICON +#undef RCD_DESTRUCTIVE_SCAN_COOLDOWN /obj/item/rcd_ammo name = "RCD matter cartridge" @@ -713,23 +526,3 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) /obj/item/rcd_ammo/large custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*24, /datum/material/glass=SHEET_MATERIAL_AMOUNT*16) ammoamt = 160 - -/obj/item/construction/rcd/combat/admin - name = "admin RCD" - max_matter = INFINITY - matter = INFINITY - upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN - - -// Ranged RCD -/obj/item/construction/rcd/arcd - name = "advanced rapid-construction-device (ARCD)" - desc = "A prototype RCD with ranged capability and infinite capacity." - max_matter = INFINITY - matter = INFINITY - delay_mod = 0.6 - ranged = TRUE - icon_state = "arcd" - inhand_icon_state = "oldrcd" - has_ammobar = FALSE - upgrade = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN diff --git a/code/game/objects/items/rcd/RHD.dm b/code/game/objects/items/rcd/RHD.dm index 92a6ab77641..d9c4c7cd9b7 100644 --- a/code/game/objects/items/rcd/RHD.dm +++ b/code/game/objects/items/rcd/RHD.dm @@ -104,6 +104,7 @@ silo_mats = AddComponent(/datum/component/remote_materials, FALSE, FALSE) playsound(loc, 'sound/machines/click.ogg', 50, TRUE) qdel(design_disk) + update_static_data_for_all_viewers() /// Inserts matter into the RCD allowing it to build /obj/item/construction/proc/insert_matter(obj/item, mob/user) @@ -184,6 +185,11 @@ silo_mats.use_materials(list(/datum/material/iron = SILO_USE_AMOUNT), multiplier = amount, action = "build", name = "consume") return TRUE +/obj/item/construction/ui_static_data(mob/user) + . = list() + + .["silo_upgraded"] = !!(upgrade & RCD_UPGRADE_SILO_LINK) + ///shared data for rcd,rld & plumbing /obj/item/construction/ui_data(mob/user) var/list/data = list() @@ -194,8 +200,6 @@ total_matter = 0 data["matterLeft"] = total_matter - //silo details - data["silo_upgraded"] = !!(upgrade & RCD_UPGRADE_SILO_LINK) data["silo_enabled"] = silo_link return data @@ -223,6 +227,15 @@ toggle_silo(ui.user) return TRUE + var/update = handle_ui_act(action, params, ui, state) + if(isnull(update)) + update = FALSE + return update + +/// overwrite to insert custom ui handling for subtypes +/obj/item/construction/proc/handle_ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + return null + /obj/item/construction/proc/checkResource(amount, mob/user) if(!silo_mats || !silo_mats.mat_container || !silo_link) if(silo_link) diff --git a/code/game/objects/items/rcd/RLD.dm b/code/game/objects/items/rcd/RLD.dm index c5853d2997a..dea42000584 100644 --- a/code/game/objects/items/rcd/RLD.dm +++ b/code/game/objects/items/rcd/RLD.dm @@ -1,8 +1,19 @@ // RAPID LIGHTING DEVICE -#define GLOW_MODE 3 +// modes of operation +#define GLOW_MODE 1 #define LIGHT_MODE 2 -#define REMOVE_MODE 1 +#define REMOVE_MODE 3 + +// operation costs +#define LIGHT_TUBE_COST 10 +#define FLOOR_LIGHT_COST 15 +#define GLOW_STICK_COST 5 +#define DECONSTRUCT_COST 10 + +//operation delays +#define BUILD_DELAY 10 +#define REMOVE_DELAY 15 /obj/item/construction/rld name = "Rapid Lighting Device" @@ -17,20 +28,13 @@ slot_flags = ITEM_SLOT_BELT has_ammobar = TRUE ammo_sections = 6 - ///it does not make sense why any of these should be installed - banned_upgrades = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN + banned_upgrades = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK + /// mode of operation see above defines var/mode = LIGHT_MODE - var/wallcost = 10 - var/floorcost = 15 - var/launchcost = 5 - var/deconcost = 10 - - var/condelay = 10 - var/decondelay = 15 ///reference to thr original icons - var/list/original_options = list( + var/static/list/original_options = list( "Color Pick" = icon(icon = 'icons/hud/radial.dmi', icon_state = "omni"), "Glow Stick" = icon(icon = 'icons/obj/lighting.dmi', icon_state = "glowstick"), "Deconstruct" = icon(icon = 'icons/obj/tools.dmi', icon_state = "wrench"), @@ -49,7 +53,7 @@ . = ..() if((upgrade & RCD_UPGRADE_SILO_LINK) && display_options["Silo Link"] == null) //silo upgrade instaled but option was not updated then update it just one - display_options["Silo Link"] = icon(icon = 'icons/obj/mining.dmi', icon_state = "silo") + display_options["Silo Link"] = icon(icon = 'icons/obj/machines/ore_silo.dmi', icon_state = "silo") var/choice = show_radial_menu(user, src, display_options, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) if(!check_menu(user)) @@ -95,17 +99,17 @@ return FALSE //resource sanity checks before & after delay - if(!checkResource(deconcost, user)) + if(!checkResource(DECONSTRUCT_COST, user)) return FALSE var/beam = user.Beam(A,icon_state="light_beam", time = 15) playsound(loc, 'sound/machines/click.ogg', 50, TRUE) - if(!do_after(user, decondelay, target = A)) + if(!do_after(user, REMOVE_DELAY, target = A)) qdel(beam) return FALSE - if(!checkResource(deconcost, user)) + if(!checkResource(DECONSTRUCT_COST, user)) return FALSE - if(!useResource(deconcost, user)) + if(!useResource(DECONSTRUCT_COST, user)) return FALSE activate() qdel(A) @@ -113,15 +117,17 @@ if(LIGHT_MODE) //resource sanity checks before & after delay - if(!checkResource(floorcost, user)) + var/cost = iswallturf(A) ? LIGHT_TUBE_COST : FLOOR_LIGHT_COST + + if(!checkResource(cost, user)) return FALSE - var/beam = user.Beam(A,icon_state="light_beam", time = condelay) + var/beam = user.Beam(A,icon_state="light_beam", time = BUILD_DELAY) playsound(loc, 'sound/machines/click.ogg', 50, TRUE) playsound(loc, 'sound/effects/light_flicker.ogg', 50, FALSE) - if(!do_after(user, condelay, target = A)) + if(!do_after(user, BUILD_DELAY, target = A)) qdel(beam) return FALSE - if(!checkResource(floorcost, user)) + if(!checkResource(cost, user)) return FALSE if(iswallturf(A)) @@ -155,7 +161,7 @@ balloon_alert(user, "no valid target!") return FALSE - if(!useResource(wallcost, user)) + if(!useResource(cost, user)) return FALSE activate() var/obj/machinery/light/L = new /obj/machinery/light(get_turf(winner)) @@ -170,7 +176,7 @@ if(istype(dupe)) return FALSE - if(!useResource(floorcost, user)) + if(!useResource(cost, user)) return FALSE activate() var/obj/machinery/light/floor/FL = new /obj/machinery/light/floor(target) @@ -179,7 +185,7 @@ return TRUE if(GLOW_MODE) - if(!useResource(launchcost, user)) + if(!useResource(GLOW_STICK_COST, user)) return FALSE activate() var/obj/item/flashlight/glowstick/G = new /obj/item/flashlight/glowstick(start) @@ -201,6 +207,14 @@ matter = 100 max_matter = 100 +#undef LIGHT_TUBE_COST +#undef FLOOR_LIGHT_COST +#undef GLOW_STICK_COST +#undef DECONSTRUCT_COST + +#undef BUILD_DELAY +#undef REMOVE_DELAY + #undef GLOW_MODE #undef LIGHT_MODE #undef REMOVE_MODE diff --git a/code/game/objects/items/rcd/RPLD.dm b/code/game/objects/items/rcd/RPLD.dm index d3f763bb21a..7f03fad1a9c 100644 --- a/code/game/objects/items/rcd/RPLD.dm +++ b/code/game/objects/items/rcd/RPLD.dm @@ -9,15 +9,16 @@ worn_icon_state = "plumbing" icon = 'icons/obj/tools.dmi' slot_flags = ITEM_SLOT_BELT - ///it does not make sense why any of these should be installed. - banned_upgrades = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN + banned_upgrades = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK matter = 200 max_matter = 200 + ///category of design selected + var/selected_category ///type of the plumbing machine var/obj/machinery/blueprint = null ///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/plumbing_design_types + var/list/plumbing_design_types = null ///Current selected layer var/current_layer = "Default Layer" ///Current selected color, for ducts @@ -68,14 +69,15 @@ /obj/item/construction/plumbing/Initialize(mapload) . = ..() - plumbing_design_types = general_design_types + if(isnull(plumbing_design_types)) + plumbing_design_types = general_design_types + selected_category = plumbing_design_types[1] /** - * plumbing_design_types[1] = "Synthesizers" * plumbing_design_types["Synthesizers"] = * [1] = */ - blueprint = plumbing_design_types[plumbing_design_types[1]][1] + blueprint = plumbing_design_types[selected_category][1] /obj/item/construction/plumbing/equipped(mob/user, slot, initial) . = ..() @@ -104,7 +106,7 @@ /obj/item/construction/plumbing/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) - ui = new(user, src, "PlumbingService", name) + ui = new(user, src, "RapidPlumbingDevice", name) ui.open() /obj/item/construction/plumbing/ui_assets(mob/user) @@ -113,15 +115,9 @@ ) /obj/item/construction/plumbing/ui_static_data(mob/user) - return list("paint_colors" = GLOB.pipe_paint_colors) - -/obj/item/construction/plumbing/ui_data(mob/user) var/list/data = ..() - data["piping_layer"] = name_to_number[current_layer] //maps layer name to layer number's 1,2,3,4,5 - data["selected_color"] = current_color - data["layer_icon"] = "plumbing_layer[GLOB.plumbing_layers[current_layer]]" - data["selected_recipe"] = initial(blueprint.name) + data["paint_colors"] = GLOB.pipe_paint_colors var/category_list = list() for(var/category_name in plumbing_design_types) @@ -140,21 +136,24 @@ "name" = initial(recipe.name), )) - //Set selected category - if(blueprint == recipe) - data["selected_category"] = category_name - data["categories"] = list() for(var/category_name in category_list) data["categories"] += list(category_list[category_name]) return data -/obj/item/construction/plumbing/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) - . = ..() - if(.) - return +/obj/item/construction/plumbing/ui_data(mob/user) + var/list/data = ..() + data["piping_layer"] = name_to_number[current_layer] //maps layer name to layer number's 1,2,3,4,5 + data["selected_color"] = current_color + data["layer_icon"] = "plumbing_layer[GLOB.plumbing_layers[current_layer]]" + data["selected_category"] = selected_category + data["selected_recipe"] = initial(blueprint.name) + + return data + +/obj/item/construction/plumbing/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state) switch(action) if("color") var/color = params["paint_color"] @@ -168,10 +167,13 @@ current_layer = layer if("recipe") var/category = params["category"] - if(!plumbing_design_types[category]) - return FALSE - var/design = plumbing_design_types[category][text2num(params["id"]) + 1] + var/list/designs = plumbing_design_types[category] + if(!length(designs)) + return FALSE + selected_category = category + + var/design = designs[text2num(params["id"]) + 1] if(!design) return FALSE blueprint = design @@ -329,10 +331,10 @@ ) /obj/item/construction/plumbing/research/Initialize(mapload) - . = ..() - plumbing_design_types = research_design_types + . = ..() + /obj/item/construction/plumbing/service name = "service plumbing constructor" desc = "A type of plumbing constructor designed to rapidly deploy the machines needed to make a brewery." @@ -370,7 +372,7 @@ ) /obj/item/construction/plumbing/service/Initialize(mapload) - . = ..() - plumbing_design_types = service_design_types + . = ..() + diff --git a/code/game/objects/items/rcd/RTD.dm b/code/game/objects/items/rcd/RTD.dm index baa3b8eb47b..69000054f86 100644 --- a/code/game/objects/items/rcd/RTD.dm +++ b/code/game/objects/items/rcd/RTD.dm @@ -23,7 +23,7 @@ slot_flags = ITEM_SLOT_BELT item_flags = NO_MAT_REDEMPTION | NOBLUDGEON has_ammobar = TRUE - banned_upgrades = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING | RCD_UPGRADE_ANTI_INTERRUPT | RCD_UPGRADE_NO_FREQUENT_USE_COOLDOWN + banned_upgrades = RCD_ALL_UPGRADES & ~RCD_UPGRADE_SILO_LINK /// main category for tile design var/root_category = "Conventional" @@ -165,21 +165,16 @@ . = ..() ui_interact(user) -/obj/item/construction/rtd/ui_data(mob/user) +/obj/item/construction/rtd/ui_static_data(mob/user) var/list/data = ..() - var/floor_designs = GLOB.floor_designs - data["selected_root"] = root_category data["root_categories"] = list() - for(var/category in floor_designs) + for(var/category in GLOB.floor_designs) data["root_categories"] += category - data["selected_category"] = design_category - - selected_design.fill_ui_data(data) data["categories"] = list() - for(var/sub_category as anything in floor_designs[root_category]) - var/list/target_category = floor_designs[root_category][sub_category] + for(var/sub_category as anything in GLOB.floor_designs[root_category]) + var/list/target_category = GLOB.floor_designs[root_category][sub_category] var/list/designs = list() //initialize all designs under this category for(var/list/design as anything in target_category) @@ -190,11 +185,16 @@ return data -/obj/item/construction/rtd/ui_act(action, params) - . = ..() - if(.) - return +/obj/item/construction/rtd/ui_data(mob/user) + var/list/data = ..() + data["selected_root"] = root_category + data["selected_category"] = design_category + selected_design.fill_ui_data(data) + + return data + +/obj/item/construction/rtd/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state) var/floor_designs = GLOB.floor_designs switch(action) if("root_category") @@ -264,7 +264,7 @@ return TRUE var/delay = CONSTRUCTION_TIME(selected_design.cost) - var/obj/effect/constructing_effect/rcd_effect = new(floor, delay, RCD_FLOORWALL) + var/obj/effect/constructing_effect/rcd_effect = new(floor, delay, RCD_TURF) //resource sanity check before & after delay along with special effects if(!checkResource(selected_design.cost, user)) diff --git a/code/game/objects/structures/construction_console/construction_actions.dm b/code/game/objects/structures/construction_console/construction_actions.dm index e190312c167..fc014d14318 100644 --- a/code/game/objects/structures/construction_console/construction_actions.dm +++ b/code/game/objects/structures/construction_console/construction_actions.dm @@ -52,11 +52,11 @@ var/atom/rcd_target = target_turf //Find airlocks and other shite for(var/obj/S in target_turf) - if(LAZYLEN(S.rcd_vals(owner,base_console.internal_rcd))) + if(LAZYLEN(S.rcd_vals(owner, base_console.internal_rcd))) rcd_target = S //If we don't break out of this loop we'll get the last placed thing owner.changeNext_move(CLICK_CD_RANGE) check_rcd() - base_console.internal_rcd.afterattack(rcd_target, owner, TRUE, "") //Activate the RCD and force it to work remotely! + base_console.internal_rcd.rcd_create(rcd_target, owner) //Activate the RCD and force it to work remotely! playsound(target_turf, 'sound/items/deconstruct.ogg', 60, TRUE) /datum/action/innate/construction/configure_mode diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 62638f44eeb..e90567a3318 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -384,13 +384,11 @@ /obj/structure/door_assembly/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if(the_rcd.mode == RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 5 SECONDS, "cost" = 16) + return list("delay" = 5 SECONDS, "cost" = 16) return FALSE -/obj/structure/door_assembly/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_DECONSTRUCT) - to_chat(user, span_notice("You deconstruct [src].")) - qdel(src) - return TRUE +/obj/structure/door_assembly/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT) + qdel(src) + return TRUE return FALSE diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index 33cab1d37ad..0310d903c48 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -444,19 +444,25 @@ /obj/structure/girder/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) - if(RCD_FLOORWALL) + if(RCD_TURF) + if(the_rcd.rcd_design_path != /turf/open/floor/plating/rcd) + return FALSE + return rcd_result_with_memory( - list("mode" = RCD_FLOORWALL, "delay" = 2 SECONDS, "cost" = 8), + list("delay" = 2 SECONDS, "cost" = 8), get_turf(src), RCD_MEMORY_WALL, ) if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 2 SECONDS, "cost" = 13) + return list("delay" = 2 SECONDS, "cost" = 13) return FALSE -/obj/structure/girder/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - var/turf/T = get_turf(src) - switch(passed_mode) - if(RCD_FLOORWALL) +/obj/structure/girder/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) + if(RCD_TURF) + if(the_rcd.rcd_design_path != /turf/open/floor/plating/rcd) + return FALSE + + var/turf/T = get_turf(src) T.PlaceOnTop(/turf/closed/wall) qdel(src) return TRUE diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index c1941e834d0..bfe7f0b4a88 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -60,29 +60,29 @@ /obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 2 SECONDS, "cost" = 5) + return list("delay" = 2 SECONDS, "cost" = 5) if(RCD_WINDOWGRILLE) var/cost = 0 var/delay = 0 - if(the_rcd.window_type == /obj/structure/window/fulltile) + + if(the_rcd.rcd_design_path == /obj/structure/window/fulltile) cost = 8 delay = 3 SECONDS - else if(the_rcd.window_type == /obj/structure/window/reinforced/fulltile) + else if(the_rcd.rcd_design_path == /obj/structure/window/reinforced/fulltile) cost = 12 delay = 4 SECONDS if(!cost) return FALSE return rcd_result_with_memory( - list("mode" = RCD_WINDOWGRILLE, "delay" = delay, "cost" = cost), + list("delay" = delay, "cost" = cost), get_turf(src), RCD_MEMORY_WINDOWGRILLE, ) return FALSE -/obj/structure/grille/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) +/obj/structure/grille/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) if(RCD_DECONSTRUCT) - to_chat(user, span_notice("You deconstruct the grille.")) qdel(src) return TRUE if(RCD_WINDOWGRILLE) @@ -95,12 +95,12 @@ if(!clear_tile(user)) return FALSE - var/obj/structure/window/window_path = the_rcd.window_type + var/obj/structure/window/window_path = rcd_data["[RCD_DESIGN_PATH]"] if(!ispath(window_path)) CRASH("Invalid window path type in RCD: [window_path]") if(!initial(window_path.fulltile)) //only fulltile windows can be built here return FALSE - var/obj/structure/window/WD = new the_rcd.window_type(T, user.dir) + var/obj/structure/window/WD = new window_path(T, user.dir) WD.set_anchored(TRUE) return TRUE return FALSE diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 9b460cc125c..f6d5b933494 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -63,25 +63,24 @@ qdel(src) /obj/structure/lattice/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if(the_rcd.mode == RCD_FLOORWALL) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) - if(the_rcd.mode == RCD_CATWALK) - return list("mode" = RCD_CATWALK, "delay" = 0, "cost" = 2) + if(the_rcd.mode == RCD_TURF) + return list("delay" = 0, "cost" = the_rcd.rcd_design_path == /obj/structure/lattice/catwalk ? 2 : 1) + return FALSE -/obj/structure/lattice/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - if(passed_mode == RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) - var/turf/T = src.loc - if(isgroundlessturf(T)) - T.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) +/obj/structure/lattice/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_TURF) + var/design_structure = rcd_data["[RCD_DESIGN_PATH]"] + if(design_structure == /turf/open/floor/plating) + var/turf/T = src.loc + if(isgroundlessturf(T)) + T.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + qdel(src) + return TRUE + if(design_structure == /obj/structure/lattice/catwalk) + var/turf/turf = loc qdel(src) + new /obj/structure/lattice/catwalk(turf) return TRUE - if(passed_mode == RCD_CATWALK) - to_chat(user, span_notice("You build a catwalk.")) - var/turf/turf = loc - qdel(src) - new /obj/structure/lattice/catwalk(turf) - return TRUE return FALSE /obj/structure/lattice/singularity_pull(S, current_size) diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index 57b5ff1c492..22d40c01412 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -330,3 +330,10 @@ if(!isnull(new_angle)) set_angle(SIMPLIFY_DEGREES(new_angle)) return TRUE + +/obj/structure/reflector/wrenched + +/obj/structure/reflector/wrenched/Initialize(mapload) + . = ..() + + set_anchored(TRUE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index f25239fe418..4da8b734bb4 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -309,17 +309,14 @@ 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" = 2.4 SECONDS, "cost" = 16) + if(the_rcd.mode == RCD_DECONSTRUCT) + return list("delay" = 2.4 SECONDS, "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, span_notice("You deconstruct the table.")) - qdel(src) - return TRUE +/obj/structure/table/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT) + qdel(src) + return TRUE return FALSE /obj/structure/table/proc/table_carbon(datum/source, mob/living/carbon/shover, mob/living/carbon/target, shove_blocked) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 77ac1f11740..71e97bdf32c 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -1,6 +1,6 @@ /obj/structure/window name = "window" - desc = "A window." + desc = "A directional window." icon_state = "window" density = TRUE layer = ABOVE_OBJ_LAYER //Just above doors @@ -91,16 +91,14 @@ . += span_notice("The window is unscrewed from the floor, and could be deconstructed by wrenching.") /obj/structure/window/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 2 SECONDS, "cost" = 5) + if(the_rcd.mode == RCD_DECONSTRUCT) + return list("delay" = 2 SECONDS, "cost" = 5) return FALSE -/obj/structure/window/rcd_act(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_DECONSTRUCT) - qdel(src) - return TRUE +/obj/structure/window/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_DECONSTRUCT) + qdel(src) + return TRUE return FALSE /obj/structure/window/narsie_act() @@ -477,9 +475,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0) acid = 100 /obj/structure/window/reinforced/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 3 SECONDS, "cost" = 15) + if(the_rcd.mode == RCD_DECONSTRUCT) + return list("delay" = 3 SECONDS, "cost" = 15) return FALSE /obj/structure/window/reinforced/attackby_secondary(obj/item/tool, mob/user, params) @@ -655,6 +652,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw /* Full Tile Windows (more atom_integrity) */ /obj/structure/window/fulltile + name = "full tile window" + desc = "A full tile window." icon = 'icons/obj/smooth_structures/window.dmi' icon_state = "window-0" base_icon_state = "window" @@ -668,9 +667,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw glass_amount = 2 /obj/structure/window/fulltile/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 2.5 SECONDS, "cost" = 10) + if(the_rcd.mode == RCD_DECONSTRUCT) + return list("delay" = 2.5 SECONDS, "cost" = 10) return FALSE /obj/structure/window/fulltile/unanchored @@ -711,6 +709,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw state = WINDOW_OUT_OF_FRAME /obj/structure/window/reinforced/fulltile + name = "full tile reinforced window" + desc = "A full tile reinforced window" icon = 'icons/obj/smooth_structures/reinforced_window.dmi' icon_state = "reinforced_window-0" base_icon_state = "reinforced_window" @@ -725,9 +725,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw glass_amount = 2 /obj/structure/window/reinforced/fulltile/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 4 SECONDS, "cost" = 20) + if(the_rcd.mode == RCD_DECONSTRUCT) + return list("mode" = RCD_DECONSTRUCT, "delay" = 4 SECONDS, "cost" = 20) return FALSE /obj/structure/window/reinforced/fulltile/unanchored diff --git a/code/game/turfs/closed/wall/reinf_walls.dm b/code/game/turfs/closed/wall/reinf_walls.dm index e3e088d2c29..8b996c66ff6 100644 --- a/code/game/turfs/closed/wall/reinf_walls.dm +++ b/code/game/turfs/closed/wall/reinf_walls.dm @@ -215,8 +215,8 @@ return ..() -/turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - if(the_rcd.canRturf || passed_mode == RCD_WALLFRAME) +/turf/closed/wall/r_wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(the_rcd.canRturf || rcd_data["[RCD_DESIGN_MODE]"] == RCD_WALLFRAME) return ..() /turf/closed/wall/r_wall/rust_heretic_act() diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 38302feaba5..e47784b98aa 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -315,15 +315,16 @@ /turf/closed/wall/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 4 SECONDS, "cost" = 26) + return list("delay" = 4 SECONDS, "cost" = 26) if(RCD_WALLFRAME) - return list("mode" = RCD_WALLFRAME, "delay" = 1 SECONDS, "cost" = 8) + return list("delay" = 1 SECONDS, "cost" = 8) return FALSE -/turf/closed/wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) +/turf/closed/wall/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) if(RCD_WALLFRAME) - var/obj/item/wallframe/new_wallmount = new the_rcd.wallframe_type(user.drop_location()) + var/obj/item/wallframe/wallmount = rcd_data["[RCD_DESIGN_PATH]"] + var/obj/item/wallframe/new_wallmount = new wallmount(user.drop_location()) return try_wallmount(new_wallmount, user, src) if(RCD_DECONSTRUCT) ScrapeAway() diff --git a/code/game/turfs/open/chasm.dm b/code/game/turfs/open/chasm.dm index 49f6663d097..3af4d12b176 100644 --- a/code/game/turfs/open/chasm.dm +++ b/code/game/turfs/open/chasm.dm @@ -36,17 +36,14 @@ return /turf/open/chasm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_FLOORWALL) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) + if(the_rcd.mode == RCD_TURF && the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) + return list("delay" = 0, "cost" = 3) return FALSE -/turf/open/chasm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - return TRUE +/turf/open/chasm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_TURF && rcd_data["[RCD_DESIGN_PATH]"] == /turf/open/floor/plating/rcd) + PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + return TRUE return FALSE /turf/open/chasm/rust_heretic_act() diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index 228b82862b2..d945fc301e9 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -204,92 +204,103 @@ /// if you are updating this make to to update /turf/open/misc/rcd_vals() too /turf/open/floor/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) - if(RCD_FLOORWALL) + if(RCD_TURF) + if(the_rcd.rcd_design_path != /turf/open/floor/plating/rcd) + return FALSE + var/obj/structure/girder/girder = locate() in src if(girder) return girder.rcd_vals(user, the_rcd) + return rcd_result_with_memory( - list("mode" = RCD_FLOORWALL, "delay" = 2 SECONDS, "cost" = 16), + list("delay" = 2 SECONDS, "cost" = 16), src, RCD_MEMORY_WALL, ) - if(RCD_REFLECTOR) - return list("mode" = RCD_REFLECTOR, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_AIRLOCK) - if(the_rcd.airlock_glass) - return list("mode" = RCD_AIRLOCK, "delay" = 5 SECONDS, "cost" = 20) - else - return list("mode" = RCD_AIRLOCK, "delay" = 5 SECONDS, "cost" = 16) - if(RCD_DECONSTRUCT) - return list("mode" = RCD_DECONSTRUCT, "delay" = 5 SECONDS, "cost" = 33) if(RCD_WINDOWGRILLE) //default cost for building a grill for fulltile windows var/cost = 4 var/delay = 1 SECONDS - if(the_rcd.window_type == /obj/structure/window) + if(the_rcd.rcd_design_path == /obj/structure/window) cost = 4 delay = 2 SECONDS - else if(the_rcd.window_type == /obj/structure/window/reinforced) + else if(the_rcd.rcd_design_path == /obj/structure/window/reinforced) cost = 6 delay = 2.5 SECONDS return rcd_result_with_memory( - list("mode" = RCD_WINDOWGRILLE, "delay" = delay, "cost" = cost), + list("delay" = delay, "cost" = cost), src, RCD_MEMORY_WINDOWGRILLE, ) - if(RCD_MACHINE) - return list("mode" = RCD_MACHINE, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_COMPUTER) - return list("mode" = RCD_COMPUTER, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_FLOODLIGHT) - return list("mode" = RCD_FLOODLIGHT, "delay" = 3 SECONDS, "cost" = 20) - if(RCD_GIRDER) - return list("mode" = RCD_GIRDER, "delay" = 1.3 SECONDS, "cost" = 8) - if(RCD_FURNISHING) - var/cost = 0 - var/delay = 0 - if(the_rcd.furnish_type == /obj/structure/chair || the_rcd.furnish_type == /obj/structure/chair/stool) - cost = 4 - delay = 1 SECONDS - else if(the_rcd.furnish_type == /obj/structure/chair/stool/bar) - cost = 4 - delay = 0.5 SECONDS - else if(the_rcd.furnish_type == /obj/structure/table) - cost = 8 - delay = 2 SECONDS - else if(the_rcd.furnish_type == /obj/structure/table/glass) - cost = 8 - delay = 2 SECONDS - else if(the_rcd.furnish_type == /obj/structure/rack) - cost = 4 - delay = 2.5 SECONDS - else if(the_rcd.furnish_type == /obj/structure/bed) - cost = 8 - delay = 1.5 SECONDS - else if(the_rcd.furnish_type == /obj/machinery/microwave/engineering) - cost = 48 - delay = 4 SECONDS - if(cost == 0) - return FALSE - return list("mode" = RCD_FURNISHING, "delay" = cost, "cost" = delay) + if(RCD_AIRLOCK) + if(ispath(the_rcd.rcd_design_path, /obj/machinery/door/airlock/glass)) + return list("delay" = 5 SECONDS, "cost" = 20) + else + return list("delay" = 5 SECONDS, "cost" = 16) + if(RCD_STRUCTURE) + var/static/list/structure_costs = list( + /obj/structure/reflector = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/girder = list("delay" = 1.3 SECONDS, "cost" = 8), + /obj/structure/frame/machine/secured = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/frame/computer/rcd = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/floodlight_frame = list("delay" = 3 SECONDS, "cost" = 20), + /obj/structure/chair = list("delay" = 1 SECONDS, "cost" = 4), + /obj/structure/chair/stool/bar = list("delay" = 0.5 SECONDS, "cost" = 4), + /obj/structure/table = list("delay" = 2 SECONDS, "cost" = 8), + /obj/structure/bed = list("delay" = 2.5 SECONDS, "cost" = 8), + /obj/structure/rack = list("delay" = 2.5 SECONDS, "cost" = 4), + ) + + var/list/design_data = structure_costs[the_rcd.rcd_design_path] + if(!isnull(design_data)) + return design_data + + for(var/structure in structure_costs) + if(ispath(the_rcd.rcd_design_path, structure)) + return structure_costs[structure] + + return FALSE + if(RCD_DECONSTRUCT) + return list("mode" = RCD_DECONSTRUCT, "delay" = 5 SECONDS, "cost" = 33) + return FALSE /// if you are updating this make to to update /turf/open/misc/rcd_act() too -/turf/open/floor/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) +/turf/open/floor/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) + if(RCD_TURF) + if(rcd_data["[RCD_DESIGN_PATH]"] != /turf/open/floor/plating/rcd) + return FALSE + var/obj/structure/girder/girder = locate() in src if(girder) - return girder.rcd_act(user, the_rcd, passed_mode) + return girder.rcd_act(user, the_rcd, rcd_data) PlaceOnTop(/turf/closed/wall) return TRUE - if(RCD_REFLECTOR) - if(locate(/obj/structure/reflector) in src) + if(RCD_WINDOWGRILLE) + //check if we are building a window + var/obj/structure/window/window_path = rcd_data["[RCD_DESIGN_PATH]"] + if(!ispath(window_path)) + CRASH("Invalid window path type in RCD: [window_path]") + + //allow directional windows to be built without grills + if(!initial(window_path.fulltile)) + if(!valid_build_direction(src, user.dir, is_fulltile = FALSE)) + balloon_alert(user, "window already here!") + return FALSE + var/obj/structure/window/WD = new window_path(src, user.dir) + WD.set_anchored(TRUE) + return TRUE + + //build grills to deal with full tile windows + if(locate(/obj/structure/grille) in src) return FALSE - var/obj/structure/reflector/reflector_base = new(src) - reflector_base.set_anchored(TRUE) + var/obj/structure/grille/new_grille = new(src) + new_grille.set_anchored(TRUE) return TRUE if(RCD_AIRLOCK) - if(ispath(the_rcd.airlock_type, /obj/machinery/door/window)) + var/obj/machinery/door/airlock_type = rcd_data["[RCD_DESIGN_PATH]"] + + if(ispath(airlock_type, /obj/machinery/door/window)) if(!valid_build_direction(src, user.dir, is_fulltile = FALSE)) balloon_alert(user, "there's already a windoor!") return FALSE @@ -299,8 +310,8 @@ balloon_alert(user, "there's already a door!") return FALSE //create the assembly and let it finish itself - var/obj/structure/windoor_assembly/assembly = new /obj/structure/windoor_assembly(src, user.dir) - assembly.secure = ispath(the_rcd.airlock_type, /obj/machinery/door/window/brigdoor) + var/obj/structure/windoor_assembly/assembly = new (src, user.dir) + assembly.secure = ispath(airlock_type, /obj/machinery/door/window/brigdoor) assembly.electronics = the_rcd.airlock_electronics.create_copy(assembly) assembly.finish_door() return TRUE @@ -312,14 +323,38 @@ return FALSE //create the assembly and let it finish itself var/obj/structure/door_assembly/assembly = new (src) - if(ispath(the_rcd.airlock_type, /obj/machinery/door/airlock/glass)) + if(initial(airlock_type.glass)) assembly.glass = TRUE - assembly.glass_type = the_rcd.airlock_type + assembly.glass_type = airlock_type else - assembly.airlock_type = the_rcd.airlock_type + assembly.airlock_type = airlock_type assembly.electronics = the_rcd.airlock_electronics.create_copy(assembly) assembly.finish_door() return TRUE + if(RCD_STRUCTURE) + var/atom/movable/design_type = rcd_data["[RCD_DESIGN_PATH]"] + + //map absolute types to basic subtypes + var/atom/movable/locate_type = design_type + if(ispath(locate_type, /obj/structure/frame/machine/secured)) + locate_type = /obj/structure/frame/machine + if(ispath(locate_type, /obj/structure/frame/computer/rcd)) + locate_type = /obj/structure/frame/computer + if(ispath(locate_type, /obj/structure/floodlight_frame/completed)) + locate_type = /obj/structure/floodlight_frame + if(locate(locate_type) in src) + return FALSE + + var/atom/movable/design = new design_type(src) + var/static/list/dir_types = list( + /obj/structure/chair, + /obj/structure/table, + /obj/structure/rack, + /obj/structure/bed, + ) + if(is_path_in_list(locate_type, dir_types)) + design.setDir(user.dir) + return TRUE if(RCD_DECONSTRUCT) if(rcd_proof) balloon_alert(user, "it's too thick!") @@ -327,68 +362,6 @@ if(!ScrapeAway(flags = CHANGETURF_INHERIT_AIR)) return FALSE return TRUE - if(RCD_WINDOWGRILLE) - //check if we are building a window - var/obj/structure/window/window_path = the_rcd.window_type - if(!ispath(window_path)) - CRASH("Invalid window path type in RCD: [window_path]") - - //allow directional windows to be built without grills - if(!initial(window_path.fulltile)) - if(!valid_build_direction(src, user.dir, is_fulltile = FALSE)) - balloon_alert(user, "window already here!") - return FALSE - var/obj/structure/window/WD = new the_rcd.window_type(src, user.dir) - WD.set_anchored(TRUE) - return TRUE - - //build grills to deal with full tile windows - if(locate(/obj/structure/grille) in src) - return FALSE - var/obj/structure/grille/new_grille = new(src) - new_grille.set_anchored(TRUE) - return TRUE - if(RCD_MACHINE) - if(locate(/obj/structure/frame/machine) in src) - return FALSE - var/obj/structure/frame/machine/new_machine = new(src) - new_machine.state = 2 - new_machine.icon_state = "box_1" - new_machine.set_anchored(TRUE) - return TRUE - if(RCD_COMPUTER) - if(locate(/obj/structure/frame/computer) in src) - return FALSE - var/obj/structure/frame/computer/new_computer = new(src) - new_computer.set_anchored(TRUE) - new_computer.state = 1 - new_computer.setDir(the_rcd.computer_dir) - return TRUE - if(RCD_FLOODLIGHT) - if(locate(/obj/structure/floodlight_frame) in src) - return FALSE - var/obj/structure/floodlight_frame/new_floodlight = new(src) - new_floodlight.name = "secured [new_floodlight.name]" - new_floodlight.desc = "A bare metal frame that looks like a floodlight. Requires a light tube to complete." - new_floodlight.icon_state = "floodlight_c3" - new_floodlight.state = FLOODLIGHT_NEEDS_LIGHTS - return TRUE - if(RCD_GIRDER) - if(locate(/obj/structure/girder) in src) - return FALSE - new /obj/structure/girder(src) - 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) - if(istype(new_furnish, /obj/machinery/microwave/engineering)) - var/obj/machinery/microwave/engineering/new_mw = new_furnish - var/obj/item/stock_parts/cell/new_cell = new() - new_mw.cell = new_cell - new_mw.update_appearance() - return TRUE return FALSE /turf/open/floor/material diff --git a/code/game/turfs/open/floor/plating.dm b/code/game/turfs/open/floor/plating.dm index 1ff83fec0c3..eee4797887b 100644 --- a/code/game/turfs/open/floor/plating.dm +++ b/code/game/turfs/open/floor/plating.dm @@ -163,12 +163,11 @@ to_chat(user, span_danger("You hit [src], to no effect!")) /turf/open/floor/plating/foam/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if(the_rcd.mode == RCD_FLOORWALL) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) + if(the_rcd.mode == RCD_TURF && the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) + return list("delay" = 0, "cost" = 1) -/turf/open/floor/plating/foam/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - if(passed_mode == RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) +/turf/open/floor/plating/foam/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_TURF && rcd_data["[RCD_DESIGN_PATH]"] == /turf/open/floor/plating/rcd) ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) return TRUE return FALSE @@ -308,6 +307,13 @@ new /obj/effect/decal/cleanable/glass/plastitanium/screws(below_turf) playsound(src, 'sound/effects/structure_stress/pop3.ogg', 100, vary = TRUE) +///not an actual turf its used just for rcd ui purposes +/turf/open/floor/plating/rcd + name = "Floor/Wall" + icon = 'icons/hud/radial.dmi' + icon_state = "wallfloor" + + #undef PLATE_INTACT #undef PLATE_BOLTS_LOOSENED #undef PLATE_CUT diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index b8e04949662..623da55f104 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -154,17 +154,14 @@ STOP_PROCESSING(SSobj, src) /turf/open/lava/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - switch(the_rcd.mode) - if(RCD_FLOORWALL) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) + if(the_rcd.mode == RCD_TURF && the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) + return list("delay" = 0, "cost" = 3) return FALSE -/turf/open/lava/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - return TRUE +/turf/open/lava/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_TURF && rcd_data["[RCD_DESIGN_PATH]"] == /turf/open/floor/plating/rcd) + PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + return TRUE return FALSE /turf/open/lava/rust_heretic_act() diff --git a/code/game/turfs/open/misc.dm b/code/game/turfs/open/misc.dm index cbbae3081a2..edf9e92c8a9 100644 --- a/code/game/turfs/open/misc.dm +++ b/code/game/turfs/open/misc.dm @@ -77,71 +77,100 @@ /turf/open/misc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) - if(RCD_FLOORWALL) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) - else - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) - if(RCD_REFLECTOR) - return list("mode" = RCD_REFLECTOR, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_AIRLOCK) - if(the_rcd.airlock_glass) - return list("mode" = RCD_AIRLOCK, "delay" = 5 SECONDS, "cost" = 20) - else - return list("mode" = RCD_AIRLOCK, "delay" = 5 SECONDS, "cost" = 16) - if(RCD_WINDOWGRILLE) + if(RCD_TURF) + if(the_rcd.rcd_design_path != /turf/open/floor/plating/rcd) + return FALSE + + var/obj/structure/girder/girder = locate() in src + if(girder) + return girder.rcd_vals(user, the_rcd) + return rcd_result_with_memory( - list("mode" = RCD_WINDOWGRILLE, "delay" = 1 SECONDS, "cost" = 4), + list("delay" = 2 SECONDS, "cost" = 16), + src, RCD_MEMORY_WALL, + ) + if(RCD_WINDOWGRILLE) + //default cost for building a grill for fulltile windows + var/cost = 4 + var/delay = 1 SECONDS + if(the_rcd.rcd_design_path == /obj/structure/window) + cost = 4 + delay = 2 SECONDS + else if(the_rcd.rcd_design_path == /obj/structure/window/reinforced) + cost = 6 + delay = 2.5 SECONDS + return rcd_result_with_memory( + list("delay" = delay, "cost" = cost), src, RCD_MEMORY_WINDOWGRILLE, ) - if(RCD_MACHINE) - return list("mode" = RCD_MACHINE, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_COMPUTER) - return list("mode" = RCD_COMPUTER, "delay" = 2 SECONDS, "cost" = 20) - if(RCD_FLOODLIGHT) - return list("mode" = RCD_FLOODLIGHT, "delay" = 3 SECONDS, "cost" = 20) - if(RCD_GIRDER) - return list("mode" = RCD_GIRDER, "delay" = 1.3 SECONDS, "cost" = 8) - if(RCD_FURNISHING) - var/cost = 0 - var/delay = 0 - if(the_rcd.furnish_type == /obj/structure/chair || the_rcd.furnish_type == /obj/structure/chair/stool) - cost = 4 - delay = 1 SECONDS - else if(the_rcd.furnish_type == /obj/structure/chair/stool/bar) - cost = 4 - delay = 0.5 SECONDS - else if(the_rcd.furnish_type == /obj/structure/table) - cost = 8 - delay = 2 SECONDS - else if(the_rcd.furnish_type == /obj/structure/table/glass) - cost = 8 - delay = 2 SECONDS - else if(the_rcd.furnish_type == /obj/structure/rack) - cost = 4 - delay = 2.5 SECONDS - else if(the_rcd.furnish_type == /obj/structure/bed) - cost = 8 - delay = 1.5 SECONDS - if(!cost) - return FALSE - return list("mode" = RCD_FURNISHING, "delay" = cost, "cost" = delay) + if(RCD_AIRLOCK) + if(ispath(the_rcd.rcd_design_path, /obj/machinery/door/airlock/glass)) + return list("delay" = 5 SECONDS, "cost" = 20) + else + return list("delay" = 5 SECONDS, "cost" = 16) + if(RCD_STRUCTURE) + var/static/list/structure_costs = list( + /obj/structure/reflector = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/girder = list("delay" = 1.3 SECONDS, "cost" = 8), + /obj/structure/frame/machine/secured = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/frame/computer/rcd = list("delay" = 2 SECONDS, "cost" = 20), + /obj/structure/floodlight_frame = list("delay" = 3 SECONDS, "cost" = 20), + /obj/structure/chair = list("delay" = 1 SECONDS, "cost" = 4), + /obj/structure/chair/stool/bar = list("delay" = 0.5 SECONDS, "cost" = 4), + /obj/structure/table = list("delay" = 2 SECONDS, "cost" = 8), + /obj/structure/bed = list("delay" = 2.5 SECONDS, "cost" = 8), + /obj/structure/rack = list("delay" = 2.5 SECONDS, "cost" = 4), + ) + + var/list/design_data = structure_costs[the_rcd.rcd_design_path] + if(!isnull(design_data)) + return design_data + + for(var/structure in structure_costs) + if(ispath(the_rcd.rcd_design_path, structure)) + return structure_costs[structure] + + return FALSE + return FALSE -/turf/open/misc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - return TRUE - if(RCD_REFLECTOR) - if(locate(/obj/structure/reflector) in src) +/turf/open/misc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + switch(rcd_data["[RCD_DESIGN_MODE]"]) + if(RCD_TURF) + if(rcd_data["[RCD_DESIGN_PATH]"] != /turf/open/floor/plating/rcd) return FALSE - var/obj/structure/reflector/reflector_base = new(src) - reflector_base.set_anchored(TRUE) + + var/obj/structure/girder/girder = locate() in src + if(girder) + return girder.rcd_act(user, the_rcd, rcd_data) + + PlaceOnTop(/turf/closed/wall) + return TRUE + if(RCD_WINDOWGRILLE) + //check if we are building a window + var/obj/structure/window/window_path = rcd_data["[RCD_DESIGN_PATH]"] + if(!ispath(window_path)) + CRASH("Invalid window path type in RCD: [window_path]") + + //allow directional windows to be built without grills + if(!initial(window_path.fulltile)) + if(!valid_build_direction(src, user.dir, is_fulltile = FALSE)) + balloon_alert(user, "window already here!") + return FALSE + var/obj/structure/window/WD = new window_path(src, user.dir) + WD.set_anchored(TRUE) + return TRUE + + //build grills to deal with full tile windows + if(locate(/obj/structure/grille) in src) + return FALSE + var/obj/structure/grille/new_grille = new(src) + new_grille.set_anchored(TRUE) return TRUE if(RCD_AIRLOCK) - if(ispath(the_rcd.airlock_type, /obj/machinery/door/window)) + var/obj/machinery/door/airlock_type = rcd_data["[RCD_DESIGN_PATH]"] + + if(ispath(airlock_type, /obj/machinery/door/window)) if(!valid_build_direction(src, user.dir, is_fulltile = FALSE)) balloon_alert(user, "there's already a windoor!") return FALSE @@ -150,15 +179,11 @@ continue balloon_alert(user, "there's already a door!") return FALSE - 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_appearance() + //create the assembly and let it finish itself + var/obj/structure/windoor_assembly/assembly = new (src, user.dir) + assembly.secure = ispath(airlock_type, /obj/machinery/door/window/brigdoor) + assembly.electronics = the_rcd.airlock_electronics.create_copy(assembly) + assembly.finish_door() return TRUE for(var/obj/machinery/door/door in src) @@ -166,70 +191,38 @@ continue balloon_alert(user, "there's already a door!") return FALSE - 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) - 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 - new_airlock.electronics.shell = the_rcd.airlock_electronics.shell - if(new_airlock.electronics.one_access) - new_airlock.req_one_access = new_airlock.electronics.accesses + //create the assembly and let it finish itself + var/obj/structure/door_assembly/assembly = new (src) + if(initial(airlock_type.glass)) + assembly.glass = TRUE + assembly.glass_type = airlock_type else - new_airlock.req_access = new_airlock.electronics.accesses - if(new_airlock.electronics.unres_sides) - new_airlock.unres_sides = new_airlock.electronics.unres_sides - new_airlock.unres_sensor = TRUE - if(new_airlock.electronics.passed_name) - new_airlock.name = sanitize(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_appearance() + assembly.airlock_type = airlock_type + assembly.electronics = the_rcd.airlock_electronics.create_copy(assembly) + assembly.finish_door() return TRUE - if(RCD_WINDOWGRILLE) - if(locate(/obj/structure/grille) in src) + if(RCD_STRUCTURE) + var/atom/movable/design_type = rcd_data["[RCD_DESIGN_PATH]"] + + //map absolute types to basic subtypes + var/atom/movable/locate_type = design_type + if(ispath(locate_type, /obj/structure/frame/machine/secured)) + locate_type = /obj/structure/frame/machine + if(ispath(locate_type, /obj/structure/frame/computer/rcd)) + locate_type = /obj/structure/frame/computer + if(ispath(locate_type, /obj/structure/floodlight_frame/completed)) + locate_type = /obj/structure/floodlight_frame + if(locate(locate_type) in src) return FALSE - var/obj/structure/grille/new_grille = new(src) - new_grille.set_anchored(TRUE) - return TRUE - if(RCD_MACHINE) - if(locate(/obj/structure/frame/machine) in src) - return FALSE - var/obj/structure/frame/machine/new_machine = new(src) - new_machine.state = 2 - new_machine.icon_state = "box_1" - new_machine.set_anchored(TRUE) - return TRUE - if(RCD_COMPUTER) - if(locate(/obj/structure/frame/computer) in src) - return FALSE - var/obj/structure/frame/computer/new_computer = new(src) - new_computer.set_anchored(TRUE) - new_computer.state = 1 - new_computer.setDir(the_rcd.computer_dir) - return TRUE - if(RCD_FLOODLIGHT) - if(locate(/obj/structure/floodlight_frame) in src) - return FALSE - var/obj/structure/floodlight_frame/new_floodlight = new(src) - new_floodlight.name = "secured [new_floodlight.name]" - new_floodlight.desc = "A bare metal frame that looks like a floodlight. Requires a light tube to complete." - new_floodlight.icon_state = "floodlight_c3" - new_floodlight.state = FLOODLIGHT_NEEDS_LIGHTS - return TRUE - if(RCD_GIRDER) - if(locate(/obj/structure/girder) in src) - return FALSE - new /obj/structure/girder(src) - 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) + + var/atom/movable/design = new design_type(src) + var/static/list/dir_types = list( + /obj/structure/chair, + /obj/structure/table, + /obj/structure/rack, + /obj/structure/bed, + ) + if(is_path_in_list(locate_type, dir_types)) + design.setDir(user.dir) return TRUE return FALSE diff --git a/code/game/turfs/open/openspace.dm b/code/game/turfs/open/openspace.dm index 91437e727a7..77a2259763a 100644 --- a/code/game/turfs/open/openspace.dm +++ b/code/game/turfs/open/openspace.dm @@ -132,21 +132,19 @@ if(!CanBuildHere()) return FALSE - switch(the_rcd.mode) - if(RCD_FLOORWALL) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) - else - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) + if(the_rcd.mode == RCD_TURF && the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) + var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) + if(L) + return list("delay" = 0, "cost" = 1) + else + return list("delay" = 0, "cost" = 3) + return FALSE -/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - return TRUE +/turf/open/openspace/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_TURF && rcd_data["[RCD_DESIGN_PATH]"] == /turf/open/floor/plating/rcd) + PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + return TRUE return FALSE /turf/open/openspace/rust_heretic_act() diff --git a/code/game/turfs/open/space/space.dm b/code/game/turfs/open/space/space.dm index 8152f910c01..fc20d9a11b1 100644 --- a/code/game/turfs/open/space/space.dm +++ b/code/game/turfs/open/space/space.dm @@ -157,34 +157,38 @@ GLOBAL_VAR_INIT(starlight_color, COLOR_STARLIGHT) if(!CanBuildHere()) return FALSE - switch(the_rcd.mode) - if(RCD_FLOORWALL) + if(the_rcd.mode == RCD_TURF) + if(the_rcd.rcd_design_path == /turf/open/floor/plating/rcd) var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) if(lattice) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) + return list("delay" = 0, "cost" = 1) else - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) - if(RCD_CATWALK) + return list("delay" = 0, "cost" = 3) + else if(the_rcd.rcd_design_path == /obj/structure/lattice/catwalk) var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) if(lattice) - return list("mode" = RCD_CATWALK, "delay" = 0, "cost" = 2) + return list("delay" = 0, "cost" = 2) else - return list("mode" = RCD_CATWALK, "delay" = 0, "cost" = 4) + return list("delay" = 0, "cost" = 4) + else + return FALSE + return FALSE -/turf/open/space/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) +/turf/open/space/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(the_rcd.mode == RCD_TURF) + if(rcd_data["[RCD_DESIGN_PATH]"] == /turf/open/floor/plating/rcd) PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) return TRUE - if(RCD_CATWALK) - to_chat(user, span_notice("You build a catwalk.")) + else if(rcd_data["[RCD_DESIGN_PATH]"] == /obj/structure/lattice/catwalk) var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) if(lattice) qdel(lattice) new /obj/structure/lattice/catwalk(src) return TRUE + else + return FALSE + return FALSE /turf/open/space/rust_heretic_act() diff --git a/code/modules/asset_cache/assets/rcd.dm b/code/modules/asset_cache/assets/rcd.dm index c57d7881d13..16dee49c60f 100644 --- a/code/modules/asset_cache/assets/rcd.dm +++ b/code/modules/asset_cache/assets/rcd.dm @@ -2,61 +2,44 @@ name = "rcd-tgui" /datum/asset/spritesheet/rcd/create_spritesheets() - //We load airlock icons seperatly from other icons cause they need overlays + for(var/root_category in GLOB.rcd_designs) - //load all category essential icon_states. format is icon_file = list of icon states we need from that file - var/list/essentials = list( - 'icons/obj/chairs.dmi' = list("bar"), - 'icons/obj/machines/wallmounts.dmi' = list("apc", "alarm_bitem", "fire_bitem"), - 'icons/obj/lighting.dmi' = list("floodlight_c1"), - 'icons/obj/assemblies/stock_parts.dmi' = list("box_1"), - 'icons/obj/bed.dmi' = list("bed"), - 'icons/obj/smooth_structures/catwalk.dmi' = list("catwalk-0"), - 'icons/hud/radial.dmi' = list("cnorth", "csouth", "ceast", "cwest", "chair", "secure_windoor", "stool", "wallfloor", "windowsize", "windowtype", "windoor"), - 'icons/obj/structures.dmi' = list("glass_table", "rack", "rwindow0", "reflector_base", "table", "window0", "girder"), - 'icons/obj/machines/microwave.dmi' = list("engi_mw_complete"), - ) - - var/icon/icon - for(var/icon_file as anything in essentials) - for(var/icon_state as anything in essentials[icon_file]) - icon = icon(icon = icon_file, icon_state = icon_state) - if(icon_state == "window0" || icon_state == "rwindow0") - icon.Blend(icon(icon = 'icons/obj/structures.dmi', icon_state = "grille"), ICON_UNDERLAY) - Insert(sprite_name = sanitize_css_class_name(icon_state), I = icon) - - //for each airlock type we create its overlayed version with the suffix Glass in the sprite name - var/list/airlocks = list( - "Standard" = 'icons/obj/doors/airlocks/station/public.dmi', - "Public" = 'icons/obj/doors/airlocks/public/glass.dmi', - "Engineering" = 'icons/obj/doors/airlocks/station/engineering.dmi', - "Atmospherics" = 'icons/obj/doors/airlocks/station/atmos.dmi', - "Security" = 'icons/obj/doors/airlocks/station/security.dmi', - "Command" = 'icons/obj/doors/airlocks/station/command.dmi', - "Medical" = 'icons/obj/doors/airlocks/station/medical.dmi', - "Research" = 'icons/obj/doors/airlocks/station/research.dmi', - "Freezer" = 'icons/obj/doors/airlocks/station/freezer.dmi', - "Virology" = 'icons/obj/doors/airlocks/station/virology.dmi', - "Mining" = 'icons/obj/doors/airlocks/station/mining.dmi', - "Maintenance" = 'icons/obj/doors/airlocks/station/maintenance.dmi', - "External" = 'icons/obj/doors/airlocks/external/external.dmi', - "External Maintenance" = 'icons/obj/doors/airlocks/station/maintenanceexternal.dmi', - "Airtight Hatch" = 'icons/obj/doors/airlocks/hatch/centcom.dmi', - "Maintenance Hatch" = 'icons/obj/doors/airlocks/hatch/maintenance.dmi' - ) - //these 3 types dont have glass doors - var/list/exclusion = list("Freezer", "Airtight Hatch", "Maintenance Hatch") - - for(var/airlock_name in airlocks) - //solid door with overlay - icon = icon(icon = airlocks[airlock_name] , icon_state = "closed" , dir = SOUTH) - icon.Blend(icon(icon = airlocks[airlock_name], icon_state = "fill_closed", dir = SOUTH), ICON_OVERLAY) - Insert(sprite_name = sanitize_css_class_name(airlock_name), I = icon) - - //exclude these glass types - if(airlock_name in exclusion) + var/list/category_designs = GLOB.rcd_designs[root_category] + if(!length(category_designs)) continue - //glass door no overlay - icon = icon(airlocks[airlock_name] , "closed" , SOUTH) - Insert(sprite_name = sanitize_css_class_name("[airlock_name]Glass"), I = icon) + for(var/category in category_designs) + var/list/designs = category_designs[category] + + var/sprite_name + var/icon/sprite_icon + for(var/list/design as anything in designs) + var/atom/movable/path = design[RCD_DESIGN_PATH] + if(!ispath(path)) + continue + sprite_name = initial(path.name) + + //icon for windows are blended with grills if required and loaded from radial menu + if(ispath(path, /obj/structure/window)) + if(path == /obj/structure/window) + sprite_icon = icon(icon = 'icons/hud/radial.dmi', icon_state = "windowsize") + else if(path == /obj/structure/window/reinforced) + sprite_icon = icon(icon = 'icons/hud/radial.dmi', icon_state = "windowtype") + else if(path == /obj/structure/window/fulltile || path == /obj/structure/window/reinforced/fulltile) + sprite_icon = icon(icon = initial(path.icon), icon_state = initial(path.icon_state)) + sprite_icon.Blend(icon(icon = 'icons/obj/structures.dmi', icon_state = "grille"), ICON_UNDERLAY) + + //icons for solid airlocks have an added solid overlay on top of their glass icons + else if(ispath(path, /obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/airlock_path = path + var/airlock_icon = initial(airlock_path.icon) + + sprite_icon = icon(icon = airlock_icon, icon_state = "closed") + if(!initial(airlock_path.glass)) + sprite_icon.Blend(icon(icon = airlock_icon, icon_state = "fill_closed"), ICON_OVERLAY) + + //for all other icons we load the paths default icon & icon state + else + sprite_icon = icon(icon = initial(path.icon), icon_state = initial(path.icon_state)) + + Insert(sanitize_css_class_name(sprite_name), sprite_icon) diff --git a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm index 3ec8fbdd99b..3ac90db0c18 100644 --- a/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm +++ b/code/modules/atmospherics/machinery/air_alarm/air_alarm_interact.dm @@ -47,17 +47,15 @@ /obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if((buildstage == AIR_ALARM_BUILD_NO_CIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) - return list("mode" = RCD_WALLFRAME, "delay" = 2 SECONDS, "cost" = 1) + return list("delay" = 2 SECONDS, "cost" = 1) return FALSE -/obj/machinery/airalarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_WALLFRAME) - user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \ - span_notice("You adapt an air alarm circuit and slot it into the assembly.")) - buildstage = AIR_ALARM_BUILD_NO_WIRES - update_appearance() - return TRUE +/obj/machinery/airalarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(rcd_data["[RCD_DESIGN_MODE]"] == RCD_WALLFRAME) + balloon_alert(user, "circuit installed") + buildstage = AIR_ALARM_BUILD_NO_WIRES + update_appearance() + return TRUE return FALSE /obj/machinery/airalarm/attack_hand_secondary(mob/user, list/modifiers) diff --git a/code/modules/power/apc/apc_tool_act.dm b/code/modules/power/apc/apc_tool_act.dm index 8884786a4eb..55c9b34a350 100644 --- a/code/modules/power/apc/apc_tool_act.dm +++ b/code/modules/power/apc/apc_tool_act.dm @@ -161,26 +161,25 @@ if(machine_stat & BROKEN) balloon_alert(user, "frame is too damaged!") return FALSE - return list("mode" = RCD_WALLFRAME, "delay" = 2 SECONDS, "cost" = 1) + return list("delay" = 2 SECONDS, "cost" = 1) if(!cell) if(machine_stat & MAINT) balloon_alert(user, "no board for a cell!") return FALSE - return list("mode" = RCD_WALLFRAME, "delay" = 5 SECONDS, "cost" = 10) + return list("delay" = 5 SECONDS, "cost" = 10) balloon_alert(user, "has both board and cell!") return FALSE -/obj/machinery/power/apc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - if(!(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) || passed_mode != RCD_WALLFRAME) +/obj/machinery/power/apc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, list/rcd_data) + if(!(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) || rcd_data["[RCD_DESIGN_MODE]"] != RCD_WALLFRAME) return FALSE if(!has_electronics) if(machine_stat & BROKEN) balloon_alert(user, "frame is too damaged!") return - user.visible_message(span_notice("[user] fabricates a circuit and places it into [src].")) balloon_alert(user, "control board placed") has_electronics = TRUE locked = TRUE @@ -194,8 +193,7 @@ C.forceMove(src) cell = C chargecount = 0 - user.visible_message(span_notice("[user] fabricates a weak power cell and places it into [src]."), \ - span_warning("Your [the_rcd.name] whirrs with strain as you create a weak power cell and place it into [src]!")) + balloon_alert(user, "power cell installed") update_appearance() return TRUE diff --git a/code/modules/power/floodlight.dm b/code/modules/power/floodlight.dm index f36c9b13038..7155ce6aa23 100644 --- a/code/modules/power/floodlight.dm +++ b/code/modules/power/floodlight.dm @@ -120,6 +120,12 @@ return ..() +/obj/structure/floodlight_frame/completed + name = "floodlight frame" + desc = "A bare metal frame that looks like a floodlight. Requires a light tube to complete." + icon_state = "floodlight_c3" + state = FLOODLIGHT_NEEDS_LIGHTS + /obj/machinery/power/floodlight name = "floodlight" desc = "A pole with powerful mounted lights on it. Due to its high power draw, it must be powered by a direct connection to a wire node." diff --git a/code/modules/unit_tests/rcd.dm b/code/modules/unit_tests/rcd.dm index 27ab66fa0be..49e9f8461fd 100644 --- a/code/modules/unit_tests/rcd.dm +++ b/code/modules/unit_tests/rcd.dm @@ -15,7 +15,7 @@ engineer.put_in_hands(rcd, forced = TRUE) - rcd.mode = RCD_MACHINE + rcd.mode = RCD_STRUCTURE var/list/adjacent_turfs = get_adjacent_open_turfs(engineer) @@ -24,7 +24,7 @@ var/turf/adjacent_turf = adjacent_turfs[1] for(var/i in 1 to 10) - adjacent_turf.rcd_act(engineer, rcd, rcd.mode) + adjacent_turf.rcd_act(engineer, rcd, list("[RCD_DESIGN_MODE]" = rcd.mode, "[RCD_DESIGN_PATH]" = /obj/structure/frame/machine/secured)) var/frame_count = 0 for(var/obj/structure/frame/machine_frame in adjacent_turf.contents) diff --git a/tgstation.dme b/tgstation.dme index e3cfa5ace3a..79e49f5c872 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -66,7 +66,6 @@ #include "code\__DEFINES\communications.dm" #include "code\__DEFINES\computers.dm" #include "code\__DEFINES\configuration.dm" -#include "code\__DEFINES\construction.dm" #include "code\__DEFINES\cooldowns.dm" #include "code\__DEFINES\crafting.dm" #include "code\__DEFINES\crushing.dm" @@ -134,7 +133,6 @@ #include "code\__DEFINES\map_switch.dm" #include "code\__DEFINES\mapping.dm" #include "code\__DEFINES\maps.dm" -#include "code\__DEFINES\materials.dm" #include "code\__DEFINES\maths.dm" #include "code\__DEFINES\matrices.dm" #include "code\__DEFINES\MC.dm" @@ -267,6 +265,10 @@ #include "code\__DEFINES\atmospherics\atmos_mapping_helpers.dm" #include "code\__DEFINES\atmospherics\atmos_mob_interaction.dm" #include "code\__DEFINES\atmospherics\atmos_piping.dm" +#include "code\__DEFINES\construction\actions.dm" +#include "code\__DEFINES\construction\material.dm" +#include "code\__DEFINES\construction\rcd.dm" +#include "code\__DEFINES\construction\structures.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" #include "code\__DEFINES\dcs\signals\mapping.dm" @@ -486,6 +488,7 @@ #include "code\_globalvars\lighting.dm" #include "code\_globalvars\logging.dm" #include "code\_globalvars\phobias.dm" +#include "code\_globalvars\rcd.dm" #include "code\_globalvars\religion.dm" #include "code\_globalvars\tgui.dm" #include "code\_globalvars\time_vars.dm" @@ -494,6 +497,7 @@ #include "code\_globalvars\lists\ambience.dm" #include "code\_globalvars\lists\client.dm" #include "code\_globalvars\lists\color.dm" +#include "code\_globalvars\lists\crafting.dm" #include "code\_globalvars\lists\flavor_misc.dm" #include "code\_globalvars\lists\icons.dm" #include "code\_globalvars\lists\keybindings.dm" @@ -504,6 +508,7 @@ #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\poll_ignore.dm" #include "code\_globalvars\lists\quirks.dm" +#include "code\_globalvars\lists\rcd.dm" #include "code\_globalvars\lists\reagents.dm" #include "code\_globalvars\lists\rtd.dm" #include "code\_globalvars\lists\typecache.dm" @@ -2000,6 +2005,7 @@ #include "code\game\objects\effects\poster_demotivational.dm" #include "code\game\objects\effects\poster_motivational.dm" #include "code\game\objects\effects\powerup.dm" +#include "code\game\objects\effects\rcd.dm" #include "code\game\objects\effects\spiderwebs.dm" #include "code\game\objects\effects\step_triggers.dm" #include "code\game\objects\effects\wanted_poster.dm" diff --git a/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx b/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx index 37400b62287..5c9ce63fd4d 100644 --- a/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx +++ b/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx @@ -133,9 +133,9 @@ const DesignSection = (props, context) => { className={classes(['rcd-tgui32x32', design.icon])} style={{ transform: - design.icon === 'window0' || - design.icon === 'rwindow0' || - design.icon === 'catwalk0' + design.title === 'full tile window' || + design.title === 'full tile reinforced window' || + design.title === 'catwalk' ? 'scale(0.7)' : 'scale(1.0)', }} diff --git a/tgui/packages/tgui/interfaces/RapidPipeDispenser.tsx b/tgui/packages/tgui/interfaces/RapidPipeDispenser.tsx index 18f66be0bdd..6a66b1d641b 100644 --- a/tgui/packages/tgui/interfaces/RapidPipeDispenser.tsx +++ b/tgui/packages/tgui/interfaces/RapidPipeDispenser.tsx @@ -17,7 +17,6 @@ export const ICON_BY_CATEGORY_NAME = { 'Devices': 'microchip', 'Heat Exchange': 'thermometer-half', 'Station Equipment': 'microchip', - 'Air Sensors': 'microchip', }; const TOOLS = [ diff --git a/tgui/packages/tgui/interfaces/PlumbingService.tsx b/tgui/packages/tgui/interfaces/RapidPlumbingDevice.tsx similarity index 98% rename from tgui/packages/tgui/interfaces/PlumbingService.tsx rename to tgui/packages/tgui/interfaces/RapidPlumbingDevice.tsx index 6256205274f..1cd98abca99 100644 --- a/tgui/packages/tgui/interfaces/PlumbingService.tsx +++ b/tgui/packages/tgui/interfaces/RapidPlumbingDevice.tsx @@ -94,7 +94,7 @@ const LayerIconSection = (props, context) => { ); }; -export const PlumbingService = (props, context) => { +export const RapidPlumbingDevice = (props, context) => { const { data } = useBackend(context); const { silo_upgraded } = data; return (