diff --git a/code/game/objects/structures/trash_pile_vr.dm b/code/game/objects/structures/trash_pile_vr.dm index bf73c6f7ec..4247891860 100644 --- a/code/game/objects/structures/trash_pile_vr.dm +++ b/code/game/objects/structures/trash_pile_vr.dm @@ -241,7 +241,8 @@ prob(4);/obj/item/weapon/storage/pill_bottle/happy, prob(4);/obj/item/weapon/storage/pill_bottle/zoom, prob(4);/obj/item/seeds/ambrosiavulgarisseed, - prob(4);/obj/item/weapon/gun/energy/sizegun/old, + prob(4);/obj/item/weapon/gun/energy/sizegun, + prob(4);/obj/item/device/slow_sizegun, prob(3);/obj/item/weapon/material/butterfly, prob(3);/obj/item/weapon/material/butterfly/switchblade, prob(3);/obj/item/clothing/gloves/knuckledusters, diff --git a/code/modules/catalogue/cataloguer.dm b/code/modules/catalogue/cataloguer.dm index 92ed97f347..358df4c455 100644 --- a/code/modules/catalogue/cataloguer.dm +++ b/code/modules/catalogue/cataloguer.dm @@ -108,7 +108,7 @@ GLOBAL_LIST_EMPTY(all_cataloguers) var/list/box_segments = list() if(user.client) box_segments = draw_box(target, scan_range, user.client) - color_box(box_segments, "#00FF00", scan_delay) + color_box(box_segments, "#00FFFF", scan_delay) playsound(src, 'sound/machines/beep.ogg', 50) diff --git a/code/modules/economy/trader.dm b/code/modules/economy/trader.dm index ae4ac824b4..b6a8d2732f 100644 --- a/code/modules/economy/trader.dm +++ b/code/modules/economy/trader.dm @@ -15,7 +15,7 @@ var/list/products = list() //Anything in this list will be listed for sale var/list/prices = list() //Enter a type path with an associated number, and if the trader tries to sell something of that type, it will expect the number as the cost for that product var/list/multiple = list() //Enter a type path with an associated number, and the trader will have however many of that type to sell as the number you entered - var/trading = FALSE //'Busy' - Only one person can trade at a time. + var/trading = FALSE //'Busy' - Only one person can trade at a time. var/welcome_msg = "This machine accepts" //The first part of the welcome message var/welcome_accepts_name = "curious coins" //The name of the kind of thing the trader expects, automatically set except on "item" mode, where if you enter a value it will not change it. var/welcome_msg_finish = ". Would you like to browse the wares?" //The final part of the welcome message. @@ -324,7 +324,8 @@ /obj/item/capture_crystal/random = 50, /obj/item/device/perfect_tele = 10, /obj/item/device/chameleon = 25, - /obj/item/weapon/gun/energy/sizegun/old = 25, + /obj/item/weapon/gun/energy/sizegun = 25, + /obj/item/device/slow_sizegun = 25, /obj/item/weapon/implant/sizecontrol = 25, /obj/item/clothing/under/hyperfiber/bluespace = 25, /obj/item/device/nif/authentic = 1, @@ -349,7 +350,8 @@ /obj/item/capture_crystal/random = 15, /obj/item/device/perfect_tele = 20, /obj/item/device/chameleon = 20, - /obj/item/weapon/gun/energy/sizegun/old = 10, + /obj/item/weapon/gun/energy/sizegun = 10, + /obj/item/device/slow_sizegun = 10, /obj/item/weapon/implant/sizecontrol = 10, /obj/item/clothing/under/hyperfiber/bluespace = 10, /obj/item/device/nif/authentic = 100, @@ -372,7 +374,8 @@ multiple = list( /obj/item/capture_crystal/basic = 10, /obj/item/capture_crystal/random = 2, - /obj/item/weapon/gun/energy/sizegun/old = 2, + /obj/item/weapon/gun/energy/sizegun = 2, + /obj/item/device/slow_sizegun = 2, /obj/item/weapon/implant/sizecontrol = 2, /obj/item/clothing/under/hyperfiber/bluespace = 2, /obj/item/weapon/reagent_containers/food/snacks/jellyfishcore = 10 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm index c096efc550..a77fbd7973 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm @@ -196,7 +196,7 @@ /mob/living/simple_mob/vore/hostile/morph/will_show_tooltip() return (!morphed) -/mob/living/simple_mob/vore/hostile/morph/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE) +/mob/living/simple_mob/vore/hostile/morph/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) if(morphed && !ismob(form)) return return ..() diff --git a/code/modules/research/designs/misc_vr.dm b/code/modules/research/designs/misc_vr.dm index afb0df0062..1756d12493 100644 --- a/code/modules/research/designs/misc_vr.dm +++ b/code/modules/research/designs/misc_vr.dm @@ -12,7 +12,7 @@ req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 3, TECH_POWER = 2) materials = list(MAT_STEEL = 4000, MAT_GLASS = 4000) build_path = /obj/item/clothing/under/hyperfiber/bluespace - sort_string = "TAVAA" + sort_string = "TAVAB" /datum/design/item/general/sizegun name = "Size gun" @@ -22,6 +22,14 @@ build_path = /obj/item/weapon/gun/energy/sizegun sort_string = "TAVBA" +/datum/design/item/general/sizegun_gradual + name = "Gradual size gun" + id = "gradsizegun" + req_tech = list(TECH_BLUESPACE = 2, TECH_MATERIAL = 3, TECH_POWER = 2) + materials = list(MAT_STEEL = 3000, MAT_GLASS = 2000) + build_path = /obj/item/device/slow_sizegun + sort_string = "TAVBB" + /datum/design/item/general/bodysnatcher name = "Body Snatcher" id = "bodysnatcher" @@ -51,7 +59,7 @@ req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_BLUESPACE = 1) materials = list(MAT_STEEL = 1000,MAT_GLASS = 500) build_path = /obj/item/weapon/mining_scanner/advanced - sort_string = "FBAAB" + sort_string = "FBAAB" /datum/design/item/general/walkpod name = "PodZu Music Player" diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index 1b0dc4ed5e..049311e9ba 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -65,7 +65,7 @@ */ -/mob/living/proc/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE) +/mob/living/proc/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) if(!uncapped) new_size = clamp(new_size, RESIZE_MINIMUM, RESIZE_MAXIMUM) var/datum/component/resize_guard/guard = GetComponent(/datum/component/resize_guard) @@ -99,17 +99,18 @@ resize.Translate(0, (vis_height/2) * (new_size - 1)) //Move the player up in the tile so their feet align with the bottom animate(src, transform = resize, time = duration) //Animate the player resizing - var/aura_grow_to = change > 0 ? 2 : 0.5 - var/aura_anim_duration = 5 - var/aura_offset = change > 0 ? 0 : 10 - var/aura_color = size_multiplier > new_size ? "#FF2222" : "#2222FF" - var/aura_loops = round((duration)/aura_anim_duration) + if(aura_animation) + var/aura_grow_to = change > 0 ? 2 : 0.5 + var/aura_anim_duration = 5 + var/aura_offset = change > 0 ? 0 : 10 + var/aura_color = size_multiplier > new_size ? "#FF2222" : "#2222FF" + var/aura_loops = round((duration)/aura_anim_duration) - animate_aura(src, color = aura_color, offset = aura_offset, anim_duration = aura_anim_duration, loops = aura_loops, grow_to = aura_grow_to) + animate_aura(src, color = aura_color, offset = aura_offset, anim_duration = aura_anim_duration, loops = aura_loops, grow_to = aura_grow_to) else update_transform() //Lame way -/mob/living/carbon/human/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE) +/mob/living/carbon/human/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) if(!resizable && !ignore_prefs) return 1 if(species) @@ -123,7 +124,7 @@ apply_hud(index, HI) // Optimize mannequins - never a point to animating or doing HUDs on these. -/mob/living/carbon/human/dummy/mannequin/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE) +/mob/living/carbon/human/dummy/mannequin/resize(var/new_size, var/animate = TRUE, var/uncapped = FALSE, var/ignore_prefs = FALSE, var/aura_animation = TRUE) size_multiplier = new_size /** diff --git a/code/modules/vore/resizing/sizegun_slow_vr.dm b/code/modules/vore/resizing/sizegun_slow_vr.dm new file mode 100644 index 0000000000..5a267cb6da --- /dev/null +++ b/code/modules/vore/resizing/sizegun_slow_vr.dm @@ -0,0 +1,221 @@ +#define SIZE_SHRINK 0 +#define SIZE_GROW 1 + +/obj/item/device/slow_sizegun + name = "gradual size gun" + desc = "A highly advanced ray gun, designed for progressive and gradual changing of size." + icon = 'icons/obj/gun_vr.dmi' + icon_state = "sizegun-old-0" + var/base_icon_state = "sizegun-old" + w_class = ITEMSIZE_NORMAL + origin_tech = list(TECH_BLUESPACE = 4) + force = 0 + slot_flags = SLOT_BELT + var/beam_range = 4 // How many tiles away it can scan. Changing this also changes the box size. + var/busy = FALSE // Set to true when scanning, to stop multiple scans. + var/sizeshift_mode = SIZE_SHRINK + var/dorm_size = TRUE + var/size_increment = 0.01 + var/current_target + +/obj/item/device/slow_sizegun/update_icon() + icon_state = "[base_icon_state]-[sizeshift_mode]" + + if(busy) + icon_state = "[icon_state]-active" + +/obj/item/device/slow_sizegun/proc/should_stop(var/mob/living/target, var/mob/living/user, var/active_hand) + if(!target || !user || !active_hand || !istype(target) || !istype(user) || !busy) + return TRUE + + if(user.get_active_hand() != active_hand) + return TRUE + + if(user.incapacitated(INCAPACITATION_DEFAULT)) + return TRUE + + if(get_dist(user, target) > beam_range) + return TRUE + + var/unresizable = FALSE + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(istype(H.gloves, /obj/item/clothing/gloves/bluespace)) + unresizable = TRUE + return + + if(!(target.resizable)) + unresizable = TRUE + + if(unresizable) + return TRUE + + if(!(target.has_large_resize_bounds()) && (target.get_effective_size() >= RESIZE_MAXIMUM) && sizeshift_mode == SIZE_GROW) + return TRUE + + if(target.get_effective_size() >= RESIZE_MAXIMUM_DORMS && sizeshift_mode == SIZE_GROW) + return TRUE + + if(!(target.has_large_resize_bounds()) && (target.get_effective_size() <= RESIZE_MINIMUM) && sizeshift_mode == SIZE_SHRINK) + return TRUE + + if(target.get_effective_size() <= RESIZE_MINIMUM_DORMS && sizeshift_mode == SIZE_SHRINK) + return TRUE + + return FALSE + +/obj/item/device/slow_sizegun/afterattack(atom/target, mob/user, proximity_flag) + // Things that invalidate the scan immediately. + if(isturf(target)) + for(var/atom/A as anything in target) // If we can't scan the turf, see if we can scan anything on it, to help with aiming. + if(isliving(A)) + target = A + break + + if(busy && !(target == current_target)) + to_chat(user, span("warning", "\The [src] is already targeting something.")) + return + + if(!isliving(target)) + to_chat(user, span("warning", "\the [target] is not a valid target.")) + return + + var/mob/living/L = target + + if(get_dist(target, user) > beam_range) + to_chat(user, span("warning", "You are too far away from \the [target] to affect it. Get closer.")) + return + + if(target == current_target && busy) + busy = FALSE + return + + var/unresizable = FALSE + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(istype(H.gloves, /obj/item/clothing/gloves/bluespace)) + unresizable = TRUE + return + + if(!(L.resizable)) + unresizable = TRUE + + if(unresizable) + to_chat(user, span("warning", "\the [target] is immune to resizing.")) + + // Start the effects + current_target = target + busy = TRUE + update_icon() + var/datum/beam/scan_beam = user.Beam(target, icon = 'icons/effects/beam_vr.dmi', icon_state = "zappy1", time = 6000) + var/filter = filter(type = "outline", size = 1, color = "#00FF00") + target.filters += filter + var/list/box_segments = list() + if(user.client) + box_segments = draw_box(target, beam_range, user.client) + color_box(box_segments, "#00FF00", 5) + + playsound(src, 'sound/weapons/wave.ogg', 50) + + var/active_hand = user.get_active_hand() + + while(!should_stop(target, user, active_hand)) + stoplag(3) + + if(sizeshift_mode == SIZE_SHRINK) + L.resize((L.get_effective_size() - size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + else if(sizeshift_mode == SIZE_GROW) + L.resize((L.get_effective_size() + size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + + busy = FALSE + current_target = null + + // Now clean up the effects. + update_icon() + QDEL_NULL(scan_beam) + if(target) + target.filters -= filter + if(user.client) // If for some reason they logged out mid-scan the box will be gone anyways. + delete_box(box_segments, user.client) + +/obj/item/device/slow_sizegun/attack_self(mob/living/user) + if(busy) + busy = !busy + else + sizeshift_mode = !sizeshift_mode + update_icon() + to_chat(user, span("notice", "\The [src] will now [sizeshift_mode ? "grow" : "shrink"] its targets.")) + + +#undef SIZE_SHRINK +#undef SIZE_GROW + + +#define ICON_SIZE 32 + +// Draws a box showing the limits of movement while scanning something. +// Only the client supplied will see the box. +/obj/item/device/slow_sizegun/proc/draw_box(atom/A, box_size, client/C) + . = list() + // Things moved with pixel_[x|y] will move the box, so this is to correct that. + var/pixel_x_correction = -A.pixel_x + var/pixel_y_correction = -A.pixel_y + + // First, place the bottom-left corner. + . += draw_line(A, SOUTHWEST, (-box_size * ICON_SIZE) + pixel_x_correction, (-box_size * ICON_SIZE) + pixel_y_correction, C) + + // Make a line on the bottom, going right. + for(var/i = 1 to (box_size * 2) - 1) + var/x_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_x_correction + var/y_displacement = (-box_size * ICON_SIZE) + pixel_y_correction + . += draw_line(A, SOUTH, x_displacement, y_displacement, C) + + // Bottom-right corner. + . += draw_line(A, SOUTHEAST, (box_size * ICON_SIZE) + pixel_x_correction, (-box_size * ICON_SIZE) + pixel_y_correction, C) + + // Second line, for the right side going up. + for(var/i = 1 to (box_size * 2) - 1) + var/x_displacement = (box_size * ICON_SIZE) + pixel_x_correction + var/y_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_y_correction + . += draw_line(A, EAST, x_displacement, y_displacement, C) + + // Top-right corner. + . += draw_line(A, NORTHEAST, (box_size * ICON_SIZE) + pixel_x_correction, (box_size * ICON_SIZE) + pixel_y_correction, C) + + // Third line, for the top, going right. + for(var/i = 1 to (box_size * 2) - 1) + var/x_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_x_correction + var/y_displacement = (box_size * ICON_SIZE) + pixel_y_correction + . += draw_line(A, NORTH, x_displacement, y_displacement, C) + + // Top-left corner. + . += draw_line(A, NORTHWEST, (-box_size * ICON_SIZE) + pixel_x_correction, (box_size * ICON_SIZE) + pixel_y_correction, C) + + // Fourth and last line, for the left side going up. + for(var/i = 1 to (box_size * 2) - 1) + var/x_displacement = (-box_size * ICON_SIZE) + pixel_x_correction + var/y_displacement = (-box_size * ICON_SIZE) + (ICON_SIZE * i) + pixel_y_correction + . += draw_line(A, WEST, x_displacement, y_displacement, C) + +#undef ICON_SIZE + +// Draws an individual segment of the box. +/obj/item/device/slow_sizegun/proc/draw_line(atom/A, line_dir, line_pixel_x, line_pixel_y, client/C) + var/image/line = image(icon = 'icons/effects/effects.dmi', loc = A, icon_state = "stripes", dir = line_dir) + line.pixel_x = line_pixel_x + line.pixel_y = line_pixel_y + line.plane = PLANE_FULLSCREEN // It's technically a HUD element but it doesn't need to show above item slots. + line.appearance_flags = RESET_TRANSFORM|RESET_COLOR|RESET_ALPHA|NO_CLIENT_COLOR|TILE_BOUND + line.alpha = 125 + C.images += line + return line + +// Removes the box that was generated before from the client. +/obj/item/device/slow_sizegun/proc/delete_box(list/box_segments, client/C) + for(var/i in box_segments) + C.images -= i + qdel(i) + +/obj/item/device/slow_sizegun/proc/color_box(list/box_segments, new_color, new_time) + for(var/i in box_segments) + animate(i, color = new_color, time = new_time) \ No newline at end of file diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index 18c900348b..b56f827340 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -73,11 +73,6 @@ . = ..() . += "It is currently set at [size_set_to*100]%" -/obj/item/weapon/gun/energy/sizegun/old - desc = "A highly advanced ray gun with a knob on the side to adjust the size you desire. This one seems to be an older model, but still functional. Warning: Do not insert into mouth." - icon_state = "sizegun-old" - item_state = "sizegun-old" - /obj/item/weapon/gun/energy/sizegun/admin name = "modified size gun" desc = "An older model sizegun, modified to be without limits on minimum/maximum size, and have an unlimited charge. Time to show 'em that size does matter." diff --git a/icons/effects/beam_vr.dmi b/icons/effects/beam_vr.dmi new file mode 100644 index 0000000000..841b6f3506 Binary files /dev/null and b/icons/effects/beam_vr.dmi differ diff --git a/icons/obj/gun_vr.dmi b/icons/obj/gun_vr.dmi index 1b305880d0..e0788a56e9 100644 Binary files a/icons/obj/gun_vr.dmi and b/icons/obj/gun_vr.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 4c502927b1..ca1e12393d 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -4314,6 +4314,7 @@ #include "code\modules\vore\resizing\holder_micro_ch.dm" #include "code\modules\vore\resizing\holder_micro_vr.dm" #include "code\modules\vore\resizing\resize_vr.dm" +#include "code\modules\vore\resizing\sizegun_slow_vr.dm" #include "code\modules\vore\resizing\sizegun_vr.dm" #include "code\modules\vore\smoleworld\smoleworld_vr.dm" #include "code\modules\vore\weight\fitness_machines_vr.dm"