diff --git a/code/_globalvars/lists/rtd.dm b/code/_globalvars/lists/rtd.dm new file mode 100644 index 00000000000..29e5b6d0069 --- /dev/null +++ b/code/_globalvars/lists/rtd.dm @@ -0,0 +1,116 @@ +//dont create icons for TGUI if direction is any of these values cause its handled inside CSS +GLOBAL_LIST_INIT(tile_dont_rotate, list(NORTH, EAST, SOUTH, WEST)) + +///all designs supported by the RTD +GLOBAL_LIST_INIT(floor_designs, list( + //what players will use most of the time + "Conventional" = list( + //The most common types + "Standard" = list( + list("name" = "Base", "type" = /obj/item/stack/tile/iron, "tile_cost" = 4), + list("name" = "Small", "type" = /obj/item/stack/tile/iron/small, "tile_cost" = 3), + list("name" = "Large", "type" = /obj/item/stack/tile/iron/large, "tile_cost" = 7), + list("name" = "Diagonal", "type" = /obj/item/stack/tile/iron/diagonal, "tile_cost" = 5), + list("name" = "Edge", "type" = /obj/item/stack/tile/iron/edge, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Half", "type" = /obj/item/stack/tile/iron/half, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Corner", "type" = /obj/item/stack/tile/iron/corner, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured", "type" = /obj/item/stack/tile/iron/textured, "tile_cost" = 5), + list("name" = "Textured Edge", "type" = /obj/item/stack/tile/iron/textured_edge, "tile_cost" = 6, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured Half", "type" = /obj/item/stack/tile/iron/textured_half, "tile_cost" = 6, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Textured Corner", "type" = /obj/item/stack/tile/iron/textured_corner, "tile_cost" = 6, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured Large", "type" = /obj/item/stack/tile/iron/textured_large, "tile_cost" = 6), + ), + //Looks slightly transparent or faded + "Translucent" = list( + list("name" = "Smooth", "type" = /obj/item/stack/tile/iron/smooth, "tile_cost" = 4), + list("name" = "Smooth Edge", "type" = /obj/item/stack/tile/iron/smooth_edge, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Half", "type" = /obj/item/stack/tile/iron/smooth_half, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Smooth Corner", "type" = /obj/item/stack/tile/iron/smooth_corner, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Large", "type" = /obj/item/stack/tile/iron/smooth_large, "tile_cost" = 7), + list("name" = "Freezer", "type" = /obj/item/stack/tile/iron/freezer, "tile_cost" = 5), + list("name" = "Showroom", "type" = /obj/item/stack/tile/iron/showroomfloor, "tile_cost" = 5), + list("name" = "Glass", "type" = /obj/item/stack/tile/glass, "tile_cost" = 5), + list("name" = "Reinforced Glass", "type" = /obj/item/stack/tile/rglass, "tile_cost" = 10) + ), + //Uses eletricity or atleast thats i think these do + "Circuit" = list( + list("name" = "Recharge", "type" = /obj/item/stack/tile/iron/recharge_floor, "tile_cost" = 5), + list("name" = "Solar Panel", "type" = /obj/item/stack/tile/iron/solarpanel, "tile_cost" = 5), + list("name" = "Blue Circuit", "type" = /obj/item/stack/tile/circuit, "tile_cost" = 5), + list("name" = "Green Circuit", "type" = /obj/item/stack/tile/circuit/green, "tile_cost" = 5), + list("name" = "Green Circuit Anim", "type" = /obj/item/stack/tile/circuit/green/anim, "tile_cost" = 5), + list("name" = "Red Circuit", "type" = /obj/item/stack/tile/circuit/red, "tile_cost" = 5), + list("name" = "Red Circuit Anim", "type" = /obj/item/stack/tile/circuit/red/anim, "tile_cost" = 5), + ) + ), + + //Floors which are decorated + "Decorated" = list( + //Dark Colored tiles + "Dark Colored" = list( + list("name" = "Base", "type" = /obj/item/stack/tile/iron/dark, "tile_cost" = 4), + list("name" = "Smooth Edge", "type" = /obj/item/stack/tile/iron/dark/smooth_edge, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Half", "type" = /obj/item/stack/tile/iron/dark/smooth_half, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Smooth Corner" ,"type" = /obj/item/stack/tile/iron/dark/smooth_corner, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Large", "type" = /obj/item/stack/tile/iron/dark/smooth_large, "tile_cost" = 7), + list("name" = "Small", "type" = /obj/item/stack/tile/iron/dark/small, "tile_cost" = 4), + list("name" = "Diagonal", "type" = /obj/item/stack/tile/iron/dark/diagonal, "tile_cost" = 4), + list("name" = "Herringbone", "type" = /obj/item/stack/tile/iron/dark/herringbone, "tile_cost" = 4), + list("name" = "Half Dark", "type" = /obj/item/stack/tile/iron/dark_side, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST, SOUTHEAST, SOUTHWEST, NORTHEAST, NORTHWEST)), + list("name" = "Dark Corner" ,"type" = /obj/item/stack/tile/iron/dark_corner, "tile_cost" = 4, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + ), + + //White Colored tiles + "White Colored" = list( + list("name" = "Base", "type" = /obj/item/stack/tile/iron/white, "tile_cost" = 5), + list("name" = "Smooth Edge", "type" = /obj/item/stack/tile/iron/white/smooth_edge, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Half", "type" = /obj/item/stack/tile/iron/white/smooth_half, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Smooth Corner", "type" = /obj/item/stack/tile/iron/white/smooth_corner, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Smooth Large", "type" = /obj/item/stack/tile/iron/white/smooth_large, "tile_cost" = 7), + list("name" = "Small", "type" = /obj/item/stack/tile/iron/white/small, "tile_cost" = 5), + list("name" = "Diagonal", "type" = /obj/item/stack/tile/iron/white/diagonal, "tile_cost" = 5), + list("name" = "Herringbone", "type" = /obj/item/stack/tile/iron/white/herringbone, "tile_cost" = 5), + list("name" = "Half White", "type" = /obj/item/stack/tile/iron/white_side, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST, SOUTHEAST, SOUTHWEST, NORTHEAST, NORTHWEST)), + list("name" = "White Corner", "type" = /obj/item/stack/tile/iron/white_corner, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + ), + + //Textured tiles + "Textured" = list( + list("name" = "Textured White", "type" = /obj/item/stack/tile/iron/white/textured, "tile_cost" = 5), + list("name" = "Textured White Edge", "type" = /obj/item/stack/tile/iron/white/textured_edge, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured White Half", "type" = /obj/item/stack/tile/iron/white/textured_half, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Textured White Corner", "type" = /obj/item/stack/tile/iron/white/textured_corner, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured White Large", "type" = /obj/item/stack/tile/iron/white/textured_large, "tile_cost" = 7), + list("name" = "Textured Dark", "type" = /obj/item/stack/tile/iron/dark/textured, "tile_cost" = 5), + list("name" = "Textured Dark Edge", "type" = /obj/item/stack/tile/iron/dark/textured_edge, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured Dark Half", "type" = /obj/item/stack/tile/iron/dark/textured_half, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH)), + list("name" = "Textured Dark Corner", "type" = /obj/item/stack/tile/iron/dark/textured_corner, "tile_cost" = 5, "tile_rotate_dirs" = list(SOUTH, NORTH, EAST, WEST)), + list("name" = "Textured Dark Large", "type" = /obj/item/stack/tile/iron/dark/textured_large, "tile_cost" = 7), + ) + ), + + //Tiles which you decorate your home with + "Interior" = list( + //Common room tiles + "Room" = list( + list("name" = "Kitchen", "type" = /obj/item/stack/tile/iron/kitchen, "tile_cost" = 4), + list("name" = "Kitchen Small", "type" = /obj/item/stack/tile/iron/kitchen/small, "tile_cost" = 4), + list("name" = "Diagonal Kitchen", "type" = /obj/item/stack/tile/iron/kitchen/diagonal, "tile_cost" = 4), + list("name" = "Chapel", "type" = /obj/item/stack/tile/iron/chapel, "tile_cost" = 4), + list("name" = "Cafeteria", "type" = /obj/item/stack/tile/iron/cafeteria, "tile_cost" = 4), + list("name" = "Grimy", "type" = /obj/item/stack/tile/iron/grimy, "tile_cost" = 5), + list("name" = "Sepia", "type" = /obj/item/stack/tile/iron/sepia, "tile_cost" = 5), + list("name" = "Herringbone", "type" = /obj/item/stack/tile/iron/kitchen/herringbone, "tile_cost" = 5), + ), + + //Culd have called it miscellaneous but nah too long + "Pattern" = list( + list("name" = "Terracotta", "type" = /obj/item/stack/tile/iron/terracotta, "tile_cost" = 5), + list("name" = "Small", "type" = /obj/item/stack/tile/iron/terracotta/small, "tile_cost" = 5), + list("name" = "Diagonal", "type" = /obj/item/stack/tile/iron/terracotta/diagonal, "tile_cost" = 5), + list("name" = "Herrigone", "type" = /obj/item/stack/tile/iron/terracotta/herringbone, "tile_cost" = 5), + list("name" = "Checkered", "type" = /obj/item/stack/tile/iron/checker, "tile_cost" = 5), + list("name" = "Herringbone", "type" = /obj/item/stack/tile/iron/herringbone, "tile_cost" = 5), + ) + ) +)) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index c32e46c5365..7bb81b30c99 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -150,6 +150,13 @@ RLD if(prob(20)) spark_system.start() +/obj/item/construction/update_overlays() + . = ..() + if(has_ammobar) + var/ratio = CEILING((matter / max_matter) * ammo_sections, 1) + if(ratio > 0) + . += "[icon_state]_charge[ratio]" + /obj/item/construction/proc/useResource(amount, mob/user) if(!silo_mats || !silo_link) if(matter < amount) @@ -628,7 +635,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) var/category_icon_state var/category_icon_suffix - for(var/list/sub_category as anything in root_categories[root_category]) + 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) continue @@ -664,7 +671,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) //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("design_id" = i, TITLE = design[TITLE], ICON = icon_state)) + designs += list(list(TITLE = design[TITLE], ICON = icon_state)) data["categories"] += list(list("cat_name" = sub_category, "designs" = designs)) //merge airlock_electronics ui data with this @@ -768,13 +775,6 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) explosion(src, light_impact_range = 3, flame_range = 1, flash_range = 1) qdel(src) -/obj/item/construction/rcd/update_overlays() - . = ..() - if(has_ammobar) - var/ratio = CEILING((matter / max_matter) * ammo_sections, 1) - if(ratio > 0) - . += "[icon_state]_charge[ratio]" - /obj/item/construction/rcd/Initialize(mapload) . = ..() update_appearance() @@ -868,7 +868,6 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) custom_materials = list(/datum/material/iron=48000, /datum/material/glass=32000) ammoamt = 160 - /obj/item/construction/rcd/combat/admin name = "admin RCD" max_matter = INFINITY @@ -927,7 +926,6 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) matter = 200 max_matter = 200 slot_flags = ITEM_SLOT_BELT - desc = "It contains the design for chairs, stools, tables, and glass tables." ///it does not make sense why any of these should be installed banned_upgrades = RCD_UPGRADE_FRAMES | RCD_UPGRADE_SIMPLE_CIRCUITS | RCD_UPGRADE_FURNISHING @@ -1492,6 +1490,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) /obj/item/rcd_upgrade/silo_link desc = "It contains direct silo connection RCD upgrade." upgrade = RCD_UPGRADE_SILO_LINK + /obj/item/rcd_upgrade/furnishing desc = "It contains the design for chairs, stools, tables, and glass tables." upgrade = RCD_UPGRADE_FURNISHING diff --git a/code/game/objects/items/RTD.dm b/code/game/objects/items/RTD.dm new file mode 100644 index 00000000000..ef600749179 --- /dev/null +++ b/code/game/objects/items/RTD.dm @@ -0,0 +1,365 @@ +/// time taken to create tile +#define CONSTRUCTION_TIME 0.4 SECONDS +/// time taken to destroy a tile +#define DECONSTRUCTION_TIME 0.2 SECONDS + +/** + * An tool used to create, destroy, and copy & clear decals of floor tiles + * Great for janitor but can be made only in engineering + * Supports silo link upgrade and refill with glass, plasteel & iron + */ +/obj/item/construction/rtd + name = "rapid-tiling-device (RTD)" + desc = "Used for fast placement & destruction of floor tiles." + icon = 'icons/obj/tools.dmi' + icon_state = "rtd" + worn_icon_state = "RCD" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + custom_premium_price = PAYCHECK_COMMAND * 3 + max_matter = 350 + 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 + + /// main category for tile design + var/root_category = "Conventional" + /// sub category for tile design + var/design_category = "Standard" + /// design selected by player + var/datum/tile_info/selected_design + /// temp var to store an single design from GLOB.floor_design while iterating through this list + var/datum/tile_info/tile_design + /// overlays on a tile + var/list/design_overlays = list() + +/// stores the name, type, icon & cost for each tile type +/datum/tile_info + /// name of this tile design for ui + var/name + /// path to create this tile type + var/obj/item/stack/tile/tile_type + /// icon for this tile to display for ui + var/icon_state + /// rcd units to consume for this tile creation + var/cost + + ///directions this tile can be placed on the turf + var/list/tile_directions + /// user friendly names of the tile_directions to be sent to ui + var/list/ui_directional_data + /// current direction this tile should be rotated in before being placed on the plating + var/selected_direction + +/// decompress a single tile design list element from GLOB.floor_designs into its individual variables +/datum/tile_info/proc/set_info(list/design) + name = design["name"] + tile_type = design["type"] + icon_state = initial(tile_type.icon_state) + cost = design["tile_cost"] + + tile_directions = design["tile_rotate_dirs"] + if(!tile_directions) + selected_direction = null + ui_directional_data = null + return + + ui_directional_data = list() + for(var/tile_direction in tile_directions) + ui_directional_data += dir2text(tile_direction) + selected_direction = tile_directions[1] + +/// fill all information to be sent to the UI +/datum/tile_info/proc/fill_ui_data(list/data) + data["selected_recipe"] = name + data["selected_icon"] = get_icon_state() + + if(!tile_directions) + data["selected_direction"] = null + return + + data["tile_dirs"] = ui_directional_data + data["selected_direction"] = dir2text(selected_direction) + +/// change the direction the tile is laid on the turf +/datum/tile_info/proc/set_direction(direction) + if(tile_directions == null || !(direction in tile_directions)) + return + selected_direction = direction + +/** + * retrive the icon for this tile design based on its direction + * for complex directions like NORTHSOUTH etc we create an seperated blended icon in the asset file for example floor-northsouth + * so we check which icons we want to retrive based on its direction + * for basic directions its rotated with CSS so there is no need for icon + */ +/datum/tile_info/proc/get_icon_state() + var/prefix = "" + if(selected_direction) + prefix = (selected_direction in GLOB.tile_dont_rotate) ? "" : "-[dir2text(selected_direction)]" + return icon_state + prefix + +///convinience proc to quickly convert the tile design into an physical tile to lay on the plating +/datum/tile_info/proc/new_tile(loc) + var/obj/item/stack/tile/final_tile = new tile_type(loc, 1) + final_tile.turf_dir = selected_direction + return final_tile + +/** + * Stores the decal & overlays on the floor to preserve texture of the design + * in short its just an wrapper for mutable appearance where we retrive the nessassary information + * to recreate an mutable appearance + */ +/datum/overlay_info + /// icon var of the mutable appearance + var/icon/icon + /// icon_state var of the mutable appearance + var/icon_state + /// direction var of the mutable appearance + var/direction + /// alpha var of the mutable appearance + var/alpha + /// color var of the mutable appearance + var/color + +//decompressing nessasary information required to re-create an mutable appearance +/datum/overlay_info/New(mutable_appearance/appearance) + icon = appearance.icon + icon_state = appearance.icon_state + alpha = appearance.alpha + direction = appearance.dir + color = appearance.color + +/// re create the appearance +/datum/overlay_info/proc/add_decal(turf/the_turf) + the_turf.AddElement(/datum/element/decal, icon, icon_state, direction, null, null, alpha, color, null, FALSE, null) + +/obj/item/construction/rtd/Initialize(mapload) + . = ..() + selected_design = new + tile_design = new + + selected_design.set_info(GLOB.floor_designs[root_category][design_category][1]) + update_appearance() + +/obj/item/construction/rtd/Destroy() + QDEL_NULL(selected_design) + QDEL_NULL(tile_design) + QDEL_LIST(design_overlays) + . = ..() + +/obj/item/construction/rtd/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RapidTilingDevice", name) + ui.open() + + +/obj/item/construction/rtd/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/rtd), + ) + +/obj/item/construction/rtd/attack_self(mob/user) + . = ..() + ui_interact(user) + +/obj/item/construction/rtd/ui_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) + 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] + + var/list/designs = list() //initialize all designs under this category + for(var/list/design as anything in target_category) + tile_design.set_info(design) + designs += list(list("name" = tile_design.name, "icon" = tile_design.get_icon_state())) + + data["categories"] += list(list("category_name" = sub_category, "recipes" = designs)) + + return data + +/obj/item/construction/rtd/ui_act(action, params) + . = ..() + if(.) + return + + var/floor_designs = GLOB.floor_designs + switch(action) + if("root_category") + var/new_root = params["root_category"] + if(floor_designs[new_root] != null) //is a valid category + root_category = new_root + + if("set_dir") + var/direction = text2dir(params["dir"]) + if(!direction) + return TRUE + selected_design.set_direction(direction) + + if("recipe") + var/list/main_root = floor_designs[root_category] + if(main_root == null) + return TRUE + var/list/sub_category = main_root[params["category_name"]] + if(sub_category == null) + return TRUE + var/list/target_design = sub_category[text2num(params["id"])] + if(target_design == null) + return + + QDEL_LIST(design_overlays) + design_category = params["category_name"] + selected_design.set_info(target_design) + + return TRUE + +/// RTD can lay floor tiles only on these 2 types of platings. this procs checks for that +/obj/item/construction/rtd/proc/is_valid_plating(turf/open/floor) + return floor.type == /turf/open/floor/plating || floor.type == /turf/open/floor/plating/reinforced + +/obj/item/construction/rtd/afterattack(turf/open/floor/floor, mob/user) + . = ..() + if(!istype(floor) || !range_check(floor,user)) + return TRUE + + var/floor_designs = GLOB.floor_designs + if(!is_valid_plating(floor)) //we infer what floor type it is if its not the usual plating + user.Beam(floor, icon_state = "light_beam", time = 5) + for(var/main_root in floor_designs) + for(var/sub_category in floor_designs[main_root]) + for(var/list/design_info in floor_designs[main_root][sub_category]) + var/obj/item/stack/tile/tile_type = design_info["type"] + if(initial(tile_type.turf_type) != floor.type) + continue + + //infer available overlays on the floor to recreate them to the best extent + QDEL_LIST(design_overlays) + var/floor_designs = floor.managed_overlays + if(isnull(floor_designs)) + floor_designs = list() + else if(!islist(floor_designs)) + floor_designs = list(floor.managed_overlays) + for(var/mutable_appearance/appearance as anything in floor_designs) + design_overlays += new /datum/overlay_info(appearance) + + //store all information about this tile + root_category = main_root + design_category = sub_category + selected_design.set_info(design_info) + selected_design.set_direction(floor.dir) + balloon_alert(user, "tile changed to [selected_design.name]") + + return TRUE + + //can't infer floor type! + balloon_alert(user, "design not supported!") + return TRUE + + if(!checkResource(selected_design.cost, user)) + return TRUE + + //All special effect stuff + user.Beam(floor, icon_state = "light_beam", time = CONSTRUCTION_TIME) + var/obj/effect/constructing_effect/rcd_effect = new(floor, CONSTRUCTION_TIME, RCD_FLOORWALL) + if(!do_after(user, CONSTRUCTION_TIME, target = floor)) + rcd_effect.end_animation() + return TRUE + + //consume resource only if tile was placed successfully + var/obj/item/stack/tile/final_tile = selected_design.new_tile(user.drop_location()) + if(QDELETED(final_tile)) //if you were standing on a stack of tiles this newly spawned tile could get merged with it cause its spawned on your location + rcd_effect.end_animation() + balloon_alert(user, "tile got merged with the stack beneath you!") + return TRUE + + var/turf/open/new_turf = final_tile.place_tile(floor, user) + if(new_turf) + //apply infered overlays + for(var/datum/overlay_info/info in design_overlays) + info.add_decal(new_turf) + //use material + useResource(selected_design.cost, user) + rcd_effect.end_animation() + + return TRUE + +/obj/item/construction/rtd/afterattack_secondary(turf/open/floor/floor, mob/user, proximity_flag, click_parameters) + ..() + if(!istype(floor) || !range_check(floor,user)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(is_valid_plating(floor)) //cant deconstruct normal plating thats the RCD's job + balloon_alert(user, "nothing to deconstruct!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/floor_designs = GLOB.floor_designs + + //we only deconstruct floors which are supported by the RTD + var/can_deconstruct = FALSE + var/cost + for(var/main_root in floor_designs) + if(can_deconstruct) + break + for(var/sub_category in floor_designs[main_root]) + if(can_deconstruct) + break + for(var/list/design_info in floor_designs[main_root][sub_category]) + var/obj/item/stack/tile/tile_type = design_info["type"] + if(initial(tile_type.turf_type) == floor.type) + cost = tile_design.cost + can_deconstruct = TRUE + break + if(!can_deconstruct || !checkResource(cost * 0.7, user)) //no ballon alert for checkResource as it already spans an alert to chat + if(!can_deconstruct) + balloon_alert(user, "can't deconstruct this type!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + //find & collect all decals + var/list/all_decals = list() + for(var/obj/effect/decal in floor.contents) + all_decals += decal + //delete all decals + for(var/obj/effect/decal in all_decals) + floor.contents -= decal + qdel(decal) + + //All special effect stuff + user.Beam(floor, icon_state = "light_beam", time = DECONSTRUCTION_TIME) + var/obj/effect/constructing_effect/rcd_effect = new(floor, DECONSTRUCTION_TIME, RCD_FLOORWALL) + if(!do_after(user, DECONSTRUCTION_TIME, target = floor)) + rcd_effect.end_animation() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/turf/new_turf = null + if(floor.baseturf_at_depth(1) == /turf/baseturf_bottom) //for turfs whose base is open space we put regular plating in its place else everyone dies + new_turf = floor.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + else // for every other turf we scarp away exposing base turf underneath + new_turf = floor.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + if(new_turf) + useResource(cost * 0.7, user) + rcd_effect.end_animation() + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/construction/rtd/loaded + matter = 350 + +/obj/item/construction/rtd/admin + name = "admin RTD" + max_matter = INFINITY + matter = INFINITY + +#undef CONSTRUCTION_TIME +#undef DECONSTRUCTION_TIME diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 314e50d59e9..3b1ab142643 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -90,8 +90,6 @@ to_chat(user, span_notice("You cannot place this tile here directly!")) return to_chat(user, span_notice("You begin replacing the floor with the tile...")) - if(!do_after(user, 3 SECONDS, target_plating)) - return if(!istype(target_plating)) return if(!use(1)) diff --git a/code/modules/asset_cache/assets/rtd.dm b/code/modules/asset_cache/assets/rtd.dm new file mode 100644 index 00000000000..23a3b0d71b2 --- /dev/null +++ b/code/modules/asset_cache/assets/rtd.dm @@ -0,0 +1,54 @@ +/datum/asset/spritesheet/rtd + name = "rtd" + +/datum/asset/spritesheet/rtd/create_spritesheets() + //some tiles may share the same icon but have diffrent properties to animate that icon + //so we keep track of what icons we registered + var/list/registered = list() + + for(var/main_root in GLOB.floor_designs) + for(var/sub_category in GLOB.floor_designs[main_root]) + for(var/list/design in GLOB.floor_designs[main_root][sub_category]) + var/obj/item/stack/tile/type = design["type"] + var/icon_state = initial(type.icon_state) + if(registered[icon_state]) + continue + + Insert(sprite_name = icon_state, I = 'icons/obj/tiles.dmi', icon_state = icon_state) + registered[icon_state] = TRUE + + var/list/tile_directions = design["tile_rotate_dirs"] + if(tile_directions == null) + continue + + for(var/direction as anything in tile_directions) + //we can rotate the icon is css for these directions + if(direction in GLOB.tile_dont_rotate) + continue + + //but for these directions we have to do some hacky stuff + var/icon/img = icon(icon = 'icons/obj/tiles.dmi', icon_state = icon_state) + switch(direction) + if(NORTHEAST) + img.Turn(-180) + var/icon/east_rotated = icon(icon = 'icons/obj/tiles.dmi', icon_state = icon_state) + east_rotated.Turn(-90) + img.Blend(east_rotated,ICON_MULTIPLY) + img.SetIntensity(2,2,2) + if(NORTHWEST) + img.Turn(-180) + var/icon/west_rotated = icon(icon = 'icons/obj/tiles.dmi', icon_state = icon_state) + west_rotated.Turn(90) + img.Blend(west_rotated,ICON_MULTIPLY) + img.SetIntensity(2,2,2) + if(SOUTHEAST) + var/icon/east_rotated = icon(icon = 'icons/obj/tiles.dmi', icon_state = icon_state) + east_rotated.Turn(-90) + img.Blend(east_rotated,ICON_MULTIPLY) + img.SetIntensity(2,2,2) + if(SOUTHWEST) + var/icon/west_rotated = icon(icon = 'icons/obj/tiles.dmi', icon_state = icon_state) + west_rotated.Turn(90) + img.Blend(west_rotated,ICON_MULTIPLY) + img.SetIntensity(2,2,2) + Insert(sprite_name = "[icon_state]-[dir2text(direction)]", I = img) diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index bca4fb650da..f0a40508b48 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -77,6 +77,7 @@ ) departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + //SKYRAT EDIT ADDITION// /datum/design/engi_plumbing name = "Engineering Plumbing Constructor" @@ -91,6 +92,19 @@ departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING //SKYRAT EDIT END// +/datum/design/rtd_loaded + name = "Rapid Tiling Device" + desc = "A tool that can lay & destory floor tiles on the fly." + id = "rtd_loaded" + build_type = PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/iron = 30000, /datum/material/glass = 2500) + build_path = /obj/item/construction/rtd/loaded + category = list( + RND_CATEGORY_TOOLS + RND_SUBCATEGORY_TOOLS_ENGINEERING_ADVANCED + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + + /datum/design/rcd_ammo name = "RCD Matter Cartridge" id = "rcd_ammo" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 55891c476e1..24f373ffeb5 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -645,6 +645,7 @@ "rcd_loaded", "rcd_ammo", "rpd_loaded", + "rtd_loaded", "sheetifier", "weldingmask", diff --git a/icons/mob/inhands/equipment/tools_lefthand.dmi b/icons/mob/inhands/equipment/tools_lefthand.dmi index 263e25ca20e..ec4f7a8a181 100644 Binary files a/icons/mob/inhands/equipment/tools_lefthand.dmi and b/icons/mob/inhands/equipment/tools_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/tools_righthand.dmi b/icons/mob/inhands/equipment/tools_righthand.dmi index 732af4e934d..11b9e5bd37f 100644 Binary files a/icons/mob/inhands/equipment/tools_righthand.dmi and b/icons/mob/inhands/equipment/tools_righthand.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index b20b38cdbf4..22612fde322 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/tgstation.dme b/tgstation.dme index f2f466591b0..76f42e9857f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -519,6 +519,7 @@ #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\poll_ignore.dm" #include "code\_globalvars\lists\quirks.dm" +#include "code\_globalvars\lists\rtd.dm" #include "code\_globalvars\lists\typecache.dm" #include "code\_globalvars\lists\wiremod.dm" #include "code\_globalvars\lists\xenobiology.dm" @@ -1810,6 +1811,7 @@ #include "code\game\objects\items\religion.dm" #include "code\game\objects\items\RPD.dm" #include "code\game\objects\items\RSF.dm" +#include "code\game\objects\items\RTD.dm" #include "code\game\objects\items\scrolls.dm" #include "code\game\objects\items\secret_documents.dm" #include "code\game\objects\items\sharpener.dm" @@ -2693,6 +2695,7 @@ #include "code\modules\asset_cache\assets\radar.dm" #include "code\modules\asset_cache\assets\rcd.dm" #include "code\modules\asset_cache\assets\research_designs.dm" +#include "code\modules\asset_cache\assets\rtd.dm" #include "code\modules\asset_cache\assets\safe.dm" #include "code\modules\asset_cache\assets\seeds.dm" #include "code\modules\asset_cache\assets\sheetmaterials.dm" diff --git a/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx b/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx index 937c4b25602..3a03463980d 100644 --- a/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx +++ b/tgui/packages/tgui/interfaces/RapidConstructionDevice.tsx @@ -24,7 +24,6 @@ type Category = { type Design = { title: string; - design_id: Number; icon: string; }; @@ -71,14 +70,14 @@ const CategoryItem = (props, context) => { ); }; -const InfoSection = (props, context) => { +export const InfoSection = (props, context) => { const { data } = useBackend(context); const { silo_upgraded } = data; return (
- + {silo_upgraded ? : ''} @@ -110,9 +109,9 @@ const DesignSection = (props, context) => { ))} - {shownCategory?.designs.map((design) => ( + {shownCategory?.designs.map((design, i) => ( + ))} +
+ ); +}; + +export const RapidTilingDevice = (props, context) => { + return ( + + + + + + + + + + + + + + + + + + + + ); +};