From f029c555f2c32e3f3ee302486d540e1a1affc1e7 Mon Sep 17 00:00:00 2001 From: Leshana Date: Sat, 25 Apr 2020 13:43:14 -0400 Subject: [PATCH 1/3] Adds the Rapid Pipe Dispenser - Adds "paintable" flag to pipe recipes so we know if we can paint it. - Ports the RPD from Yawn Wider. - Brings RPD sprites from /tg instead. - Slightly refactors recipes to keep type-specifc vars on subtypes. - Refactors RPD UI icons to use iconsheet assets: Instead of sending each individual icon to the client as needed, we declare an icon sheet asset and send the entire thing to client. Then we just use the given CSS classes to display the icons! - Adds icon sheet asset datum for pipe and diposals construction. --- code/game/machinery/pipe/pipe_recipes.dm | 4 + code/game/objects/items/weapons/RPD_vr.dm | 360 ++++++++++++++++++ code/modules/client/asset_cache.dm | 12 + .../recycling/disposal-construction.dm | 19 + icons/mob/items/lefthand_vr.dmi | Bin 2222 -> 2549 bytes icons/mob/items/righthand_vr.dmi | Bin 2112 -> 2412 bytes icons/obj/tools_vr.dmi | Bin 14475 -> 15256 bytes vorestation.dme | 1 + 8 files changed, 396 insertions(+) create mode 100644 code/game/objects/items/weapons/RPD_vr.dm diff --git a/code/game/machinery/pipe/pipe_recipes.dm b/code/game/machinery/pipe/pipe_recipes.dm index 0bf8f10105..14dbfc2603 100644 --- a/code/game/machinery/pipe/pipe_recipes.dm +++ b/code/game/machinery/pipe/pipe_recipes.dm @@ -4,6 +4,7 @@ var/global/list/atmos_pipe_recipes = null var/global/list/disposal_pipe_recipes = null +var/global/list/all_pipe_recipes = null // VOREStation Add /hook/startup/proc/init_pipe_recipes() global.atmos_pipe_recipes = list( @@ -68,6 +69,7 @@ var/global/list/disposal_pipe_recipes = null new /datum/pipe_recipe/disposal("Chute", DISPOSAL_PIPE_CHUTE, "intake"), ) ) + global.all_pipe_recipes = disposal_pipe_recipes + atmos_pipe_recipes // VOREStation Add return TRUE // @@ -96,6 +98,7 @@ var/global/list/disposal_pipe_recipes = null /datum/pipe_recipe/pipe var/obj/item/pipe/construction_type // The type PATH to the type of pipe fitting object the recipe makes. var/obj/machinery/atmospherics/pipe_type // The type PATH of what actual pipe the fitting becomes. + var/paintable = FALSE // If TRUE, allow the RPD to paint this pipe. // VOREStation Add /datum/pipe_recipe/pipe/New(var/label, var/obj/machinery/atmospherics/path) name = label @@ -105,6 +108,7 @@ var/global/list/disposal_pipe_recipes = null dirtype = initial(construction_type.dispenser_class) if (dirtype == PIPE_TRIN_M) icon_state_m = "[icon_state]m" + paintable = ispath(path, /obj/machinery/atmospherics/pipe) && !(ispath(path, /obj/machinery/atmospherics/pipe/vent)) // VOREStation Add // Render an HTML link to select this pipe type /datum/pipe_recipe/pipe/Render(dispenser) diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm new file mode 100644 index 0000000000..aa6d586939 --- /dev/null +++ b/code/game/objects/items/weapons/RPD_vr.dm @@ -0,0 +1,360 @@ +#define PAINT_MODE -2 +#define EATING_MODE -1 +#define ATMOS_MODE 0 +#define DISPOSALS_MODE 1 +#define TRANSIT_MODE 2 + +/obj/item/weapon/pipe_dispenser + name = "Rapid Piping Device (RPD)" + desc = "A device used to rapidly pipe things." + icon = 'icons/obj/tools_vr.dmi' + icon_state = "rpd" + item_state = "rpd" + item_icons = list( + slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi', + slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi', + ) + 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/effect/system/spark_spread/spark_system + var/mode = ATMOS_MODE + 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/screen = ATMOS_MODE // Starts on the atmos tab. + var/piping_layer = PIPING_LAYER_DEFAULT + var/wrench_mode = FALSE + var/obj/item/weapon/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/static/datum/asset/iconsheet/pipes/icon_assets + 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/weapon/pipe_dispenser/Initialize() + . = ..() + src.spark_system = new /datum/effect/effect/system/spark_spread + spark_system.set_up(5, 0, src) + spark_system.attach(src) + tool = new /obj/item/weapon/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/weapon/pipe_dispenser/proc/SetupPipes() + if(!first_atmos) + first_atmos = atmos_pipe_recipes[atmos_pipe_recipes[1]][1] + recipe = first_atmos + if(!first_disposal) + first_disposal = disposal_pipe_recipes[disposal_pipe_recipes[1]][1] + +/obj/item/weapon/pipe_dispenser/Destroy() + qdel_null(spark_system) + qdel_null(tool) + return ..() + +/obj/item/weapon/pipe_dispenser/suicide_act(mob/user) + var/datum/gender/TU = gender_datums[user.get_visible_gender()] + user.visible_message("[user] points the end of the RPD down [TU.his] throat and presses a button! It looks like [TU.hes] trying to commit suicide...") + playsound(get_turf(user), 'sound/machines/click.ogg', 50, 1) + playsound(get_turf(user), 'sound/items/deconstruct.ogg', 50, 1) + return(BRUTELOSS) + +/obj/item/weapon/pipe_dispenser/attack_self(mob/user) + src.interact(user) + +// TODO - Wouldn't it be nice to have nanoui? +/obj/item/weapon/pipe_dispenser/interact(mob/user) + SetupPipes() + if(!icon_assets) + icon_assets = get_asset_datum(/datum/asset/iconsheet/pipes) + icon_assets.send(user) + + var/list/lines = list() + if(mode >= ATMOS_MODE) + lines += "

