diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 08adb8e5..31776bd0 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -47,8 +47,8 @@ //Basically syntax is species_restricted = list("Species Name","Species Name") //Add a "exclude" string to do the opposite, making it only only species listed that can't wear it. //You append this to clothing objects. - - + //Hyper change// - Variables for HS13 checks + var/roomy = 0 //0 For false /obj/item/clothing/Initialize() @@ -95,6 +95,18 @@ obj_integrity = max_integrity to_chat(user, "You fix the damage on [src] with [C].") return 1 + //Hyper Change// + if(istype(W, /obj/item/bluespace_thread)) + var/obj/item/bluespace_thread/B = W + if (istype(src, /obj/item/clothing/under) || istype(src, /obj/item/clothing/suit)) //Make sure the thread is used on an item that could be ripped off in the first place + roomy = 1 //True + user.show_message("You add a few stiches to your clothing, and find them to fit a little looser.", 1) + B.uses -= 1 //One use has been used + if(B.uses <= 0) + user.show_message("The thread has been used up!", 1) + qdel(B) + else + user.show_message("You probably don't need any more room in that.", 1) return ..() /obj/item/clothing/Destroy() diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 0e4252bb..4c77e09f 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -130,7 +130,8 @@ /obj/item/clothing/suit/jacket/leather/overcoat = 4, /obj/item/clothing/under/pants/mustangjeans = 3, /obj/item/clothing/neck/necklace/dope = 5, - /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5) + /obj/item/clothing/suit/jacket/letterman_nanotrasen = 5, + /obj/item/bluespace_thread = 3) refill_canister = /obj/item/vending_refill/clothing /obj/item/vending_refill/clothing diff --git a/hyperstation/code/obj/bluespace sewing kit.dm b/hyperstation/code/obj/bluespace sewing kit.dm new file mode 100644 index 00000000..f466460e --- /dev/null +++ b/hyperstation/code/obj/bluespace sewing kit.dm @@ -0,0 +1,35 @@ +//Jay Sparrow +#define ROOMY = "ROOMY" + +/obj/item/bluespace_thread + name = "Bluespace Sewing Kit" + desc = "Thread infused with bluespace dust to make your clothes a little more roomy." + icon = 'hyperstation/icons/obj/bluespace_thread.dmi' + icon_state = "thread" + item_state = "thread" + var/uses = 2 //Give it two charges, so you can hit your uniform and jacket + +/obj/item/bluespace_thread/attack_obj(obj/O, mob/living/user) + . = ..() + if(!istype(O, /obj/item/clothing)) + user.show_message("You find yourself unable to stitch this.", 1) + return + + +/obj/item/bluespace_thread/attack_self(mob/living/user) + user.show_message("The spool has [uses] uses remaining.", 1) + +//Let's add this to the loadout screen +/datum/gear/bluespace_thread + name = "Bluespace Sewing Kit" + category = SLOT_IN_BACKPACK + path = /obj/item/bluespace_thread + +//Crafting recipe +/datum/crafting_recipe/bluespace_thread + name = "Bluespace Sewing Kit" + result = /obj/item/bluespace_thread + time = 40 + reqs = list(/obj/item/stack/ore/bluespace_crystal = 1, + /obj/item/stack/sheet/cloth = 2) + category = CAT_MISC \ No newline at end of file diff --git a/hyperstation/code/obj/leash.dm b/hyperstation/code/obj/leash.dm index 235fcc25..75ce8c00 100644 --- a/hyperstation/code/obj/leash.dm +++ b/hyperstation/code/obj/leash.dm @@ -1,396 +1,403 @@ -//Jay Sparrow -//TODO -/* -Icons, maybe? -*/ - -#define STATUS_EFFECT_LEASH_PET /datum/status_effect/leash_pet -#define STATUS_EFFECT_LEASH_DOM /datum/status_effect/leash_dom -#define STATUS_EFFECT_LEASH_FREEPET /datum/status_effect/leash_freepet -#define MOVESPEED_ID_LEASH "LEASH" - -/////STATUS EFFECTS///// -//These are mostly used as flags for the states each member can be in - -/datum/status_effect/leash_dom - status_type = STATUS_EFFECT_UNIQUE - alert_type = /obj/screen/alert/status_effect/leash_dom - -/obj/screen/alert/status_effect/leash_dom - name = "Leash Master" - desc = "You've got a leash, and a cute pet on the other end." - icon_state = "leash_master" //These call icons that don't exist, so no icon comes up. Which is good. - //As a result, the descriptions also don't proc, which is fine. - -/datum/status_effect/leash_freepet - status_type = STATUS_EFFECT_UNIQUE - alert_type = /obj/screen/alert/status_effect/leash_freepet - -/obj/screen/alert/status_effect/leash_freepet - name = "Escaped Pet" - desc = "You're on a leash, but you've no master. If anyone grabs the leash they'll gain control!" - icon_state = "leash_freepet" - - -/datum/status_effect/leash_pet - id = "leashed" - status_type = STATUS_EFFECT_UNIQUE - var/datum/weakref/redirect_component - alert_type = /obj/screen/alert/status_effect/leash_pet - -/obj/screen/alert/status_effect/leash_pet - name = "Leashed Pet" - desc = "You're on the hook now! Be good for your master." - icon_state = "leash_pet" - - -/datum/status_effect/leash_pet/on_apply() - redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) - if(!owner.stat) - to_chat(owner, "You have been leashed!") - return ..() - -//This lets the pet resist their leash -/datum/status_effect/leash_pet/proc/owner_resist() - to_chat(owner, "You reach for the hook on your collar...") - //Determine how long it takes to remove the leash - var/deleash = 15 - //if(owner.get_item_by_slot(SLOT_HANDCUFFED)) //Commented out because there is no clear way to make this proc BEFORE decuff on resist. - //deleash = 100 - if(do_mob(owner, owner, deleash))//do_mob creates a progress bar and then enacts the code after. Owner, owner, because it's an act on themself - if(!QDELETED(src)) - to_chat(owner, "[owner] has removed their leash!") - owner.remove_status_effect(/datum/status_effect/leash_pet) - -///// OBJECT ///// -//The leash object itself -//The component variables are used for hooks, used later. - -/obj/item/leash - name = "leash" - desc = "A simple tether that can easily be hooked onto a collar. Perfect for your pet." - icon = 'hyperstation/icons/obj/leash.dmi' - icon_state = "leash" - item_state = "leash" - throw_range = 4 - slot_flags = ITEM_SLOT_BELT - force = 1 - throwforce = 1 - w_class = WEIGHT_CLASS_SMALL - var/leash_used = 0 //A flag to see if the leash has been used yet, because for some reason picking up an unused leash is weird - var/mob/living/leash_pet = "null" //Variable to store our pet later - var/mob/living/leash_master = "null" //And our master too - var/datum/component/mobhook_leash_pet - var/datum/component/mobhook_leash_master //Needed to watch for these entities to move - var/datum/component/mobhook_leash_freepet - var/leash_location[3] //Three digit list for us to store coordinates later - -//Called when someone is clicked with the leash -/obj/item/leash/attack(mob/living/carbon/C, mob/living/user) //C is the target, user is the one with the leash - if(istype(C.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/petcollar) || istype(C.get_item_by_slot(SLOT_NECK), /obj/item/electropack/shockcollar)) //TODO: Shock collars too why not - var/leashtime = 50 - if(C.handcuffed) - leashtime = 5 - if(do_mob(user, C, leashtime)) //do_mob adds a progress bar, but then we also check to see if they have a collar - log_combat(user, C, "leashed", addition="playfully") - //TODO: Figure out how to make an easy breakout for leashed leash_pets - C.apply_status_effect(/datum/status_effect/leash_pet)//Has now been leashed - user.apply_status_effect(/datum/status_effect/leash_dom) //Is the leasher - leash_pet = C //Save pet reference for later - leash_master = user //Save dom reference for later - mobhook_leash_pet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_pet_move))) - mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) - leash_used = 1 - if(!leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Add slowdown if the pet didn't leash themselves - leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5) - for(var/mob/viewing in viewers(user, null)) - if(viewing == leash_master) - to_chat(leash_master, "You have hooked a leash onto [leash_pet]!") - else - viewing.show_message("[leash_pet] has been leashed by [leash_master]!", 1) - if(leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Pet leashed themself. They are not the dom - leash_pet.apply_status_effect(/datum/status_effect/leash_freepet) - leash_pet.remove_status_effect(/datum/status_effect/leash_dom) - while(1) //While true loop. The mark of a genius coder. ##MAINLOOP START - sleep(2) //Check every other tick - if(leash_pet == "null") //No pet, break loop - return - if(!(leash_pet.get_item_by_slot(SLOT_NECK))) //The pet has slipped their collar and is not the pet anymore. - for(var/mob/viewing in viewers(user, null)) - viewing.show_message("[leash_pet] has slipped out of their collar!!", 1) - to_chat(leash_pet, "You have slipped out of your collar!") - to_chat(loc, "[leash_pet] has slipped out of their collar!") - leash_pet.remove_status_effect(/datum/status_effect/leash_pet) - - if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) //If there is no pet, there is no dom. Loop breaks. - QDEL_NULL(mobhook_leash_master) - QDEL_NULL(mobhook_leash_pet) - QDEL_NULL(mobhook_leash_freepet) - if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet)) - leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) - if(leash_pet.has_movespeed_modifier(MOVESPEED_ID_LEASH)) - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) - if(!leash_master == "null") - leash_master.remove_status_effect(/datum/status_effect/leash_dom) - leash_used = 0 //reset the leash to neutral - leash_pet = "null" - return - - else //No collar, no fun - var/leash_message = pick("Your pet needs a collar") - to_chat(user, "[leash_message]") - -//Called when the leash is used in hand -//Tugs the pet closer -/obj/item/leash/attack_self(mob/living/user) - if(!leash_pet == "null") //No pet, no tug. - return - //Yank the pet. Yank em in close. - if(leash_pet.x > leash_master.x + 1) - step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master - step(leash_pet, SOUTH, 1) - if(leash_pet.y < leash_master.y) - step(leash_pet, NORTH, 1) - if(leash_pet.x < leash_master.x - 1) - step(leash_pet, EAST, 1) - if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master - step(leash_pet, SOUTH, 1) - if(leash_pet.y < leash_master.y) - step(leash_pet, NORTH, 1) - if(leash_pet.y > leash_master.y + 1) - step(leash_pet, SOUTH, 1) - if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master - step(leash_pet, WEST, 1) - if(leash_pet.x < leash_master.x) - step(leash_pet, EAST, 1) - if(leash_pet.y < leash_master.y - 1) - step(leash_pet, NORTH, 1) - if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master - step(leash_pet, WEST, 1) - if(leash_pet.x < leash_master.x) - step(leash_pet, EAST, 1) - -/obj/item/leash/proc/on_master_move() - //Make sure the dom still has a pet - if(leash_master == "null") //There must be a master - return - if(leash_pet == "null") //There must be a pet - return - if(leash_pet == leash_master) //Pet is the master - return - if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) - QDEL_NULL(mobhook_leash_master) //Probably redundant, but it's nice to be safe - leash_master.remove_status_effect(/datum/status_effect/leash_dom) - return - - //If the master moves, pull the pet in behind - sleep(2) //A small sleep so the pet kind of bounces back after they make the step - //Also, the sleep means that the distance check for master happens before the pet, to prevent both from proccing. - - if(leash_master == "null") //Just to stop error messages - return - if(leash_pet == "null") - return - if(leash_pet.x > leash_master.x + 2) - step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master - step(leash_pet, SOUTH, 1) - if(leash_pet.y < leash_master.y) - step(leash_pet, NORTH, 1) - if(leash_pet.x < leash_master.x - 2) - step(leash_pet, EAST, 1) - if(leash_pet.y > leash_master.y) - step(leash_pet, SOUTH, 1) - if(leash_pet.y < leash_master.y) - step(leash_pet, NORTH, 1) - if(leash_pet.y > leash_master.y + 2) - step(leash_pet, SOUTH, 1) - if(leash_pet.x > leash_master.x) - step(leash_pet, WEST, 1) - if(leash_pet.x < leash_master.x) - step(leash_pet, EAST, 1) - if(leash_pet.y < leash_master.y - 2) - step(leash_pet, NORTH, 1) - if(leash_pet.x > leash_master.x) - step(leash_pet, WEST, 1) - if(leash_pet.x < leash_master.x) - step(leash_pet, EAST, 1) - - //Knock the pet over if they get further behind. Shouldn't happen too often. - sleep(3) //This way running normally won't just yank the pet to the ground. - if(leash_master == "null") //Just to stop error messages. Break the loop early if something removed the master - return - if(leash_pet == "null") - return - if(leash_pet.x > leash_master.x + 3 || leash_pet.x < leash_master.x - 3 || leash_pet.y > leash_master.y + 3 || leash_pet.y < leash_master.y - 3) - //var/leash_knockdown_message = "[leash_pet] got pulled to the ground by their leash!" - //to_chat(leash_master, "[leash_knockdown_message]") - //to_chat(leash_pet, "[leash_knockdown_message]") - leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) - - //This code is to check if the pet has gotten too far away, and then break the leash. - sleep(3) //Wait to snap the leash - if(leash_master == "null") //Just to stop error messages - return - if(leash_pet == "null") - return - if(leash_pet.x > leash_master.x + 5 || leash_pet.x < leash_master.x - 5 || leash_pet.y > leash_master.y + 5 || leash_pet.y < leash_master.y - 5) - var/leash_break_message = "The leash snapped free from [leash_pet]!" - for(var/mob/viewing in viewers(leash_pet, null)) - if(viewing == leash_master) - to_chat(leash_master, "The leash snapped free from your pet!") - if(viewing == leash_pet) - to_chat(leash_pet, "Your leash has popped from your collar!") - else - viewing.show_message("[leash_break_message]", 1) - leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) - leash_pet.adjustOxyLoss(5) - leash_pet.remove_status_effect(/datum/status_effect/leash_pet) - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) - leash_master.remove_status_effect(/datum/status_effect/leash_dom) - QDEL_NULL(mobhook_leash_master) - QDEL_NULL(mobhook_leash_pet) - leash_pet = "null" - leash_master = "null" - leash_used = 0 - -/obj/item/leash/proc/on_pet_move() - //This should only work if there is a pet and a master. - //This is here pretty much just to stop the console from flooding with errors - if(leash_master == "null") - return - if(leash_pet == "null") - return - //Make sure the pet is still a pet - if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) - QDEL_NULL(mobhook_leash_pet) //Probably redundant, but it's nice to be safe - return - - //The pet has escaped. There is no DOM. GO PET RUN. - if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet))//If the pet is free, break - return - - //If the pet gets too far away, they get tugged back - sleep(3)//A small sleep so the pet kind of bounces back after they make the step - if(leash_master == "null") - return - if(leash_pet == "null") - return - //West tug - if(leash_pet.x > leash_master.x + 2) - step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - //East tug - if(leash_pet.x < leash_master.x - 2) - step(leash_pet, EAST, 1) - //South tug - if(leash_pet.y > leash_master.y + 2) - step(leash_pet, SOUTH, 1) - //North tug - if(leash_pet.y < leash_master.y - 2) - step(leash_pet, NORTH, 1) - -/obj/item/leash/proc/on_freepet_move() - . = ..() - //Pet is on the run. Let's drag the leash behind them. - if(!leash_master == "null") //If there is a master, don't do this - return - if(leash_pet == "null") //If there is no pet, don't do this - return - if(leash_pet.is_holding_item_of_type(/obj/item/leash)) //If the pet is holding the leash, don't do this - return - - sleep(2) - if(leash_pet == "null") - return - //Double move to catch the leash up to the pet - if(src.x > leash_pet.x + 2) - . = step(src, WEST, 1) - if(src.x < leash_pet.x - 2) - . = step(src, EAST, 1) - if(src.y > leash_pet.y + 2) - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y - 2) - . = step(src, NORTH, 1) - //Primary dragging code - if(src.x > leash_pet.x + 1) - . = step(src, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - if(src.y > leash_pet.y)//Check the other axis, and tug them into alignment so they are behind the pet - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y) - . = step(src, NORTH, 1) - if(src.x < leash_pet.x - 1) - . = step(src, EAST, 1) - if(src.y > leash_pet.y) - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y) - . = step(src, NORTH, 1) - if(src.y > leash_pet.y + 1) - . = step(src, SOUTH, 1) - if(src.x > leash_pet.x) - . = step(src, WEST, 1) - if(src.x < leash_pet.x) - . = step(src, EAST, 1) - if(src.y < leash_pet.y - 1) - . = step(src, NORTH, 1) - if(src.x > leash_pet.x) - . = step(src, WEST, 1) - if(src.x < leash_pet.x) - . = step(src, EAST, 1) - - sleep(1) - //Just to prevent error messages - if(leash_pet == "null") - return - if(src.x > leash_pet.x + 5 || src.x < leash_pet.x - 5 || src.y > leash_pet.y + 5 || src.y < leash_pet.y - 5) - var/leash_break_message = "The leash snapped free from [leash_pet]!" - for(var/mob/viewing in viewers(leash_pet, null)) - if(viewing == leash_pet) - to_chat(leash_pet, "Your leash has popped from your collar!") - else - viewing.show_message("[leash_break_message]", 1) - leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) - leash_pet.adjustOxyLoss(5) - leash_pet.remove_status_effect(/datum/status_effect/leash_pet) - leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) - QDEL_NULL(mobhook_leash_pet) - QDEL_NULL(mobhook_leash_freepet) - leash_pet = "null" - leash_used = 0 - -/obj/item/leash/dropped() //Drop the leash, and the leash effects stop - . = ..() - if(leash_pet == "null") //There is no pet. Stop this silliness - return - if(leash_master == "null") - return - //Dropping procs any time the leash changes slots. So, we will wait a tick and see if the leash was actually dropped - sleep(1) - if(leash_master.is_holding_item_of_type(/obj/item/leash) || istype(leash_master.get_item_by_slot(SLOT_BELT), /obj/item/leash)) - return //Dom still has the leash as it turns out. Cancel the proc. - for(var/mob/viewing in viewers(leash_master, null)) - viewing.show_message("[leash_master] has dropped the leash.", 1) - //DOM HAS DROPPED LEASH. PET IS FREE. SCP HAS BREACHED CONTAINMENT. - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) - mobhook_leash_freepet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_freepet_move))) - leash_master.remove_status_effect(/datum/status_effect/leash_dom) //No dom with no leash. We will get a new dom if the leash is picked back up. - leash_master = "null" - QDEL_NULL(mobhook_leash_master) - -/obj/item/leash/equipped(mob/user) - . = ..() - if(leash_used == 0) //Don't apply statuses with a fresh leash. Keeps things clean on the backend. - return - sleep(2) - if(leash_pet == "null") - return - leash_master = user - if(leash_master.has_status_effect(/datum/status_effect/leash_freepet) || leash_master.has_status_effect(/datum/status_effect/leash_pet)) //Pet picked up their own leash. - leash_master = "null" - return - leash_master.apply_status_effect(/datum/status_effect/leash_dom) - mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) - leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) - QDEL_NULL(mobhook_leash_freepet) - leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5) - +//Jay Sparrow +//TODO +/* +Icons, maybe? +*/ + +#define STATUS_EFFECT_LEASH_PET /datum/status_effect/leash_pet +#define STATUS_EFFECT_LEASH_DOM /datum/status_effect/leash_dom +#define STATUS_EFFECT_LEASH_FREEPET /datum/status_effect/leash_freepet +#define MOVESPEED_ID_LEASH "LEASH" + +/////STATUS EFFECTS///// +//These are mostly used as flags for the states each member can be in + +/datum/status_effect/leash_dom + status_type = STATUS_EFFECT_UNIQUE + alert_type = /obj/screen/alert/status_effect/leash_dom + +/obj/screen/alert/status_effect/leash_dom + name = "Leash Master" + desc = "You've got a leash, and a cute pet on the other end." + icon_state = "leash_master" //These call icons that don't exist, so no icon comes up. Which is good. + //As a result, the descriptions also don't proc, which is fine. + +/datum/status_effect/leash_freepet + status_type = STATUS_EFFECT_UNIQUE + alert_type = /obj/screen/alert/status_effect/leash_freepet + +/obj/screen/alert/status_effect/leash_freepet + name = "Escaped Pet" + desc = "You're on a leash, but you've no master. If anyone grabs the leash they'll gain control!" + icon_state = "leash_freepet" + + +/datum/status_effect/leash_pet + id = "leashed" + status_type = STATUS_EFFECT_UNIQUE + var/datum/weakref/redirect_component + alert_type = /obj/screen/alert/status_effect/leash_pet + +/obj/screen/alert/status_effect/leash_pet + name = "Leashed Pet" + desc = "You're on the hook now! Be good for your master." + icon_state = "leash_pet" + + +/datum/status_effect/leash_pet/on_apply() + redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) + if(!owner.stat) + to_chat(owner, "You have been leashed!") + return ..() + +//This lets the pet resist their leash +/datum/status_effect/leash_pet/proc/owner_resist() + to_chat(owner, "You reach for the hook on your collar...") + //Determine how long it takes to remove the leash + var/deleash = 15 + //if(owner.get_item_by_slot(SLOT_HANDCUFFED)) //Commented out because there is no clear way to make this proc BEFORE decuff on resist. + //deleash = 100 + if(do_mob(owner, owner, deleash))//do_mob creates a progress bar and then enacts the code after. Owner, owner, because it's an act on themself + if(!QDELETED(src)) + to_chat(owner, "[owner] has removed their leash!") + owner.remove_status_effect(/datum/status_effect/leash_pet) + +///// OBJECT ///// +//The leash object itself +//The component variables are used for hooks, used later. + +/obj/item/leash + name = "leash" + desc = "A simple tether that can easily be hooked onto a collar. Perfect for your pet." + icon = 'hyperstation/icons/obj/leash.dmi' + icon_state = "leash" + item_state = "leash" + throw_range = 4 + slot_flags = ITEM_SLOT_BELT + force = 1 + throwforce = 1 + w_class = WEIGHT_CLASS_SMALL + var/leash_used = 0 //A flag to see if the leash has been used yet, because for some reason picking up an unused leash is weird + var/mob/living/leash_pet = "null" //Variable to store our pet later + var/mob/living/leash_master = "null" //And our master too + var/datum/component/mobhook_leash_pet + var/datum/component/mobhook_leash_master //Needed to watch for these entities to move + var/datum/component/mobhook_leash_freepet + var/leash_location[3] //Three digit list for us to store coordinates later + +//Called when someone is clicked with the leash +/obj/item/leash/attack(mob/living/carbon/C, mob/living/user) //C is the target, user is the one with the leash + if(istype(C.get_item_by_slot(SLOT_NECK), /obj/item/clothing/neck/petcollar) || istype(C.get_item_by_slot(SLOT_NECK), /obj/item/electropack/shockcollar)) + var/leashtime = 50 + if(C.handcuffed) + leashtime = 5 + if(do_mob(user, C, leashtime)) //do_mob adds a progress bar, but then we also check to see if they have a collar + log_combat(user, C, "leashed", addition="playfully") + //TODO: Figure out how to make an easy breakout for leashed leash_pets + C.apply_status_effect(/datum/status_effect/leash_pet)//Has now been leashed + user.apply_status_effect(/datum/status_effect/leash_dom) //Is the leasher + leash_pet = C //Save pet reference for later + leash_master = user //Save dom reference for later + mobhook_leash_pet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_pet_move))) + mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) + leash_used = 1 + if(!leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Add slowdown if the pet didn't leash themselves + leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5) + for(var/mob/viewing in viewers(user, null)) + if(viewing == leash_master) + to_chat(leash_master, "You have hooked a leash onto [leash_pet]!") + else + viewing.show_message("[leash_pet] has been leashed by [leash_master]!", 1) + if(leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Pet leashed themself. They are not the dom + leash_pet.apply_status_effect(/datum/status_effect/leash_freepet) + leash_pet.remove_status_effect(/datum/status_effect/leash_dom) + while(1) //While true loop. The mark of a genius coder. ##MAINLOOP START + sleep(2) //Check every other tick + if(leash_pet == "null") //No pet, break loop + return + if(!(leash_pet.get_item_by_slot(SLOT_NECK))) //The pet has slipped their collar and is not the pet anymore. + for(var/mob/viewing in viewers(user, null)) + viewing.show_message("[leash_pet] has slipped out of their collar!!", 1) + to_chat(leash_pet, "You have slipped out of your collar!") + to_chat(loc, "[leash_pet] has slipped out of their collar!") + leash_pet.remove_status_effect(/datum/status_effect/leash_pet) + + if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) //If there is no pet, there is no dom. Loop breaks. + QDEL_NULL(mobhook_leash_master) + QDEL_NULL(mobhook_leash_pet) + QDEL_NULL(mobhook_leash_freepet) + if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet)) + leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) + if(leash_pet.has_movespeed_modifier(MOVESPEED_ID_LEASH)) + leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) + if(!leash_master == "null") + leash_master.remove_status_effect(/datum/status_effect/leash_dom) + leash_used = 0 //reset the leash to neutral + leash_pet = "null" + return + + else //No collar, no fun + var/leash_message = pick("Your pet needs a collar") + to_chat(user, "[leash_message]") + +//Called when the leash is used in hand +//Tugs the pet closer +/obj/item/leash/attack_self(mob/living/user) + if(!leash_pet == "null") //No pet, no tug. + return + //Yank the pet. Yank em in close. + if(leash_pet.x > leash_master.x + 1) + step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. + if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master + step(leash_pet, SOUTH, 1) + if(leash_pet.y < leash_master.y) + step(leash_pet, NORTH, 1) + if(leash_pet.x < leash_master.x - 1) + step(leash_pet, EAST, 1) + if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master + step(leash_pet, SOUTH, 1) + if(leash_pet.y < leash_master.y) + step(leash_pet, NORTH, 1) + if(leash_pet.y > leash_master.y + 1) + step(leash_pet, SOUTH, 1) + if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master + step(leash_pet, WEST, 1) + if(leash_pet.x < leash_master.x) + step(leash_pet, EAST, 1) + if(leash_pet.y < leash_master.y - 1) + step(leash_pet, NORTH, 1) + if(leash_pet.x > leash_master.x)//Check the other axis, and tug them into alignment so they are behind the master + step(leash_pet, WEST, 1) + if(leash_pet.x < leash_master.x) + step(leash_pet, EAST, 1) + +/obj/item/leash/proc/on_master_move() + //Make sure the dom still has a pet + if(leash_master == "null") //There must be a master + return + if(leash_pet == "null") //There must be a pet + return + if(leash_pet == leash_master) //Pet is the master + return + if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) + QDEL_NULL(mobhook_leash_master) //Probably redundant, but it's nice to be safe + leash_master.remove_status_effect(/datum/status_effect/leash_dom) + return + + //If the master moves, pull the pet in behind + sleep(2) //A small sleep so the pet kind of bounces back after they make the step + //Also, the sleep means that the distance check for master happens before the pet, to prevent both from proccing. + + if(leash_master == "null") //Just to stop error messages + return + if(leash_pet == "null") + return + if(leash_pet.x > leash_master.x + 2) + step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. + if(leash_pet.y > leash_master.y)//Check the other axis, and tug them into alignment so they are behind the master + step(leash_pet, SOUTH, 1) + if(leash_pet.y < leash_master.y) + step(leash_pet, NORTH, 1) + if(leash_pet.x < leash_master.x - 2) + step(leash_pet, EAST, 1) + if(leash_pet.y > leash_master.y) + step(leash_pet, SOUTH, 1) + if(leash_pet.y < leash_master.y) + step(leash_pet, NORTH, 1) + if(leash_pet.y > leash_master.y + 2) + step(leash_pet, SOUTH, 1) + if(leash_pet.x > leash_master.x) + step(leash_pet, WEST, 1) + if(leash_pet.x < leash_master.x) + step(leash_pet, EAST, 1) + if(leash_pet.y < leash_master.y - 2) + step(leash_pet, NORTH, 1) + if(leash_pet.x > leash_master.x) + step(leash_pet, WEST, 1) + if(leash_pet.x < leash_master.x) + step(leash_pet, EAST, 1) + + //Knock the pet over if they get further behind. Shouldn't happen too often. + sleep(3) //This way running normally won't just yank the pet to the ground. + if(leash_master == "null") //Just to stop error messages. Break the loop early if something removed the master + return + if(leash_pet == "null") + return + if(leash_pet.x > leash_master.x + 3 || leash_pet.x < leash_master.x - 3 || leash_pet.y > leash_master.y + 3 || leash_pet.y < leash_master.y - 3) + //var/leash_knockdown_message = "[leash_pet] got pulled to the ground by their leash!" + //to_chat(leash_master, "[leash_knockdown_message]") + //to_chat(leash_pet, "[leash_knockdown_message]") + leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) + + //This code is to check if the pet has gotten too far away, and then break the leash. + sleep(3) //Wait to snap the leash + if(leash_master == "null") //Just to stop error messages + return + if(leash_pet == "null") + return + if(leash_pet.x > leash_master.x + 5 || leash_pet.x < leash_master.x - 5 || leash_pet.y > leash_master.y + 5 || leash_pet.y < leash_master.y - 5) + var/leash_break_message = "The leash snapped free from [leash_pet]!" + for(var/mob/viewing in viewers(leash_pet, null)) + if(viewing == leash_master) + to_chat(leash_master, "The leash snapped free from your pet!") + if(viewing == leash_pet) + to_chat(leash_pet, "Your leash has popped from your collar!") + else + viewing.show_message("[leash_break_message]", 1) + leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) + leash_pet.adjustOxyLoss(5) + leash_pet.remove_status_effect(/datum/status_effect/leash_pet) + leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) + leash_master.remove_status_effect(/datum/status_effect/leash_dom) + QDEL_NULL(mobhook_leash_master) + QDEL_NULL(mobhook_leash_pet) + leash_pet = "null" + leash_master = "null" + leash_used = 0 + +/obj/item/leash/proc/on_pet_move() + //This should only work if there is a pet and a master. + //This is here pretty much just to stop the console from flooding with errors + if(leash_master == "null") + return + if(leash_pet == "null") + return + //Make sure the pet is still a pet + if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) + QDEL_NULL(mobhook_leash_pet) //Probably redundant, but it's nice to be safe + return + + //The pet has escaped. There is no DOM. GO PET RUN. + if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet))//If the pet is free, break + return + + //If the pet gets too far away, they get tugged back + sleep(3)//A small sleep so the pet kind of bounces back after they make the step + if(leash_master == "null") + return + if(leash_pet == "null") + return + //West tug + if(leash_pet.x > leash_master.x + 2) + step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. + //East tug + if(leash_pet.x < leash_master.x - 2) + step(leash_pet, EAST, 1) + //South tug + if(leash_pet.y > leash_master.y + 2) + step(leash_pet, SOUTH, 1) + //North tug + if(leash_pet.y < leash_master.y - 2) + step(leash_pet, NORTH, 1) + +/obj/item/leash/proc/on_freepet_move() + . = ..() + //Pet is on the run. Let's drag the leash behind them. + if(!leash_master == "null") //If there is a master, don't do this + return + if(leash_pet == "null") //If there is no pet, don't do this + return + if(leash_pet.is_holding_item_of_type(/obj/item/leash)) //If the pet is holding the leash, don't do this + return + + sleep(2) + if(leash_pet == "null") + return + //Double move to catch the leash up to the pet + if(src.x > leash_pet.x + 2) + . = step(src, WEST, 1) + if(src.x < leash_pet.x - 2) + . = step(src, EAST, 1) + if(src.y > leash_pet.y + 2) + . = step(src, SOUTH, 1) + if(src.y < leash_pet.y - 2) + . = step(src, NORTH, 1) + //Primary dragging code + if(src.x > leash_pet.x + 1) + . = step(src, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. + if(src.y > leash_pet.y)//Check the other axis, and tug them into alignment so they are behind the pet + . = step(src, SOUTH, 1) + if(src.y < leash_pet.y) + . = step(src, NORTH, 1) + if(src.x < leash_pet.x - 1) + . = step(src, EAST, 1) + if(src.y > leash_pet.y) + . = step(src, SOUTH, 1) + if(src.y < leash_pet.y) + . = step(src, NORTH, 1) + if(src.y > leash_pet.y + 1) + . = step(src, SOUTH, 1) + if(src.x > leash_pet.x) + . = step(src, WEST, 1) + if(src.x < leash_pet.x) + . = step(src, EAST, 1) + if(src.y < leash_pet.y - 1) + . = step(src, NORTH, 1) + if(src.x > leash_pet.x) + . = step(src, WEST, 1) + if(src.x < leash_pet.x) + . = step(src, EAST, 1) + + sleep(1) + //Just to prevent error messages + if(leash_pet == "null") + return + if(src.x > leash_pet.x + 5 || src.x < leash_pet.x - 5 || src.y > leash_pet.y + 5 || src.y < leash_pet.y - 5) + var/leash_break_message = "The leash snapped free from [leash_pet]!" + for(var/mob/viewing in viewers(leash_pet, null)) + if(viewing == leash_pet) + to_chat(leash_pet, "Your leash has popped from your collar!") + else + viewing.show_message("[leash_break_message]", 1) + leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) + leash_pet.adjustOxyLoss(5) + leash_pet.remove_status_effect(/datum/status_effect/leash_pet) + leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) + QDEL_NULL(mobhook_leash_pet) + QDEL_NULL(mobhook_leash_freepet) + leash_pet = "null" + leash_used = 0 + +/obj/item/leash/dropped() //Drop the leash, and the leash effects stop + . = ..() + if(leash_pet == "null") //There is no pet. Stop this silliness + return + if(leash_master == "null") + return + //Dropping procs any time the leash changes slots. So, we will wait a tick and see if the leash was actually dropped + sleep(1) + if(leash_master.is_holding_item_of_type(/obj/item/leash) || istype(leash_master.get_item_by_slot(SLOT_BELT), /obj/item/leash)) + return //Dom still has the leash as it turns out. Cancel the proc. + for(var/mob/viewing in viewers(leash_master, null)) + viewing.show_message("[leash_master] has dropped the leash.", 1) + //DOM HAS DROPPED LEASH. PET IS FREE. SCP HAS BREACHED CONTAINMENT. + leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) + mobhook_leash_freepet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_freepet_move))) + leash_master.remove_status_effect(/datum/status_effect/leash_dom) //No dom with no leash. We will get a new dom if the leash is picked back up. + leash_master = "null" + QDEL_NULL(mobhook_leash_master) + +/obj/item/leash/equipped(mob/user) + . = ..() + if(leash_used == 0) //Don't apply statuses with a fresh leash. Keeps things clean on the backend. + return + sleep(2) + if(leash_pet == "null") + return + leash_master = user + if(leash_master.has_status_effect(/datum/status_effect/leash_freepet) || leash_master.has_status_effect(/datum/status_effect/leash_pet)) //Pet picked up their own leash. + leash_master = "null" + return + leash_master.apply_status_effect(/datum/status_effect/leash_dom) + mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) + leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) + QDEL_NULL(mobhook_leash_freepet) + leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH, multiplicative_slowdown = 5) + +/datum/crafting_recipe/leash + name = "Leash" + result = /obj/item/leash + time = 40 + reqs = list(/obj/item/stack/sheet/metal = 1, + /obj/item/stack/sheet/cloth = 3) + category = CAT_MISC \ No newline at end of file diff --git a/hyperstation/code/obj/rope.dm b/hyperstation/code/obj/rope.dm index 829257e4..98c933a2 100644 --- a/hyperstation/code/obj/rope.dm +++ b/hyperstation/code/obj/rope.dm @@ -47,3 +47,9 @@ if (!C.handcuffed) return //Break when the rope is removed +/datum/crafting_recipe/rope + name = "Soft Rope" + result = /obj/item/restraints/handcuffs/rope + time = 40 + reqs = list(/obj/item/stack/sheet/cloth = 5) + category = CAT_MISC \ No newline at end of file diff --git a/hyperstation/icons/obj/bluespace_thread.dmi b/hyperstation/icons/obj/bluespace_thread.dmi new file mode 100644 index 00000000..77b9e6d5 Binary files /dev/null and b/hyperstation/icons/obj/bluespace_thread.dmi differ diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 099d4559..599a590a 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -44,12 +44,16 @@ var/items = o.get_contents() for(var/obj/item/W in items) if(W == o.w_uniform || W == o.wear_suit) - o.dropItemToGround(W, TRUE) - playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) - to_chat(o, "Your clothes give, ripping into pieces under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!") - o.visible_message("[o]'s chest suddenly bursts forth, ripping their clothes off!'") - else - to_chat(o, "Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.") + //Hyper change + var/obj/item/clothing/W2 = W + if(!W2.roomy == 1) //If the clothes are "roomy" then don't do this. + //Hyper change end + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(o, "Your clothes give, ripping into pieces under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..!") + o.visible_message("[o]'s chest suddenly bursts forth, ripping their clothes off!'") + else + to_chat(o, "Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it.") return ..() /datum/status_effect/chem/breast_enlarger/tick(mob/living/carbon/human/H)//If you try to wear clothes, you fail. Slows you down if you're comically huge @@ -66,9 +70,13 @@ var/items = o.get_contents() for(var/obj/item/W in items) if(W == o.w_uniform || W == o.wear_suit) - o.dropItemToGround(W, TRUE) - playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) - to_chat(owner, "Your enormous breasts are way too large to fit anything over them!") + //Hyper change// Check for a flag before we remove clothes. + var/obj/item/clothing/W2 = W + if(!W2.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(owner, "Your enormous breasts are way too large to fit anything over them!") /* if (B.size == "huge") if(prob(1)) @@ -125,14 +133,23 @@ var/mob/living/carbon/human/o = owner var/items = o.get_contents() if(o.w_uniform || o.wear_suit) - to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!") - owner.visible_message("[o]'s schlong suddenly bursts forth, ripping their clothes off!'") + //Hyper change// Check for a flag before we remove clothes. + var/obj/item/clothing/suit = o.get_item_by_slot(SLOT_W_UNIFORM) + var/obj/item/clothing/jacket = o.get_item_by_slot(SLOT_WEAR_SUIT) + if(!suit.roomy == 1 || !jacket.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..!") + owner.visible_message("[o]'s schlong suddenly bursts forth, ripping their clothes off!'") else to_chat(o, "Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it.") for(var/obj/item/W in items) if(W == o.w_uniform || W == o.wear_suit) - o.dropItemToGround(W, TRUE) - playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + //Hyper change// Check for a flag before we remove clothes. + var/obj/item/clothing/W2 = W + if(!W2.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) return ..() @@ -151,14 +168,19 @@ var/items = o.get_contents() for(var/obj/item/W in items) - if (o.arousalloss > 32) // warning that your shaft is getting errect! - if(W == o.w_uniform || W == o.wear_suit ) - to_chat(M, "Your swelling cock begins to strain against your clothes tightly!") - if (o.arousalloss > 33) - if(W == o.w_uniform || W == o.wear_suit ) - o.dropItemToGround(W, TRUE) - playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) - to_chat(owner, "Your erect member is way to large to fit anything over! You will need to be flaccid again to wear clothes!") + //Hyper change// Check for a flag before we remove clothes. + if(istype(W, /obj/item/clothing)) + var/obj/item/clothing/W2 = W + if(!W2.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + if (o.arousalloss > 32) // warning that your shaft is getting errect! + if(W == o.w_uniform || W == o.wear_suit ) + to_chat(M, "Your swelling cock begins to strain against your clothes tightly!") + if (o.arousalloss > 33) + if(W == o.w_uniform || W == o.wear_suit ) + o.dropItemToGround(W, TRUE) + playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1) + to_chat(owner, "Your erect member is way to large to fit anything over! You will need to be flaccid again to wear clothes!") /* switch(round(P.cached_length)) if(21) diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm index 6bed45ce..fd6294dd 100644 --- a/modular_citadel/code/game/machinery/vending.dm +++ b/modular_citadel/code/game/machinery/vending.dm @@ -63,7 +63,9 @@ ) premium = list( /obj/item/electropack/shockcollar = 3, - /obj/item/clothing/neck/petcollar/locked = 1 + /obj/item/clothing/neck/petcollar/locked = 1, + /obj/item/restraints/handcuffs/rope = 1, + /obj/item/leash = 1 ) refill_canister = /obj/item/vending_refill/kink /* diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 5ebad3b2..6f8954f7 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -98,10 +98,15 @@ B.cached_size = B.cached_size + 0.05 if (B.cached_size >= 8.5 && B.cached_size < 9) if(H.w_uniform || H.wear_suit) - var/target = M.get_bodypart(BODY_ZONE_CHEST) - to_chat(M, "Your breasts begin to strain against your clothes tightly!") - M.adjustOxyLoss(5, 0) - M.apply_damage(1, BRUTE, target) + //Hyper change// Check for a flag before we remove clothes. + var/obj/item/clothing/suit = H.get_item_by_slot(SLOT_W_UNIFORM) + var/obj/item/clothing/jacket = H.get_item_by_slot(SLOT_WEAR_SUIT) + if(!suit.roomy == 1 || !jacket.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + var/target = M.get_bodypart(BODY_ZONE_CHEST) + to_chat(M, "Your breasts begin to strain against your clothes tightly!") + M.adjustOxyLoss(5, 0) + M.apply_damage(1, BRUTE, target) B.update() ..() @@ -272,9 +277,14 @@ P.cached_length = P.cached_length + 0.1 if (P.cached_length >= 20.5 && P.cached_length < 21) if(H.w_uniform || H.wear_suit|| H.arousalloss > 33) - var/target = M.get_bodypart(BODY_ZONE_CHEST) - to_chat(M, "Your cock begins to strain against your clothes tightly!") - M.apply_damage(1, BRUTE, target) + //Hyper change// Check for a flag before we remove clothes. + var/obj/item/clothing/suit = H.get_item_by_slot(SLOT_W_UNIFORM) + var/obj/item/clothing/jacket = H.get_item_by_slot(SLOT_WEAR_SUIT) + if(!suit.roomy == 1 || !jacket.roomy == 1) //If the clothes are "roomy" then don't do this. + //End Hyper Change// + var/target = M.get_bodypart(BODY_ZONE_CHEST) + to_chat(M, "Your cock begins to strain against your clothes tightly!") + M.apply_damage(1, BRUTE, target) P.update() ..() diff --git a/tgstation.dme b/tgstation.dme index ff636be0..9bd0c7b8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2891,6 +2891,7 @@ #include "hyperstation\code\modules\resize\holder_micro.dm" #include "hyperstation\code\modules\resize\resizing.dm" #include "hyperstation\code\modules\resize\sizegun.dm" +#include "hyperstation\code\obj\bluespace sewing kit.dm" #include "hyperstation\code\obj\decal.dm" #include "hyperstation\code\obj\fluff.dm" #include "hyperstation\code\obj\kinkyclothes.dm"