diff --git a/code/modules/clothing/under/accessories/accessory_vr.dm b/code/modules/clothing/under/accessories/accessory_vr.dm index d70e7c0df6f..5a4a910e5e2 100644 --- a/code/modules/clothing/under/accessories/accessory_vr.dm +++ b/code/modules/clothing/under/accessories/accessory_vr.dm @@ -493,7 +493,14 @@ /obj/item/clothing/accessory/collar/shock/bluespace/relaymove(var/mob/living/user,var/direction) return //For some reason equipping this item was triggering this proc, putting the wearer inside of the collars belly for some reason. -/obj/item/clothing/accessory/collar/shock/bluespace/attackby(var/obj/item/device/assembly/signaler/component, mob/user as mob) +/obj/item/clothing/accessory/collar/shock/bluespace/attackby(var/obj/item/component, mob/user as mob) + if (component.has_tool_quality(TOOL_WRENCH)) + to_chat(user, "You crack the bluespace crystal [src].") + var/turf/T = get_turf(src) + new /obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning(T) + user.drop_from_inventory(src) + qdel(src) + return if (!istype(component,/obj/item/device/assembly/signaler)) ..() return @@ -517,7 +524,14 @@ target_size = 1 on = 1 -/obj/item/clothing/accessory/collar/shock/bluespace/modified/attackby(var/obj/item/device/assembly/signaler/component, mob/user as mob) +/obj/item/clothing/accessory/collar/shock/bluespace/modified/attackby(var/obj/item/component, mob/user as mob) + if (component.has_tool_quality(TOOL_WRENCH)) + to_chat(user, "You crack the bluespace crystal [src], the attached signaler disconnects.") + var/turf/T = get_turf(src) + new /obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning(T) + user.drop_from_inventory(src) + qdel(src) + return if (!istype(component,/obj/item/device/assembly/signaler)) ..() return @@ -625,6 +639,141 @@ s.start() return +//bluespace collar malfunctioning (random size) + +/obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning + name = "Bluespace collar" + desc = "A collar that can manipulate the size of the wearer, and can be modified when unequiped. It has a crack on the crystal." + icon_state = "collar_size_malf" + item_state = "collar_size" + overlay_state = "collar_size" + target_size = 1 + on = 1 + var/currently_shrinking = 0 + +/obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning/attackby(var/obj/item/component, mob/user as mob) + if (!istype(component,/obj/item/device/assembly/signaler)) + ..() + return + to_chat(user, "The signaler doesn't respond to the connection attempt [src].") + return + +/obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning/attack_self(mob/user as mob, flag1) + if(!istype(user, /mob/living/carbon/human)) + return + user.set_machine(src) + var/dat = {" + Frequency/Code for collar:
+ Frequency: + - + - [format_frequency(frequency)] + + + +
+ + Code: + - + - [code] + + + +
+ + Tag: + Set tag
+ + Size: + Input Disabled!
+
"} + user << browse(dat, "window=radio") + onclose(user, "radio") + return + +/obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning/Topic(href, href_list) + if(usr.stat || usr.restrained()) + return + if(((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(master) || (in_range(src, usr) && istype(loc, /turf))))) + usr.set_machine(src) + if(href_list["freq"]) + var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"])) + set_frequency(new_frequency) + if(href_list["tag"]) + var/str = copytext(reject_bad_text(tgui_input_text(usr,"Tag text?","Set tag","",MAX_NAME_LEN)),1,MAX_NAME_LEN) + if(!str || !length(str)) + to_chat(usr,"[name]'s tag set to be blank.") + name = initial(name) + desc = initial(desc) + else + to_chat(usr,"You set the [name]'s tag to '[str]'.") + name = initial(name) + " ([str])" + desc = initial(desc) + " The tag says \"[str]\"." + else + if(href_list["code"]) + code += text2num(href_list["code"]) + code = round(code) + code = min(100, code) + code = max(1, code) + if(!( master )) + if(istype(loc, /mob)) + attack_self(loc) + else + for(var/mob/M in viewers(1, src)) + if(M.client) + attack_self(M) + else + if(istype(master.loc, /mob)) + attack_self(master.loc) + else + for(var/mob/M in viewers(1, master)) + if(M.client) + attack_self(M) + else + usr << browse(null, "window=radio") + return + return + +/obj/item/clothing/accessory/collar/shock/bluespace/malfunctioning/receive_signal(datum/signal/signal) + if(!signal) + return + target_size = (rand(25,200)) /100 + if(on) + var/mob/M = null + if(ismob(loc)) + M = loc + if(ismob(loc.loc)) + M = loc.loc // This is about as terse as I can make my solution to the whole 'collar won't work when attached as accessory' thing. + var/mob/living/carbon/human/H = M + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + if(!H.resizable) + H.visible_message("The space around [H] compresses for a moment but then nothing happens.","The space around you distorts but nothing happens to you.") + return + if (target_size < 0.25) + H.visible_message("The collar on [H] flickers, but fizzles out.","Your collar flickers, but is not powerful enough to shrink you that small.") + return + if(currently_shrinking == 0) + if(!(world.time - last_activated > 10 SECONDS)) + to_chat(M, "\The [src] flickers. It seems to be recharging.") + return + last_activated = world.time + original_size = H.size_multiplier + currently_shrinking = 1 + H.resize(target_size, ignore_prefs = FALSE) //In case someone else tries to put it on you. + H.visible_message("The space around [H] distorts as they change size!","The space around you distorts as you change size!") + log_admin("Admin [key_name(M)]'s size was altered by a bluespace collar.") + s.set_up(3, 1, M) + s.start() + else if(currently_shrinking == 1) + if(original_size == null) + H.visible_message("The space around [H] twists and turns for a moment but then nothing happens.","The space around you distorts but stay the same size.") + return + last_activated = world.time + H.resize(original_size, ignore_prefs = FALSE) + original_size = null + currently_shrinking = 0 + H.visible_message("The space around [H] distorts as they return to their original size!","The space around you distorts as you return to your original size!") + log_admin("Admin [key_name(M)]'s size was altered by a bluespace collar.") + to_chat(M, "\The [src] flickers. It is now recharging and will be ready again in ten seconds.") + s.set_up(3, 1, M) + s.start() + return + //Machete Holsters /obj/item/clothing/accessory/holster/machete name = "machete sheath" diff --git a/code/modules/vore/resizing/sizegun_slow_vr.dm b/code/modules/vore/resizing/sizegun_slow_vr.dm index 648c0f91c7e..9a993e7a872 100644 --- a/code/modules/vore/resizing/sizegun_slow_vr.dm +++ b/code/modules/vore/resizing/sizegun_slow_vr.dm @@ -3,7 +3,7 @@ /obj/item/device/slow_sizegun name = "gradual size gun" - desc = "A highly advanced ray gun, designed for progressive and gradual changing of size." + desc = "A highly advanced ray gun, designed for progressive and gradual changing of size. Size trading can be toggled on via alt-clicking." icon = 'icons/obj/gun_vr.dmi' icon_state = "sizegun-old-0" var/base_icon_state = "sizegun-old" @@ -17,6 +17,7 @@ var/dorm_size = TRUE var/size_increment = 0.01 var/current_target + var/trading = 0 /obj/item/device/slow_sizegun/update_icon() icon_state = "[base_icon_state]-[sizeshift_mode]" @@ -50,6 +51,9 @@ if(unresizable) return TRUE + if(trading == 1 && !(user.resizable)) + return TRUE + if(!(target.has_large_resize_bounds()) && (target.size_multiplier >= RESIZE_MAXIMUM) && sizeshift_mode == SIZE_GROW) return TRUE @@ -62,6 +66,18 @@ if(target.size_multiplier <= RESIZE_MINIMUM_DORMS && sizeshift_mode == SIZE_SHRINK) return TRUE + if(trading == 1 && !(user.has_large_resize_bounds()) && (user.size_multiplier >= RESIZE_MAXIMUM) && sizeshift_mode == SIZE_GROW) + return TRUE + + if(trading == 1 && user.size_multiplier >= RESIZE_MAXIMUM_DORMS && sizeshift_mode == SIZE_GROW) + return TRUE + + if(trading == 1 && !(user.has_large_resize_bounds()) && (user.size_multiplier <= RESIZE_MINIMUM) && sizeshift_mode == SIZE_SHRINK) + return TRUE + + if(trading == 1 && user.size_multiplier <= RESIZE_MINIMUM_DORMS && sizeshift_mode == SIZE_SHRINK) + return TRUE + return FALSE /obj/item/device/slow_sizegun/afterattack(atom/target, mob/user, proximity_flag) @@ -81,6 +97,7 @@ return var/mob/living/L = target + var/mob/living/U = user 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.")) @@ -100,6 +117,9 @@ if(!(L.resizable)) unresizable = TRUE + if(trading == 1 && !(user.resizable)) + unresizable = TRUE + if(unresizable) to_chat(user, span("warning", "\the [target] is immune to resizing.")) @@ -119,14 +139,25 @@ var/active_hand = user.get_active_hand() - while(!should_stop(target, user, active_hand)) - stoplag(3) + if (trading == 0) + while(!should_stop(target, user, active_hand)) + stoplag(3) - if(sizeshift_mode == SIZE_SHRINK) - L.resize((L.size_multiplier - size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) - else if(sizeshift_mode == SIZE_GROW) - L.resize((L.size_multiplier + size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + if(sizeshift_mode == SIZE_SHRINK) + L.resize((L.size_multiplier - size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + else if(sizeshift_mode == SIZE_GROW) + L.resize((L.size_multiplier + size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + if (trading == 1) + while(!should_stop(target, user, active_hand)) + stoplag(3) + + if(sizeshift_mode == SIZE_SHRINK) + L.resize((L.size_multiplier - size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + U.resize((U.size_multiplier + size_increment), uncapped = U.has_large_resize_bounds(), aura_animation = FALSE) + else if(sizeshift_mode == SIZE_GROW) + L.resize((L.size_multiplier + size_increment), uncapped = L.has_large_resize_bounds(), aura_animation = FALSE) + U.resize((U.size_multiplier - size_increment), uncapped = U.has_large_resize_bounds(), aura_animation = FALSE) busy = FALSE current_target = null @@ -219,3 +250,13 @@ /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) + +//Alt click to activate size trading + +/obj/item/device/slow_sizegun/AltClick(mob/user) + if (trading == 0) + trading = 1 + to_chat(user, span("notice", "\The [src] will now trade your targets size for your own.")) + else + trading = 0 + to_chat(user, span("notice", "\The [src] will no longer trade your targets size for your own.")) diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index c5fc1f3648e..982d5185f98 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -26,11 +26,20 @@ /obj/item/weapon/gun/energy/sizegun/New() ..() verbs += PROC_REF(select_size) + verbs += PROC_REF(spin_dial) /obj/item/weapon/gun/energy/sizegun/attack_self(mob/user) . = ..() select_size() +/obj/item/weapon/gun/energy/sizegun/proc/spin_dial() + set name = "Spin Size Dial" + set category = "Object" + set src in view(1) + + size_set_to = (rand(25,200)) /100 + usr.visible_message("\The [usr] spins the size dial to a random value!","You spin the dial to a random value!") + /obj/item/weapon/gun/energy/sizegun/consume_next_projectile() . = ..() var/obj/item/projectile/beam/sizelaser/G = . diff --git a/icons/inventory/accessory/item_vr.dmi b/icons/inventory/accessory/item_vr.dmi index de59e5e17d2..5a85d7bb33a 100644 Binary files a/icons/inventory/accessory/item_vr.dmi and b/icons/inventory/accessory/item_vr.dmi differ