Direction:

" + switch(recipe.dirtype) + + if(PIPE_STRAIGHT) // Straight, N-S, W-E + lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕") + lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔") + + if(PIPE_BENDABLE) // Bent, N-W, N-E etc + lines += render_dir_img(recipe.icon_state,user,NORTH,"Vertical","↕") + lines += render_dir_img(recipe.icon_state,user,EAST,"Horizontal","↔") + lines += "
" + lines += render_dir_img(recipe.icon_state,user,NORTHWEST,"West to North","╝") + lines += render_dir_img(recipe.icon_state,user,NORTHEAST,"North to East","╚") + lines += "
" + lines += render_dir_img(recipe.icon_state,user,SOUTHWEST,"South to West","╗") + lines += render_dir_img(recipe.icon_state,user,SOUTHEAST,"East to South","╔") + + if(PIPE_TRINARY) // Manifold + lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") + lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") + lines += "
" + lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") + lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") + + if(PIPE_TRIN_M) // Mirrored ones + //each mirror icon is 45 anticlockwise from it's real direction + lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") + lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") + lines += "
" + lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") + lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") + lines += "
" + lines += render_dir_img(recipe.icon_state_m,user,SOUTH,"West South East","╦", 1) + lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","╣", 1) + lines += "
" + lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","╩", 1) + lines += render_dir_img(recipe.icon_state_m,user,WEST,"South East North","╠", 1) + + if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc. + lines += render_dir_img(recipe.icon_state,user,NORTH,"North","↑") + lines += render_dir_img(recipe.icon_state,user,EAST,"East","→") + lines += render_dir_img(recipe.icon_state,user,SOUTH,"South","↓") + lines += render_dir_img(recipe.icon_state,user,WEST,"West","←") + + if(PIPE_ONEDIR) // Single icon_state (eg 4-way manifolds) + lines += render_dir_img(recipe.icon_state,user,SOUTH,"Pipe","↕") + lines += "
" + + if(mode == ATMOS_MODE || mode == PAINT_MODE) + lines += "

