From 72b4e29f7066b6bf39dfac638e408fe1542f19ff Mon Sep 17 00:00:00 2001 From: CHOMPStation2StaffMirrorBot <94713762+CHOMPStation2StaffMirrorBot@users.noreply.github.com> Date: Tue, 6 Jan 2026 06:15:35 -0700 Subject: [PATCH] [MIRROR] vacpack upport [NO GBP] (#12223) Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> --- code/game/objects/items/devices/vacpack.dm | 99 ++++++++++++++---- icons/mob/vacpack.dmi | Bin 4185 -> 4973 bytes icons/mob/vacpack_swoop.dmi | Bin 2879 -> 3179 bytes .../VorePanelElements/VorePanelEditColor.tsx | 25 ++--- 4 files changed, 92 insertions(+), 32 deletions(-) diff --git a/code/game/objects/items/devices/vacpack.dm b/code/game/objects/items/devices/vacpack.dm index 90f56a293a..bc820ef128 100644 --- a/code/game/objects/items/devices/vacpack.dm +++ b/code/game/objects/items/devices/vacpack.dm @@ -9,7 +9,7 @@ slot_flags = SLOT_BELT | SLOT_BACK var/vac_power = 0 var/output_dest = null - var/static/list/vac_settings = list( + var/list/vac_settings = list( "power off" = 0, "dust and grime" = 1, "tiny objects" = 2, @@ -18,9 +18,15 @@ "large objects" = 5, "large pests" = 6, "auto-level" = 7, - "output destination" = 8 + "DANGEROUS" = 8, + "output destination" = 9 ) var/vac_owner = null + var/sucksound = 'sound/machines/kitchen/candymaker/candymaker-mid1.ogg' + var/suckverb = "vacuum" + var/suckanim = TRUE + var/pull_range = 1 + var/max_items = 20 flags = NOBLUDGEON /obj/item/vac_attachment/attack_self(mob/user) @@ -31,7 +37,7 @@ if(!output_dest) set_input = "output destination" if(!set_input) - set_input = tgui_input_list(user, "Set your vacuum attachment's power level or output mode.", "Vac Settings", vac_settings) + set_input = tgui_input_list(user, "Set your [suckverb] attachment's power level or output mode.", "Vac Settings", vac_settings) if(set_input) if(set_input == "output destination") if(vac_owner && user != vac_owner) @@ -40,7 +46,7 @@ var/vac_options = list("Vore Belly", "Trash Bag") //Dont show option for borg belly if the user isnt even a borg. QOL! if(isrobot(user)) vac_options = list("Vore Belly", "Borg Belly", "Trash Bag") - var/set_output = tgui_input_list(user, "Set your vacuum attachment's connection port", "Vac Settings", vac_options) + var/set_output = tgui_input_list(user, "Set your [suckverb] attachment's connection port", "Vac Settings", vac_options) switch(set_output) if("Borg Belly") if(isrobot(user)) @@ -114,8 +120,20 @@ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) var/auto_setting = 1 if(isturf(target)) - user.visible_message(span_filter_notice("[user] begins vacuuming the mess off \the [target.name]..."), span_notice("You begin vacuuming the mess off \the [target.name]...")) + user.visible_message(span_filter_notice("[user] begins [suckverb]ing the mess off \the [target.name]..."), span_notice("You begin [suckverb]ing the mess off \the [target.name]...")) var/list/suckables = list() + if(vac_power == 8) + playsound(src, 'sound/machines/hiss.ogg', 100, 1, -1) + for(var/obj/item/I in oview(pull_range, target)) + if(I.anchored) + continue + I.singularity_pull(target, STAGE_THREE) + suckables += I + for(var/mob/living/L in target) + if(L.anchored || !L.devourable || L == user || L.buckled || !L.can_be_drop_prey) + continue + L.singularity_pull(target, STAGE_THREE) + suckables += L if(vac_power >= 1) for(var/obj/effect/decal/cleanable/C in target) suckables += C @@ -151,10 +169,13 @@ else auto_setting = vac_power - playsound(src, 'sound/machines/kitchen/candymaker/candymaker-mid1.ogg', auto_setting * 20, 1, -1) + playsound(src, sucksound, auto_setting * 20, 1, -1) var/vac_conga = 0 + var/sucklimit = max_items for(var/atom/movable/F in suckables) - if(is_type_in_list(F, GLOB.item_vore_blacklist) || F.loc != target) + if(sucklimit <= 0) + continue + if(is_type_in_list(F, GLOB.item_vore_blacklist)) continue if(istype(F,/obj/effect/decal/cleanable)) if(isbelly(output_dest)) @@ -166,11 +187,17 @@ var/obj/item/storage/bag/trash/B = output_dest if(LAZYLEN(B.contents) >= B.max_storage_space) to_chat(user, span_warning("Trash bag full. Empty trash bag contents to continue.")) - return - if(vac_conga < 100) - vac_conga += 3 - addtimer(CALLBACK(src, PROC_REF(prepare_sucking), F, user, auto_setting, target), 0.3 SECONDS + vac_conga) - + break + sucklimit -= 1 + if(suckanim) + if(vac_conga < 100) + vac_conga += 2 + addtimer(CALLBACK(src, PROC_REF(prepare_sucking), F, user, auto_setting, target), 0.2 SECONDS + vac_conga) + else + handle_consumption(F, user, auto_setting) + if(vac_conga > 0) + var/obj/effect/vac_visual/V = new(target) + V.ready(0.5 SECONDS + vac_conga) if(istype(target, /turf/simulated)) var/turf/simulated/T = target if(isbelly(output_dest) && T.dirt > 50) @@ -192,15 +219,16 @@ auto_setting = min(I.w_class, 5) else auto_setting = vac_power - playsound(src, 'sound/machines/kitchen/candymaker/candymaker-mid1.ogg', auto_setting * 20, 1, -1) - user.visible_message(span_filter_notice("[user] vacuums up \the [target.name]."), span_notice("You vacuum up \the [target.name]...")) - I.SpinAnimation(5,1) + playsound(src, sucksound, auto_setting * 20, 1, -1) + user.visible_message(span_filter_notice("[user] [suckverb]s up \the [target.name]."), span_notice("You [suckverb] up \the [target.name]...")) + if(suckanim) + I.SpinAnimation(5,1) addtimer(CALLBACK(src, PROC_REF(handle_consumption), I, user, auto_setting), 0.5 SECONDS) return if(istype(target,/obj/effect/decal/cleanable)) - playsound(src, 'sound/machines/kitchen/candymaker/candymaker-mid1.ogg', auto_setting * 20, 1, -1) - user.visible_message(span_filter_notice("[user] vacuums up \the [target.name]."), span_notice("You vacuum up \the [target.name]...")) + playsound(src, sucksound, auto_setting * 20, 1, -1) + user.visible_message(span_filter_notice("[user] [suckverb]s up \the [target.name]."), span_notice("You [suckverb] up \the [target.name]...")) qdel(target) return @@ -217,9 +245,10 @@ valid_to_suck = TRUE auto_setting = 6 if(valid_to_suck) - playsound(src, 'sound/machines/kitchen/candymaker/candymaker-mid1.ogg', auto_setting * 20, 1, -1) - user.visible_message(span_filter_notice("[user] vacuums up \the [target.name]."), span_notice("You vacuum up \the [target.name]...")) - L.SpinAnimation(5,1) + playsound(src, sucksound, auto_setting * 20, 1, -1) + user.visible_message(span_filter_notice("[user] [suckverb]s up \the [target.name]."), span_notice("You [suckverb] up \the [target.name]...")) + if(suckanim) + L.SpinAnimation(5,1) addtimer(CALLBACK(src, PROC_REF(handle_consumption), L, user, auto_setting), 0.5 SECONDS) /obj/item/vac_attachment/proc/prepare_sucking(atom/movable/target, mob/user, turf/target_turf) @@ -287,3 +316,33 @@ var/mob/living/L = thing var/mob_holder_type = L.holder_type || /obj/item/holder new mob_holder_type(src, L) + +/obj/item/vac_attachment/scoop + name = "\improper Scoop Hopper" + desc = "Useful for scooping clutter off the floors. Even things and stuff depending on settings. Can be connected to a trash bag or vore belly. On-mob sprites can be toggled via verb in Objects tab." + sucksound = 'sound/machines/hatchclose.ogg' + suckverb = "scoop" + suckanim = FALSE + vac_settings = list( + "power off" = 0, + "dust and grime" = 1, + "tiny objects" = 2, + "pests and small objects" = 3, + "medium objects" = 4, + "large objects" = 5, + "large pests" = 6, + "auto-level" = 7, + "output destination" = 8 + ) + +/obj/effect/vac_visual + icon = 'icons/effects/anomalies.dmi' + icon_state = "vortex" + anchored = TRUE + layer = ABOVE_MOB_LAYER + plane = TURF_PLANE + mouse_opacity = 0 + blend_mode = BLEND_ADD + +/obj/effect/vac_visual/proc/ready(effect_time) + QDEL_IN(src, effect_time) diff --git a/icons/mob/vacpack.dmi b/icons/mob/vacpack.dmi index c58865cf8d5100b8881609be0d49367205affd16..65a2c5cebe57f3d4b265f2ecddae8b27e49a9281 100644 GIT binary patch literal 4973 zcmai2cT^KiyI*=!L5hGN0i?Z(fQXbAOi)3HlmG$>NRy68kuFIsd ziiPv%XpinO7JPJ>#fy_4>aEDr+A4V>F6c(weE)Ibdv?G2PKR5K+S_^bGV!lSOH))* zHzaF}4TGlYpJ9`>`tBRDu7~K{*TyjOr`DX{zxX7}O8CkGLL|_+GtNlKxLJkVDJ1;v zslOjdh0c{gd2S2cIGT3b>P@@7&Q-9XA~mw?a78L(P?g*Ki`MV*65+e@_#~-ut62cx z4}t4lwG1mfnJ?P6nt1{*sx`3klN0m#7x2jg=Dp+t#;{@0 z62}c}(NXc!C9S|ABn>m{-Jr|o<)*X(a7x1&1X^!zFFVfv2Q%>fYn?~*7%aE#0*uL@ zqhoBhcw%<6ap5*FF@>>>rZi)t3b&13sj@_cOp{c}!^(91NQU~p79(4M zULjGp>^|IkV$r@`$(WJiK&&yTtE*3rzr9^kT^)6w`0mH<+Vp_zH*IR?#&T6E7ewIz z_0xcRr4(^wEbOT%J~!8sEOLzfarAd95A?c_JUs*_+x?ZAg{E#JggS7c8!F-_=zz)GF*Puw0Wg>A6`$OrzWL;-0q2X7VDpA^2YG*6j0xh!OH~$#Vgwy~`txdFV z$6eVyt&5xGe>ugL`A_dDHdV!CF~*yA5A>O2Hz{z0LTZp;qT%H_q;!hpwd-uUC8y5; z(&PL25Xlr+L|FyQPm9+QKY%c!zM>%j63hOJ)={d#O0MetDr8~|?DxjcDg=szYT)yd z`b7gW=B^(_pi~n#DxvcN`XX{E{xoQY19Ffzy&i@?>2e;yca=*AraQ;jEG=cBUR6$n z_?%kX)ylAt#zG`PC-k~~Pujk4g*k5Lo)5{J>#Dp#;x()!%_&?&tz5GNhNIN(1Hz8&^O7tTFVxxWn{h(P`pCW6P>&!86!|eEG<3vA-6i=iFO-#) zP2;qF6|rk)l~~ikkE})y5>jsIy1pIO1qD`*xRD=a*s?1psu08W@RNHmSrR4R6N4> zs8s^ryYN-i7YwpHj*cEc$A$7{*rAh(Q$WGITqW$n{8sq@?JFzMy&L+<$IBlWm6x9@n5Xf%%fKJ{tjx}F zNEbq!tm!}K&lQr$eL;sh=UQf!a&mJCkq&m+FmN^RTUxl`nZv6)KIF|QVp@!CrQ9Ta z*P)67o>>hxl}d94X>CtTS7XrVmH{p!=;nz55?= zy3b5GW_^XhviYvk=tWKhqqw*@K-wn5^*64kgJ*Af`C|Q&E;* z-=^6At`cW&Br1gD9a{-XA9N?UFfnX%+}`8yDW;`?KNZaR($dm~H}*z6)mR&SyVW{5 z)_kWgY#+afU$`tM6@>F{CDFM%NP6ZoNnKE7CDc~ZTjFZ8LQ=Zh*Y}R1p~-jNjp5Wzmxw7kP(CQ#8sPByAbyCFpsB0@FJ>T@jDE1FD z$(swtJx#`&DST(p4}H*R^gVlNee+3AwQDcTs%ZoJ`F=*Y*1$JcI>I*-8aw}b0$L;u zgURS$sBUUX1nt;H{drz}C1)7V@%@YU<;Mhw+-r0@Y~7lYWn{hD-2`2q#VtMhB71Dy zJ9`!vidlH5B@ThuonVCDcdWD)MW9RBrTm!+g~7S+_iEg#BF24i0(vLI7OLL8o9oLy z4?x9FrL1K#Z4DwbfQ{b+%g(SUHvB^1WBV1mtYLoNy zrGigzuuwdCaZX%!1(7_^ z&kc$#0lo4U%;1+oK!*1lAkp$a;QQa7Y#P6^aOQ+yZNKe`esEXukcvH6NqErD2% z{K41NINbdMo0+UYk)6Rk=l)vpu!reyQfdYAvp-Z>_C9|Y^(wilN=gj_5 z1-dJyU5@IfQ;&@PmQ%KTJKhe@+!omDrML*p^{NeEI%aFM`uqDI?|2<^iiv|UNLgv0 zI3o9cVm1=CG-1p_QEcjredWxwehy_km3;U^X9)AX8E~~JYGSGoD=&vuhbd=jrZV8h>PTPv-B(J513df z1guQ0;!)}JS|3;u_R->ueZYx$guM}obgA%V?4zp#J;YG_%7!X z1N#&ZR&zeNf`}PQr=tc2pFL<#VeD^hZDkneIqT)P?Ji*>@1fBWAeH&J@bG=jW>~as zgIFtKuo5@ByO-?tWgdf-h(y8yHc5dCeL{D7?u}2zUeGN)T8aPy3(+|n;k>$x{iQJo z2_X*nlY3JsEe%OMc;fMC5v>O<9HdX!GR#dA%GP~1eeGM1!B z>&}fem6yap4Y*j-DD>VRmwEAvslxjqi_^rijJiGndGX4VpCDMyYj?v12qAKQX42!s zulW8S*Zu#zyEj+kO?i36^x8|}>JRG9>g3E!VNwACv}!~|M7j)D^Ic!>IqBDs&l=qz z#6D{MR(5D&W#tB!FVKnyF;ND7lXmLbJ@w5mY!+5K#=luQ78hUhHJd zCEO>PX2@H_-SO#%lb@e*trKmoYF*wJ763r#l(l;o z56N5h{^`L^4y7T1k|H~O3#vSIL#ZXshuTG)XCsjjL&>l<0k26$P4o3E7{h0uOz5fb ziL5oiJhu5wKxqF1Rob2Z8=?#^x80RWT>dM!AD)oz?Fm9&e%UmOkB?6^kFXK|6kUl3 z`RR%PIV>>j+Za3QxV_|OcWp(OesI%Bfo>Oxek=R0ws9=T>t59|@WIq@Y3i%r80tfY z#>|v-r>a#%RBGz+ke#1aii(QgryA}zp$>QT{N5YdV)Jy0_JHi0ZiUAN-M5VUS9Y6k z$9GAoK0U@B^Ffm<+-SxZ`=F*+&I@&~Hf)MTBnx*(vFOntO!-uD4r#CJ-+9wT@e=`* zxt?2aPlhj;E_t@6s!L@}$jf1>l+5bB3WDqr%$IuM4rP{igkrk7uFr2B+^R%3PM>N2%p>(HEUK=pZAi(nEyY+a2E4Pf1pX)ryaocOnu&JU zAy)b1sw+`4aPs^{(BI1;xaFX~L6G^lv{jRb(4XaJ(Ji~{PV2V(N9{CMkqpImY#o^2 zuBxKHHa5tcn|!b%+NIjBzb12HLSyD?&FXJ<{)ggDBCKUA5#0$c!in;*c3vw%eb4;( z5zkm~5`eB;7SrYrR(|>Nb&Tk@GvWV7=GSuF{O2uU1sk6|U~&Gld)=_waS&Vy1VUax zLD$TTIA~2Yedji9ciIn_GeUoNF}kaG3bYoFVdnhQ+Nj!Epvf2-tg>Hwg}U2d6D0^r zdp7Mt+1{6eqEOH2q`kz@NPtv`d(ji1KM|P0c(#yi3@eSAK{AqD}jy!nXxD znEcr@>`lg?9M$ZSs<_&cohP2vXISl0nf7ZK;3gpx?(;3>wHIQ0UQGThRAwfhkxlH4 zEtEr@{$tN#-Cly%Ip!k&UYSB6)VV0vfGfPL|NFG& zW@QQDNG|w;P0drfpi}RE-viCsOK`9It2-d)%lSu*UA3>q?dERBH%?TvY4lU|)WTZM z4y-H>?e4w@R{=E*!Qsm8ITczys%`yu+WN={&n}s!WIjsOW7Ts{E9ln0AJ3W`oGw-h zO=ZfIwFvbLJc$qAVy9Wd_05+poOs>dM7A0mO5mCaqV+1|H zqHI9gxDQ;H$df^l{-2MYO4d(TMy`C?o+KP`ng?IaoRFWBwZ7l2@NPsyW>kY_9{HK} w_bGBY*dy$PRwsXa8nbM_Wq1sKcgaB{VSd_Z*(rGdJU;{A`lfpCt~o{j7Zj4yXaE2J literal 4185 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 MF*G%()N>C1AJ`)nG5`Po delta 2872 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 W0g<?In5u0000(false); const [lastSelectedColor, setLastSelectedColor] = useState(''); - useEffect(() => { - const newHeColor = hsvaToHex(currentColor); - if (!isOpen && back_color !== newHeColor) { - act(action, { attribute: subAction, val: newHeColor }); - } - }, [isOpen]); - useEffect(() => { let timeoutId: NodeJS.Timeout; @@ -146,12 +139,20 @@ export const VorePanelEditColor = ( ); } - const handleSetColor = ( - value: HsvaColor | ((prev: HsvaColor) => HsvaColor), - ) => { + function handleSetColor(value: HsvaColor | ((prev: HsvaColor) => HsvaColor)) { const newColor = typeof value === 'function' ? value(currentColor) : value; setCurrentColor(newColor); - }; + } + + function handleIsOpen(newState: boolean) { + setIsOpen(newState); + if (!newState) { + const newHeColor = hsvaToHex(currentColor).toLowerCase(); + if (back_color.toLowerCase() !== newHeColor) { + act(action, { attribute: subAction, val: newHeColor }); + } + } + } return ( <> @@ -163,7 +164,7 @@ export const VorePanelEditColor = ( {editMode && alpha === undefined ? (