From 4efd54d7aea20b06b2b992047a009ac5c633cf65 Mon Sep 17 00:00:00 2001 From: Mechoid Date: Tue, 14 Mar 2023 00:43:25 -0700 Subject: [PATCH] Finally allows RPD to be used. --- code/datums/supplypacks/atmospherics.dm | 8 + code/game/objects/items/weapons/RPD.dm | 294 ++++++++++++++++++ .../silicon/robot/robot_modules/station.dm | 21 ++ 3 files changed, 323 insertions(+) create mode 100644 code/game/objects/items/weapons/RPD.dm diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm index e6fb05f2207..3b93492c799 100644 --- a/code/datums/supplypacks/atmospherics.dm +++ b/code/datums/supplypacks/atmospherics.dm @@ -82,6 +82,14 @@ containername = "Disposal Dispenser Crate" access = access_atmospherics +/datum/supply_pack/atmos/rapid_pipe_dispenser + contains = list(/obj/item/pipe_dispenser) + name = "Rapid Pipe Dispenser" + cost = 100 + containertype = /obj/structure/closet/crate/secure/aether + containername = "Rapid Pipe Dispenser Crate" + access = access_atmospherics + /datum/supply_pack/atmos/internals name = "Internals crate" contains = list( diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm new file mode 100644 index 00000000000..4e32d69bb05 --- /dev/null +++ b/code/game/objects/items/weapons/RPD.dm @@ -0,0 +1,294 @@ +#define ATMOS_CATEGORY 0 +#define DISPOSALS_CATEGORY 1 +#define TRANSIT_CATEGORY 2 + +#define BUILD_MODE (1<<0) +#define WRENCH_MODE (1<<1) +#define DESTROY_MODE (1<<2) +#define PAINT_MODE (1<<3) + +/obj/item/pipe_dispenser + name = "Rapid Piping Device (RPD)" + desc = "A device used to rapidly pipe things." + icon = 'icons/obj/tools.dmi' + icon_state = "rpd" + item_state = "rpd" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand.dmi', + slot_r_hand_str = 'icons/mob/items/righthand.dmi', + ) + item_flags = NOBLUDGEON + force = 10 + throwforce = 10 + throw_speed = 1 + throw_range = 5 + w_class = ITEMSIZE_NORMAL + matter = list(MAT_STEEL = 50000, MAT_GLASS = 25000) + var/datum/effect_system/spark_spread/spark_system + var/p_dir = NORTH // Next pipe will be built with this dir + var/p_flipped = FALSE // If the next pipe should be built flipped + var/paint_color = "grey" // Pipe color index for next pipe painted/built. + var/category = ATMOS_CATEGORY + var/piping_layer = PIPING_LAYER_DEFAULT + var/obj/item/tool/wrench/tool + var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction + var/static/datum/pipe_recipe/first_atmos + var/static/datum/pipe_recipe/first_disposal + var/mode = BUILD_MODE | DESTROY_MODE | WRENCH_MODE + var/static/list/pipe_layers = list( + "Regular" = PIPING_LAYER_REGULAR, + "Supply" = PIPING_LAYER_SUPPLY, + "Scrubber" = PIPING_LAYER_SCRUBBER, + "Fuel" = PIPING_LAYER_FUEL, + "Aux" = PIPING_LAYER_AUX + ) + +/obj/item/pipe_dispenser/Initialize() + . = ..() + src.spark_system = new /datum/effect_system/spark_spread + spark_system.set_up(5, 0, src) + spark_system.attach(src) + tool = new /obj/item/tool/wrench/cyborg(src) // RPDs have wrenches inside of them, so that they can wrench down spawned pipes without being used as superior wrenches themselves. + +/obj/item/pipe_dispenser/proc/SetupPipes() + if(!first_atmos) + first_atmos = GLOB.atmos_pipe_recipes[GLOB.atmos_pipe_recipes[1]][1] + recipe = first_atmos + if(!first_disposal) + first_disposal = GLOB.disposal_pipe_recipes[GLOB.disposal_pipe_recipes[1]][1] + +/obj/item/pipe_dispenser/Destroy() + QDEL_NULL(spark_system) + QDEL_NULL(tool) + return ..() + +/obj/item/pipe_dispenser/attack_self(mob/user) + tgui_interact(user) + +/obj/item/pipe_dispenser/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/pipes), + ) + +/obj/item/pipe_dispenser/tgui_state(mob/user) + return GLOB.tgui_inventory_state + +/obj/item/pipe_dispenser/tgui_interact(mob/user, datum/tgui/ui) + SetupPipes() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "RapidPipeDispenser", name) + ui.open() + +/obj/item/pipe_dispenser/tgui_data(mob/user) + var/list/data = list( + "category" = category, + "piping_layer" = piping_layer, + "pipe_layers" = pipe_layers, + "preview_rows" = recipe.get_preview(p_dir), + "categories" = list(), + "selected_color" = paint_color, + "paint_colors" = pipe_colors, + "mode" = mode + ) + + var/list/recipes + switch(category) + if(ATMOS_CATEGORY) + recipes = GLOB.atmos_pipe_recipes + if(DISPOSALS_CATEGORY) + recipes = GLOB.disposal_pipe_recipes + // if(TRANSIT_CATEGORY) + // recipes = transit_tube_recipes + for(var/c in recipes) + var/list/cat = recipes[c] + var/list/r = list() + for(var/i in 1 to cat.len) + var/datum/pipe_recipe/info = cat[i] + r += list(list("pipe_name" = info.name, "pipe_index" = i, "selected" = (info == recipe))) + data["categories"] += list(list("cat_name" = c, "recipes" = r)) + + return data + +/obj/item/pipe_dispenser/tgui_act(action, params) + SetupPipes() + if(..()) + return TRUE + if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) + return TRUE + var/playeffect = TRUE + switch(action) + if("color") + paint_color = params["paint_color"] + if("category") + category = text2num(params["category"]) + switch(category) + if(DISPOSALS_CATEGORY) + recipe = first_disposal + if(ATMOS_CATEGORY) + recipe = first_atmos + // if(TRANSIT_CATEGORY) + // recipe = first_transit + p_dir = NORTH + playeffect = FALSE + if("piping_layer") + piping_layer = text2num(params["piping_layer"]) + playeffect = FALSE + // if("ducting_layer") + // ducting_layer = text2num(params["ducting_layer"]) + // playeffect = FALSE + if("pipe_type") + var/static/list/recipes + if(!recipes) + recipes = GLOB.disposal_pipe_recipes + GLOB.atmos_pipe_recipes + recipe = recipes[params["category"]][text2num(params["pipe_type"])] + p_dir = NORTH + if("setdir") + p_dir = text2dir(params["dir"]) + p_flipped = text2num(params["flipped"]) + playeffect = FALSE + if("mode") + var/n = text2num(params["mode"]) + if(mode & n) + mode &= ~n + else + mode |= n + if(playeffect) + spark_system.start() + playsound(get_turf(src), 'sound/effects/pop.ogg', 50, FALSE) + return TRUE + +/obj/item/pipe_dispenser/afterattack(atom/A, mob/user as mob, proximity) + if(!user.IsAdvancedToolUser() || istype(A, /turf/space/transit) || !proximity) + return ..() + + //So that changing the menu settings doesn't affect the pipes already being built. + var/queued_piping_layer = piping_layer + var/queued_p_dir = p_dir + var/queued_p_flipped = p_flipped + + //make sure what we're clicking is valid for the current mode + var/static/list/make_pipe_whitelist // This should probably be changed to be in line with polaris standards. Oh well. + if(!make_pipe_whitelist) + make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe)) + var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist)) + + var/can_destroy_pipe = istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct) + + . = TRUE + if((mode & DESTROY_MODE) && can_destroy_pipe) + to_chat(user, "You start destroying a pipe...") + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 2, target = A)) + activate() + animate_deletion(A) + return + + if((mode & PAINT_MODE)) //Paint pipes + if(istype(A, /obj/machinery/atmospherics/pipe)) + var/obj/machinery/atmospherics/pipe/P = A + playsound(src, 'sound/machines/click.ogg', 50, 1) + P.change_color(pipe_colors[paint_color]) + user.visible_message("[user] paints \the [P] [paint_color].", "You paint \the [P] [paint_color].") + return + + if(mode & BUILD_MODE) //Making pipes + switch(category) + if(ATMOS_CATEGORY) + if(!can_make_pipe) + return ..() + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(istype(recipe, /datum/pipe_recipe/meter)) + to_chat(user, "You start building a meter...") + if(do_after(user, 2, target = A)) + activate() + var/obj/item/pipe_meter/PM = new /obj/item/pipe_meter(get_turf(A)) + PM.setAttachLayer(queued_piping_layer) + if(mode & WRENCH_MODE) + do_wrench(PM, user) + else if(istype(recipe, /datum/pipe_recipe/pipe)) + var/datum/pipe_recipe/pipe/R = recipe + to_chat(user, "You start building a pipe...") + if(do_after(user, 2, target = A)) + activate() + var/obj/machinery/atmospherics/path = R.pipe_type + var/pipe_item_type = initial(path.construction_type) || /obj/item/pipe + var/obj/item/pipe/P = new pipe_item_type(get_turf(A), path, queued_p_dir) + + P.update() + P.add_fingerprint(usr) + if(R.paintable) + P.color = pipe_colors[paint_color] + P.setPipingLayer(queued_piping_layer) + if(queued_p_flipped) + P.do_a_flip() + if(mode & WRENCH_MODE) + do_wrench(P, user) + else + build_effect(P) + + if(DISPOSALS_CATEGORY) //Making disposals pipes + var/datum/pipe_recipe/disposal/R = recipe + if(!istype(R) || !can_make_pipe) + return ..() + A = get_turf(A) + if(istype(A, /turf/unsimulated)) + to_chat(user, "[src]'s error light flickers; there's something in the way!") + return + to_chat(user, "You start building a disposals pipe...") + playsound(src, 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 4, target = A)) + var/obj/structure/disposalconstruct/C = new(A, R.pipe_type, queued_p_dir, queued_p_flipped, R.subtype) + + if(!C.can_place()) + to_chat(user, "There's not enough room to build that here!") + qdel(C) + return + + activate() + + C.add_fingerprint(usr) + C.update_icon() + if(mode & WRENCH_MODE) + do_wrench(C, user) + else + build_effect(C) + + else + return ..() + +/obj/item/pipe_dispenser/proc/build_effect(var/obj/P, var/time = 1.5) + set waitfor = FALSE + P.filters += filter(type = "angular_blur", size = 30) + animate(P.filters[P.filters.len], size = 0, time = time) + var/outline = filter(type = "outline", size = 1, color = "#22AAFF") + P.filters += outline + sleep(time) + P.filters -= outline + P.filters -= filter(type = "angular_blur", size = 0) + +/obj/item/pipe_dispenser/proc/animate_deletion(var/obj/P, var/time = 1.5) + set waitfor = FALSE + P.filters += filter(type = "angular_blur", size = 0) + animate(P.filters[P.filters.len], size = 30, time = time) + sleep(time) + if(!QDELETED(P)) + P.filters -= filter(type = "angular_blur", size = 30) + qdel(P) + +/obj/item/pipe_dispenser/proc/activate() + playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + +/obj/item/pipe_dispenser/proc/do_wrench(var/atom/target, mob/user) + var/resolved = target.attackby(tool,user) + if(!resolved && tool && target) + tool.afterattack(target,user,1) + +#undef ATMOS_CATEGORY +#undef DISPOSALS_CATEGORY +#undef TRANSIT_CATEGORY + +#undef BUILD_MODE +#undef WRENCH_MODE +#undef DESTROY_MODE +#undef PAINT_MODE diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station.dm b/code/modules/mob/living/silicon/robot/robot_modules/station.dm index a178a60606a..46a41fb4c42 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station.dm @@ -418,6 +418,7 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/device/t_scanner(src) src.modules += new /obj/item/device/analyzer(src) src.modules += new /obj/item/taperoll/engineering(src) +<<<<<<< HEAD src.modules += new /obj/item/weapon/gripper(src) src.modules += new /obj/item/weapon/gripper/circuit(src) src.modules += new /obj/item/device/lightreplacer(src) @@ -431,6 +432,20 @@ var/global/list/robot_modules = list( src.modules += new /obj/item/weapon/rcd/electric/mounted/borg(src) src.modules += new /obj/item/weapon/pickaxe/plasmacutter/borg(src) src.modules += new /obj/item/weapon/gripper/no_use/loader(src) +======= + src.modules += new /obj/item/gripper(src) + src.modules += new /obj/item/gripper/circuit(src) + src.modules += new /obj/item/lightreplacer(src) + src.modules += new /obj/item/pipe_painter(src) + src.modules += new /obj/item/floor_painter(src) + src.modules += new /obj/item/inflatable_dispenser/robot(src) + src.emag = new /obj/item/melee/baton/robot/arm(src) + src.modules += new /obj/item/geiger(src) + src.modules += new /obj/item/rcd/electric/mounted/borg(src) + src.modules += new /obj/item/pipe_dispenser(src) + src.modules += new /obj/item/pickaxe/plasmacutter(src) + src.modules += new /obj/item/gripper/no_use/loader(src) +>>>>>>> 7402020403d... Finally allows RPD to be used. (#9028) var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000) var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000) @@ -945,7 +960,13 @@ var/global/list/robot_modules = list( P.synths = list(plastic) src.modules += P +<<<<<<< HEAD /obj/item/weapon/robot_module/drone/construction +======= + src.modules += new /obj/item/pipe_dispenser(src) // At the end to go beside the construction's RCD. + +/obj/item/robot_module/drone/construction +>>>>>>> 7402020403d... Finally allows RPD to be used. (#9028) name = "construction drone module" hide_on_manifest = TRUE channels = list("Engineering" = 1)