Color:

" + var/i = 0 + for(var/c in pipe_colors) + ++i + lines += "[c]" + if(i == 4) + lines += "
" + i = 0 + lines += "
" + + lines += "

Mode:

" + lines += "Lay Pipes" + lines += "Eat Pipes" + lines += "Paint Pipes" + lines += "
" + + lines += "

Category:

" + lines += "Atmospherics" + lines += "Disposals" + //lines += "Transit Tube" + lines += "
Wrench Mode" + lines += "
" + + if(screen == ATMOS_MODE) + for(var/category in atmos_pipe_recipes) + lines += "

[category]:

" + + if(category == "Pipes") + lines += "
" + for(var/pipename in pipe_layers) + var/pipelayer = pipe_layers[pipename] + lines += "[pipename] " + lines += "
" + lines += "
" + for(var/i in 1 to atmos_pipe_recipes[category].len) + var/datum/pipe_recipe/PI = atmos_pipe_recipes[category][i] + lines += "
" + lines += "[PI.name]" + lines += "
" + lines += "
" + else if(screen == DISPOSALS_MODE) + for(var/category in disposal_pipe_recipes) + lines += "

[category]:

" + for(var/i in 1 to disposal_pipe_recipes[category].len) + var/datum/pipe_recipe/PI = disposal_pipe_recipes[category][i] + lines += "
" + lines += "[PI.name]" + lines += "
" + lines += "
" + + var/dat = lines.Join() + var/datum/browser/popup = new(user, "rpd", name, 300, 800, src) + popup.set_content("[dat]") + popup.add_head_content(icon_assets.css_tag()) + popup.open() + +/obj/item/weapon/pipe_dispenser/Topic(href, href_list, state = global.inventory_state) + SetupPipes() + if(..()) + return 1 + if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) + return 1 + var/playeffect = TRUE // Do we spark the device + var/anyclicked = FALSE // Tells us if we need to refresh the window. + if(href_list["paint_color"]) + paint_color = href_list["paint_color"] + playeffect = FALSE + anyclicked = TRUE + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + anyclicked = TRUE + if(href_list["screen"]) + if(mode == screen) + mode = text2num(href_list["screen"]) + screen = text2num(href_list["screen"]) + switch(screen) + if(DISPOSALS_MODE) + recipe = first_disposal + if(ATMOS_MODE) + recipe = first_atmos + p_dir = NORTH + playeffect = FALSE + anyclicked = TRUE + if(href_list["piping_layer"]) + piping_layer = text2num(href_list["piping_layer"]) + playeffect = FALSE + anyclicked = TRUE + if(href_list["pipe_type"]) + recipe = all_pipe_recipes[href_list["category"]][text2num(href_list["pipe_type"])] + if(recipe.dirtype == PIPE_ONEDIR) // One hell of a hack for the fact that the image previews for the onedir types only show on the south, but the default pipe type is north. + p_dir = SOUTH // Did I fuck this up? Maybe. Or maybe it's just the icon files not being ready for an RPD. + else // If going to try and fix this hack, be aware the pipe dispensers might rely on pipes defaulting south instead of north. + p_dir = NORTH + p_flipped = FALSE + anyclicked = TRUE + if(href_list["dir"]) + p_dir = text2dir(href_list["dir"]) + p_flipped = text2num(href_list["flipped"]) + playeffect = FALSE + anyclicked = TRUE + if(href_list["switch_wrench"]) + wrench_mode = text2num(href_list["wrench_mode"]) + anyclicked = TRUE + if(anyclicked) + if(playeffect) + spark_system.start() + playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0) + src.interact(usr) + +/obj/item/weapon/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)) + + . = FALSE + switch(mode) //if we've gotten this var, the target is valid + if(PAINT_MODE) //Paint pipes + if(!istype(A, /obj/machinery/atmospherics/pipe)) + return ..() + var/obj/machinery/atmospherics/pipe/P = A + playsound(get_turf(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(EATING_MODE) //Eating pipes + if(!(istype(A, /obj/item/pipe) || istype(A, /obj/item/pipe_meter) || istype(A, /obj/structure/disposalconstruct))) + return ..() + to_chat(user, "You start destroying a pipe...") + playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) + if(do_after(user, 2, target = A)) + activate() + qdel(A) + + if(ATMOS_MODE) //Making pipes + if(!can_make_pipe) + return ..() + playsound(get_turf(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(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(wrench_mode) + do_wrench(P, user) + + if(DISPOSALS_MODE) //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(get_turf(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(wrench_mode) + do_wrench(C, user) + return + + else + return ..() + + +/obj/item/weapon/pipe_dispenser/proc/activate() + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + +/obj/item/weapon/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) + +/obj/item/weapon/pipe_dispenser/proc/render_dir_img(icon_state, user, _dir, title, noimg, flipped = FALSE) + var/dirtext = dir2text(_dir) + var/attrs = " style=\"height:34px;width:34px;display:inline-block\"" + if(_dir == p_dir && flipped == p_flipped) + attrs += " class=\"linkOn\"" + if(icon_state) + var/img_tag = icon_assets.icon_tag(icon_state, _dir) + return "[img_tag]" + else + return "[noimg]" + + +#undef PAINT_MODE +#undef EATING_MODE +#undef ATMOS_MODE +#undef DISPOSALS_MODE diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 0206b901dc..5580c7fd98 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -334,3 +334,15 @@ You can set verify to TRUE if you want send() to sleep until the client has the send_asset_list(client, uncommon) send_asset_list(client, common) + + +// VOREStation Add Start - pipes iconsheet asset +/datum/asset/iconsheet/pipes + name = "pipes" + +/datum/asset/iconsheet/pipes/register() + var/list/sprites = list() + for (var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi')) + sprites += build_sprite_list(each, global.alldirs) + ..(sprites) +// VOREStation Add End diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index e9d4e4227d..eccc71d33c 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -344,3 +344,22 @@ return 1 else return 0 + +// VOREStation Add Start - Helper procs for RCD +/obj/structure/disposalconstruct/proc/is_pipe() + return (ptype != DISPOSAL_PIPE_BIN && ptype != DISPOSAL_PIPE_OUTLET && ptype != DISPOSAL_PIPE_CHUTE) + +//helper proc that makes sure you can place the construct (i.e no dense objects stacking) +/obj/structure/disposalconstruct/proc/can_place() + if(is_pipe()) + return TRUE + + for(var/obj/structure/disposalconstruct/DC in get_turf(src)) + if(DC == src) + continue + + if(!DC.is_pipe()) //there's already a chute/outlet/bin there + return FALSE + + return TRUE +// VOREStation Add End diff --git a/icons/mob/items/lefthand_vr.dmi b/icons/mob/items/lefthand_vr.dmi index c033b491179cbfbd161854e63557a18215fe9dcc..39a6e5bdbdde517b60e068d07712602f3be830be 100644 GIT binary patch delta 2446 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 Q9k<&qq_s1m+R{JcFC#5bWdHyG delta 2009 zcmV;~2PXLJ62K58iBL{Q4GJ0x0000DNk~Le0002s0002s2m=5B04?*H(*OVg3y~!^ zIj_6MR#s-@=jx7+n2`VgP*r5SLPFCwH>fBmFf~SzkpR2AVyLJ?;o^26BP}(N0A;mm zT%}+~nN5+EDt~(=B|PzWQg1vXGyngYnE*4H|AbUNT3T8&GBs6HSx84r zD=IC^0RgT606RK9xQs>Xy(AD25C8xG0A|cZEI_)DOaRQxpP;n9l~wW5YF$uAot>Q} zB_(43k(mIQvk(N<*49;3RsaA0GiLvyo1Pp10004WQVUK~06^y0W&i*HvXglMCVz(P z;9fy$8`pqMr0tZwy_;T@&RhQQ3rQfQI@HIeRn@7H4+s&N)L!kDD=D66lN-Z!BZUL( zT>6BVbb_%g0z@XAI22M?3~_3d;u^Gvsa}7P=RRvm6MME1!ABc0% zXtekFwUBIYAS{47oQmk$!a1-Z3t4bDitqnPcE(3GhHhzkB!e;U z_Xm}td;0ZL>!_kDjspMy008i~aozhl^HBP(`VJvrimDan zq1XDZJCqV%LUkZDM0Z7X8|J}v({}o4Lw$F6NVO`xN7Q8*8m10W*S38PX$^NIowm_W zr$>zRU3YX?$%_S2L&Kxw%}C6)eGTag?q;5)ZS>R6GMs+bY~5^XOgj_`D1T$A?A=p( zP`78>xrVgCY$`L7mg}cSGJl-@t=VR?sZkq)qp56`tbb>=ooh&IDE*9$!3?W^d$vkp zO#BeIV^n>osVH z*q?KsX8Kbf0000000000002A{lH6zZBQ`t8$Arxe@-flgK@P6N_J0m?U=4P5kPm9` z`HSAw?(86WgJSg;&!v%aB z@mCYVh%+(H1T<4EjMSOj@RgHRe{ED=^P26JkAxbWnx2}Ool!px#3i|1>XIiU$9Bs{ zCUSFZy{XyhnVFgCS$`vgf?P9oin$y&4n8u;O3W|3SzK6HSbVcMAE_+KHB%>+9?JwYAkmbNhzXwS0d4@AZ7%$e?*{|9`OBA>mvA00000GYW-= z?x4pMHU`EbV?;T;=SF%%VNi@PJOzJ)Y!Ln)H;MWyXuAIK;3VizS=#trto85E%AQfx z_F9JB>_s+}jK6~ZWNvhgt?idB?`@hmv|G#k(L^Htv=xW2QfQi_&v=_#Ua=Ti+HNiL zM`MZ1Z$nFrV$0350L3r0O9jm_TqK(_s5$0?iE;TTQASa)Jp22h~9Ex3yx?+hQEj zf#wE_E!R|+{AsUP462MnI#3M`zVP~Y>-*)h@=>BV zS26+f!J`Agclm;;SYjS2G7z@GvQbwu-LnUe6WEC4r{08{*=R0!phHoYqg*Jnd4*g-q>78k#5dvH9>Z*c1HX*{3UvP zVm`tXZcuC>nlq|pVRC4V2c94R00000000000002=8Rwd~*|H+tG&DU)Zt?5l;^J4_ zY*~?R8kd)s<_0CnEzYm5t^^aLvt>oPX@B_FzPUk3atqy?V7Q$wTms24 z3_6k*zw{#k0000000000000001B%63&F(Cd97o?wSH6__|Lo1pjk!TOSyaOYi(a*w z-B~6%j=q`ha)L4R&1hKPp~>v; r8oj+kop^h-B=&dM>j3}&06@ZjRQxlMRxjyv00000NkvXXu0mjfbRV^f diff --git a/icons/obj/tools_vr.dmi b/icons/obj/tools_vr.dmi index 0b8f5f04900947dc63e76d91487389335700791b..53cf6041567bb5e8c33e91a2d02e49c4a3a58074 100644 GIT binary patch literal 15256 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 xljDg+mc*xCDNBTXgEqQL()?= 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 Og0wYs)r;@gg#9meNkYE> diff --git a/vorestation.dme b/vorestation.dme index 0f2cb48d5d..d7dac91f9b 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1185,6 +1185,7 @@ #include "code\game\objects\items\weapons\policetape.dm" #include "code\game\objects\items\weapons\RCD.dm" #include "code\game\objects\items\weapons\RCD_vr.dm" +#include "code\game\objects\items\weapons\RPD_vr.dm" #include "code\game\objects\items\weapons\RSF.dm" #include "code\game\objects\items\weapons\scrolls.dm" #include "code\game\objects\items\weapons\shields.dm" From ab75305bca32d9721f5da1cdb04c209348d05341 Mon Sep 17 00:00:00 2001 From: Leshana Date: Sat, 2 May 2020 19:17:27 -0400 Subject: [PATCH 2/3] Sort the directional selection images more nicely. --- code/game/objects/items/weapons/RPD_vr.dm | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm index aa6d586939..445e0b0e94 100644 --- a/code/game/objects/items/weapons/RPD_vr.dm +++ b/code/game/objects/items/weapons/RPD_vr.dm @@ -93,14 +93,12 @@ lines += "
" lines += render_dir_img(recipe.icon_state,user,NORTHWEST,"West to North","╝") lines += render_dir_img(recipe.icon_state,user,NORTHEAST,"North to East","╚") - lines += "
" lines += render_dir_img(recipe.icon_state,user,SOUTHWEST,"South to West","╗") lines += render_dir_img(recipe.icon_state,user,SOUTHEAST,"East to South","╔") if(PIPE_TRINARY) // Manifold lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") - lines += "
" lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") @@ -108,15 +106,13 @@ //each mirror icon is 45 anticlockwise from it's real direction lines += render_dir_img(recipe.icon_state,user,NORTH,"West South East","╦") lines += render_dir_img(recipe.icon_state,user,EAST,"North West South","╣") - lines += "
" lines += render_dir_img(recipe.icon_state,user,SOUTH,"East North West","╩") lines += render_dir_img(recipe.icon_state,user,WEST,"South East North","╠") lines += "
" lines += render_dir_img(recipe.icon_state_m,user,SOUTH,"West South East","╦", 1) - lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","╣", 1) - lines += "
" - lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","╩", 1) lines += render_dir_img(recipe.icon_state_m,user,WEST,"South East North","╠", 1) + lines += render_dir_img(recipe.icon_state_m,user,NORTH,"East North West","╩", 1) + lines += render_dir_img(recipe.icon_state_m,user,EAST,"North West South","╣", 1) if(PIPE_DIRECTIONAL) // Stuff with four directions - includes pumps etc. lines += render_dir_img(recipe.icon_state,user,NORTH,"North","↑") From 28be8da4e47cb0cfc8ca860a2ad297e592af926a Mon Sep 17 00:00:00 2001 From: Leshana Date: Sat, 25 Apr 2020 18:57:39 -0400 Subject: [PATCH 3/3] Add build and destroy visual effects. --- code/game/objects/items/weapons/RPD_vr.dm | 25 +++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/RPD_vr.dm b/code/game/objects/items/weapons/RPD_vr.dm index 445e0b0e94..c627956d63 100644 --- a/code/game/objects/items/weapons/RPD_vr.dm +++ b/code/game/objects/items/weapons/RPD_vr.dm @@ -267,7 +267,7 @@ playsound(get_turf(src), 'sound/machines/click.ogg', 50, 1) if(do_after(user, 2, target = A)) activate() - qdel(A) + animate_deletion(A) if(ATMOS_MODE) //Making pipes if(!can_make_pipe) @@ -299,6 +299,8 @@ P.do_a_flip() if(wrench_mode) do_wrench(P, user) + else + build_effect(P) if(DISPOSALS_MODE) //Making disposals pipes var/datum/pipe_recipe/disposal/R = recipe @@ -324,11 +326,30 @@ C.update_icon() if(wrench_mode) do_wrench(C, user) - return + else + build_effect(C) else return ..() +/obj/item/weapon/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/weapon/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/weapon/pipe_dispenser/proc/activate() playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)