From 8fd779ef024b53108278b45ed1cc6c9bba5d3941 Mon Sep 17 00:00:00 2001
From: Metis <100518708+sheepishgoat@users.noreply.github.com>
Date: Thu, 12 Sep 2024 23:53:35 -0400
Subject: [PATCH] whole lotta stuff
---
GainStation13/code/clothing/accessory.dm | 16 +
.../code/clothing/calorite_collar.dm | 53 ++
GainStation13/code/clothing/fat_mask.dm | 29 +
GainStation13/code/clothing/haydee_suit.dm | 68 ++
GainStation13/code/clothing/head.dm | 28 +
GainStation13/code/clothing/suits.dm | 66 ++
.../code/datums/components/fattening_door.dm | 44 ++
.../datums/diseases/advance/symptoms/berry.dm | 71 ++
.../code/datums/mutations/fatfang.dm | 63 ++
GainStation13/code/datums/mutations/radfat.dm | 42 ++
.../code/datums/status_effects/fatstun.dm | 64 ++
GainStation13/code/game/area/ruins.dm | 38 ++
GainStation13/code/game/lore_papers.dm | 547 ++++++++++++++++
.../effects/spawners/choco_slime_delivery.dm | 29 +
GainStation13/code/game/objects/items/RCD.dm | 47 ++
.../game/objects/items/docility_implant.dm | 134 ++++
.../code/game/objects/items/storage/bags.dm | 48 ++
GainStation13/code/game/sound.dm | 37 ++
GainStation13/code/game/turfs/closed.dm | 27 +
GainStation13/code/game/turfs/open.dm | 50 ++
.../code/machinery/adipoelectric_generator.dm | 164 +++++
.../machinery/adipoelectric_transformer.dm | 167 +++++
.../code/machinery/fattening_turret.dm | 31 +
GainStation13/code/machinery/feeding_tube.dm | 94 +++
.../code/machinery/supply_teleporter.dm | 15 +
.../code/mechanics/den abductors/console.dm | 248 +++++++
.../den abductors/purchaseble_goodies.dm | 88 +++
GainStation13/code/mechanics/fatness.dm | 247 +++++++
GainStation13/code/mechanics/fatrousal.dm | 30 +
.../code/mechanics/fattening_trap.dm | 27 +
GainStation13/code/mechanics/helplessness.dm | 20 +
GainStation13/code/mechanics/hunger.dm | 30 +
GainStation13/code/mechanics/infestation.dm | 100 +++
.../code/mechanics/metal_cruncher.dm | 87 +++
GainStation13/code/mechanics/permanent_fat.dm | 53 ++
GainStation13/code/mechanics/spells.dm | 141 ++++
GainStation13/code/mechanics/wand.dm | 57 ++
GainStation13/code/mechanics/water_sponge.dm | 93 +++
GainStation13/code/mechanics/web_weaving.dm | 114 ++++
GainStation13/code/mobs/cakegolem.dm | 51 ++
GainStation13/code/mobs/chocoslime.dm | 95 +++
.../code/mobs/races/caloritegolem.dm | 139 ++++
GainStation13/code/mobs/slugcat.dm | 119 ++++
GainStation13/code/mobs/unusualtentical.dm | 5 +
.../modules/client/preferences/preferences.dm | 101 +++
.../clothing/under/jobs/modcivilian.dm | 156 +++++
.../code/modules/food_and_drinks/drinks.dm | 26 +
.../code/modules/food_and_drinks/food.dm | 139 ++++
.../food_and_drinks/objects/candy_flora.dm | 47 ++
.../food_and_drinks/recipes/recipes_ported.dm | 126 ++++
.../food_and_drinks/recipes_bigpizza.dm | 93 +++
GainStation13/code/modules/gym/gym.dm | 113 ++++
.../code/modules/hydroponics/grown/berries.dm | 25 +
.../code/modules/hydroponics/lipoplant.dm | 127 ++++
.../code/modules/hydroponics/munchies_weed.dm | 53 ++
.../code/modules/mob/living/emote.dm | 100 +++
.../code/modules/mob/living/emote_modular.dm | 4 +
.../code/modules/mob/living/emote_ported.dm | 239 +++++++
.../code/modules/mob/living/fullness.dm | 16 +
.../code/modules/mob/living/nutribot.dm | 609 ++++++++++++++++++
.../code/modules/mob/living/species.dm | 423 ++++++++++++
.../mob/living/vore/eating/trasheat_lists.dm | 94 +++
.../chemistry/reagents/consumable_reagents.dm | 149 +++++
.../chemistry/reagents/dwarverndrinks.dm | 28 +
.../chemistry/reagents/fatty_drinks.dm | 159 +++++
.../reagents/chemistry/reagents/fermi_fat.dm | 196 ++++++
.../chemistry/recipes/ROCKANDSTONEdrinks.dm | 14 +
.../reagents/chemistry/recipes/fatchem.dm | 29 +
.../reagents/chemistry/recipes/fatdrinks.dm | 55 ++
.../reagent_containers/barrel_tank.dm | 79 +++
.../modules/research/designs/autolathe.dm | 7 +
.../modules/research/designs/nutri_designs.dm | 251 ++++++++
.../nanites/nanite_programs/fattening.dm | 161 +++++
.../research/techweb/nutritech_nodes.dm | 23 +
.../code/modules/surgery/organs/augments.dm | 25 +
.../code/modules/vending/gatocola.dm | 29 +
GainStation13/code/modules/vending/mealdor.dm | 54 ++
.../code/obj/items/bluespace_belt.dm | 34 +
GainStation13/code/obj/items/circuits.dm | 30 +
GainStation13/code/obj/items/holy.dm | 93 +++
GainStation13/code/obj/items/minor_items.dm | 171 +++++
GainStation13/code/obj/items/pride_pins.dm | 47 ++
.../code/obj/items/sensors/weight_infared.dm | 79 +++
GainStation13/code/obj/structure/airlock.dm | 37 ++
.../code/obj/structure/calorite_doors.dm | 18 +
.../code/obj/structure/candylight.dm | 9 +
GainStation13/code/obj/structure/fountain.dm | 43 ++
GainStation13/code/obj/structure/gsstatues.dm | 6 +
GainStation13/code/obj/structure/scale.dm | 81 +++
GainStation13/code/obj/weapons/alter_rays.dm | 171 +++++
GainStation13/code/obj/weapons/fatbeam.dm | 126 ++++
GainStation13/code/obj/weapons/fatoray.dm | 142 ++++
GainStation13/code/obj/weapons/feeder_ebow.dm | 25 +
.../code/structures/trapped_items.dm | 39 ++
GainStation13/icons/mob/AI.dmi | Bin 0 -> 15045 bytes
GainStation13/icons/mob/accessories.dmi | Bin 0 -> 506 bytes
GainStation13/icons/mob/action_icons.dmi | Bin 0 -> 729 bytes
GainStation13/icons/mob/blueberry.dmi | Bin 0 -> 7026 bytes
GainStation13/icons/mob/cakegolem.dmi | Bin 0 -> 1382 bytes
GainStation13/icons/mob/candymonster.dmi | Bin 0 -> 1402 bytes
GainStation13/icons/mob/ghoster.dmi | Bin 0 -> 1261 bytes
GainStation13/icons/mob/head.dmi | Bin 0 -> 863 bytes
.../icons/mob/modclothes/chefmodular.dmi | Bin 0 -> 55125 bytes
.../icons/mob/modclothes/gray_bra.dmi | Bin 0 -> 384 bytes
.../icons/mob/modclothes/graymodular.dmi | Bin 0 -> 31981 bytes
.../icons/mob/modclothes/graymodular_bra.dmi | Bin 0 -> 2481 bytes
GainStation13/icons/mob/nutribot.dmi | Bin 0 -> 1329 bytes
GainStation13/icons/mob/pets.dmi | Bin 0 -> 1396 bytes
GainStation13/icons/mob/robots.dmi | Bin 0 -> 14689 bytes
GainStation13/icons/mob/shitass.dmi | Bin 0 -> 299 bytes
GainStation13/icons/mob/suits.dmi | Bin 0 -> 3853 bytes
GainStation13/icons/mob/uniforms/grey.dmi | Bin 0 -> 741 bytes
GainStation13/icons/mob/web.dmi | Bin 0 -> 798 bytes
.../icons/obj/adipoelectric_transformer.dmi | Bin 0 -> 1177 bytes
GainStation13/icons/obj/barrel_tank.dmi | Bin 0 -> 385 bytes
GainStation13/icons/obj/berrybush.dmi | Bin 0 -> 946 bytes
GainStation13/icons/obj/blueberries.dmi | Bin 0 -> 313 bytes
.../icons/obj/clothing/bluespace_belt.dmi | Bin 0 -> 793 bytes
GainStation13/icons/obj/clothing/fat_mask.dmi | Bin 0 -> 525 bytes
.../icons/obj/clothing/haydee_modular.dmi | Bin 0 -> 3124 bytes
.../obj/clothing/haydee_modular_anthro.dmi | Bin 0 -> 2781 bytes
GainStation13/icons/obj/clothing/web.dmi | Bin 0 -> 477 bytes
GainStation13/icons/obj/cursed_fountain.dmi | Bin 0 -> 547 bytes
GainStation13/icons/obj/dreambreaker.dmi | Bin 0 -> 658 bytes
GainStation13/icons/obj/dreambreaker_left.dmi | Bin 0 -> 446 bytes
.../icons/obj/dreambreaker_right.dmi | Bin 0 -> 440 bytes
GainStation13/icons/obj/drinks.dmi | Bin 0 -> 891 bytes
GainStation13/icons/obj/dumbbell.dmi | Bin 0 -> 292 bytes
GainStation13/icons/obj/fatoray.dmi | Bin 0 -> 1703 bytes
GainStation13/icons/obj/feeding_tube.dmi | Bin 0 -> 4291 bytes
GainStation13/icons/obj/food_lefthand.dmi | Bin 0 -> 411 bytes
GainStation13/icons/obj/food_righthand.dmi | Bin 0 -> 403 bytes
GainStation13/icons/obj/full_incense.dmi | Bin 0 -> 438 bytes
GainStation13/icons/obj/gslight.dmi | Bin 0 -> 443 bytes
GainStation13/icons/obj/gum.dmi | Bin 0 -> 471 bytes
GainStation13/icons/obj/guns_lefthand.dmi | Bin 0 -> 337 bytes
GainStation13/icons/obj/guns_righthand.dmi | Bin 0 -> 341 bytes
GainStation13/icons/obj/holosign.dmi | Bin 0 -> 2371 bytes
.../icons/obj/hydroponics/lipo_growing.dmi | Bin 0 -> 981 bytes
.../icons/obj/hydroponics/lipo_harvest.dmi | Bin 0 -> 649 bytes
.../icons/obj/hydroponics/lipo_seeds.dmi | Bin 0 -> 357 bytes
.../obj/lavaland_demone/donutfactory.dmi | Bin 0 -> 574 bytes
GainStation13/icons/obj/library.dmi | Bin 0 -> 574 bytes
GainStation13/icons/obj/magic.dmi | Bin 0 -> 397 bytes
.../icons/obj/mobs/unusualtentical.dmi | Bin 0 -> 886 bytes
GainStation13/icons/obj/paper_cups.dmi | Bin 0 -> 736 bytes
GainStation13/icons/obj/pballoon.dmi | Bin 0 -> 462 bytes
GainStation13/icons/obj/scale.dmi | Bin 0 -> 838 bytes
GainStation13/icons/obj/service_sign.dmi | Bin 0 -> 399 bytes
.../icons/obj/spells/spell_items.dmi | Bin 0 -> 909 bytes
GainStation13/icons/obj/spells/spellbooks.dmi | Bin 0 -> 683 bytes
.../icons/obj/structure/calorite_door.dmi | Bin 0 -> 2319 bytes
GainStation13/icons/obj/structure/statues.dmi | Bin 0 -> 1214 bytes
GainStation13/icons/obj/structure/traps.dmi | Bin 0 -> 765 bytes
GainStation13/icons/obj/vairous_weapons.dm | 2 +
GainStation13/icons/obj/voodooballoon.dmi | Bin 0 -> 437 bytes
GainStation13/icons/turf/64x64.dmi | Bin 0 -> 514 bytes
GainStation13/icons/turf/96x96.dmi | Bin 0 -> 1838 bytes
GainStation13/icons/turf/berry_decal.dmi | Bin 0 -> 2645 bytes
GainStation13/icons/turf/decals_candy.dmi | Bin 0 -> 2887 bytes
.../icons/turf/decals_large_candy.dmi | Bin 0 -> 1091 bytes
GainStation13/icons/turf/floor_candy.dmi | Bin 0 -> 4420 bytes
GainStation13/icons/turf/wall_candy.dmi | Bin 0 -> 755 bytes
GainStation13/icons/turf/walls_candy.dmi | Bin 0 -> 182 bytes
GainStation13/sound/effects/hold_loop.wav | Bin 0 -> 108064 bytes
GainStation13/sound/effects/hoverchair.wav | Bin 0 -> 215920 bytes
GainStation13/sound/voice/belch1.ogg | Bin 0 -> 78086 bytes
GainStation13/sound/voice/belch10.ogg | Bin 0 -> 58669 bytes
GainStation13/sound/voice/belch11.ogg | Bin 0 -> 47168 bytes
GainStation13/sound/voice/belch2.ogg | Bin 0 -> 98497 bytes
GainStation13/sound/voice/belch3.ogg | Bin 0 -> 127368 bytes
GainStation13/sound/voice/belch4.ogg | Bin 0 -> 97054 bytes
GainStation13/sound/voice/belch5.ogg | Bin 0 -> 116964 bytes
GainStation13/sound/voice/belch6.ogg | Bin 0 -> 61703 bytes
GainStation13/sound/voice/belch7.ogg | Bin 0 -> 58445 bytes
GainStation13/sound/voice/belch8.ogg | Bin 0 -> 60654 bytes
GainStation13/sound/voice/belch9.ogg | Bin 0 -> 58438 bytes
GainStation13/sound/voice/brap1.ogg | Bin 0 -> 19929 bytes
GainStation13/sound/voice/brap2.ogg | Bin 0 -> 19030 bytes
GainStation13/sound/voice/brap3.ogg | Bin 0 -> 22812 bytes
GainStation13/sound/voice/brap4.ogg | Bin 0 -> 12632 bytes
GainStation13/sound/voice/brap5.ogg | Bin 0 -> 19765 bytes
GainStation13/sound/voice/brap6.ogg | Bin 0 -> 22103 bytes
GainStation13/sound/voice/brap7.ogg | Bin 0 -> 21472 bytes
GainStation13/sound/voice/brap8.ogg | Bin 0 -> 14004 bytes
GainStation13/sound/voice/burp1.ogg | Bin 0 -> 9564 bytes
GainStation13/sound/voice/emotes/prbt.ogg | Bin 0 -> 8421 bytes
GainStation13/sound/voice/emotes/wawa.ogg | Bin 0 -> 13962 bytes
GainStation13/sound/voice/fart1.ogg | Bin 0 -> 35629 bytes
GainStation13/sound/voice/fart2.ogg | Bin 0 -> 12397 bytes
GainStation13/sound/voice/fart3.ogg | Bin 0 -> 15860 bytes
GainStation13/sound/voice/fart4.ogg | Bin 0 -> 40629 bytes
GainStation13/sound/voice/funnycat.ogg | Bin 0 -> 18592 bytes
GainStation13/sound/voice/gurgle1.ogg | Bin 0 -> 18889 bytes
GainStation13/sound/voice/gurgle2.ogg | Bin 0 -> 26063 bytes
GainStation13/sound/voice/gurgle3.ogg | Bin 0 -> 95938 bytes
.../sound/voice/teppi/cute_rumble.ogg | Bin 0 -> 21929 bytes
GainStation13/sound/voice/teppi/gyooh1.ogg | Bin 0 -> 26022 bytes
GainStation13/sound/voice/teppi/gyooh2.ogg | Bin 0 -> 17025 bytes
GainStation13/sound/voice/teppi/gyooh3.ogg | Bin 0 -> 22678 bytes
GainStation13/sound/voice/teppi/gyooh4.ogg | Bin 0 -> 19969 bytes
GainStation13/sound/voice/teppi/gyooh5.ogg | Bin 0 -> 18894 bytes
GainStation13/sound/voice/teppi/gyooh6.ogg | Bin 0 -> 35554 bytes
GainStation13/sound/voice/teppi/roar.ogg | Bin 0 -> 11763 bytes
GainStation13/sound/voice/teppi/rumble.ogg | Bin 0 -> 15006 bytes
GainStation13/sound/voice/teppi/snoot1.ogg | Bin 0 -> 15978 bytes
GainStation13/sound/voice/teppi/snoot2.ogg | Bin 0 -> 15842 bytes
GainStation13/sound/voice/teppi/whine1.ogg | Bin 0 -> 18450 bytes
GainStation13/sound/voice/teppi/whine2.ogg | Bin 0 -> 29369 bytes
.../sound/voice/teshari/tesharicougha.ogg | Bin 0 -> 55953 bytes
.../sound/voice/teshari/tesharicoughb.ogg | Bin 0 -> 58888 bytes
.../sound/voice/teshari/teshariscream.ogg | Bin 0 -> 10608 bytes
.../sound/voice/teshari/tesharisneeze.ogg | Bin 0 -> 45284 bytes
.../sound/voice/teshari/tesharisneezeb.ogg | Bin 0 -> 31863 bytes
.../sound/voice/teshari/teshchirp.ogg | Bin 0 -> 17707 bytes
.../sound/voice/teshari/teshscream.ogg | Bin 0 -> 10608 bytes
.../sound/voice/teshari/teshsqueak.ogg | Bin 0 -> 8631 bytes
.../sound/voice/teshari/teshtrill.ogg | Bin 0 -> 19292 bytes
GainStation13/sound/voice/voices/human.ogg | Bin 0 -> 4542 bytes
.../sound/voice/voices/human_ask.ogg | Bin 0 -> 4803 bytes
.../sound/voice/voices/human_exclaim.ogg | Bin 0 -> 4718 bytes
GainStation13/sound/voice/voices/lizard.ogg | Bin 0 -> 6718 bytes
.../sound/voice/voices/lizard_ask.ogg | Bin 0 -> 6088 bytes
.../sound/voice/voices/lizard_exclaim.ogg | Bin 0 -> 5312 bytes
GainStation13/sound/voice/voices/roach.ogg | Bin 0 -> 5789 bytes
.../sound/voice/voices/roach_ask.ogg | Bin 0 -> 6497 bytes
.../sound/voice/voices/roach_exclaim.ogg | Bin 0 -> 6575 bytes
code/__DEFINES/misc.dm | 15 +
code/__DEFINES/mobs.dm | 28 +
code/__DEFINES/nanites.dm | 4 +
code/__DEFINES/traits.dm | 33 +
tgstation.dme | 94 +++
232 files changed, 8793 insertions(+)
create mode 100644 GainStation13/code/clothing/accessory.dm
create mode 100644 GainStation13/code/clothing/calorite_collar.dm
create mode 100644 GainStation13/code/clothing/fat_mask.dm
create mode 100644 GainStation13/code/clothing/haydee_suit.dm
create mode 100644 GainStation13/code/clothing/head.dm
create mode 100644 GainStation13/code/clothing/suits.dm
create mode 100644 GainStation13/code/datums/components/fattening_door.dm
create mode 100644 GainStation13/code/datums/diseases/advance/symptoms/berry.dm
create mode 100644 GainStation13/code/datums/mutations/fatfang.dm
create mode 100644 GainStation13/code/datums/mutations/radfat.dm
create mode 100644 GainStation13/code/datums/status_effects/fatstun.dm
create mode 100644 GainStation13/code/game/area/ruins.dm
create mode 100644 GainStation13/code/game/lore_papers.dm
create mode 100644 GainStation13/code/game/objects/effects/spawners/choco_slime_delivery.dm
create mode 100644 GainStation13/code/game/objects/items/RCD.dm
create mode 100644 GainStation13/code/game/objects/items/docility_implant.dm
create mode 100644 GainStation13/code/game/objects/items/storage/bags.dm
create mode 100644 GainStation13/code/game/sound.dm
create mode 100644 GainStation13/code/game/turfs/closed.dm
create mode 100644 GainStation13/code/game/turfs/open.dm
create mode 100644 GainStation13/code/machinery/adipoelectric_generator.dm
create mode 100644 GainStation13/code/machinery/adipoelectric_transformer.dm
create mode 100644 GainStation13/code/machinery/fattening_turret.dm
create mode 100644 GainStation13/code/machinery/feeding_tube.dm
create mode 100644 GainStation13/code/machinery/supply_teleporter.dm
create mode 100644 GainStation13/code/mechanics/den abductors/console.dm
create mode 100644 GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm
create mode 100644 GainStation13/code/mechanics/fatness.dm
create mode 100644 GainStation13/code/mechanics/fatrousal.dm
create mode 100644 GainStation13/code/mechanics/fattening_trap.dm
create mode 100644 GainStation13/code/mechanics/helplessness.dm
create mode 100644 GainStation13/code/mechanics/hunger.dm
create mode 100644 GainStation13/code/mechanics/infestation.dm
create mode 100644 GainStation13/code/mechanics/metal_cruncher.dm
create mode 100644 GainStation13/code/mechanics/permanent_fat.dm
create mode 100644 GainStation13/code/mechanics/spells.dm
create mode 100644 GainStation13/code/mechanics/wand.dm
create mode 100644 GainStation13/code/mechanics/water_sponge.dm
create mode 100644 GainStation13/code/mechanics/web_weaving.dm
create mode 100644 GainStation13/code/mobs/cakegolem.dm
create mode 100644 GainStation13/code/mobs/chocoslime.dm
create mode 100644 GainStation13/code/mobs/races/caloritegolem.dm
create mode 100644 GainStation13/code/mobs/slugcat.dm
create mode 100644 GainStation13/code/mobs/unusualtentical.dm
create mode 100644 GainStation13/code/modules/client/preferences/preferences.dm
create mode 100644 GainStation13/code/modules/clothing/under/jobs/modcivilian.dm
create mode 100644 GainStation13/code/modules/food_and_drinks/drinks.dm
create mode 100644 GainStation13/code/modules/food_and_drinks/food.dm
create mode 100644 GainStation13/code/modules/food_and_drinks/objects/candy_flora.dm
create mode 100644 GainStation13/code/modules/food_and_drinks/recipes/recipes_ported.dm
create mode 100644 GainStation13/code/modules/food_and_drinks/recipes_bigpizza.dm
create mode 100644 GainStation13/code/modules/gym/gym.dm
create mode 100644 GainStation13/code/modules/hydroponics/grown/berries.dm
create mode 100644 GainStation13/code/modules/hydroponics/lipoplant.dm
create mode 100644 GainStation13/code/modules/hydroponics/munchies_weed.dm
create mode 100644 GainStation13/code/modules/mob/living/emote.dm
create mode 100644 GainStation13/code/modules/mob/living/emote_modular.dm
create mode 100644 GainStation13/code/modules/mob/living/emote_ported.dm
create mode 100644 GainStation13/code/modules/mob/living/fullness.dm
create mode 100644 GainStation13/code/modules/mob/living/nutribot.dm
create mode 100644 GainStation13/code/modules/mob/living/species.dm
create mode 100644 GainStation13/code/modules/mob/living/vore/eating/trasheat_lists.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/reagents/consumable_reagents.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/reagents/dwarverndrinks.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/reagents/fatty_drinks.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/reagents/fermi_fat.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/recipes/ROCKANDSTONEdrinks.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/recipes/fatchem.dm
create mode 100644 GainStation13/code/modules/reagents/chemistry/recipes/fatdrinks.dm
create mode 100644 GainStation13/code/modules/reagents/reagent_containers/barrel_tank.dm
create mode 100644 GainStation13/code/modules/research/designs/autolathe.dm
create mode 100644 GainStation13/code/modules/research/designs/nutri_designs.dm
create mode 100644 GainStation13/code/modules/research/nanites/nanite_programs/fattening.dm
create mode 100644 GainStation13/code/modules/research/techweb/nutritech_nodes.dm
create mode 100644 GainStation13/code/modules/surgery/organs/augments.dm
create mode 100644 GainStation13/code/modules/vending/gatocola.dm
create mode 100644 GainStation13/code/modules/vending/mealdor.dm
create mode 100644 GainStation13/code/obj/items/bluespace_belt.dm
create mode 100644 GainStation13/code/obj/items/circuits.dm
create mode 100644 GainStation13/code/obj/items/holy.dm
create mode 100644 GainStation13/code/obj/items/minor_items.dm
create mode 100644 GainStation13/code/obj/items/pride_pins.dm
create mode 100644 GainStation13/code/obj/items/sensors/weight_infared.dm
create mode 100644 GainStation13/code/obj/structure/airlock.dm
create mode 100644 GainStation13/code/obj/structure/calorite_doors.dm
create mode 100644 GainStation13/code/obj/structure/candylight.dm
create mode 100644 GainStation13/code/obj/structure/fountain.dm
create mode 100644 GainStation13/code/obj/structure/gsstatues.dm
create mode 100644 GainStation13/code/obj/structure/scale.dm
create mode 100644 GainStation13/code/obj/weapons/alter_rays.dm
create mode 100644 GainStation13/code/obj/weapons/fatbeam.dm
create mode 100644 GainStation13/code/obj/weapons/fatoray.dm
create mode 100644 GainStation13/code/obj/weapons/feeder_ebow.dm
create mode 100644 GainStation13/code/structures/trapped_items.dm
create mode 100644 GainStation13/icons/mob/AI.dmi
create mode 100644 GainStation13/icons/mob/accessories.dmi
create mode 100644 GainStation13/icons/mob/action_icons.dmi
create mode 100644 GainStation13/icons/mob/blueberry.dmi
create mode 100644 GainStation13/icons/mob/cakegolem.dmi
create mode 100644 GainStation13/icons/mob/candymonster.dmi
create mode 100644 GainStation13/icons/mob/ghoster.dmi
create mode 100644 GainStation13/icons/mob/head.dmi
create mode 100644 GainStation13/icons/mob/modclothes/chefmodular.dmi
create mode 100644 GainStation13/icons/mob/modclothes/gray_bra.dmi
create mode 100644 GainStation13/icons/mob/modclothes/graymodular.dmi
create mode 100644 GainStation13/icons/mob/modclothes/graymodular_bra.dmi
create mode 100644 GainStation13/icons/mob/nutribot.dmi
create mode 100644 GainStation13/icons/mob/pets.dmi
create mode 100644 GainStation13/icons/mob/robots.dmi
create mode 100644 GainStation13/icons/mob/shitass.dmi
create mode 100644 GainStation13/icons/mob/suits.dmi
create mode 100644 GainStation13/icons/mob/uniforms/grey.dmi
create mode 100644 GainStation13/icons/mob/web.dmi
create mode 100644 GainStation13/icons/obj/adipoelectric_transformer.dmi
create mode 100644 GainStation13/icons/obj/barrel_tank.dmi
create mode 100644 GainStation13/icons/obj/berrybush.dmi
create mode 100644 GainStation13/icons/obj/blueberries.dmi
create mode 100644 GainStation13/icons/obj/clothing/bluespace_belt.dmi
create mode 100644 GainStation13/icons/obj/clothing/fat_mask.dmi
create mode 100644 GainStation13/icons/obj/clothing/haydee_modular.dmi
create mode 100644 GainStation13/icons/obj/clothing/haydee_modular_anthro.dmi
create mode 100644 GainStation13/icons/obj/clothing/web.dmi
create mode 100644 GainStation13/icons/obj/cursed_fountain.dmi
create mode 100644 GainStation13/icons/obj/dreambreaker.dmi
create mode 100644 GainStation13/icons/obj/dreambreaker_left.dmi
create mode 100644 GainStation13/icons/obj/dreambreaker_right.dmi
create mode 100644 GainStation13/icons/obj/drinks.dmi
create mode 100644 GainStation13/icons/obj/dumbbell.dmi
create mode 100644 GainStation13/icons/obj/fatoray.dmi
create mode 100644 GainStation13/icons/obj/feeding_tube.dmi
create mode 100644 GainStation13/icons/obj/food_lefthand.dmi
create mode 100644 GainStation13/icons/obj/food_righthand.dmi
create mode 100644 GainStation13/icons/obj/full_incense.dmi
create mode 100644 GainStation13/icons/obj/gslight.dmi
create mode 100644 GainStation13/icons/obj/gum.dmi
create mode 100644 GainStation13/icons/obj/guns_lefthand.dmi
create mode 100644 GainStation13/icons/obj/guns_righthand.dmi
create mode 100644 GainStation13/icons/obj/holosign.dmi
create mode 100644 GainStation13/icons/obj/hydroponics/lipo_growing.dmi
create mode 100644 GainStation13/icons/obj/hydroponics/lipo_harvest.dmi
create mode 100644 GainStation13/icons/obj/hydroponics/lipo_seeds.dmi
create mode 100644 GainStation13/icons/obj/lavaland_demone/donutfactory.dmi
create mode 100644 GainStation13/icons/obj/library.dmi
create mode 100644 GainStation13/icons/obj/magic.dmi
create mode 100644 GainStation13/icons/obj/mobs/unusualtentical.dmi
create mode 100644 GainStation13/icons/obj/paper_cups.dmi
create mode 100644 GainStation13/icons/obj/pballoon.dmi
create mode 100644 GainStation13/icons/obj/scale.dmi
create mode 100644 GainStation13/icons/obj/service_sign.dmi
create mode 100644 GainStation13/icons/obj/spells/spell_items.dmi
create mode 100644 GainStation13/icons/obj/spells/spellbooks.dmi
create mode 100644 GainStation13/icons/obj/structure/calorite_door.dmi
create mode 100644 GainStation13/icons/obj/structure/statues.dmi
create mode 100644 GainStation13/icons/obj/structure/traps.dmi
create mode 100644 GainStation13/icons/obj/vairous_weapons.dm
create mode 100644 GainStation13/icons/obj/voodooballoon.dmi
create mode 100644 GainStation13/icons/turf/64x64.dmi
create mode 100644 GainStation13/icons/turf/96x96.dmi
create mode 100644 GainStation13/icons/turf/berry_decal.dmi
create mode 100644 GainStation13/icons/turf/decals_candy.dmi
create mode 100644 GainStation13/icons/turf/decals_large_candy.dmi
create mode 100644 GainStation13/icons/turf/floor_candy.dmi
create mode 100644 GainStation13/icons/turf/wall_candy.dmi
create mode 100644 GainStation13/icons/turf/walls_candy.dmi
create mode 100644 GainStation13/sound/effects/hold_loop.wav
create mode 100644 GainStation13/sound/effects/hoverchair.wav
create mode 100644 GainStation13/sound/voice/belch1.ogg
create mode 100644 GainStation13/sound/voice/belch10.ogg
create mode 100644 GainStation13/sound/voice/belch11.ogg
create mode 100644 GainStation13/sound/voice/belch2.ogg
create mode 100644 GainStation13/sound/voice/belch3.ogg
create mode 100644 GainStation13/sound/voice/belch4.ogg
create mode 100644 GainStation13/sound/voice/belch5.ogg
create mode 100644 GainStation13/sound/voice/belch6.ogg
create mode 100644 GainStation13/sound/voice/belch7.ogg
create mode 100644 GainStation13/sound/voice/belch8.ogg
create mode 100644 GainStation13/sound/voice/belch9.ogg
create mode 100644 GainStation13/sound/voice/brap1.ogg
create mode 100644 GainStation13/sound/voice/brap2.ogg
create mode 100644 GainStation13/sound/voice/brap3.ogg
create mode 100644 GainStation13/sound/voice/brap4.ogg
create mode 100644 GainStation13/sound/voice/brap5.ogg
create mode 100644 GainStation13/sound/voice/brap6.ogg
create mode 100644 GainStation13/sound/voice/brap7.ogg
create mode 100644 GainStation13/sound/voice/brap8.ogg
create mode 100644 GainStation13/sound/voice/burp1.ogg
create mode 100644 GainStation13/sound/voice/emotes/prbt.ogg
create mode 100644 GainStation13/sound/voice/emotes/wawa.ogg
create mode 100644 GainStation13/sound/voice/fart1.ogg
create mode 100644 GainStation13/sound/voice/fart2.ogg
create mode 100644 GainStation13/sound/voice/fart3.ogg
create mode 100644 GainStation13/sound/voice/fart4.ogg
create mode 100644 GainStation13/sound/voice/funnycat.ogg
create mode 100644 GainStation13/sound/voice/gurgle1.ogg
create mode 100644 GainStation13/sound/voice/gurgle2.ogg
create mode 100644 GainStation13/sound/voice/gurgle3.ogg
create mode 100644 GainStation13/sound/voice/teppi/cute_rumble.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh1.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh2.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh3.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh4.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh5.ogg
create mode 100644 GainStation13/sound/voice/teppi/gyooh6.ogg
create mode 100644 GainStation13/sound/voice/teppi/roar.ogg
create mode 100644 GainStation13/sound/voice/teppi/rumble.ogg
create mode 100644 GainStation13/sound/voice/teppi/snoot1.ogg
create mode 100644 GainStation13/sound/voice/teppi/snoot2.ogg
create mode 100644 GainStation13/sound/voice/teppi/whine1.ogg
create mode 100644 GainStation13/sound/voice/teppi/whine2.ogg
create mode 100644 GainStation13/sound/voice/teshari/tesharicougha.ogg
create mode 100644 GainStation13/sound/voice/teshari/tesharicoughb.ogg
create mode 100644 GainStation13/sound/voice/teshari/teshariscream.ogg
create mode 100644 GainStation13/sound/voice/teshari/tesharisneeze.ogg
create mode 100644 GainStation13/sound/voice/teshari/tesharisneezeb.ogg
create mode 100644 GainStation13/sound/voice/teshari/teshchirp.ogg
create mode 100644 GainStation13/sound/voice/teshari/teshscream.ogg
create mode 100644 GainStation13/sound/voice/teshari/teshsqueak.ogg
create mode 100644 GainStation13/sound/voice/teshari/teshtrill.ogg
create mode 100644 GainStation13/sound/voice/voices/human.ogg
create mode 100644 GainStation13/sound/voice/voices/human_ask.ogg
create mode 100644 GainStation13/sound/voice/voices/human_exclaim.ogg
create mode 100644 GainStation13/sound/voice/voices/lizard.ogg
create mode 100644 GainStation13/sound/voice/voices/lizard_ask.ogg
create mode 100644 GainStation13/sound/voice/voices/lizard_exclaim.ogg
create mode 100644 GainStation13/sound/voice/voices/roach.ogg
create mode 100644 GainStation13/sound/voice/voices/roach_ask.ogg
create mode 100644 GainStation13/sound/voice/voices/roach_exclaim.ogg
diff --git a/GainStation13/code/clothing/accessory.dm b/GainStation13/code/clothing/accessory.dm
new file mode 100644
index 0000000000..d02172d1d7
--- /dev/null
+++ b/GainStation13/code/clothing/accessory.dm
@@ -0,0 +1,16 @@
+/obj/item/clothing/accessory/medal/gato_badge
+ name = "GATO Badge"
+ desc = "You shouldn't see this."
+ icon = 'GainStation13/icons/mob/accessories.dmi'
+ icon_state = "gato_middleman"
+ item_color = "gato" //btw I had to move the sprite for this to 'icons/mob/accessories.dmi', the shitty code made me do it!! GS13 will just have a backup but it's not referenced here
+ above_suit = TRUE
+
+/obj/item/clothing/accessory/medal/gato_badge/middleman
+ name = "GATO Correspondent Badge"
+ desc = "Badge given to GATO employees who work as info relay, middlemen or negotiators between station and Central Command. Commonly given to HR-related positions."
+
+/obj/item/clothing/accessory/medal/gato_badge/employee
+ name = "GATO Employee Badge"
+ desc = "Badge given to certified GATO employees who have a full-time position in GATO Central Command."
+ icon_state = "gato_employee"
diff --git a/GainStation13/code/clothing/calorite_collar.dm b/GainStation13/code/clothing/calorite_collar.dm
new file mode 100644
index 0000000000..b65315d761
--- /dev/null
+++ b/GainStation13/code/clothing/calorite_collar.dm
@@ -0,0 +1,53 @@
+/obj/item/clothing/neck
+ ///How much faster does the wearer gain weight? 1 = 100% faster
+ var/weight_gain_rate_modifier = 0
+
+/obj/item/clothing/neck/equipped(mob/user, slot)
+ . = ..()
+
+ var/mob/living/carbon/wearer = user
+ if(!weight_gain_rate_modifier)
+ return FALSE
+
+ if(!iscarbon(wearer) || slot != SLOT_NECK || !wearer?.client?.prefs?.weight_gain_items)
+ return FALSE
+
+ wearer.weight_gain_rate = wearer.weight_gain_rate * weight_gain_rate_modifier
+
+/obj/item/clothing/neck/dropped(mob/user)
+ . = ..()
+ var/mob/living/carbon/wearer = user
+ if(!weight_gain_rate_modifier)
+ return FALSE
+
+ if(!iscarbon(wearer) || !(wearer.get_item_by_slot(SLOT_NECK) == src) || !wearer?.client?.prefs?.weight_gain_items)
+ return FALSE
+
+ wearer.weight_gain_rate = (wearer.weight_gain_rate / weight_gain_rate_modifier)
+
+
+/obj/item/clothing/neck/petcollar/calorite
+ name = "calorite collar"
+ desc = "A modified pet collar infused with calorite, magnifying the caloric impact of any food the wearer eats"
+ weight_gain_rate_modifier = 1.5
+
+/obj/item/clothing/neck/petcollar/locked/calorite
+ name = "locked calorite collar"
+ desc = "A modified locked collar infused with calorite, magnifying the caloric impact of any food the wearer eats"
+ weight_gain_rate_modifier = 1.5
+
+/datum/crafting_recipe/calorite_collar
+ name = "Calorite Collar"
+ result = /obj/item/clothing/neck/petcollar/calorite
+ time = 25
+ reqs = list(/obj/item/clothing/neck/petcollar = 1,
+ /obj/item/stack/sheet/mineral/calorite = 3)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/locked_calorite_collar
+ name = "Locked Calorite Collar"
+ result = /obj/item/clothing/neck/petcollar/locked/calorite
+ time = 25
+ reqs = list(/obj/item/clothing/neck/petcollar/locked = 1,
+ /obj/item/stack/sheet/mineral/calorite = 3)
+ category = CAT_CLOTHING
diff --git a/GainStation13/code/clothing/fat_mask.dm b/GainStation13/code/clothing/fat_mask.dm
new file mode 100644
index 0000000000..db8091cab4
--- /dev/null
+++ b/GainStation13/code/clothing/fat_mask.dm
@@ -0,0 +1,29 @@
+/obj/item/clothing/mask/gas/fattening
+ name = "drone mask"
+ desc = "A mask that can be connected to an air supply. When seen from certain angles, an orange light is reflected by it."
+ icon = 'GainStation13/icons/obj/clothing/fat_mask.dmi'
+ icon_state = "fat_mask"
+ item_state = "fat_mask"
+ var/mob/living/carbon/C
+
+/obj/item/clothing/mask/gas/fattening/equipped(mob/M, slot)
+ . = ..()
+ if (slot == SLOT_WEAR_MASK)
+ if(iscarbon(M))
+ C = M
+ START_PROCESSING(SSobj, src)
+ else
+ C = null
+ return PROCESS_KILL
+
+/obj/item/clothing/mask/gas/fattening/process()
+ if(C != null)
+ C.adjust_fatness(5, FATTENING_TYPE_ITEM)
+ else
+ return PROCESS_KILL
+
+/datum/crafting_recipe/fat_mask
+ name = "Drone Mask"
+ result = /obj/item/clothing/mask/gas/fattening
+ reqs = list(/obj/item/stack/sheet/mineral/calorite = 1, /obj/item/clothing/mask/gas = 1)
+ category = CAT_CLOTHING
diff --git a/GainStation13/code/clothing/haydee_suit.dm b/GainStation13/code/clothing/haydee_suit.dm
new file mode 100644
index 0000000000..4df8e9c44c
--- /dev/null
+++ b/GainStation13/code/clothing/haydee_suit.dm
@@ -0,0 +1,68 @@
+/obj/item/clothing/head/helmet/space/hardsuit/engine/haydee
+ name = "Haydee Helmet"
+ desc = "A strange helmet. Offers little to no protection."
+ icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ alternate_worn_icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ icon_state = "haydee_helmet"
+ item_state = "item_haydee_helmet"
+ armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 25, "fire" = 25, "acid" = 25)
+ item_color = "white"
+ slowdown = 0
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+ actions_types = list()
+
+/obj/item/clothing/suit/space/hardsuit/engine/haydee
+ name = "Haydee Suit"
+ desc = "A strangely voluptous suit. Offers little to no protection. It also appears to have minor flab-compressing properties."
+ icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ alternate_worn_icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ icon_state = "haydee_suit1"
+ item_state = "item_haydee"
+ armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 0, "rad" = 25, "fire" = 25, "acid" = 25)
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals)
+ actions_types = list(/datum/action/item_action/toggle_helmet)
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/haydee
+ slowdown = 0
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+ var/icon_location = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ var/mob/living/carbon/U
+
+//haydee gun
+/obj/item/gun/ballistic/automatic/pistol/haydee
+ name = "Simplistic Pistol"
+ desc = "10mm handgun. It seems to be clad in overly simplistic white shell."
+ icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ icon_state = "pistol"
+ can_suppress = FALSE
+
+/obj/item/gun/ballistic/automatic/toy/pistol/haydee
+ name = "Simplistic Toy Pistol"
+ desc = "A small, easily concealable toy handgun."
+ icon = 'GainStation13/icons/obj/clothing/haydee_modular.dmi'
+ icon_state = "pistol"
+
+
+/obj/item/clothing/suit/space/hardsuit/engine/haydee/equipped(mob/user, slot) //whenever the clothes are in someone's inventory the clothes keep track of who that user is
+ ..()
+ U = user
+
+/obj/item/clothing/suit/space/hardsuit/engine/haydee/dropped() //whenever the clothes leave a person's inventory, they forget who held them
+ ..()
+ U = null
+
+/obj/item/clothing/suit/space/hardsuit/engine/haydee/worn_overlays(isinhands = FALSE)
+ if(U)
+ if(!isinhands)
+ . = list()
+ if(U.fatness <= 439)
+ . += mutable_appearance(icon_location, "haydee_suit1", GENITALS_UNDER_LAYER)
+ if(U.fatness >= 440)
+ . += mutable_appearance(icon_location, "haydee_suit2", GENITALS_UNDER_LAYER)
+ if(U.fatness >= 1240)
+ . += mutable_appearance(icon_location, "haydee_suit3", GENITALS_UNDER_LAYER)
+ if(U.fatness >= 3440)
+ . += mutable_appearance(icon_location, "haydee_suit4", GENITALS_UNDER_LAYER)
+ if(damaged_clothes)
+ . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
diff --git a/GainStation13/code/clothing/head.dm b/GainStation13/code/clothing/head.dm
new file mode 100644
index 0000000000..49e448fa0d
--- /dev/null
+++ b/GainStation13/code/clothing/head.dm
@@ -0,0 +1,28 @@
+//most of those are probably recolors, but this is just generally GATO / GS13 stuff
+
+/obj/item/clothing/head/helmet/space/hardsuit/ert/alert/gato
+ name = "GATO Hardsuit Helmet"
+ desc = "Exclusive version of a hardsuit helmet, usually reserved for GATO CC personnel."
+ icon = 'GainStation13/icons/mob/head.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/head.dmi'
+ icon_state = "hardsuit0-gato"
+ item_state = "hardsuit0-gato"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/head/HoS/beret/gato
+ name = "GT-CC Beret"
+ desc = "A robust beret for the CC personnel, for looking stylish while not sacrificing protection."
+ icon = 'GainStation13/icons/mob/head.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/head.dmi'
+ icon_state = "gato_beret"
+ item_state = "gato_beret"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/head/HoS/gato
+ name = "GT-CC Cap"
+ desc = "The robust standard-issue cap of the CC personnel."
+ icon = 'GainStation13/icons/mob/head.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/head.dmi'
+ icon_state = "gato_cap"
+ item_state = "gato_cap"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
diff --git a/GainStation13/code/clothing/suits.dm b/GainStation13/code/clothing/suits.dm
new file mode 100644
index 0000000000..24b14ff6c4
--- /dev/null
+++ b/GainStation13/code/clothing/suits.dm
@@ -0,0 +1,66 @@
+//most of those are probably recolors, but this is just generally GATO / GS13 stuff
+
+
+/obj/item/clothing/suit/jacket/letterman_gato
+ name = "GATO letterman jacket"
+ desc = "A GATO themed letterman jacket. Perfect for repping your pride in the company as you violently murder russian mobsters"
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "letterman_gato"
+ item_state = "letterman_gato"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/armor/vest/capcarapace/cc
+ name = "Elegant Carapace"
+ desc = "A fireproof armored chestpiece reinforced with ceramic plates and plasteel pauldrons to provide additional protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest, although it does chafe your nipples."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "cc_carapace"
+ item_state = "cc_carapace"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/armor/vest/capcarapace/gato
+ name = "CC-GT Carapace"
+ desc = "A fireproof armored chestpiece reinforced with ceramic plates and plasteel pauldrons to provide additional protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest, although it does chafe your nipples."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "gato_carapace"
+ item_state = "gato_carapace"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/armor/vest/capcarapace/moka
+ name = "Hellcat Overcoat"
+ desc = "Badass. Seems to be specifically made for some CentComm Commander."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "hellcat_overcoat"
+ item_state = "hellcat_overcoat"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/armor/vest/capcarapace/paradeblack
+ name = "CC Parade Jacket"
+ desc = "This elegant and highly protective parade jacket seems to have been made into color purple."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "paradejacket_black"
+ item_state = "paradejacket_black"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/armor/vest/capcarapace/paradepurple
+ name = "CC Parade Jacket"
+ desc = "This elegant and highly protective parade jacket seems to have been made into color purple."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "paradejacket_purple"
+ item_state = "paradejacket_purple"
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/space/hardsuit/ert/alert/gato
+ name = "GATO Hardsuit"
+ desc = "Exclusive variant of a hardsuit, primarily reserved for CC GATO personnel."
+ icon = 'GainStation13/icons/mob/suits.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/suits.dmi'
+ icon_state = "gato_hardsuit"
+ item_state = "gato_hardsuit"
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert/gato
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
diff --git a/GainStation13/code/datums/components/fattening_door.dm b/GainStation13/code/datums/components/fattening_door.dm
new file mode 100644
index 0000000000..00690ae749
--- /dev/null
+++ b/GainStation13/code/datums/components/fattening_door.dm
@@ -0,0 +1,44 @@
+/datum/component/fattening_door
+ var/fatten = FALSE // whether player will be fattened
+ var/fat_to_add = 2 // fatness per tick stunned
+
+/datum/component/fattening_door/Initialize()
+ if(!istype(parent, /obj/structure/mineral_door)) // if the attached object isn't a door, return incompatible!
+ return COMPONENT_INCOMPATIBLE
+
+ RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED),PROC_REF(Fatten))
+
+/datum/component/fattening_door/proc/Fatten() //GS13
+ var/stuck_delay = 0
+ var/turf/T = get_turf(parent)
+
+ for(var/mob/living/carbon/M in T)
+ var/vis_message_self = ""
+ var/vis_message_others = ""
+ // determine if mob should get stuck and be fattened
+ if(M.fatness >= FATNESS_LEVEL_FAT)
+ if(!M.AmountFatStunned())
+ fatten = TRUE
+ stuck_delay = 5
+ vis_message_self = "You feel your sides briefly brush against the doorway!"
+ vis_message_others = "[M]'s sides briefly brush against the doorway."
+
+ // Scales depending on this switch.
+ switch(M.fatness)
+ if(FATNESS_LEVEL_BARELYMOBILE to INFINITY)
+ stuck_delay = 120
+ vis_message_self = "You feel yourself get stuck in the doorway!"
+ vis_message_others = "[M] gets stuck in the doorway!"
+ if((FATNESS_LEVEL_FATTER+1) to FATNESS_LEVEL_MORBIDLY_OBESE)
+ stuck_delay = 50
+ vis_message_self ="You feel your sides barely squeeze through the doorway!"
+ vis_message_others = "[M] barely squeezes through the doorway!"
+ if((FATNESS_LEVEL_FAT+1) to FATNESS_LEVEL_FATTER)
+ stuck_delay = 15
+ vis_message_self = "You feel your sides smush against the doorway!."
+ vis_message_others = "[M]'s sides briefly smush against the doorway."
+
+ // Apply the fatstun
+ if(fatten)
+ M.visible_message("[vis_message_others]", "[vis_message_self]")
+ M.FatStun(stuck_delay, fatAmount = fat_to_add) // DOOR STUCK
diff --git a/GainStation13/code/datums/diseases/advance/symptoms/berry.dm b/GainStation13/code/datums/diseases/advance/symptoms/berry.dm
new file mode 100644
index 0000000000..21e6e9c8af
--- /dev/null
+++ b/GainStation13/code/datums/diseases/advance/symptoms/berry.dm
@@ -0,0 +1,71 @@
+/datum/symptom/berry
+ name = "Berrification"
+ desc = "The virus causes the host's biology to overflow with a blue substance. Infection ends if the substance is completely removed from their body, besides ordinary cures."
+ stealth = -5
+ resistance = -4
+ stage_speed = 1
+ transmittable = 6
+ level = 7
+ severity = 5
+ base_message_chance = 100
+ symptom_delay_min = 15
+ symptom_delay_max = 45
+ threshold_desc = list(
+ "Stage Speed" = "Increases the rate of liquid production.",
+ )
+ var/datum/reagent/infection_reagent = /datum/reagent/blueberry_juice
+
+/datum/symptom/berry/Start(datum/disease/advance/A)
+ if(!..())
+ return
+ if(A.affected_mob?.client?.prefs?.blueberry_inflation)
+ A.affected_mob.reagents.add_reagent(infection_reagent, max(1, A.totalStageSpeed()) * 10)
+ ..()
+
+/datum/symptom/berry/Activate(datum/disease/advance/A)
+ if(!..())
+ return
+ var/mob/living/carbon/M = A.affected_mob
+ if(!(M?.client?.prefs?.blueberry_inflation))
+ return
+ if(M.reagents.get_reagent_amount(infection_reagent) <= 0)
+ A.remove_disease()
+ switch(A.stage)
+ if(1, 2, 3, 4)
+ if(prob(base_message_chance))
+ to_chat(M, "[pick("You feel oddly full...", "Your stomach churns...", "You hear a gurgle...", "You taste berries...")]")
+ else
+ to_chat(M, "[pick("A deep slosh comes from inside you...", "Your mind feels light...", "You think blue really suits you...", "Your skin feels so tight...")]")
+ M.reagents.add_reagent(infection_reagent, max(A.totalStageSpeed(), 1))
+
+/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
+ if(M.reagents.get_reagent_amount(/datum/reagent/blueberry_juice) > 0 && (reagents.total_volume + min(amount_per_transfer_from_this, 10)) <= volume)
+ reagents.add_reagent(/datum/reagent/blueberry_juice, min(10, amount_per_transfer_from_this))
+ M.reagents.remove_reagent(/datum/reagent/blueberry_juice, min(10, amount_per_transfer_from_this))
+ if(M != user)
+ to_chat(user, "You juice [M.name]...")
+ to_chat(M, "[user.name] juices you...")
+ else
+ to_chat(user, "You get some juice out of you...")
+ if(prob(5))
+ new /obj/effect/decal/cleanable/juice(M.loc)
+ playsound(M.loc, 'sound/effects/splat.ogg',rand(10,50), 1)
+ return
+ ..()
+
+/obj/effect/decal/cleanable/juice
+ name = "berry juice"
+ desc = "It's blue and smells enticingly sweet."
+ icon = 'GainStation13/icons/turf/berry_decal.dmi'
+ icon_state = "floor1"
+ random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
+ blood_state = BLOOD_STATE_JUICE
+ bloodiness = BLOOD_AMOUNT_PER_DECAL
+
+/obj/effect/decal/cleanable/juice/Initialize(mapload)
+ . = ..()
+ reagents.add_reagent(/datum/reagent/blueberry_juice = 5)
+
+/obj/effect/decal/cleanable/juice/streak
+ random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
+
diff --git a/GainStation13/code/datums/mutations/fatfang.dm b/GainStation13/code/datums/mutations/fatfang.dm
new file mode 100644
index 0000000000..718345c110
--- /dev/null
+++ b/GainStation13/code/datums/mutations/fatfang.dm
@@ -0,0 +1,63 @@
+/datum/mutation/human/fatfang
+ name = "The Nibble"
+ desc = "A rare mutation that grows a pair of fangs in the user's mouth that inject a chemical that develops the target's adipose tissue."
+ quality = POSITIVE
+ text_gain_indication = "You feel something growing in your mouth!"
+ text_lose_indication = "You feel your fangs shrink away."
+ difficulty = 8
+ power = /obj/effect/proc_holder/spell/targeted/touch/fatfang
+ instability = 10
+ energy_coeff = 1
+ power_coeff = 1
+ ///Which chem is added (lipo default) and how much?
+ var/chem_to_add = /datum/reagent/consumable/lipoifier
+ var/chem_amount = 5
+
+/obj/effect/proc_holder/spell/targeted/touch/fatfang
+ name = "The Nibble"
+ desc = "Draw out fangs that inject fattening venom"
+ drawmessage = "You draw out your fangs."
+ dropmessage = "You retract your fangs."
+ hand_path = /obj/item/melee/touch_attack/fatfang
+ action_icon = 'icons/mob/actions/bloodsucker.dmi'
+ action_icon_state = "power_feed"
+ charge_max = 50
+ clothes_req = FALSE
+
+/obj/item/melee/touch_attack/fatfang
+ name = "\improper fattening fangs"
+ desc = "Fangs armed with a venom most ample."
+ catchphrase = null
+ icon = 'icons/mob/actions/bloodsucker.dmi'
+ icon_state = "power_feed"
+
+ var/starttime = 0
+
+/obj/item/melee/touch_attack/fatfang/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || !iscarbon(target))
+ return FALSE
+
+ if(!target || !user.dna.get_mutation(FATFANG).chem_to_add || !user.dna.get_mutation(FATFANG).chem_amount)
+ return FALSE
+ target.visible_message("[user] nibbles [target]!","[user] nibbles you!")
+ if(target == user.pulling && ishuman(user.pulling))
+ starttime = world.time
+ user.dna.get_mutation(FATFANG).power.charge_max = 600 * GET_MUTATION_ENERGY(user.dna.get_mutation(FATFANG))
+ while(starttime + 300 > world.time && in_range(user, target))
+ if(do_mob(user, target, 10, 0, 1))
+ target.reagents.add_reagent(user.dna.get_mutation(FATFANG).chem_to_add, (user.dna.get_mutation(FATFANG).chem_amount * GET_MUTATION_POWER(user.dna.get_mutation(FATFANG))/2))
+ target.visible_message("[user] pumps some venom in [target]!","[user] pumps some venom in you!")
+ else
+ user.dna.get_mutation(FATFANG).power.charge_max = 50 * GET_MUTATION_ENERGY(user.dna.get_mutation(FATFANG))
+ target.reagents.add_reagent(user.dna.get_mutation(FATFANG).chem_to_add, user.dna.get_mutation(FATFANG).chem_amount * GET_MUTATION_POWER(user.dna.get_mutation(FATFANG)))
+ user.changeNext_move(50)
+
+/obj/item/dnainjector/antifang
+ name = "\improper DNA injector (Anti-The Nibble)"
+ desc = "By the power of sugar, their fangs shall fall."
+ remove_mutations = list(FATFANG)
+
+/obj/item/dnainjector/fatfang
+ name = "\improper DNA injector (The Nibble)"
+ desc = "Give 'em just a teeny tiny bite."
+ add_mutations = list(FATFANG)
diff --git a/GainStation13/code/datums/mutations/radfat.dm b/GainStation13/code/datums/mutations/radfat.dm
new file mode 100644
index 0000000000..f66a93e883
--- /dev/null
+++ b/GainStation13/code/datums/mutations/radfat.dm
@@ -0,0 +1,42 @@
+/datum/mutation/human/radfat
+ name = "Radiotrophic Metabolism"
+ desc = "A mutation that causes the user to be immune to the adverse effects of radiations, but causes sudden cell multiplication with increased strength under irradiation."
+ quality = POSITIVE
+ text_gain_indication = "You crave the taste of... radiation?"
+ text_lose_indication = "You no longer desire the taste of radiation..."
+ difficulty = 14
+ instability = 30
+ power_coeff = 1
+
+ var/FATCAP = 100
+
+/datum/mutation/human/radfat/on_life()
+ . = ..()
+ var/fat_add = 1
+ var/pwr = GET_MUTATION_POWER(src)
+ if(owner.radiation > 0)
+ fat_add += round(owner.radiation * (0.10 * pwr))
+ owner.radiation -= round(owner.radiation * 0.05) + 1
+ if(fat_add > (FATCAP * pwr))
+ fat_add = (FATCAP * pwr)
+ owner.adjust_fatness(fat_add, FATTENING_TYPE_RADIATIONS)
+
+/datum/mutation/human/radfat/on_acquiring(mob/living/carbon/human/owner)
+ if(..())
+ return
+ ADD_TRAIT(owner, TRAIT_RADRESONANCE, src)
+
+/datum/mutation/human/radfat/on_losing(mob/living/carbon/human/owner)
+ if(..())
+ return
+ REMOVE_TRAIT(owner, TRAIT_RADRESONANCE, src)
+
+/obj/item/dnainjector/antiradfat
+ name = "\improper DNA injector (Anti-Radiotrophic Metabolism)"
+ desc = "The green kills."
+ remove_mutations = list(RADFAT)
+
+/obj/item/dnainjector/radfat
+ name = "\improper DNA injector (Radiotrophic Metabolism)"
+ desc = "Nuclear fallout protection at an heavy price."
+ add_mutations = list(RADFAT)
diff --git a/GainStation13/code/datums/status_effects/fatstun.dm b/GainStation13/code/datums/status_effects/fatstun.dm
new file mode 100644
index 0000000000..51ee3f269c
--- /dev/null
+++ b/GainStation13/code/datums/status_effects/fatstun.dm
@@ -0,0 +1,64 @@
+// Cba making a define file just for status effects so all the helper stuff goes here!~
+#define STATUS_EFFECT_FATSTUN /datum/status_effect/incapacitating/stun/fat //the affected is knocked down
+
+////
+// Makes it so player is stunned and while stunned, fatness level grows.
+////
+/datum/status_effect/incapacitating/stun/fat
+ var/fatAmount = 1
+
+/datum/status_effect/incapacitating/stun/fat/on_creation(mob/living/new_owner, set_duration, updating_canmove, fatnessAmount)
+ fatAmount = fatnessAmount
+ ..()
+
+/datum/status_effect/incapacitating/stun/fat/tick()
+ var/mob/living/carbon/C = owner
+ if(C)
+ C.adjust_fatness(fatAmount, FATTENING_TYPE_ITEM) // simply adds/removes the fat overtime.
+ // to_chat(owner, "You feel larger...") // debugging to see if the stun works.
+
+////
+// Helpers so it applies to the mob. (I cannot be bothered making a new file for this AUGH)
+////
+/mob/proc/IsFatStunned() //non-living mobs shouldn't be stunned
+ return FALSE
+
+/mob/living/IsFatStunned() //If we're knocked down
+ return has_status_effect(STATUS_EFFECT_FATSTUN)
+
+/mob/living/proc/AmountFatStunned() //How many deciseconds remain in our knockdown
+ var/datum/status_effect/incapacitating/stun/fat/F = IsFatStunned()
+ if(F)
+ return F.duration - world.time
+ return FALSE
+
+/mob/living/proc/FatStun(amount, updating = TRUE, ignore_canstun = FALSE, fatAmount)
+ if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/fat/F = IsFatStunned()
+ if(F)
+ F.duration = max(world.time + amount, F.duration)
+ else if(amount > 0)
+ F = apply_status_effect(STATUS_EFFECT_FATSTUN, amount, updating, fatAmount)
+ return F
+
+/mob/living/proc/SetFatStun(amount, updating = TRUE, ignore_canstun = FALSE) //Sets remaining duration
+ if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/fat/F = IsFatStunned()
+ if(amount <= 0)
+ if(F)
+ qdel(F)
+ else
+ if(F)
+ F.duration = world.time + amount
+ else
+ F = apply_status_effect(STATUS_EFFECT_FATSTUN, amount, updating)
+ return F
+
+/mob/living/proc/AdjustFatStun(amount, updating = TRUE, ignore_canstun = FALSE) //Adds to remaining duration
+ if(((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) || ignore_canstun)
+ var/datum/status_effect/incapacitating/stun/fat/F = IsFatStunned()
+ if(F)
+ F.duration += amount
+ else if(amount > 0)
+ F = apply_status_effect(STATUS_EFFECT_FATSTUN, amount, updating)
+ return F
diff --git a/GainStation13/code/game/area/ruins.dm b/GainStation13/code/game/area/ruins.dm
new file mode 100644
index 0000000000..8c92b14fcf
--- /dev/null
+++ b/GainStation13/code/game/area/ruins.dm
@@ -0,0 +1,38 @@
+//Stuff for the quantum hub
+/area/ruin/space/has_grav/powered/quantum_hub
+ name = "Quantum Pad Hub"
+ icon_state = "purple"
+
+/obj/item/storage/box/quantum_pad_parts
+ name = "box of quantum pad parts"
+ desc = "Contains a all the parts you'd need to make a quantum pad."
+ icon_state = "syndiebox"
+
+/obj/item/storage/box/quantum_pad_parts/PopulateContents()
+ new /obj/item/circuitboard/machine/quantumpad(src)
+ new /obj/item/stack/ore/bluespace_crystal(src)
+ new /obj/item/stock_parts/capacitor/quadratic(src)
+ new /obj/item/stock_parts/manipulator/femto(src)
+ new /obj/item/stack/cable_coil(src, 15)
+ new /obj/item/stack/sheet/metal/twenty(src)
+
+/area/ruin/unpowered/caloriteshrine
+ name = "Calorite Shrine"
+ icon_state = "away"
+
+/area/ruin/powered/snackstore
+ name = "Snack Store"
+ icon_state = "away"
+
+/area/ruin/powered/candyland/inside
+ name = "Candy Land"
+ icon_state = "away"
+
+/area/ruin/powered/candyland/outside
+ name = "Candy Land"
+ icon_state = "away"
+ dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
+
+/area/ruin/powered/candycaveLower/inside
+ name = "Candy Cave"
+ icon_state = "away"
diff --git a/GainStation13/code/game/lore_papers.dm b/GainStation13/code/game/lore_papers.dm
new file mode 100644
index 0000000000..2c8d6b9807
--- /dev/null
+++ b/GainStation13/code/game/lore_papers.dm
@@ -0,0 +1,547 @@
+//////// feeder den, GS13
+
+/obj/item/paper/fluff/ruins/feeder_den/hidden
+ name = "hastily scribbled note"
+ info = "It took so long for me to make this hideout, but it might all be in vain. In the short breaks when I'm not observed, I'm trying to fix this radio I managed to sneak by... but judging by how I can barely squeeze my ass past this stupid hole less and less each day, I might not fix it in time..."
+
+/obj/item/paper/fluff/ruins/feeder_den/report1
+ name = "Captive report No 1"
+ info = "We've managed to obtain two captives - one woman, and one lizard. They seem promising so far... already quite chunky and eager to scarf down whatever we give them. It might be even easier to turn them into proper beds once we're past the chemical treatment."
+
+/obj/item/paper/fluff/ruins/feeder_den/report2
+ name = "Captive report No 2"
+ info = "The woman seems to be showing great progress, we'll be moving her into the larger cell soon. The lizard guy is still a bit reluctant about eating himself into immobility... but no matter, we'll just double his portions. Perhaps a painfully overstuffed stomach will change his mind."
+
+/obj/item/paper/fluff/ruins/feeder_den/report3
+ name = "Captive report No 3"
+ info = "We've captured another one! A curious space explorer, snooping around near our entrance. Fierce bastard, even managed to cut my arm open! A short treatment of a room full of lipoifier smoke ensured that they won't be able to fit back into their hardsuit."
+
+/obj/item/paper/fluff/ruins/feeder_den/report4
+ name = "Captive report No 4"
+ info = "(the page seems to be full of food stains, making the writing unreadable.)"
+
+/obj/item/paper/fluff/ruins/feeder_den/augment_note
+ name = "READ ME!"
+ info = "Don't use this auto-surgeon on yourself, dumbass!"
+
+/obj/item/paper/fluff/ruins/feeder_den/tool_warning
+ name = "READ ME BEFORE USING!"
+ info = "For those interested in grabbing more victims, make sure to read this first
\n\n\
+ OOC: Your goal here is to capture people to fatten up. Avoid intentionally killing and causing chaos on the station if you can at all help it.
\
+ Before capturing someone, be sure to check their preferences and make sure that they are not already occupied. A discord message or LOOC never hurts if you aren't sure. OOC communication is very important.
\
+ You have the power to send people back to the station, make sure that you talk with them before sending them back. Especially if they are someone that wasn't on the station in the first place, like a Den Victim. \
+
\
+ It is heavily advised that you find a target before you teleport onto the station as some crew members are not good canidates.
\
+ With the camera console you have access to the entire camera network of the station, use this to your advantage to formulate a plan. \
+
\
+ Right before heading onto the station, make sure that you grab a science tool and sync it with the feeder console. \
+ Syncing it will allow you to beam both yourself and captives back to the den. \
+ To do this, mark the person you want to mark by touching them with the tool. Once someone is marked you can use the tool on them again to beam them up.
\
+ Additionally, if you have someone to help you, they can beam up anyone that is marked, by using the camera console.\
+
\
+ Credits can be gained by having someone you fattened up use the tracking scale. Keep in mind that credits can only be gained when someone surpasses their previous max weight.\
+ Additionally, you are only able to get 900 credits from a person.\
+
\
+ You are able to use the console and pad to send victims back to the station after you are done with them. Avoid sending them anywhere dangerous or obvious unless you want to risk the ire of GATO. "
+
+// calorite research facility
+
+/obj/item/paper/fluff/ruins/calorite_facility/note1
+ name = "Research Department - Report #1"
+ info = "The facility appears to be ready for usage. We've already imported a couple willing subjects, currently waiting in their designated areas. The testing shall begin according to the schedule."
+
+/obj/item/paper/fluff/ruins/calorite_facility/note4
+ name = "Research Department - Report #4"
+ info = "I'm aware of the fact that we're pioneers in this field of science, but this facility seems a little... oddly designed? In the next designs or iterations, instruct the architects to provide larger, more secluded labs. Why do we even need those three conveyor belts?"
+
+/obj/item/paper/fluff/ruins/calorite_facility/note18
+ name = "Research Department - Report #18"
+ info = "The research is going excellently, though the miners have reported strange figures seemingly observing them within the mining shafts. I've suggested that it's just fauna, but they insist that it's unlike anything they've ever seen before... and yet they can never describe those things. Just to keep morale high, please send more security supplies."
+
+/obj/item/paper/fluff/ruins/calorite_facility/note37
+ name = "Research Department - Report #37"
+ info = "I'm not sure who I'm writing this paper for. The connection with HQ has been severed days ago and since then, half of our personnel has gone missing. I swear someone's sabotaging this fucking place too... Until someone fixes the telecomms relay, I'll probably hide myself in the medbay. Seems like the safest place."
+
+/obj/item/paper/fluff/ruins/calorite_facility/security_note
+ name = "Scribbled note"
+ info = "Funny work so far, but admittedly pretty easy. I'm only supposed to not touch the orange junk and rally up some lardasses and-- let's be real, how much harm can someone like that do?"
+
+/obj/item/paper/fluff/ruins/calorite_facility/engineer_note
+ name = "Oil-stained note"
+ info = "Please tell those fucking deadbrained amoebas at HQ that a full facility needs a PROPER engine, not a bunch of fucking PACMANs. Even a damned SM shard would suffice..."
+
+/obj/item/paper/fluff/ruins/calorite_facility/charred
+ name = "Charred note"
+ info = "They've g-- -all, -- s--en. Cloak-d fig----, ---...(the rest of the note seems unreadable)"
+
+//GS13 Datapads and Books
+/obj/item/book/manual/blubbery_bartender
+ name = "The Blubbery Bartender"
+ icon = 'GainStation13/icons/obj/library.dmi'
+ icon_state ="bookblubberybartender"
+ author = "Anonymous" // Whoever wrote the paper or book, can be changed by pen or PC. It is not automatically assigned.
+ title = "The Blubbery Bartender"
+ //book contents below
+ dat = {"
+
+
+
+
+ Drinks for Growing Guts
+
+ Been a bartender for Gato quite a while now. In my time here, I've taken notice of how certain mixes produced...
+ Certain effects, that the same mixtures don't produce elsewhere. I'm writing down my findings here.
+
+
+ - Belly Bloats: equal parts gibb floats and beer. Really bulks up a belly. Some folks got real bloated with air after drinking this one.
+ - Blobby Mary: equal parts tomato juice, vodka and lipoifier. If you want to get back at some rich folks, this is your drink.
+ - Heavy Cafe: equal parts latte, either cafe or soy, sugar and cream. One hell of a bomb to start a shift with.
+ - Fruits Tea: equal parts berry juice, lemon juice and tea. Even teetotal folks aren't safe from growing. Some folks become... Real sloshy. Note: I once mixed it with blueberry juice from a vendor. Be ready to juice if you do too.
+ - Snakebite: equal parts toxins, lime juice and lipoifier. Feels like a snake biting your throat when it goes down. Sure "paralyzes" like some real snake bites.
+ - Beltbuster Mead: equal parts mead, ethanol, cream and lipoifier. Very alcoholic and immensely fattening. Clothes won't hold after this one.
+
+
+ Remember, this stuff is quite something. Don't serve these to folks that don't want it.
+
+
+
+ "}
+
+/obj/item/book/manual/fatty_chems
+ name = "The Strange Chems of GATO's Sector"
+ icon = 'GainStation13/icons/obj/library.dmi'
+ icon_state ="bookblubberybartender"
+ author = "Unknown"
+ title = "The Strange Chems of GATO's Sector"
+ //book contents below
+ dat = {"
+
+
+
+
+ The Strange Chems of GATO-Controlled Sectors
+
+ Peculiar reactions not found anywhere else taken within the sector of GATO's control, especially within the station of GS13.
+ To ensure that the knowledge isn't lost to time, I've decided some of the simpler reactions here.
+
+
+ - Lipoifier: The opposite of Lipolicide. Seems to multiply fat cells in one's body. Equal parts corn oil, sugar and synthflesh.
+ - Fizulphite: Seems to stir up a strange reaction in stomachs, making them all bubbly. 1u of nitrogen, 1u sugar and 3u of oxygen.
+ - Extilphite: Very useful chem! Helps soothe stomach bloat and relieves fullness. 1u sugar, 2u hydrogen, 2u carbon.
+ - Flatulose: This chemical is similar to Fizulphite, but results in uncontrolled release of rear gasses. 1u sugar, 1u of Bad Food, 1u of Cream.
+
+
+ Remember to be responsible with those chems. They aren't lethal or toxic, but they can be undesired by locals.
+
+
+
+ "}
+
+
+//fastfood
+/obj/item/paper/fluff/ruins/fastfood/general_info
+ name = "Welcome to GATO!"
+ info = "We are glad to have you be a part of our galaxy-wide GATO franchise locations! As a restaurant worker / manager, you are a part of the GATO Corp and for security purposes, you may be treated as a part of the General Station 13's crew. Make sure to keep your restaurant clean and well-stocked. Good luck!"
+
+
+//space law - we still keep the old updated version, but might as well use this one too
+
+/obj/item/book/manual/gato_spacelaw
+ name = "GATO Space Law"
+ desc = "A set of GATO-Station guidelines for keeping law and order on their space stations."
+ icon_state = "bookSpaceLaw"
+ author = "GATO PMC"
+ title = "Space Law"
+ dat = {"
+
+
+
+
+ The Strange Chems of GATO-Controlled Sectors
+
+
+ GATO Corp Guide to Station Laws
+
+ OOC: (Remember use everything in this document to try and create or enhance possible roleplay scenarios and how characters can be roleplayed in relation to respect, or lack thereof, of laws. If you believe it is instead taking away from a scenario, talk it out in OOC/LOOC. If you find an issue with these, you are encouraged to start or participate in discussion over them.)
+
+ This document contains information pertaining to workplace laws, their application and standard procedures on GATO Corp owned space stations. Employees are expected to follow these laws and respect the Chain of Command. Security and Command also hold the additional responsibility of making sure they are being followed.
+
+ Chain of Command
+
+ -
+
The Captain holds responsibility for a station's operations during a shift, while the responsibility for the individual departments and their members is given to the other members of Command, also referred to as Heads. These are the Head of Security for Security, Head of Personnel for Service, Chief Medical Officer for Medical, Chief Engineer for Engineering, the Quartermaster for Cargo and the Research Director for Science.
+
+ -
+
Command members besides the Captain do not hold authority over other Heads or crew from departments outside their own. The same goes for any Security member over departments that are not Security.
+
+ -
+
Departments hold authority over their own activities, no department has to comply with the request of other departments that do not fall under the scope of one's duties, that are considered potentially harmful to others and to their discretion.
+
+ -
+
Should no Captain be on duty during a shift but someone is required to fill in the position, an Acting Captain can be assigned from between the present members of Command. This position gives them the same authority as a Captain, but the position is relinquished as soon as someone is assigned to the position proper. Democratic vote can be used, if need be, to decide who should hold the position and to revoke it should the majority of Command deem one unfit for the role.
+
+ -
+
CenterCom Commanders, while not part of the standard crew present on station, hold authority over the Captain. All station personnel must follow their orders.
+
+
+
+
+
+
+ Standard Operating Procedures
+ Alert Levels
+
Code Green
+
+ -
+
All Clear Standard operating levels.
+
+ -
+
No immediate or clear threat to the station.
+
+ -
+
All departments may carry out work as normal.
+
+ -
+
Suit sensors are not required to be on.
+
+ -
+
Weapons worn by security are to be hidden except when in the case of an emergency.
+
+ -
+
Crew members may freely walk in the hallways.
+
+ -
+
AI/Cyborgs have no need to bolt down any secure areas.
+
+ -
+
Security must respect the privacy of crew members and no unauthorized searches are allowed.
Code Blue
+
+ -
+
Confirmed Threat Elevated alert level.
+
+ -
+
There are reports or other proof available to indicate that there is a threat to the station.
+
+ -
+
When a Centcom threat summary is received and printed at communication consoles), the blue alert level is applied.
+
+ -
+
Suit sensors are mandatory, but coordinate positions are not required.
+
+ -
+
Security may have weapons visible.
+
+ -
+
Crew members may be searched by security with probable cause.
+
+ -
+
AI/Cyborgs may bolt down high secure areas.
+
+ -
+
Energy guns, laser guns and riot gear are allowed to be given out to security personnel if the HoS or Warden agree.
Code Red
+
+ -
+
Immediate Threat Maximum alert level.
+
+ -
+
There is an immediate threat to the station or severe damage.
+
+ -
+
Martial Law is in effect.
+
+ -
+
Suit sensors are to be turned fully on at all times.
+
+ -
+
Security can raid departments and arrest any crew member deemed a threat to the station.
+
+ -
+
All crew members must remain in their departments.
+
+ -
+
AI/Cyborgs may bolt down maintenance and airlocks leading to space.
+
+ -
+
Code Delta
+
+ -
+
Imminent Destruction
+
+ -
+
The station's self destruct mechanism has been engaged due to overwhelming threat to the station.
+
+ -
+
Martial Law is in effect.
+
+ -
+
Suit sensors are to be turned fully on at all times.
+
+ -
+
All orders from Heads of Staff and Security must be followed, any disobedience is punishable by death.
+
+ -
+
All crew members are to evacuate immediately, if possible.
+
+
+
+
+
+ Emergencies
+
+ Evacuation Or Transfer
+
+ -
+
In case of a crew transfer or due to an emergency, a shuttle can be called to transport personnel back to Central Command through the shuttle or escape pods located on the station.
+
+ -
+
All personnel are required to assist with reaching the shuttle or pods.
+
+ -
+
All crew should be brought on board of either, regardless of their consciousness.
+
+ -
+
Prisoners are to be brought to the secure area of the escape shuttle, except for prisoners who pose a severe threat.
+
+ -
+
AI units may be brought to Central Command on portable card devices (InteliCards) if structural failure is likely or AI units wish to leave. Mechs and Cyborg units are to be hauled to the escape shuttle for Central Command to inspect.
+
+ -
+
Authorizing early shuttle launches is not allowed unless there is an immediate threat to shuttle integrity.
+
+
+ Fire and Other Environmental Hazards
+
+ -
+
Immediate evacuation of all untrained personnel.
+
+ -
+
Fire alarms to be used to control the hazard.
+
+ -
+
Atmospheric Technicians and Station Engineers are to remove the hazard.
+
+ -
+
Pump air back into the area when fixed. Ensure the damage is repaired.
+
+
+
+ Viral Outbreak
+
+ -
+
If severe viral strain is on board the station, the Chief Medical Officer is required to quarantine infected parts of the station with the help of security.
+
+ -
+
All infected crew are to be isolated in Virology or Medbay.
+
+ -
+
Sterile masks/Internals and gloves are mandatory for medical personnel and recommended for crew.
+
+ -
+
Quarantine must be maintained until the outbreak is contained and resolved.
+
+ -
+
If the Emergency Shuttle is called, medical and security are to ensure no infected crew board the shuttle.
Meteor Storm
+
+ -
+
All crew to move to central parts of the station.
+
+ -
+
Engineers must employ, if available, either anti-meteor turrets or shields to protect the station and its personnel; along with repairs of any salvageable damage to the station.
+
+ -
+
Shuttle must be called if the station becomes unsalvageable.
+
+
+
+
+
+ On Security Activities
+
+
+ -
+
Arrest and actions are only to be taken if they are in active transgression of any laws, other actions require authorization from relevant authority (Captain or Heads). Suspicion without probable cause, as in there is no legitimate reason to take any action, is not, usually, reason enough to search or detain crew members.
+
+ -
+
An officer should apply a sentence to arrested people proportionate to the severity of the crime, the intent behind them, their number and it should be influenced by any applicable modifiers. Sentences reported here are suggestions, not hard rules.
+
+ -
+
Use of force should be applied carefully and proportionately to the threat law transgressions represent and unlawful applications can represent Abuse of Power. Always avoid force and taking a life whenever circumstances allow.
+
+
+
+ Minor Crimes
+ 101 Resisting Arrest, to not cooperate with an officer who attempts a proper arrest.
+ 102 Minor Contraband, to be in unauthorized possession of not dangerous contraband (drugs, chemicals, ect...).
+ 103 Indecent Exposure, to be intentionally and publicly unclothed.
+ 104 Trespass, to be in in non-dangerous areas that one does not have access to without permission.
+ 105 Petty Theft, to take insignificant items belonging to another crew member or other departments.
+ 106 Battery, to use physical force against someone without intent to injure and that does not result in serious, but not critical, physical harm.
+ 107 Harassment, to persistently insult, stalk, ridicule, or otherwise intentionally be obnoxious to another crew member in a not harmful way.
+ 108 Disruptive Behavior, to behave in a way that may lead to harm to workers or damage to the station (littering, vandalism, taking items from public places with no reason, leaving airlocks open...) , to disrupt the activities of a department (ignoring minor orders without cause, excessively repeated requests, abuse of radio...).
+
+ For Minor Crimes, consider verbal reprimands. If certain items, areas or actions were involved, also consider a ban from said item, area or action. Discuss bans with Heads.
+
+
Medium Crimes
+ 201 Obstruction of Authority, to willfully interfere with Security ongoing activities or to go against a superior's authority without proper cause, that would cause damage to the crew or station.
+ 202 Contraband, to distribute contraband without authorization (drugs, dangerous chemicals, items that would need an Head's or Command's approval. The Head of a different department can't approve in place of a relevant Head.).
+ 203 Creating Workplace Hazards, to endanger the crew or station through negligent but not malicious behavior.
+ 204 Major Trespass, to be in a restricted area that one does not have access to without permission.
+ 205 Theft, to take significant items from a department or crew member without permission (includes using items from evidence).
+ 206 Assault, to use physical force against someone without the intent to kill that results in serious harm.
+ 207 Major Harassment, to harmfully and repeatedly harass a crew member. To threaten crew members into performing any activity.
+ 208 Fraud & Sabotage, to willfully misrepresent one's action or intentions to abuse of other crew members or departments (tricking someone into having their genes messed with, receiving a virus that was not as described, asking for items that will not be used for what stated).
+ 209 Abuse of Power, to use one's position (Security or Command) to exploit or cause undue harm to other crew members. To issue orders that interfere or compromise a department's activities.
+
+ For Medium Crimes, consider small amounts of brig time, labor or community service. Discuss labor with Heads and generally keep to tasks that do not involve in-depth job knowledge- Especially if they'd be without supervision from someone who is already doing that job or a Head.
+
+
Major Crimes
+ 301 Dereliction of Duty, to willfully abandon obligations critical to the station.
+ 302 Weapons Possession & Major Contraband, to possess or distribute harmful weaponry or items that can cause damage to crew members or the station without authorization.
+ 303 Kidnapping & Spiking, to illegally abduct or hold a crew member without their will. To have other crew non-willfully members consume chemicals or substances.
+ 304 Strong-arm, to threaten crew members into performing any activity under the threat of serious harm or through usage of harmful items.
+ 305 Major Theft, to take dangerous or restricted items or weapons from a department or crew member without permission.
+ 306 Major Assault, to use physical force against someone without the intent to kill that results in life-threatening situations. To use physical force through deadly weapons.
+ 307 Sexual Assault, to perform unwanted and forced sexual advances (rape and other non-con IC things)
+ 308 Major Sabotage, to willfully disrupt station activities by causing damage to it or a crew member, or by manipulating critical equipment.
+ 309 Conspiracy, to aid an enemy of the corporation, to incite riots against authority without cause, to use false or someone else's identity.
+
+ For Major Crimes, consider harsher times in brig, labor or for community service. Additionally consider demotions or return of their ID- Though try and not leave them with nothing to do if that is the case. Only in very, very severe cases, consider leaving them jobless (or a return to CC?)
+
+
+ Capital Crimes
+ 401 Enemy of the Corporation, to be part of enemies of the corporation. To represent an immediate and dangerous threat to the station and its crew.
+ 402 Manslaughter, to willfully kill or attempt to kill a crew member through any means or through negligence.
+ 403 Mutiny, to unlawfully and without cause overthrow or attempt to overthrow the Chain of Command.
+ 404 Terrorism, to willfully perform or attempt to perform activities that are destructive to the station and its crew (bombs, virus outbreaks, engine/atmos manipulation, brainwashing...).
+
+ Capital Crimes apply to active threats to the station. Enemies should be put in brig or labor permanently, sent to CC or outright executed if they are believed to be too dangerous. Executions can only be sentenced by the Captain or, if no Captain is present, the Head of Security.
+
+ Crime Modifiers
+ - Dire Need, to perform unlawful activities due to the threat inaction would cause to the
+ station, its activities or its members. Immediate release, removal from area and return of items if needed.
+
+ - Brainwashed, prisoners found to have been brainwashed or converted by illegal means.
+ Prisoner is to be held until they can be returned to normal state. Immediate release following deconversion.
+
+ - Self Defense, defined as "The protection of oneself, the protection of thy colleagues, and the
+ protection of thine workplace". Vigilantism does not fall under this. Immediate release.
+ - Cooperation & Surrender, to help re-establishing a secure environment through information or actions. To surrender oneself to authority and admitting to being guilty. Less severe sentence.
+
+ - Immediate Threat, for something to threaten the life of a prisoner. Relocate or release.
+
- Medical Reasons, prisoners have the right to receive medical attention. Timers still run during medical personnel activities or relocation to medbay.
+
+ - Sparking a Manhunt, to escape from an attempted arrest, causing a chase. Harsher sentences.
+
+ - Repeated Offense, to repeatedly commit crimes even after previous corrective actions. Harsher sentences.
+
+ - Escape & Dereliction, to flee from confinement or to ignore a previous sentence. Reset timer.
+
+ Additional notes (tied to GS13)
+
+ -
+
Disruptive Behavior may contain many sorts of minor infractions, enforcement should be applied with reason. Taking a pen for a minute to write down something does not cause an actual disruption, neither does leaving a single O2 closet open or ignoring orders that would clearly cause harm to others or the station. Do not use this as an umbrella law to arrest or act against crew members who are doing no actual wrong, especially if the behavior is not being repeated or has caused no actual disruption.
+
+
+
+
+ -
+
Dereliction of Duty implies that, through willful inaction, damage was inflicted on the station or its personnel. Simply not doing anything can be considered, AT WORST, Disruptive Behavior. A doctor hanging by the bar is not Dereliction nor Disruption- It is Dereliction if they decide to not do their job when a medical emergency is happening.
+
+
+
+
+ -
+
In case of “skeleton crew”, as in there are very few people present and many of the roles are not covered, apply Dire Need generously. If, for example, someone really needs a chemical from Chemistry to do something related to their job, give them a pass for sneaking in to get it when no Medical Staff is present. This is all to favor roleplay after all.
+
+
+
+
+
+ "}
+
+//gato pamphlets
+/obj/item/book/lorebooks/welcome_to_gato
+ name = "Welcome to GATO Industrial Concern!"
+ icon_state = "bookwelcometogato"
+ desc = "A book stamped with GATO's feline logo. It serves the purpose of introducing employees to their current accommodations"
+ author = "A. Tenebrae"
+ title = "Welcome to Gato Industrial Concern!"
+ dat = {"
+
+
+
+
+ Welcome to GATO Industrial Concern!
+
+ Thank you, valued employee, for signing up to do work for GATO Industrial Concern. Whether you are working full-time or as a contractor for us, the contents within this little guide will help you get started on what you need to know!
+
+
Table of Contents...
+
+ - What is GATO?
+
- The origin of GATO
+
- The current state of GATO
+
- GS13: Current development projects
+
+
+
+ Chapter 1
+ What is GATO?
+
+ GATO Industrial Concern is a corporation that operates in every sector known to all sapients. Agriculture, luxurious goods, R&D, pharmaceuticals- if it exists, we make it! Your current employment is upon a....:
+ GENERAL STATION
+
+ Lucky you! A General Station is one that does not specialize in any particular type of production, and profits off of whatever it can manage to export. You've heard us! So long as the crew can attain profitable goods and ship it off to Central Command, you're doing your job! Here at Gato, we understand how autonomy for stations can improve both the conditions of workers and stimulate both creativity and innovation. As a result, we have permitted you to have nearly free reign over your activities, far from bureaucracy and regulation. That's much better than Nanotrasen, right?
+
+
+ Chapter 2
+ The origin of GATO
+
+ Gato's story begins around the beginning of the 22nd century. It was a truly hard time, indeed! Between the troublesome and expensive startup process of making a small business, and the crushing weight of bigger corporations, one would think that setting up a business was financial suicide. But our founder,
+ ~~-`11@#\[ERROR\]
+ , thought otherwise! So, GatoMart was founded, and we were instantly known for our creativity. Cute designs and friendly service built us the profit and recognition we needed to expand! And expand we did, taking on more and more corporations under our wing until we became the way we are today. Now, you can find Gato products all across the galaxy, ranging from simple things like cheese slices to more complex heavy artillery platforms! Isn't it grand to participate in maintaining such an awesome corporation like ours?
+
+
+ Chapter 3
+ The current state of Gato
+
+ Many people have begun to circulate bad rumors that Gato is beginning to decline. Dear employees, as honest, loving, and trustworthy employers, we must deny those claims! The Syndicate does not pose much of a threat, and we have continued to profit despite the odds! So do not fear, neither your wages nor your employment are currently at risk. We would never think of doing something that would cause such anguish to the members of our beloved company! Perhaps it is time to go onto a more pleasant topic... how the corporate hierarchy works! At the bottom, we have common workers, above that are your Department Heads, and above that is your Captain! And your Captain answers to our Central Command teams, who are subordinate to the Head of Central Command, who reports to the Branch Manager, who answers to the Executive Officers, who answer to the CEO(Chief Executive Officer!), who answers to the Board of Directors. The Board of Directors equally listens to the input of our most trusted shareholders, and the Head of the Board!
+
+
Chapter 4
+ GS13: Current development projects
+
+ (GS13 SECTOR PRINT EXCLUSIVE SECTION) As an employee of our thirteenth General Station, you've chosen (or have been chosen) to become a pioneer in some of our R&D projects! GS13 has been located in a relatively peaceful area of one of the rim-systems, home to immensely rare mineral known as "Calorite", exclusive to this sector! You'll get a chance to make your name in history by helping us furthen our knowledge of this strange material. Additionally, please be aware of employee shortages: GS13's location makes it a challenge to properly deliver supplies, but GATO assures you - you have nothing to worry about!
+
+ Got it? Good! Now you understand all that you might need to know about Gato Industrial Concern!
+
+
+
+
+
+
+
+ "}
diff --git a/GainStation13/code/game/objects/effects/spawners/choco_slime_delivery.dm b/GainStation13/code/game/objects/effects/spawners/choco_slime_delivery.dm
new file mode 100644
index 0000000000..ae4162d302
--- /dev/null
+++ b/GainStation13/code/game/objects/effects/spawners/choco_slime_delivery.dm
@@ -0,0 +1,29 @@
+/obj/effect/spawner/chocoslime_delivery
+ name = "choco slime delivery"
+ icon = 'GainStation13/icons/mob/candymonster.dmi'
+ icon_state = "a_c_slime"
+ var/announcement_time = 2
+
+/obj/effect/spawner/chocoslime_delivery/Initialize(mapload)
+ ..()
+ var/turf/T = get_turf(src)
+
+ new /mob/living/simple_animal/hostile/feed/chocolate_slime(T)
+ new /obj/effect/temp_visual/gravpush(T)
+ playsound(T, 'sound/items/party_horn.ogg', 50, 1, -1)
+
+ message_admins("A choco slime has been delivered to [ADMIN_VERBOSEJMP(T)].")
+ log_game("A choco slime has been delivered to [AREACOORD(T)]")
+ var/message = "Attention [station_name()], we have entrusted you with a research specimen in [get_area_name(T, TRUE)]. Remember to follow all safety precautions when dealing with the specimen."
+ SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(addtimer), CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(print_command_report), message), announcement_time))
+ return INITIALIZE_HINT_QDEL
+
+
+
+// spawner object used for mapping
+
+/obj/effect/spawner/lootdrop/fiftypercent_chocoslimespawn
+ name = "50% Chocolate Slime Spawn"
+ loot = list(
+ /obj/item/reagent_containers/food/snacks/chocolatebar = 70,
+ /obj/effect/spawner/chocoslime_delivery = 30)
diff --git a/GainStation13/code/game/objects/items/RCD.dm b/GainStation13/code/game/objects/items/RCD.dm
new file mode 100644
index 0000000000..1b8a011db1
--- /dev/null
+++ b/GainStation13/code/game/objects/items/RCD.dm
@@ -0,0 +1,47 @@
+/datum/design/arcd
+ name = "Advanced Rapid Construction Device (ARCD)"
+ desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly. This model works at a distance."
+ id = "arcd_design"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT, MAT_DIAMOND = 500, MAT_BLUESPACE = 500) // costs more than what it did in the autolathe, this one comes loaded.
+ build_path = /obj/item/construction/rcd/arcd
+ category = list("Equipment")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+
+/datum/techweb_node/blue_construct
+ id = "blue_construct"
+ display_name = "Bluespace Construction"
+ description = "Augument rapid construction designs using bluespace tech for ranged operations"
+ prereq_ids = list("adv_engi", "adv_bluespace")
+ design_ids = list("arcd_design")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7000)
+ export_price = 7000
+
+/obj/item/borg/upgrade/arcd
+ name = "cyborg ARCD"
+ desc = "A cybord RCG upgrade module to an ARCD model."
+ icon_state = "cyborg_upgrade3"
+ require_module = 1
+ module_type = /obj/item/robot_module/engineering
+
+/obj/item/borg/upgrade/arcd/action(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if(.)
+ var/obj/item/construction/rcd/arcd/S = new(R.module)
+ R.module.basic_modules += S
+ R.module.add_module(S, FALSE, TRUE)
+
+/obj/item/borg/upgrade/arcd/deactivate(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if (.)
+ var/obj/item/construction/rcd/arcd/S = locate() in R.module
+ R.module.remove_module(S, TRUE)
+
+/datum/design/borg_arcd
+ name = "Cyborg ARCD"
+ id = "borg_arcd"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/arcd
+ materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT, MAT_DIAMOND = 500, MAT_BLUESPACE = 500)
+ construction_time = 100
+ category = list("Cyborg Upgrade Modules")
diff --git a/GainStation13/code/game/objects/items/docility_implant.dm b/GainStation13/code/game/objects/items/docility_implant.dm
new file mode 100644
index 0000000000..5cedf0645a
--- /dev/null
+++ b/GainStation13/code/game/objects/items/docility_implant.dm
@@ -0,0 +1,134 @@
+/obj/item/implant/docile
+ name = "docility implant"
+ activated = FALSE
+ /// What fatness level does the target need to be for the implant to work?
+ var/required_fatness = FATNESS_LEVEL_BLOB
+ /// What traits do we want to give the implanted mob?
+ var/list/traits_list = list(
+ TRAIT_WEIGHT_LOSS_IMMUNE,
+ TRAIT_PACIFISM,
+ TRAIT_CLUMSY,
+ TRAIT_FAT_GOOD,
+ TRAIT_HEAVY_SLEEPER,
+ TRAIT_DOCILE,
+ )
+
+/obj/item/implant/docile/can_be_implanted_in(mob/living/target)
+ var/mob/living/carbon/human/target_human = target
+ if(!istype(target_human) || (target_human.fatness_real < required_fatness))
+ return FALSE
+
+ if(HAS_TRAIT(target_human, TRAIT_DOCILE))
+ return FALSE //They probably already have an implant, they likely don't need this.
+
+ return target?.client?.prefs?.fatness_vulnerable
+
+/obj/item/implant/docile/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(!.)
+ return
+
+ var/mob/living/carbon/human/target_human = target
+ if(!istype(target_human))
+ return
+
+ for(var/trait in traits_list)
+ ADD_TRAIT(target, trait, src)
+
+ target_human.nutri_mult += 1
+ return TRUE
+
+/obj/item/implant/docile/removed(mob/living/source, silent = FALSE, special = 0)
+ . = ..()
+ if(!.)
+ return
+
+ var/mob/living/carbon/human/target_human = source
+ if(!istype(target_human))
+ return
+
+ for(var/trait in traits_list)
+ REMOVE_TRAIT(target_human, trait, src)
+
+ target_human.nutri_mult -= 1
+ return TRUE
+
+
+/obj/item/implant/docile/livestock
+ name = "livestock implant"
+ traits_list = list(
+ TRAIT_WEIGHT_LOSS_IMMUNE,
+ TRAIT_PACIFISM,
+ TRAIT_CLUMSY,
+ TRAIT_FAT_GOOD,
+ TRAIT_HEAVY_SLEEPER,
+ TRAIT_DOCILE,
+ TRAIT_LIVESTOCK,
+ TRAIT_NO_MISC,
+ TRAIT_NORUNNING,
+ )
+
+ /// What is the name of the mob before we change it?
+ var/stored_name = ""
+ /// What name do we want to give the mob before adding the randomized number
+ var/name_to_give = "Livestock"
+ /// How much do we want to modifiy the productivity stats of the mob's current sex organs by?
+ var/productivity_mult = 4
+
+/obj/item/implant/docile/livestock/can_be_implanted_in(mob/living/target)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ return target?.client?.prefs?.extreme_fatness_vulnerable
+
+/obj/item/implant/docile/livestock/implant(mob/living/target, mob/user, silent)
+ . = ..()
+ if(!.)
+ return
+
+ var/mob/living/carbon/human/target_human = target
+ stored_name = target_human.real_name
+ var/new_name = "[name_to_give] ([rand(0,999)])"
+
+ target_human.real_name = new_name
+ target_human.name = new_name
+
+ if(target_human?.getorganslot("testicles"))
+ var/obj/item/organ/genital/testicles/balls = target_human?.getorganslot("testicles")
+ balls.fluid_mult = balls.fluid_mult * productivity_mult
+ balls.fluid_max_volume = balls.fluid_max_volume * productivity_mult
+
+ if(target_human?.getorganslot("breasts"))
+ var/obj/item/organ/genital/breasts/boobs = target_human?.getorganslot("breasts")
+ boobs.fluid_mult = boobs.fluid_mult * productivity_mult
+ boobs.fluid_max_volume = boobs.fluid_max_volume * productivity_mult
+
+/obj/item/implant/docile/livestock/removed(mob/living/source, silent, special)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ var/mob/living/carbon/human/target_human = source
+ target_human.real_name = stored_name
+ target_human.name = stored_name
+
+ if(target_human?.getorganslot("testicles"))
+ var/obj/item/organ/genital/testicles/balls = target_human?.getorganslot("testicles")
+ balls.fluid_mult = balls.fluid_mult / productivity_mult
+ balls.fluid_max_volume = balls.fluid_max_volume / productivity_mult
+
+ if(target_human?.getorganslot("breasts"))
+ var/obj/item/organ/genital/breasts/boobs = target_human?.getorganslot("breasts")
+ boobs.fluid_mult = boobs.fluid_mult / productivity_mult
+ boobs.fluid_max_volume = boobs.fluid_max_volume / productivity_mult
+
+/obj/item/implantcase/docile
+ name = "implant case - 'Docility'"
+ desc = "A glass case containing a docility implant. Used to make those at high weights docile."
+ imp_type = /obj/item/implant/docile
+
+/obj/item/implantcase/docile/livestock
+ name = "implant case - 'Livestock'"
+ desc = "A glass case containing a livestock implant. Functions similar to the docility implant, but changes the implantee's name and makes them even more helpless. cannot be combined with the docility implant."
+ imp_type = /obj/item/implant/docile/livestock
diff --git a/GainStation13/code/game/objects/items/storage/bags.dm b/GainStation13/code/game/objects/items/storage/bags.dm
new file mode 100644
index 0000000000..786e375c5f
--- /dev/null
+++ b/GainStation13/code/game/objects/items/storage/bags.dm
@@ -0,0 +1,48 @@
+/obj/item/storage/bag/tray/holding
+ name = "serving tray of holding"
+ desc = "A tray for food, now featuring bluesapce technology. Don't ask."
+
+/obj/item/storage/bag/tray/holding/ComponentInitialize()
+ . = ..()
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
+ STR.max_combined_w_class = INFINITY
+ STR.max_items = 50
+
+/datum/design/tray_holding
+ name = "Serving Tray of Holding"
+ desc = "A serving tray for food, now somehow using bluespace to hold more stuff."
+ id = "tray_holding"
+ build_type = PROTOLATHE
+ materials = list(MAT_GOLD = 250, MAT_URANIUM = 500)
+ build_path =/obj/item/storage/bag/tray/holding
+ category = list("Bluespace Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+
+/obj/item/borg/upgrade/tray_hold
+ name = "cyborg tray of holding"
+ desc = "A tray of holding replacement for service borg's tray."
+ icon_state = "cyborg_upgrade3"
+ require_module = 1
+ module_type = /obj/item/robot_module/butler
+
+/obj/item/borg/upgrade/tray_hold/action(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if(.)
+ var/obj/item/storage/bag/tray/holding/S = new(R.module)
+ R.module.basic_modules += S
+ R.module.add_module(S, FALSE, TRUE)
+
+/obj/item/borg/upgrade/tray_hold/deactivate(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if (.)
+ var/obj/item/storage/bag/tray/holding/S = locate() in R.module
+ R.module.remove_module(S, TRUE)
+
+/datum/design/borg_tray_hold
+ name = "Cyborg Tray of Holding"
+ id = "borg_tray_hold"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/tray_hold
+ materials = list(MAT_GOLD = 250, MAT_URANIUM = 500)
+ construction_time = 100
+ category = list("Cyborg Upgrade Modules")
diff --git a/GainStation13/code/game/sound.dm b/GainStation13/code/game/sound.dm
new file mode 100644
index 0000000000..6c8cb7bb6d
--- /dev/null
+++ b/GainStation13/code/game/sound.dm
@@ -0,0 +1,37 @@
+/proc/playsound_prefed(atom/source, soundin, pref, vol as num, vary, extrarange as num, falloff, frequency = null, channel = 0, pressure_affected = TRUE, ignore_walls = TRUE, soundenvwet = -10000, soundenvdry = 0)
+ if(isarea(source))
+ throw EXCEPTION("playsound(): source is an area")
+ return
+
+ var/turf/turf_source = get_turf(source)
+
+ if (!turf_source)
+ return
+
+ //allocate a channel if necessary now so its the same for everyone
+ channel = channel || open_sound_channel()
+
+ // Looping through the player list has the added bonus of working for mobs inside containers
+ var/sound/S = sound(get_sfx(soundin))
+ var/maxdistance = (world.view + extrarange)
+ var/z = turf_source.z
+ var/list/listeners = SSmobs.clients_by_zlevel[z]
+ if(!ignore_walls) //these sounds don't carry through walls
+ listeners = listeners & hearers(maxdistance,turf_source)
+
+ for(var/P in listeners)
+ var/mob/M = P
+ if(!M.client)
+ continue
+ if((!M.client?.prefs.cit_toggles & pref))
+ continue
+ if(get_dist(M, turf_source) <= maxdistance)
+ M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S, soundenvwet, soundenvdry)
+ for(var/P in SSmobs.dead_players_by_zlevel[z])
+ var/mob/M = P
+ if(!M.client)
+ continue
+ if((!M.client?.prefs.cit_toggles & pref))
+ continue
+ if(get_dist(M, turf_source) <= maxdistance)
+ M.playsound_local(turf_source, soundin, vol, vary, frequency, falloff, channel, pressure_affected, S, soundenvwet, soundenvdry)
diff --git a/GainStation13/code/game/turfs/closed.dm b/GainStation13/code/game/turfs/closed.dm
new file mode 100644
index 0000000000..1863f20fb1
--- /dev/null
+++ b/GainStation13/code/game/turfs/closed.dm
@@ -0,0 +1,27 @@
+// /turf/closed
+// layer = CLOSED_TURF_LAYER
+// opacity = 1
+// density = TRUE
+// blocks_air = 1
+// rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
+// rad_insulation = RAD_MEDIUM_INSULATION
+
+
+// leaving this helper for remembering vars - Sono
+
+
+///////////////////////////////// GS13 CLOSED TURFS ///////////////////////////////
+
+
+/turf/closed/indestructible/candy
+ name = "Candy wall"
+ desc = "Despite being made out of mere candy, this wall is harder than stone!"
+ icon = 'Gainstation13/icons/turf/wall_candy.dmi'
+ icon_state = "candywall"
+
+
+/turf/closed/indestructible/chocolate
+ name = "Chocolate wall"
+ desc = "Somehow, it doesn't melt at all..."
+ icon = 'Gainstation13/icons/turf/wall_candy.dmi'
+ icon_state = "choco_wall1"
diff --git a/GainStation13/code/game/turfs/open.dm b/GainStation13/code/game/turfs/open.dm
new file mode 100644
index 0000000000..470ab0ef08
--- /dev/null
+++ b/GainStation13/code/game/turfs/open.dm
@@ -0,0 +1,50 @@
+// /turf/open
+// plane = FLOOR_PLANE
+// var/slowdown = 0 //negative for faster, positive for slower
+
+// var/postdig_icon_change = FALSE
+// var/postdig_icon
+// var/wet
+
+// var/footstep = null
+// var/barefootstep = null
+// var/clawfootstep = null
+// var/heavyfootstep = null
+
+// leaving this helper for remembering vars - Sono
+
+///////////////////////////////// GS13 OPEN TURFS ///////////////////////////////
+
+/turf/open/indestructible/chocolate
+ name = "chocolate floor"
+ desc = "A rather tasty floor, hopefully it does not ruin your shoes."
+ icon = 'Gainstation13/icons/turf/floor_candy.dmi'
+ icon_state = "choclit_2"
+
+
+/turf/open/indestructible/bubblegum
+ name = "bubblegum floor"
+ desc = "A rather tasty floor, hopefully it does not ruin your shoes."
+ icon = 'Gainstation13/icons/turf/floor_candy.dmi'
+ icon_state = "floor_pinkgum"
+
+/turf/open/candyfloor
+ name = "candy grass"
+ desc = "This weird grass smells of cinnamon and liquorice."
+ icon = 'Gainstation13/icons/turf/floor_candy.dmi'
+ icon_state = "candyfloor"
+
+/turf/open/chocolateriver
+ gender = PLURAL
+ name = "liquid chocolate"
+ desc = "This is probably used for some kind of huge fountain."
+ icon = 'Gainstation13/icons/turf/floor_candy.dmi'
+ icon_state = "chocwater"
+ slowdown = 1
+ bullet_sizzle = TRUE
+ bullet_bounce_sound = null //needs a splashing sound one day.
+
+ footstep = FOOTSTEP_WATER
+ barefootstep = FOOTSTEP_WATER
+ clawfootstep = FOOTSTEP_WATER
+ heavyfootstep = FOOTSTEP_WATER
diff --git a/GainStation13/code/machinery/adipoelectric_generator.dm b/GainStation13/code/machinery/adipoelectric_generator.dm
new file mode 100644
index 0000000000..e8b8d25c3f
--- /dev/null
+++ b/GainStation13/code/machinery/adipoelectric_generator.dm
@@ -0,0 +1,164 @@
+/obj/machinery/power/adipoelectric_generator
+ name = "adipoelectric generator"
+ desc = "This device uses calorite technology to transform excess blubber into power!"
+ icon = 'GainStation13/icons/obj/adipoelectric_transformer.dmi'
+ icon_state = "state_off"
+ density = FALSE
+ anchored = FALSE
+ use_power = NO_POWER_USE
+ state_open = TRUE
+ circuit = /obj/item/circuitboard/machine/power/adipoelectric_generator
+ occupant_typecache = list(/mob/living/carbon)
+ var/laser_modifier
+ var/max_fat
+ var/obj/structure/cable/attached
+ var/conversion_rate = 10000
+ var/emp_timer = 0
+ var/active = FALSE
+ var/datum/looping_sound/generator/soundloop
+
+/obj/machinery/power/adipoelectric_generator/Initialize(mapload)
+ . = ..()
+ soundloop = new(list(src), active)
+ if(anchored)
+ connect_to_network()
+ update_icon()
+
+/obj/machinery/power/adipoelectric_generator/RefreshParts()
+ laser_modifier = 0
+ max_fat = 0
+ for(var/obj/item/stock_parts/micro_laser/C in component_parts)
+ laser_modifier += C.rating
+ for(var/obj/item/stock_parts/matter_bin/C in component_parts)
+ max_fat += C.rating * 2
+
+/obj/machinery/power/adipoelectric_generator/process()
+ if(!occupant)
+ src.visible_message("The [src] buzzes. It needs someone inside.")
+ playsound(src, 'sound/machines/buzz-two.ogg', 50)
+ return PROCESS_KILL
+ if(occupant:fatness_real > 0 && powernet && anchored && (emp_timer < world.time))
+ active = TRUE
+ add_avail(conversion_rate * laser_modifier * max_fat)
+ occupant:adjust_fatness(-max_fat, FATTENING_TYPE_ITEM)
+ soundloop.start()
+ else
+ active = FALSE
+ soundloop.stop()
+ update_icon()
+
+/obj/machinery/power/adipoelectric_generator/relaymove(mob/user)
+ if(user.stat)
+ return
+ open_machine()
+ soundloop.stop()
+
+/obj/machinery/power/adipoelectric_generator/emp_act(severity)
+ . = ..()
+ if(!(stat & (BROKEN|NOPOWER)))
+ emp_timer = world.time + 600
+ if(occupant)
+ src.visible_message("The [src] buzzes and expels anyone inside!.")
+ open_machine()
+
+/obj/machinery/power/adipoelectric_generator/attackby(obj/item/P, mob/user, params)
+ if(state_open)
+ if(default_deconstruction_screwdriver(user, "state_open", "state_off", P))
+ return
+
+ if(default_pry_open(P))
+ return
+
+ if(default_deconstruction_crowbar(P))
+ return
+
+ if(P.tool_behaviour == TOOL_WRENCH && !active)
+ if(!anchored && !isinspace())
+ connect_to_network()
+ to_chat(user, "You secure the generator to the floor.")
+ anchored = TRUE
+ dir = SOUTH
+ else if(anchored)
+ disconnect_from_network()
+ to_chat(user, "You unsecure the generator from the floor.")
+ anchored = FALSE
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ return
+
+ return ..()
+
+/obj/machinery/power/adipoelectric_generator/interact(mob/user)
+ toggle_open()
+ return TRUE
+
+/obj/machinery/power/adipoelectric_generator/proc/toggle_open()
+ if(state_open)
+ close_machine()
+ else
+ open_machine()
+ soundloop.stop()
+ update_icon()
+
+/obj/machinery/power/adipoelectric_generator/open_machine()
+ . = ..()
+ STOP_PROCESSING(SSobj, src)
+
+/obj/machinery/power/adipoelectric_generator/close_machine()
+ . = ..()
+ if(occupant && anchored && !panel_open)
+ add_fingerprint(occupant)
+ START_PROCESSING(SSobj, src)
+ else
+ src.visible_message("[src] needs to be anchored to a working wire and have a person going inside!")
+ open_machine()
+
+/obj/machinery/power/adipoelectric_generator/update_icon()
+ cut_overlays()
+ if(panel_open)
+ icon_state = "state_open"
+ return
+ if(occupant)
+ var/image/occupant_overlay
+ occupant_overlay = image(occupant.icon, occupant.icon_state)
+ occupant_overlay.copy_overlays(occupant)
+ occupant_overlay.dir = SOUTH
+ occupant_overlay.pixel_y = 10
+ add_overlay(occupant_overlay)
+ if(!active)
+ icon_state = "state_off"
+ else
+ icon_state = "state_on"
+ else
+ icon_state = "state_off"
+
+/obj/machinery/power/adipoelectric_generator/power_change()
+ ..()
+ update_icon()
+
+/obj/machinery/power/adipoelectric_generator/Destroy()
+ QDEL_NULL(soundloop)
+ . = ..()
+
+/obj/machinery/power/adipoelectric_generator/examine(mob/user)
+ . = ..()
+ if(is_operational())
+ . += "[src]'s show it can produce [conversion_rate * laser_modifier]W per adipose unit, taking in [max_fat] max each time."
+ else
+ . += "[src]'s display is currently offline."
+
+/obj/item/circuitboard/machine/power/adipoelectric_generator
+ name = "Adipoelectric Generator (Machine Board)"
+ build_path = /obj/machinery/power/adipoelectric_generator
+ req_components = list(
+ /obj/item/stock_parts/micro_laser = 5,
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/stack/cable_coil = 2)
+ needs_anchored = FALSE
+
+/datum/design/board/adipoelectric_generator
+ name = "Machine Design (Adipoelectric Generator Board)"
+ desc = "The circuit board for an Adipoelectric Generator."
+ id = "adipoelectric_generator"
+ build_path = /obj/item/circuitboard/machine/power/adipoelectric_generator
+ category = list("Engineering Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
diff --git a/GainStation13/code/machinery/adipoelectric_transformer.dm b/GainStation13/code/machinery/adipoelectric_transformer.dm
new file mode 100644
index 0000000000..15fbaa9e78
--- /dev/null
+++ b/GainStation13/code/machinery/adipoelectric_transformer.dm
@@ -0,0 +1,167 @@
+GLOBAL_LIST_EMPTY(adipoelectric_transformer)
+
+/obj/machinery/adipoelectric_transformer
+ name = "adipoelectric transformer"
+ desc = "This device uses calorite technology to store excess current in the wire it's placed on into whoever steps on!"
+ icon = 'GainStation13/icons/obj/adipoelectric_transformer.dmi'
+ icon_state = "state_off"
+ density = FALSE
+ use_power = NO_POWER_USE
+ state_open = TRUE
+ circuit = /obj/item/circuitboard/machine/adipoelectric_transformer
+ occupant_typecache = list(/mob/living/carbon)
+ var/recharge_speed
+ var/obj/structure/cable/attached
+ var/drain_rate = 1000000
+ var/lastprocessed = 0
+ var/power_avaliable = 0
+ var/conversion_rate = 0.000001
+ var/emp_timer = 0
+ var/emp_multiplier = 5
+ var/datum/powernet/PN
+
+/obj/machinery/adipoelectric_transformer/Initialize(mapload)
+ . = ..()
+ update_icon()
+
+/obj/machinery/adipoelectric_transformer/RefreshParts()
+ recharge_speed = 0
+ for(var/obj/item/stock_parts/capacitor/C in component_parts)
+ recharge_speed += C.rating
+
+/obj/machinery/adipoelectric_transformer/process()
+ if(!is_operational())
+ return
+ if(!attached)
+ src.visible_message("[src] buzzes. Seems like it's not attached to a working power net.")
+ playsound(src, 'sound/machines/buzz-two.ogg', 50)
+ return PROCESS_KILL
+ PN = attached.powernet
+ if(PN)
+ power_avaliable = PN.netexcess
+ update_icon()
+ if(power_avaliable <= 0)
+ return
+ if(occupant)
+ if(power_avaliable > drain_rate)
+ lastprocessed = ((power_avaliable - drain_rate) * (conversion_rate / 10)) + 1
+ else
+ lastprocessed = power_avaliable * conversion_rate
+ if(!(world.time >= emp_timer + 600))
+ lastprocessed = lastprocessed * emp_multiplier
+ occupant:adjust_fatness(lastprocessed * recharge_speed, FATTENING_TYPE_ITEM)
+ return TRUE
+
+/obj/machinery/adipoelectric_transformer/relaymove(mob/user)
+ if(user.stat)
+ return
+ open_machine()
+
+/obj/machinery/adipoelectric_transformer/emp_act(severity)
+ . = ..()
+ if(!(stat & (BROKEN|NOPOWER)))
+ if(occupant)
+ src.visible_message("[src] emits ominous cracking noises!")
+ emp_timer = world.time //stuck in for 600 ticks, about 60 seconds
+
+/obj/machinery/adipoelectric_transformer/attackby(obj/item/P, mob/user, params)
+ if(state_open)
+ if(default_deconstruction_screwdriver(user, "state_open", "state_off", P))
+ return
+
+ if(default_pry_open(P))
+ return
+
+ if(default_deconstruction_crowbar(P))
+ return
+ return ..()
+
+/obj/machinery/adipoelectric_transformer/interact(mob/user)
+ toggle_open()
+ return TRUE
+
+/obj/machinery/adipoelectric_transformer/proc/toggle_open()
+ if(state_open)
+ close_machine()
+ else
+ open_machine()
+ update_icon()
+
+/obj/machinery/adipoelectric_transformer/open_machine()
+ if(!(world.time >= emp_timer + 600))
+ return
+ . = ..()
+ GLOB.adipoelectric_transformer -= src
+ STOP_PROCESSING(SSobj, src)
+
+/obj/machinery/adipoelectric_transformer/close_machine()
+ . = ..()
+ if(LAZYLEN(GLOB.adipoelectric_transformer) < 1 && occupant)
+ var/turf/T = loc
+ if(isturf(T) && !T.intact)
+ attached = locate() in T
+ add_fingerprint(occupant)
+ GLOB.adipoelectric_transformer += src
+ START_PROCESSING(SSobj, src)
+ else
+ src.visible_message("[src] buzzes. There must be another a person going in an no other transformer active in the area.")
+ playsound(src, 'sound/machines/buzz-two.ogg', 50)
+ open_machine()
+
+/obj/machinery/adipoelectric_transformer/update_icon()
+ cut_overlays()
+ if(occupant)
+ var/image/occupant_overlay
+ occupant_overlay = image(occupant.icon, occupant.icon_state)
+ occupant_overlay.copy_overlays(occupant)
+ occupant_overlay.dir = SOUTH
+ occupant_overlay.pixel_y = 10
+ add_overlay(occupant_overlay)
+ if(power_avaliable <= 0)
+ icon_state = "state_off"
+ else
+ if(!(world.time >= emp_timer + 600))
+ icon_state = "state_overdrive"
+ add_overlay("particles_overdrive")
+ else
+ icon_state = "state_on"
+ add_overlay("particles_on")
+ else
+ icon_state = "state_off"
+
+/obj/machinery/adipoelectric_transformer/power_change()
+ ..()
+ update_icon()
+
+/obj/machinery/adipoelectric_transformer/Destroy()
+ . = ..()
+ GLOB.adipoelectric_transformer -= src
+
+/obj/machinery/adipoelectric_transformer/examine(mob/user)
+ . = ..()
+ if(is_operational() && attached)
+ if(PN)
+ if(lastprocessed)
+ . += "[src]'s last reading on display was [lastprocessed * recharge_speed] adipose units."
+ else
+ . += "[src] has no last reading."
+ else
+ . += "[src]'s display states 'ERROR'. There must be something wrong with the power."
+ else
+ . += "[src]'s display is currently offline."
+
+/obj/item/circuitboard/machine/adipoelectric_transformer
+ name = "Adipoelectric Transformer (Machine Board)"
+ build_path = /obj/machinery/adipoelectric_transformer
+ req_components = list(
+ /obj/item/stock_parts/capacitor = 5,
+ /obj/item/stack/sheet/glass = 1,
+ /obj/item/stack/sheet/mineral/calorite = 1)
+
+/datum/design/board/adipoelectric_transformer
+ name = "Machine Design (Adipoelectric Transformer Board)"
+ desc = "The circuit board for an Adipoelectric Transformer."
+ id = "adipoelectric_transformer"
+ build_path = /obj/item/circuitboard/machine/adipoelectric_transformer
+ category = list("Research Machinery")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
diff --git a/GainStation13/code/machinery/fattening_turret.dm b/GainStation13/code/machinery/fattening_turret.dm
new file mode 100644
index 0000000000..c928150312
--- /dev/null
+++ b/GainStation13/code/machinery/fattening_turret.dm
@@ -0,0 +1,31 @@
+
+/obj/machinery/porta_turret/fattening
+ name = "Fatoray Turret"
+ installation = null
+ always_up = 1
+ use_power = NO_POWER_USE
+ has_cover = 0
+ scan_range = 9
+ req_access = list(ACCESS_SYNDICATE)
+ mode = TURRET_LETHAL
+ lethal_projectile = /obj/item/projectile/beam/fattening
+ lethal_projectile_sound = 'sound/weapons/laser.ogg'
+ icon_state = "turretCover"
+ base_icon_state = "standard"
+ faction = list(ROLE_SYNDICATE)
+ desc = "A laser turret with calorite focusing lens."
+
+/obj/machinery/porta_turret/fattening/heavy
+ name = "Heavy Fatoray Turret"
+ lethal_projectile = /obj/item/projectile/beam/fattening/cannon
+ shot_delay = 30
+
+/obj/machinery/porta_turret/fattening/ComponentInitialize()
+ . = ..()
+ AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES)
+
+/obj/machinery/porta_turret/fattening/setup()
+ return
+
+/obj/machinery/porta_turret/fattening/assess_perp(mob/living/carbon/human/perp)
+ return 10 //fattening turrets shoot everything except the syndicate
diff --git a/GainStation13/code/machinery/feeding_tube.dm b/GainStation13/code/machinery/feeding_tube.dm
new file mode 100644
index 0000000000..498b174ca8
--- /dev/null
+++ b/GainStation13/code/machinery/feeding_tube.dm
@@ -0,0 +1,94 @@
+/obj/machinery/iv_drip/feeding_tube
+ name = "\improper Feeding tube"
+ desc = "Originally meant to automatically feed cattle and farm animals, this model was repurposed for more... personal usage."
+ icon = 'GainStation13/icons/obj/feeding_tube.dmi'
+ icon_state = "feeding_tube"
+ var/static/list/food_containers = typecacheof(list(/obj/item/reagent_containers/food,
+ /obj/item/reagent_containers/glass,))
+ attachment_point = "tube"
+
+/obj/machinery/iv_drip/feeding_tube/update_icon()
+ if(attached)
+ if(mode)
+ icon_state = "injecting"
+ else
+ if(mode)
+ icon_state = "injectidle"
+
+ cut_overlays()
+
+ if(beaker)
+ if(attached)
+ add_overlay("beakeractive")
+ else
+ add_overlay("beakeridle")
+ if(beaker.reagents.total_volume)
+ var/mutable_appearance/filling_overlay = mutable_appearance('GainStation13/icons/obj/feeding_tube.dmi', "reagent")
+
+ var/percent = round((beaker.reagents.total_volume / beaker.volume) * 100)
+ switch(percent)
+ if(0 to 9)
+ filling_overlay.icon_state = "reagent0"
+ if(10 to 24)
+ filling_overlay.icon_state = "reagent10"
+ if(25 to 49)
+ filling_overlay.icon_state = "reagent25"
+ if(50 to 74)
+ filling_overlay.icon_state = "reagent50"
+ if(75 to 79)
+ filling_overlay.icon_state = "reagent75"
+ if(80 to 90)
+ filling_overlay.icon_state = "reagent80"
+ if(91 to INFINITY)
+ filling_overlay.icon_state = "reagent100"
+
+ filling_overlay.color = mix_color_from_reagents(beaker.reagents.reagent_list)
+ add_overlay(filling_overlay)
+
+/obj/machinery/iv_drip/feeding_tube/process()
+ if(!attached)
+ return PROCESS_KILL
+
+ if(!(get_dist(src, attached) <= 1 && isturf(attached.loc)))
+ to_chat(attached, "The feeding hose is yanked out of you!")
+ update_icon()
+ return PROCESS_KILL
+
+ if(beaker)
+ if(mode)
+ if(beaker.reagents.total_volume)
+ var/transfer_amount = 5
+ var/fraction = min(transfer_amount/beaker.reagents.total_volume, 1) //the fraction that is transfered of the total volume
+ beaker.reagents.reaction(attached, INJECT, fraction, FALSE) //make reagents reacts, but don't spam messages
+ beaker.reagents.trans_to(attached, transfer_amount)
+ update_icon()
+
+ else if(!beaker.reagents.total_volume && istype(beaker, /obj/item/reagent_containers/food))
+ qdel(beaker)
+ beaker = null
+ if(attached)
+ attached = null
+ update_icon()
+
+ return PROCESS_KILL
+
+/obj/machinery/iv_drip/feeding_tube/attackby(obj/item/W, mob/user, params)
+ if(is_type_in_typecache(W, food_containers))
+ if(beaker)
+ to_chat(user, "There is already a reagent container loaded!")
+ return
+ if(!user.transferItemToLoc(W, src))
+ return
+ beaker = W
+ to_chat(user, "You attach [W] to [src].")
+ user.log_message("attached a [W] to [src] at [AREACOORD(src)] containing ([beaker.reagents.log_list()])", LOG_ATTACK)
+ add_fingerprint(user)
+ update_icon()
+ return
+ else
+ return FALSE
+
+
+//it sure is a solution.
+/obj/machinery/iv_drip/feeding_tube/toggle_mode()
+ return FALSE
diff --git a/GainStation13/code/machinery/supply_teleporter.dm b/GainStation13/code/machinery/supply_teleporter.dm
new file mode 100644
index 0000000000..c33203633e
--- /dev/null
+++ b/GainStation13/code/machinery/supply_teleporter.dm
@@ -0,0 +1,15 @@
+/obj/machinery/quantumpad/supply_only
+ name = "supply pad"
+ desc = "A modified version of the quantum pad, only able to teleport supplies and livestock."
+ circuit = /obj/item/circuitboard/machine/quantumpad/supply_only
+
+/obj/machinery/quantumpad/supply_only/check_mob_teleportability(mob/living/mob_to_check)
+ if(istype(mob_to_check, /mob/living/simple_animal))
+ return TRUE
+
+ return HAS_TRAIT(mob_to_check, TRAIT_LIVESTOCK)
+
+/obj/item/circuitboard/machine/quantumpad/supply_only
+ name = "Supply Pad (Machine Board)"
+ build_path = /obj/machinery/quantumpad/supply_only
+
diff --git a/GainStation13/code/mechanics/den abductors/console.dm b/GainStation13/code/mechanics/den abductors/console.dm
new file mode 100644
index 0000000000..4293c5e203
--- /dev/null
+++ b/GainStation13/code/mechanics/den abductors/console.dm
@@ -0,0 +1,248 @@
+/obj/machinery/abductor/feeder_console
+ name = "feeder console"
+ desc = "You were into feeding enough that you managed to reverse-engineer alien technology to suit your goals, Amazing."
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "console"
+ density = TRUE
+ team_number = 27 // 6(F) + 1(A) + 20(T) :3
+ /// What pad is linked with the console?
+ var/obj/machinery/abductor/pad/pad
+ /// What camera console is linked with the console?
+ var/obj/machinery/computer/camera_advanced/abductor/camera
+ /// What abductor gizmo is linked with the console?
+ var/obj/item/abductor/gizmo/gizmo
+ /// The current scale linked with the console
+ var/obj/structure/scale/credits/linked_scale
+ /// How much of each goodie have we purchased?
+ var/list/buy_counts = list()
+
+/obj/machinery/abductor/feeder_console/attack_hand(mob/user)
+ . = ..()
+ if(.)
+ return
+ user.set_machine(src)
+ var/dat = ""
+ dat += " FeederSoft 3000
"
+
+ var/credits = linked_scale?.credits
+ dat += "Gear Credits: [credits]
"
+ dat += "Transfer credits in exchange for supplies:
"
+ for(var/goodie in subtypesof(/datum/feeders_den_goodie))
+ var/datum/feeders_den_goodie/temp_goodie = new goodie()
+ dat += "[temp_goodie.name] (Cost: [temp_goodie.credit_cost])
"
+ qdel(temp_goodie)
+
+ if(pad)
+ dat += "Emergency Teleporter System."
+ dat += "Consider using primary observation console first."
+ dat += "Activate Teleporter
"
+ if(gizmo && gizmo.marked)
+ dat += "Retrieve Mark
"
+ else
+ dat += "Retrieve Mark
"
+ else
+ dat += "NO TELEPAD DETECTED"
+
+ var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
+ popup.set_content(dat)
+ popup.open()
+
+/obj/machinery/abductor/feeder_console/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.set_machine(src)
+ if(href_list["teleporter_send"])
+ TeleporterSend()
+ if(href_list["dispense"])
+ var/datum_path = href_list["dispense"]
+ var/datum/feeders_den_goodie/goodie_datum = new datum_path()
+ var/price = goodie_datum.credit_cost
+ var/item_path = goodie_datum.item_to_dispense
+
+ if(!isnull(goodie_datum.initial_stock) && buy_counts[goodie_datum.name] && (buy_counts[goodie_datum.name] >= goodie_datum.initial_stock))
+ say("Unable to purchase more!")
+ return FALSE
+
+ if(!Dispense(item_path, price))
+ return FALSE
+
+ if(buy_counts[goodie_datum.name] == null)
+ buy_counts[goodie_datum.name] = 0
+
+ buy_counts[goodie_datum.name] += 1
+ qdel(goodie_datum)
+
+ updateUsrDialog()
+
+/obj/machinery/abductor/feeder_console/proc/TeleporterRetrieve()
+ if(pad && gizmo && gizmo.marked)
+ pad.Retrieve(gizmo.marked)
+
+/obj/machinery/abductor/feeder_console/proc/TeleporterSend()
+ if(pad)
+ pad.Send()
+
+/obj/machinery/abductor/feeder_console/proc/SetDroppoint(turf/open/location,user)
+ if(!istype(location))
+ to_chat(user, "That place is not safe for the specimen.")
+ return
+
+ if(pad)
+ pad.teleport_target = location
+ to_chat(user, "Location marked as test subject release point.")
+
+/obj/machinery/abductor/feeder_console/Initialize(mapload)
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/machinery/abductor/feeder_console/LateInitialize()
+ if(!team_number)
+ return
+
+ for(var/obj/machinery/abductor/pad/found_pad in GLOB.machines)
+ if(found_pad.team_number == team_number)
+ pad = found_pad
+ break
+
+ for(var/obj/machinery/computer/camera_advanced/abductor/found_console in GLOB.machines)
+ if(found_console.team_number == team_number)
+ camera = found_console
+ found_console.console = src
+
+/obj/machinery/abductor/feeder_console/proc/AddGizmo(obj/item/abductor/gizmo/G)
+ if(G == gizmo && G.console == src)
+ return FALSE
+
+ if(G.console)
+ G.console.gizmo = null
+
+ gizmo = G
+ G.console = src
+ return TRUE
+
+/obj/machinery/abductor/feeder_console/proc/Dispense(obj/item/new_item, cost = 1)
+ if(!ispath(new_item))
+ return FALSE
+
+ if(!linked_scale?.credits || linked_scale.credits < cost)
+ say("Insufficent credits!")
+ return FALSE
+
+ linked_scale.credits -= cost
+ say("Incoming supply!")
+ var/drop_location = loc
+
+ if(pad)
+ flick("alien-pad", pad)
+ drop_location = pad.loc
+
+ new new_item(drop_location)
+ return TRUE
+
+/obj/machinery/abductor/feeder_console/attackby(obj/item/used_tool, mob/user, params)
+ if(istype(used_tool, /obj/item/abductor/gizmo) && AddGizmo(used_tool))
+ to_chat(user, "You link the tool to the console.")
+ return TRUE
+
+ return ..()
+
+/obj/structure/scale/credits
+ name = "tracking scale"
+ desc = "A upgraded scale that tracks to weight of all of those that have stepped on it. Using this will add credits to the feeder console"
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ flags_1 = NODECONSTRUCT_1
+ /// How much credits do we currently have?
+ var/credits = 0
+ /// How many credits are we going to reward per pound gained?
+ var/credits_per_fatness = 0.25
+ /// A list containing all of the people we've scanned and their maximum weight.
+ var/list/scanned_people = list()
+ /// What is the current team number?
+ var/team_number = 27
+ /// What is the maximum ammount of credits that can be gained per person?
+ var/maximum_credits = 1000 // A little bit over the fattness for blob.
+
+/obj/structure/scale/credits/Initialize(mapload)
+ ..()
+ return INITIALIZE_HINT_LATELOAD
+
+/obj/structure/scale/credits/attackby(obj/item/used_tool, mob/user, params)
+ if(!used_tool.tool_behaviour == TOOL_WRENCH)
+ return ..()
+
+ anchored = !anchored
+ to_chat(user, "You [anchored ? "secure" : "unsecure"] \the [src].")
+ used_tool.play_tool_sound(src)
+ return TRUE
+
+/obj/structure/scale/credits/LateInitialize()
+ for(var/obj/machinery/abductor/feeder_console/found_console in GLOB.machines)
+ if(found_console.team_number != team_number)
+ continue
+
+ found_console.linked_scale = src
+
+/obj/structure/scale/credits/weighperson(mob/living/carbon/human/fatty)
+ . = ..()
+ if(!istype(fatty))
+ return FALSE
+
+ var/credits_to_add = min((fatty.fatness * credits_per_fatness), maximum_credits)
+ var/credits_to_remove = 0
+ if(scanned_people[fatty])
+ if(scanned_people[fatty] >= maximum_credits)
+ return TRUE
+
+ credits_to_remove = scanned_people[fatty]
+ else
+ scanned_people[fatty] = 0
+
+ var/credit_total = max((credits_to_add - credits_to_remove), 0)
+ if(credit_total > 0)
+ say("[credit_total] credits have been deposited into the console.")
+
+ credits += credit_total
+ scanned_people[fatty] += credit_total
+
+ return TRUE
+
+/obj/machinery/abductor/pad/feeder
+ team_number = 27
+
+/obj/machinery/computer/camera_advanced/abductor/feeder
+ team_number = 27
+ vest_mode_action = null
+ vest_disguise_action = null
+
+/obj/machinery/computer/camera_advanced/abductor/feeder/IsScientist(mob/living/carbon/human/H)
+ return TRUE
+
+/obj/item/abductor/gizmo/feeder
+ mode = GIZMO_MARK
+
+/obj/item/abductor/gizmo/feeder/ScientistCheck(mob/user)
+ return TRUE
+
+/obj/item/abductor/gizmo/attack_self(mob/user)
+ return
+
+/obj/item/abductor/gizmo/feeder/mark(atom/target, mob/living/user)
+ if(!ishuman(target))
+ return FALSE
+
+ if(target == marked)
+ to_chat(user, "You begin to teleport [target]...")
+ if(!do_after(user, 45 SECONDS, target = target)) // You have to be standing still for a while
+ return FALSE
+
+ console?.pad.Retrieve(marked)
+ return TRUE
+
+ if(target == user)
+ marked = user
+ return TRUE
+
+ prepare(target,user)
+ return TRUE
+
diff --git a/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm b/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm
new file mode 100644
index 0000000000..e7147be734
--- /dev/null
+++ b/GainStation13/code/mechanics/den abductors/purchaseble_goodies.dm
@@ -0,0 +1,88 @@
+/datum/feeders_den_goodie
+ /// What is the name of the goodie we want to buy?
+ var/name
+ /// How much credits does this cost to buy?
+ var/credit_cost = 0
+ /// How much stock of this can be bought? If this is null, infinite can be bought
+ var/initial_stock
+ /// What is the path of the item to dispense?
+ var/item_to_dispense
+
+/datum/feeders_den_goodie/food_vendor_refill
+ name = "Food Vendor Refill"
+ credit_cost = 100
+ item_to_dispense = /obj/item/vending_refill/mealdor
+
+/datum/feeders_den_goodie/gizmo
+ name = "Science Tool"
+ credit_cost = 120
+ item_to_dispense = /obj/item/abductor/gizmo/feeder
+
+/datum/feeders_den_goodie/nutripump_turbo
+ name = "Nutri-Pump TURBO Autosurgeon"
+ credit_cost = 150
+ item_to_dispense = /obj/item/autosurgeon/nutripump_turbo
+
+/datum/feeders_den_goodie/nutripump_turbo
+ name = "Mobility Nanite Core Autosurgeon"
+ credit_cost = 400
+ item_to_dispense = /obj/item/autosurgeon/fat_mobility
+
+/datum/feeders_den_goodie/fatbeam_gun
+ name = "Fatbeam gun"
+ credit_cost = 400
+ item_to_dispense = /obj/item/gun/fatbeam
+ initial_stock = 2
+
+/datum/feeders_den_goodie/grenade_weak
+ name = "Lipofier Grenade (Weak)"
+ credit_cost = 120
+ item_to_dispense = /obj/item/grenade/chem_grenade/lipoifier_weak
+ initial_stock = 6
+
+/datum/feeders_den_goodie/grenade_strong
+ name = "Lipofier Grenade (Strong)"
+ credit_cost = 360
+ item_to_dispense = /obj/item/grenade/chem_grenade/lipoifier_strong
+ initial_stock = 3
+
+/datum/feeders_den_goodie/chameleon
+ name = "Chameleon Kit"
+ credit_cost = 300
+ item_to_dispense = /obj/item/storage/box/syndie_kit/chameleon
+ initial_stock = 2
+
+/datum/feeders_den_goodie/pie_cannon
+ name = "Banana Cream Pie Cannon"
+ credit_cost = 500
+ item_to_dispense = /obj/item/pneumatic_cannon/pie/selfcharge
+ initial_stock = 2
+
+/datum/feeders_den_goodie/thermals
+ name = "Thermal Imaging Glasses"
+ credit_cost = 400
+ item_to_dispense = /obj/item/clothing/glasses/thermal/syndi
+ initial_stock = 2
+
+/datum/feeders_den_goodie/reagent_gun
+ name = "Reagent Gun"
+ credit_cost = 500
+ item_to_dispense = /obj/item/gun/chem
+
+/datum/feeders_den_goodie/protolathe
+ name = "R&D Kit"
+ credit_cost = 1500
+ item_to_dispense = /obj/item/storage/box/rndboards
+ initial_stock = 2
+
+/datum/feeders_den_goodie/docility_implant
+ name = "Docility Implant"
+ credit_cost = 100
+ item_to_dispense = /obj/item/implantcase/docile
+ initial_stock = 5
+
+/datum/feeders_den_goodie/docility_implant/livestock
+ name = "Livestock Implant"
+ credit_cost = 250
+ item_to_dispense = /obj/item/implantcase/docile/livestock
+ initial_stock = 5
diff --git a/GainStation13/code/mechanics/fatness.dm b/GainStation13/code/mechanics/fatness.dm
new file mode 100644
index 0000000000..568116eb8e
--- /dev/null
+++ b/GainStation13/code/mechanics/fatness.dm
@@ -0,0 +1,247 @@
+GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters, /area/maintenance, /area/security/prison, /area/holodeck, /area/security/vacantoffice, /area/space, /area/ruin, /area/lavaland, /area/awaymission, /area/centcom, /area/fatlab))
+
+/mob/living/carbon
+ //Due to the changes needed to create the system to hide fatness, here's some notes:
+ // -If you are making a mob simply gain or lose weight, use adjust_fatness. Try to not touch the variables directly unless you know 'em well
+ // -fatness is the value a mob is being displayed and calculated as by most things. Changes to fatness are not permanent
+ // -fatness_real is the value a mob is actually at, even if it's being hidden. For permanent changes, use this one
+ //What level of fatness is the parent mob currently at?
+ var/fatness = 0
+ //The list of items/effects that are being added/subtracted from our real fatness
+ var/fat_hiders = list()
+ //The actual value a mob is at. Is equal to fatness if fat_hider is FALSE.
+ var/fatness_real = 0
+ //Permanent fatness, which sticks around between rounds
+ var/fatness_perma = 0
+ ///At what rate does the parent mob gain weight? 1 = 100%
+ var/weight_gain_rate = 1
+ //At what rate does the parent mob lose weight? 1 = 100%
+ var/weight_loss_rate = 1
+ //Variable related to door stuckage code
+ var/doorstuck = 0
+
+ var/fullness = FULLNESS_LEVEL_HALF_FULL
+ var/fullness_reduction_timer = 0
+ var/burpslurring = 0
+
+/**
+* Adjusts the fatness level of the parent mob.
+*
+* * adjustment_amount - adjusts how much weight is gained or loss. Positive numbers add weight.
+* * type_of_fattening - what type of fattening is being used. Look at the traits in fatness.dm for valid options.
+* * ignore_rate - do we want to ignore the mob's weight gain/loss rate? This is only here for niche uses.
+*/
+/mob/living/carbon/proc/adjust_fatness(adjustment_amount, type_of_fattening = FATTENING_TYPE_ITEM, ignore_rate = FALSE)
+ if(!adjustment_amount || !type_of_fattening)
+ return FALSE
+
+ if(!HAS_TRAIT(src, TRAIT_UNIVERSAL_GAINER) && client?.prefs)
+ if(!check_weight_prefs(type_of_fattening))
+ return FALSE
+
+ var/amount_to_change = adjustment_amount
+ if(!ignore_rate)
+ if(adjustment_amount > 0)
+ amount_to_change = amount_to_change * weight_gain_rate
+ else
+ amount_to_change = amount_to_change * weight_loss_rate
+
+ fatness_real += amount_to_change
+ fatness_real = max(fatness_real, MINIMUM_FATNESS_LEVEL) //It would be a little silly if someone got negative fat.
+
+ if(client?.prefs?.max_weight) // GS13
+ fatness_real = min(fatness_real, (client?.prefs?.max_weight - 1))
+
+ fatness = fatness_real //Make their current fatness their real fatness
+
+ hiders_apply() //Check and apply hiders
+ perma_apply() //Check and apply for permanent fat
+ xwg_resize() //Apply XWG
+
+ return TRUE
+
+/mob/living/carbon/fully_heal(admin_revive)
+ fatness = 0
+ fatness_real = 0
+ . = ..()
+
+///Checks the parent mob's prefs to see if they can be fattened by the fattening_type
+/mob/living/carbon/proc/check_weight_prefs(type_of_fattening = FATTENING_TYPE_ITEM)
+ if(HAS_TRAIT(src, TRAIT_UNIVERSAL_GAINER) && !client.prefs) //Comment this second part out
+ return TRUE
+
+ if(!client?.prefs || !type_of_fattening)
+ return FALSE
+
+ switch(type_of_fattening)
+ if(FATTENING_TYPE_ITEM)
+ if(!client?.prefs?.weight_gain_items)
+ return FALSE
+
+ if(FATTENING_TYPE_FOOD)
+ if(!client?.prefs?.weight_gain_food)
+ return FALSE
+
+ if(FATTENING_TYPE_CHEM)
+ if(!client?.prefs?.weight_gain_chems)
+ return FALSE
+
+ if(FATTENING_TYPE_WEAPON)
+ if(!client?.prefs?.weight_gain_weapons)
+ return FALSE
+
+ if(FATTENING_TYPE_MAGIC)
+ if(!client?.prefs?.weight_gain_magic)
+ return FALSE
+
+ if(FATTENING_TYPE_VIRUS)
+ if(!client?.prefs?.weight_gain_viruses)
+ return FALSE
+
+ if(FATTENING_TYPE_NANITES)
+ if(!client?.prefs?.weight_gain_nanites)
+ return FALSE
+
+ if(FATTENING_TYPE_WEIGHT_LOSS)
+ if(HAS_TRAIT(src, TRAIT_WEIGHT_LOSS_IMMUNE))
+ return FALSE
+
+ return TRUE
+
+ // THE FATNESS HIDING GUIDE!!!
+ // HOW 2 FATNESS HIDE
+ //Step 1) Grab a thing that will add or reduce fatness!
+ //Step 2) Give it a character.hider_add(src) and a character.hider_remove(src) depending on the conditions you want it to meet for which it will add or remove itself from messing with a character's fatness!
+ //Step 3) Give it a proc/fat_hide([character argument]), with a return that will give the amount to shift that character's fatness by!
+ //Step 4) There is no step 4, you did it bucko!
+ //Wanna see an example? Search for /obj/item/bluespace_belt !!!
+
+/mob/living/carbon/proc/hider_add(hide_source)
+ if(!(hide_source in fat_hiders))
+ fat_hiders += hide_source
+
+ return TRUE
+
+/mob/living/carbon/proc/hider_remove(hide_source)
+ if(hide_source in fat_hiders)
+ fat_hiders -= hide_source
+ return TRUE
+
+/mob/living/carbon/proc/hiders_calc()
+ var/hiders_value = 0
+ for(var/hider in fat_hiders)
+ var/hide_values = hider:fat_hide(src)
+ if(!islist(hide_values))
+ hiders_value += hide_values
+ else
+ for(var/hide_value in hide_values)
+ hiders_value += hide_value
+ return hiders_value
+
+/mob/living/carbon/proc/hiders_apply()
+ if(fat_hiders) //do we have any hiders active?
+ var/fatness_over = hiders_calc() //calculate the sum of all hiders
+ fatness = fatness + fatness_over //Then, make their current fatness the sum of their real plus/minus the calculated amount
+ if(client?.prefs?.max_weight) //Check their prefs
+ fatness = min(fatness, (client?.prefs?.max_weight - 1)) //And make sure it's not above their preferred max
+
+/mob/living/carbon/proc/perma_apply()
+ if(fatness_perma > 0) //Check if we need to make calcs at all
+ fatness = fatness + fatness_perma //Add permanent fat to fatness
+ if(client?.prefs?.max_weight) //Check for max weight prefs
+ fatness = min(fatness, (client?.prefs?.max_weight - 1)) //Apply max weight prefs
+
+/mob/living/carbon/proc/adjust_perma(adjustment_amount, type_of_fattening = FATTENING_TYPE_ITEM)
+ if(!client)
+ return FALSE
+ if(!client.prefs.weight_gain_permanent)
+ return FALSE
+
+ if(!adjustment_amount || !type_of_fattening)
+ return FALSE
+
+ if(!HAS_TRAIT(src, TRAIT_UNIVERSAL_GAINER) && client?.prefs)
+ if(!check_weight_prefs(type_of_fattening))
+ return FALSE
+ var/amount_to_change = adjustment_amount
+
+ if(adjustment_amount > 0)
+ amount_to_change = amount_to_change * weight_gain_rate
+ else
+ amount_to_change = amount_to_change * weight_loss_rate
+
+ fatness_perma += amount_to_change
+ fatness_perma = max(fatness_perma, MINIMUM_FATNESS_LEVEL)
+
+ if(client?.prefs?.max_weight) // GS13
+ fatness_perma = min(fatness_perma, (client?.prefs?.max_weight - 1))
+
+/mob/living/carbon/human/handle_breathing(times_fired)
+ . = ..()
+ fatness = fatness_real
+ hiders_apply()
+ perma_apply()
+ xwg_resize()
+
+/mob/living/carbon/proc/xwg_resize()
+ if(client?.prefs?.weight_gain_extreme && !normalized)
+ var/xwg_size = sqrt(fatness/FATNESS_LEVEL_BLOB)
+ xwg_size = min(xwg_size, RESIZE_MACRO)
+ xwg_size = max(xwg_size, custom_body_size*0.01)
+ if(xwg_size > RESIZE_BIG) //check if the size needs capping otherwise don't bother searching the list
+ if(!is_type_in_list(get_area(src), GLOB.uncapped_resize_areas)) //if the area is not int the uncapped whitelist and new size is over the cap
+ xwg_size = RESIZE_BIG
+ resize(xwg_size)
+
+/proc/get_fatness_level_name(fatness_amount)
+ if(fatness_amount < FATNESS_LEVEL_FAT)
+ return "Normal"
+ if(fatness_amount < FATNESS_LEVEL_FATTER)
+ return "Fat"
+ if(fatness_amount < FATNESS_LEVEL_VERYFAT)
+ return "Fatter"
+ if(fatness_amount < FATNESS_LEVEL_OBESE)
+ return "Very Fat"
+ if(fatness_amount < FATNESS_LEVEL_MORBIDLY_OBESE)
+ return "Obese"
+ if(fatness_amount < FATNESS_LEVEL_EXTREMELY_OBESE)
+ return "Morbidly Obese"
+ if(fatness_amount < FATNESS_LEVEL_BARELYMOBILE)
+ return "Extremely Obese"
+ if(fatness_amount < FATNESS_LEVEL_IMMOBILE)
+ return "Barely Mobile"
+ if(fatness_amount < FATNESS_LEVEL_BLOB)
+ return "Immobile"
+
+ return "Blob"
+
+/// Finds what the next fatness level for the parent mob would be based off of fatness_real.
+/mob/living/carbon/proc/get_next_fatness_level()
+ if(fatness_real < FATNESS_LEVEL_FAT)
+ return FATNESS_LEVEL_FAT
+ if(fatness_real < FATNESS_LEVEL_FATTER)
+ return FATNESS_LEVEL_FATTER
+ if(fatness_real < FATNESS_LEVEL_VERYFAT)
+ return FATNESS_LEVEL_VERYFAT
+ if(fatness_real < FATNESS_LEVEL_OBESE)
+ return FATNESS_LEVEL_OBESE
+ if(fatness_real < FATNESS_LEVEL_MORBIDLY_OBESE)
+ return FATNESS_LEVEL_MORBIDLY_OBESE
+ if(fatness_real < FATNESS_LEVEL_EXTREMELY_OBESE)
+ return FATNESS_LEVEL_EXTREMELY_OBESE
+ if(fatness_real < FATNESS_LEVEL_BARELYMOBILE)
+ return FATNESS_LEVEL_BARELYMOBILE
+ if(fatness_real < FATNESS_LEVEL_IMMOBILE)
+ return FATNESS_LEVEL_IMMOBILE
+ if(fatness_real < FATNESS_LEVEL_BLOB)
+ return FATNESS_LEVEL_BLOB
+
+ return FATNESS_LEVEL_BLOB
+
+/// How much real fatness does the current mob have to gain until they reach the next level? Return FALSE if they are maxed out.
+/mob/living/carbon/proc/fatness_until_next_level()
+ var/needed_fatness = get_next_fatness_level() - fatness_real
+ needed_fatness = max(needed_fatness, 0)
+
+ return needed_fatness
+
diff --git a/GainStation13/code/mechanics/fatrousal.dm b/GainStation13/code/mechanics/fatrousal.dm
new file mode 100644
index 0000000000..65d28bb30b
--- /dev/null
+++ b/GainStation13/code/mechanics/fatrousal.dm
@@ -0,0 +1,30 @@
+/datum/quirk/fatrousal
+ name = "Adiposexual Response"
+ desc = "Your adipose tissue develops and shrinks depending on your arousal."
+ value = 0 //ERP quirk
+ gain_text = "Your body feels like it could grow at any moment."
+ lose_text = "The feeling of impending growth is gone..."
+ category = CATEGORY_SEXUAL
+ mob_trait = TRAIT_FATROUSAL
+
+/datum/quirk/fatrousal/add()
+ if(iscarbon(quirk_holder))
+ var/mob/living/carbon/C = quirk_holder
+ C.hider_add(src)
+
+/datum/quirk/fatrousal/remove()
+ if(iscarbon(quirk_holder))
+ var/mob/living/carbon/C = quirk_holder
+ C.hider_remove(src)
+
+/datum/quirk/fatrousal/proc/fat_hide(var/mob/living/carbon/user)
+ if(iscarbon(quirk_holder))
+ var/mob/living/carbon/C = quirk_holder
+ return C.getArousalLoss()*35
+ return FALSE
+
+///mob/living/adjustArousalLoss(amount, updating_arousal=1)
+// if(HAS_TRAIT(src, TRAIT_FATROUSAL))
+// amount = amount * 0.2
+// ..()
+//
diff --git a/GainStation13/code/mechanics/fattening_trap.dm b/GainStation13/code/mechanics/fattening_trap.dm
new file mode 100644
index 0000000000..6a43ffe7cb
--- /dev/null
+++ b/GainStation13/code/mechanics/fattening_trap.dm
@@ -0,0 +1,27 @@
+/obj/structure/trap/fattening
+ name = "fattening trap"
+ desc = "A trap that ensures you won't be stepping around for much longer."
+ icon = 'GainStation13/icons/obj/structure/traps.dmi'
+ icon_state = "trap-fattening"
+
+ var/fattening_amount = 250 // Using a variable incase we want to have a stronger version.
+ // This is at half of the power of the singe-use cannonshot fatray.
+
+/obj/structure/trap/fattening/trap_effect(mob/living/carbon/crosser)
+ if(ishuman(crosser))
+ to_chat(crosser, "You feel heavier!")
+ crosser.adjust_fatness(fattening_amount, FATTENING_TYPE_MAGIC)
+
+/obj/structure/trap/belch
+ name = "belch trap"
+ desc = "A trap that forcefully releases all the air in your stomach."
+ icon = 'GainStation13/icons/obj/structure/traps.dmi'
+ icon_state = "trap-belching"
+
+/obj/structure/trap/belch/trap_effect(mob/living/crosser)
+ if(crosser?.client?.prefs.weight_gain_chems)
+ to_chat(crosser, "You feel all of the air leave your stomach!")
+ crosser.emote(pick("belch","burp"))
+
+ crosser.Knockdown(500)
+
\ No newline at end of file
diff --git a/GainStation13/code/mechanics/helplessness.dm b/GainStation13/code/mechanics/helplessness.dm
new file mode 100644
index 0000000000..7e5a6828f6
--- /dev/null
+++ b/GainStation13/code/mechanics/helplessness.dm
@@ -0,0 +1,20 @@
+/mob/living/carbon/can_buckle()
+ if(HAS_TRAIT(src, TRAIT_NO_BUCKLE))
+ return FALSE
+
+ return ..()
+
+/datum/species/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self)
+ if(HAS_TRAIT(H, TRAIT_NO_BACKPACK) && slot == SLOT_BACK)
+ to_chat(H, "You are too fat to wear anything on your back.")
+ return FALSE
+
+ if(!istype(I, /obj/item/clothing/under/color/grey/modular) && HAS_TRAIT(H, TRAIT_NO_JUMPSUIT) && slot == SLOT_W_UNIFORM)
+ to_chat(H, "You are too fat to wear [I].")
+ return FALSE
+
+ if(HAS_TRAIT(H, TRAIT_NO_MISC) && (slot == SLOT_SHOES || slot == SLOT_GLOVES || slot == SLOT_WEAR_SUIT))
+ to_chat(H, "You are too fat to wear [I].")
+ return FALSE
+
+ return ..()
diff --git a/GainStation13/code/mechanics/hunger.dm b/GainStation13/code/mechanics/hunger.dm
new file mode 100644
index 0000000000..c87a34d7cc
--- /dev/null
+++ b/GainStation13/code/mechanics/hunger.dm
@@ -0,0 +1,30 @@
+///I'm trying my best allright
+/mob/living/carbon/human
+ icon = 'GainStation13/icons/mob/fat.dmi'
+ var/hunger = 0
+
+/mob/living/carbon/human/Life()
+ . = ..()
+ hunger = hunger + 1
+ switch(hunger)
+ if(0 to 10)
+ icon_state = "fat_m_body"
+
+ update_body()
+ //chubby
+ if(11 to 20)
+ icon_state = "obese_m_body"
+ update_body()
+ //fed
+ if(21 to 30)
+ icon_state = "mobese_m_body"
+ update_body()
+ //full
+ if(31 to 40)
+ icon_state = "imm_m_body"
+ update_body()
+ //fat
+ else
+ icon_state = "blob_m_body"
+ update_body()
+ //chungus
\ No newline at end of file
diff --git a/GainStation13/code/mechanics/infestation.dm b/GainStation13/code/mechanics/infestation.dm
new file mode 100644
index 0000000000..2374e9c05a
--- /dev/null
+++ b/GainStation13/code/mechanics/infestation.dm
@@ -0,0 +1,100 @@
+
+/datum/round_event_control/dessert_infestation
+ name = "Dessert Infestation"
+ typepath = /datum/round_event/dessert_infestation
+ weight = 6
+ max_occurrences = 3
+ min_players = 6
+
+/datum/round_event/dessert_infestation
+ announceWhen = 100
+ var/static/list/dessert_station_areas_blacklist = typecacheof(/area/space,
+ /area/shuttle,
+ /area/mine,
+ /area/holodeck,
+ /area/ruin,
+ /area/hallway,
+ /area/hallway/primary,
+ /area/hallway/secondary,
+ /area/hallway/secondary/entry,
+ /area/engine/supermatter,
+ /area/engine/atmospherics_engine,
+ /area/engine/engineering/reactor_core,
+ /area/engine/engineering/reactor_control,
+ /area/ai_monitored/turret_protected,
+ /area/layenia/cloudlayer,
+ /area/asteroid/nearstation,
+ /area/science/server,
+ /area/science/explab,
+ /area/science/xenobiology,
+ /area/security/processing)
+ var/spawncount = 1
+ fakeable = FALSE
+
+/datum/round_event/dessert_infestation/setup()
+ announceWhen = rand(announceWhen, announceWhen + 50)
+ spawncount = rand(4, 7)
+
+/datum/round_event/dessert_infestation/announce(fake)
+ priority_announce("Unidentified lifesigns detected aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
+
+/datum/round_event/dessert_infestation/start()
+ var/list/area/stationAreas = list()
+ var/list/area/eligible_areas = list()
+ for(var/area/A in world) // Get the areas in the Z level
+ if(A.z == SSmapping.station_start)
+ stationAreas += A
+ for(var/area/place in stationAreas) // first we check if it's a valid area
+ if(place.outdoors)
+ continue
+ if(place.areasize < 16)
+ continue
+ if(is_type_in_typecache(place, dessert_station_areas_blacklist))
+ continue
+ eligible_areas += place
+ for(var/area/place in eligible_areas) // now we check if there are people in that area
+ var/numOfPeople
+ for(var/mob/living/carbon/H in place)
+ numOfPeople++
+ break
+ if(numOfPeople > 0)
+ eligible_areas -= place
+
+ var/validFound = FALSE
+ var/list/turf/validTurfs = list()
+ var/area/pickedArea
+ while(!validFound || !eligible_areas.len)
+ pickedArea = pick_n_take(eligible_areas)
+ var/list/turf/t = get_area_turfs(pickedArea, SSmapping.station_start)
+ for(var/turf/thisTurf in t) // now we check if it's a closed turf, cold turf or occupied turf and yeet it
+ if(isopenturf(thisTurf))
+ var/turf/open/tempGet = thisTurf
+ if(tempGet.air.temperature <= T0C)
+ t -= thisTurf
+ continue
+ if(isclosedturf(thisTurf))
+ t -= thisTurf
+ else
+ for(var/obj/O in thisTurf)
+ if(O.density && !(istype(O, /obj/structure/table)))
+ t -= thisTurf
+ break
+ if(t.len >= spawncount) //Is the number of available turfs equal or bigger than spawncount?
+ validFound = TRUE
+ validTurfs = t
+
+ if(!eligible_areas.len)
+ message_admins("No eligible areas for spawning dessert mobs.")
+ return WAITING_FOR_SOMETHING
+
+ notify_ghosts("A group of feeder mobs has spawned in [pickedArea]!", source=pickedArea, action=NOTIFY_ATTACK, flashwindow = FALSE)
+ while(spawncount > 0 && validTurfs.len)
+ spawncount--
+ var/turf/pickedTurf = pick_n_take(validTurfs)
+ if(spawncount != 0)
+ var/spawn_type = /mob/living/simple_animal/hostile/feed/chocolate_slime
+ spawn_atom_to_turf(spawn_type, pickedTurf, 1, FALSE)
+ else
+ var/spawn_type = /mob/living/simple_animal/hostile/feed/chocolate_slime/creambeast
+ spawn_atom_to_turf(spawn_type, pickedTurf, 1, FALSE)
+ return SUCCESSFUL_SPAWN
diff --git a/GainStation13/code/mechanics/metal_cruncher.dm b/GainStation13/code/mechanics/metal_cruncher.dm
new file mode 100644
index 0000000000..2dcd57f9cf
--- /dev/null
+++ b/GainStation13/code/mechanics/metal_cruncher.dm
@@ -0,0 +1,87 @@
+/datum/quirk/metal_cruncher
+ name = "Metal Cruncher"
+ desc = "You can eat most minerals. Brush your teeth."
+ value = 0 //ERP quirk
+ gain_text = "You feel like you could eat steel."
+ lose_text = "Your teeth hurt too much..."
+ category = CATEGORY_FOOD
+ mob_trait = TRAIT_METAL_CRUNCHER
+
+/obj/item/stack
+ var/crunch_value = 0
+
+/obj/item/stack/attack(mob/living/M, mob/living/user)
+ if(HAS_TRAIT(M, TRAIT_METAL_CRUNCHER))
+ if(crunch_value > 0)
+ if(M == user)
+ user.visible_message("[user] crunches on some of [src].", "You crunch on some of [src].")
+ else
+ M.visible_message("[user] attempts to feed some of [src] to [M].", "[user] attempts to feed some of [src] to [M].")
+ playsound(M,'sound/items/eatfood.ogg', rand(10,50), 1)
+ use(1)
+ M.nutrition += crunch_value
+ if(HAS_TRAIT(M, TRAIT_VORACIOUS))
+ M.changeNext_move(CLICK_CD_MELEE * 0.5)
+ return
+ . = ..()
+
+/obj/item/stack/cable_coil
+ crunch_value = 2
+/obj/item/stack/sheet/metal
+ crunch_value = 4
+/obj/item/stack/rods
+ crunch_value = 2
+/obj/item/stack/sheet/glass
+ crunch_value = 2
+/obj/item/stack/sheet/rglass
+ crunch_value = 4
+/obj/item/stack/sheet/plasmaglass
+ crunch_value = 12
+/obj/item/stack/sheet/plasmarglass
+ crunch_value = 14
+/obj/item/stack/sheet/titaniumglass
+ crunch_value = 27
+/obj/item/stack/sheet/plastitaniumglass
+ crunch_value = 37
+/obj/item/stack/sheet/plasteel
+ crunch_value = 14
+/obj/item/stack/sheet/durathread
+ crunch_value = 10
+/obj/item/stack/sheet/plastic
+ crunch_value = 2
+/obj/item/stack/sheet/micro_bricks
+ crunch_value = 1
+/obj/item/stack/sheet/cardboard
+ crunch_value = 1
+/obj/item/stack/sheet/mineral/calorite
+ crunch_value = 100
+/obj/item/stack/sheet/mineral/sandstone
+ crunch_value = 1
+/obj/item/stack/sheet/mineral/uranium
+ crunch_value = 50
+/obj/item/stack/sheet/mineral/plasma
+ crunch_value = 10
+/obj/item/stack/sheet/mineral/gold
+ crunch_value = 20
+/obj/item/stack/sheet/mineral/silver
+ crunch_value = 15
+/obj/item/stack/sheet/mineral/titanium
+ crunch_value = 25
+/obj/item/stack/sheet/mineral/plastitanium
+ crunch_value = 35
+/obj/item/stack/sheet/mineral/adamantine
+ crunch_value = 75
+/obj/item/stack/sheet/mineral/mythril
+ crunch_value = 75
+/obj/item/stack/sheet/mineral/coal
+ crunch_value = 50
+/obj/item/stack/sheet/mineral/wood
+ crunch_value = 4
+/obj/item/stack/sheet/mineral/bamboo
+ crunch_value = 10
+/obj/item/stack/sheet/mineral/shadoww
+ crunch_value = 15
+/obj/item/stack/sheet/mineral/gmushroom
+ crunch_value = 15
+/obj/item/stack/sheet/mineral/plaswood
+ crunch_value = 15
diff --git a/GainStation13/code/mechanics/permanent_fat.dm b/GainStation13/code/mechanics/permanent_fat.dm
new file mode 100644
index 0000000000..fe9cba908f
--- /dev/null
+++ b/GainStation13/code/mechanics/permanent_fat.dm
@@ -0,0 +1,53 @@
+/mob/living/carbon
+ var/savekey
+ var/ckeyslot
+
+/mob/living/carbon/proc/perma_fat_save(mob/living/carbon/character)
+ var/key = savekey
+ if(!key)
+ return FALSE
+ var/filename = "preferences.sav"
+ var/path = "data/player_saves/[key[1]]/[key]/[filename]"
+
+ var/savefile/S = new /savefile(path)
+ if(!path)
+ return FALSE
+
+ if(character.ckeyslot)
+ var/slot = character.ckeyslot
+ S.cd = "/character[slot]"
+
+ var/persi
+ S["weight_gain_persistent"] >> persi
+ if(persi)
+ WRITE_FILE(S["starting_weight"] , character.fatness_real)
+ var/perma
+ S["weight_gain_permanent"] >> perma
+ if(S["weight_gain_permanent"])
+ WRITE_FILE(S["permanent_fat"] , character.fatness_perma)
+
+/*
+/datum/preferences/proc/perma_fat_save(character)
+ if(iscarbon(character))
+ var/mob/living/carbon/C = character
+ if(!C.client.prefs.weight_gain_permanent && !C.client.prefs.weight_gain_persistent)
+ return FALSE
+ if(!path)
+ return FALSE
+ if(world.time < savecharcooldown)
+ if(istype(parent))
+ to_chat(parent, "You're attempting to save your character a little too fast. Wait half a second, then try again.")
+
+ return FALSE
+
+ savecharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
+ var/savefile/S = new /savefile(path)
+ if(!S)
+ return FALSE
+ S.cd = "/character[default_slot]"
+
+ if(C.client.prefs.weight_gain_persistent)
+ WRITE_FILE(S["starting_weight"] , C.fatness_real)
+ if(C.client.prefs.weight_gain_permanent)
+ WRITE_FILE(S["permanent_fat"] , C.fatness_perma)
+*/
diff --git a/GainStation13/code/mechanics/spells.dm b/GainStation13/code/mechanics/spells.dm
new file mode 100644
index 0000000000..198bc0bf66
--- /dev/null
+++ b/GainStation13/code/mechanics/spells.dm
@@ -0,0 +1,141 @@
+/obj/effect/proc_holder/spell/targeted/touch/add_weight
+ name = "Fattening"
+ desc = "Channel fattening energy to your hand to fatten people with."
+ drawmessage = "You channel fattening energy into your hand."
+ dropmessage = "You let the fattening energy from your hand dissipate."
+ hand_path = /obj/item/melee/touch_attack/fattening
+ action_icon_state = "spell_default"
+ charge_max = 200
+ clothes_req = FALSE
+
+/obj/effect/proc_holder/spell/targeted/touch/add_weight/transfer
+ name = "Weight transfer"
+ hand_path = /obj/item/melee/touch_attack/fattening/transfer
+ charge_max = 100
+
+/obj/effect/proc_holder/spell/targeted/touch/add_weight/steal
+ name = "Weight steal"
+ hand_path = /obj/item/melee/touch_attack/fattening/steal
+ charge_max = 100
+
+/obj/item/melee/touch_attack/fattening
+ name = "\improper fattening touch"
+ desc = "The calories from multiple donuts compressed into pure energy."
+ catchphrase = null
+ on_use_sound = 'sound/weapons/pulse.ogg'
+ icon = 'GainStation13/icons/obj/spells/spell_items.dmi'
+ icon_state = "add-hand"
+ ///How much weight is added?
+ var/weight_to_add = 300
+ ///What verb is used for the spell?
+ var/fattening_verb = "fattens"
+ ///Is weight being transfered from the user to another mob?
+
+
+/obj/item/melee/touch_attack/fattening/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || !iscarbon(target) || target == user)
+ return FALSE
+
+ var/mob/living/carbon/gainer = target
+ if(!gainer || !weight_to_add)
+ return FALSE
+
+ if(!gainer.adjust_fatness(weight_to_add, FATTENING_TYPE_MAGIC))
+ to_chat(user,"")
+ return FALSE
+
+ gainer.visible_message("[user] [fattening_verb] [target]!","[user] [fattening_verb] you!")
+ return ..()
+
+/obj/item/melee/touch_attack/fattening/transfer
+ name = "\improper weight transfer touch"
+ desc = "Your weight compressed into a fattening energy."
+ fattening_verb = "transfers weight to"
+ icon_state = "transfer-hand"
+
+/obj/item/melee/touch_attack/fattening/transfer/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(!proximity || !target || target == user)
+ return FALSE
+
+ if(weight_to_add > user.fatness_real || !user.adjust_fatness(-weight_to_add, FATTENING_TYPE_MAGIC))
+ to_chat(user, "")
+ return FALSE
+
+ return ..()
+
+/obj/item/melee/touch_attack/fattening/steal
+ name = "\improper weight theft touch"
+ desc = "Energy that is eager to take weight."
+ fattening_verb = "steals weight from"
+ weight_to_add = -300
+ icon_state = "steal-hand"
+
+/obj/item/melee/touch_attack/fattening/steal/afterattack(atom/target, mob/living/carbon/user, proximity)
+ var/mob/living/carbon/loser = target
+ if(!proximity || !iscarbon(target) || target == user)
+ return FALSE
+
+ if(loser.fatness < -weight_to_add)
+ to_chat(user, "")
+ return FALSE
+
+ . = ..()
+ if(. != null && !.)
+ return FALSE
+
+ user.adjust_fatness(-weight_to_add, FATTENING_TYPE_MAGIC)
+
+/obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps/fat
+ name = "Fat Traps!"
+ desc = "Summon a number of traps to fatten your enemies."
+ action_icon = 'GainStation13/icons/obj/structure/traps.dmi'
+ action_icon_state = "trap-fattening"
+
+ clothes_req = FALSE
+ summon_type = list(
+ /obj/structure/trap/fattening
+ )
+
+ summon_amt = 4
+
+/obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps/fat/belch
+ name = "Belch Traps!"
+ desc = "Summon a number of traps to force your enemies to belch."
+ action_icon_state = "trap-belching"
+ summon_type = list(
+ /obj/structure/trap/belch
+ )
+
+///Spellbooks
+/obj/item/book/granter/spell/fattening
+ name = "fattening tome"
+ spell = /obj/effect/proc_holder/spell/targeted/touch/add_weight
+ spellname = "fattening"
+ icon = 'GainStation13/icons/obj/spells/spellbooks.dmi'
+ icon_state = "add_weight"
+ desc = "This book feels warm to the touch."
+ page_time = 10
+
+/obj/item/book/granter/spell/fattening/transfer
+ name = "weight transfer tome"
+ spell = /obj/effect/proc_holder/spell/targeted/touch/add_weight/transfer
+ spellname = "weight transfer"
+ icon_state = "transfer_weight"
+ desc = "This book feels warm to the touch."
+
+/obj/item/book/granter/spell/fattening/steal
+ name = "weight steal tome"
+ spell = /obj/effect/proc_holder/spell/targeted/touch/add_weight/steal
+ spellname = "weight steal"
+ icon_state = "steal_weight"
+ desc = "This book feels warm to the touch."
+
+/obj/item/book/granter/spell/fattening/traps
+ name = "fattening trap tome"
+ spell = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps/fat
+ spellname = "fattening traps"
+
+/obj/item/book/granter/spell/fattening/belch
+ name = "belch trap tome"
+ spell = /obj/effect/proc_holder/spell/aoe_turf/conjure/the_traps/fat/belch
+ spellname = "belch traps"
diff --git a/GainStation13/code/mechanics/wand.dm b/GainStation13/code/mechanics/wand.dm
new file mode 100644
index 0000000000..d345ca008a
--- /dev/null
+++ b/GainStation13/code/mechanics/wand.dm
@@ -0,0 +1,57 @@
+/obj/item/gun/magic/wand/food
+ name = "Wand of Gluttony"
+ desc = "Summons delicious fattening foods"
+ icon = 'GainStation13/icons/obj/magic.dmi'
+ icon_state = "food_wand"
+ max_charges = 15
+ ammo_type = /obj/item/ammo_casing/magic/food
+
+/obj/item/gun/magic/wand/food/overpowered //This is a more overpowered version of the item
+ name = "Strong wand of Gluttony"
+ max_charges = 100
+ ammo_type = /obj/item/ammo_casing/magic/food/strong
+
+/obj/item/ammo_casing/magic/food
+ projectile_type = /obj/item/projectile/magic/food
+
+/obj/item/ammo_casing/magic/food/strong
+ projectile_type = /obj/item/projectile/magic/food/strong
+
+/obj/item/projectile/magic/food
+ name = "bolt of food"
+ pass_flags = PASSGLASS|PASSDOOR|PASSGRILLE
+ ///What foods are able to be spawned by the wand?
+ var/list/spawnable_foods = list(
+ /obj/item/reagent_containers/food/snacks/burger/bigbite,
+ /obj/item/reagent_containers/food/snacks/donut/plain,
+ /obj/item/reagent_containers/food/snacks/donut/glaze,
+ /obj/item/reagent_containers/food/snacks/store/cake/cheese,
+ /obj/item/reagent_containers/food/snacks/store/cake/bscc,
+ /obj/item/reagent_containers/food/snacks/store/cake/bsvc,
+ /obj/item/reagent_containers/food/snacks/store/cake/chocolate,
+ /obj/item/reagent_containers/food/snacks/hotdog,
+ /obj/item/reagent_containers/food/snacks/pizza/margherita,
+ /obj/item/reagent_containers/food/snacks/pizza/meat,
+ )
+
+ ///How much Lipoifier should be added to the spawned in food? Keep this at 10 maximum.
+ var/lipoifier_to_add = 5
+
+/obj/item/projectile/magic/food/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/turf/floor = get_turf(target)
+ if(!floor || iswallturf(floor))
+ return FALSE
+
+ var/food_to_spawn = pick(spawnable_foods)
+ var/obj/item/reagent_containers/food/snacks/spawned_food = new food_to_spawn(floor)
+ if(!spawned_food)
+ return FALSE
+
+ spawned_food.reagents.add_reagent(/datum/reagent/consumable/lipoifier, lipoifier_to_add)
+ return TRUE
+
+/obj/item/projectile/magic/food/strong
+ name = "strong bolt of food"
+ lipoifier_to_add = 10
diff --git a/GainStation13/code/mechanics/water_sponge.dm b/GainStation13/code/mechanics/water_sponge.dm
new file mode 100644
index 0000000000..b349a9cc3d
--- /dev/null
+++ b/GainStation13/code/mechanics/water_sponge.dm
@@ -0,0 +1,93 @@
+/datum/quirk/water_sponge
+ name = "Water Sponge"
+ desc = "You can hold lots of water in you! Careful with showers!"
+ value = 0 //ERP quirk
+ gain_text = "You feel absorbant."
+ lose_text = "You don't feel absorbant anymore."
+ category = CATEGORY_FOOD
+ mob_trait = TRAIT_WATER_SPONGE
+
+/datum/reagent/water/on_mob_add(mob/living/L, amount)
+ if(HAS_TRAIT(L, TRAIT_WATER_SPONGE))
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ C.hider_add(src)
+ . = ..()
+
+/datum/reagent/water/on_mob_delete(mob/living/L)
+ if(HAS_TRAIT(L, TRAIT_WATER_SPONGE))
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ C.hider_remove(src)
+ . = ..()
+
+/datum/reagent/water/reaction_mob(mob/living/M, method, reac_volume)
+ . = ..()
+ if(HAS_TRAIT(M, TRAIT_WATER_SPONGE))
+ if(method == TOUCH)
+ M.reagents.add_reagent(/datum/reagent/water, reac_volume/2)
+ if(method == VAPOR)
+ M.reagents.add_reagent(/datum/reagent/water, reac_volume/3)
+
+
+/datum/reagent/water/proc/fat_hide(mob/living/carbon/user)
+ return volume * 3.5
+
+/obj/machinery/shower/process()
+ ..()
+ for(var/atom/movable/AM in loc)
+ if(iscarbon(AM))
+ if(HAS_TRAIT(AM, TRAIT_WATER_SPONGE))
+ var/mob/living/carbon/L = AM
+ L.reagents.add_reagent(/datum/reagent/water, 3)
+
+/mob/living/carbon/proc/water_check(datum/gas_mixture/breath)
+ if(HAS_TRAIT(src, TRAIT_WATER_SPONGE))
+ if(breath)
+ if(breath.gases)
+ var/breath_gases = breath.gases
+ if(breath_gases[/datum/gas/water_vapor])
+ var/H2O_pp = breath.get_breath_partial_pressure(breath_gases[/datum/gas/water_vapor])
+ reagents.add_reagent(/datum/reagent/water, H2O_pp/10)
+ breath_gases[/datum/gas/water_vapor] -= H2O_pp
+
+/obj/structure/sink
+ var/mob/living/attached
+
+/obj/structure/sink/MouseDrop(mob/living/target)
+ . = ..()
+ if(!ishuman(usr) || !usr.canUseTopic(src, BE_CLOSE) || !isliving(target))
+ return
+ if(attached)
+ visible_message("[attached] is detached from [src].")
+ attached = null
+ return
+ if(Adjacent(target) && usr.Adjacent(target))
+ usr.visible_message("[usr] attaches [target] to [src].", "You attach [target] to [src].")
+ add_fingerprint(usr)
+ attached = target
+ START_PROCESSING(SSobj, src)
+
+/obj/structure/sink/process()
+ if(!(get_dist(src, attached) <= 1 && isturf(attached.loc)))
+ to_chat(attached, "[attached] is ripped from the sink!") // GS13
+ attached = null
+ return PROCESS_KILL
+ if(attached)
+ playsound(attached, 'sound/vore/pred/swallow_02.ogg', rand(10,50), 1)
+ attached.reagents.add_reagent(/datum/reagent/water, 5)
+ else
+ return PROCESS_KILL
+
+/obj/structure/sink/attack_hand(mob/living/user)
+ if(attached)
+ visible_message("[attached] is detached from [src]")
+ attached = null
+ return
+
+/obj/machinery/pool/controller/process_reagents()
+ for(var/turf/open/pool/W in linked_turfs)
+ for(var/mob/living/carbon/human/swimee in W)
+ if(HAS_TRAIT(swimee, TRAIT_WATER_SPONGE))
+ swimee.reagents.add_reagent(/datum/reagent/water, 5)
+ ..()
diff --git a/GainStation13/code/mechanics/web_weaving.dm b/GainStation13/code/mechanics/web_weaving.dm
new file mode 100644
index 0000000000..a2a761eedf
--- /dev/null
+++ b/GainStation13/code/mechanics/web_weaving.dm
@@ -0,0 +1,114 @@
+/datum/quirk/web_weaving
+ name = "Web Weaver"
+ desc = "for whatever reason, you are able to weave silk webs, albeit to a limited extent"
+ value = 0 //ERP quirk
+ gain_text = "You find yourself able to weave webs."
+ lose_text = "You are no longer able to weave webs."
+ category = CATEGORY_SEXUAL
+ mob_trait = TRAIT_WEB_WEAVER
+ ///What action is linked with this quirk?
+ var/datum/action/innate/wrap_target/linked_action1
+ var/datum/action/innate/make_web/linked_action2
+
+/datum/quirk/web_weaving/post_add()
+ linked_action1 = new
+ linked_action1.Grant(quirk_holder)
+ linked_action2 = new
+ linked_action2.Grant(quirk_holder)
+
+/datum/quirk/web_weaving/remove()
+ linked_action1.Remove(quirk_holder)
+ linked_action2.Remove(quirk_holder)
+ return ..()
+
+/datum/action/innate/wrap_target
+ name = "wrap"
+ desc = "encases a humanoid in a web cocoon."
+ icon_icon = 'GainStation13/icons/obj/clothing/web.dmi'
+ button_icon_state = "web_bindings"
+ background_icon_state = "bg_alien"
+
+/datum/action/innate/wrap_target/Activate()
+ var/mob/living/carbon/user = owner
+ if(!user || !ishuman(user))
+ return FALSE
+
+ var/mob/living/carbon/human/target = user.pulling
+ if(!target || !ishuman(target) || user.grab_state < GRAB_AGGRESSIVE) //Add a check for a bondage pref whenever that gets added in.
+ to_chat(user, "You need to aggressively grab a humanoid to use this.")
+ return FALSE
+
+ if(target.wear_suit)
+ var/obj/item/clothing/suit = target.wear_suit
+ if(istype(suit, /obj/item/clothing/suit/straight_jacket/web))
+ user.visible_message("[user] begins to fully encase [target] in a cocoon!", "You begin to fully encase [target] in a cocoon.")
+ if(!do_after_mob(user, target, 30 SECONDS))
+ return FALSE
+
+ var/obj/structure/spider/cocoon/quirk/spawned_cocoon = new(target.loc)
+ if(!target.forceMove(spawned_cocoon))
+ qdel(spawned_cocoon)
+ return FALSE
+
+ spawned_cocoon.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
+ var/cocoon_size = target.size_multiplier
+ var/matrix/new_matrix = new
+
+ new_matrix.Scale(cocoon_size)
+ new_matrix.Translate(0,16 * (cocoon_size-1))
+ spawned_cocoon.transform = new_matrix
+
+ return TRUE
+
+ user.visible_message("[user] attempts to remove [target]'s [target.wear_suit]!", "You attempt to remove [target]'s [target.wear_suit].")
+ if(!do_after_mob(user, target, 10 SECONDS) || !target.dropItemToGround(suit))
+ return FALSE
+
+ var/obj/item/clothing/suit/straight_jacket/web/wrapping = new
+ if(!wrapping)
+ return FALSE
+
+ user.visible_message("[user] attempts to wrap [target] inside of [wrapping]!", "You attempt to wrap [target] inside of [wrapping].")
+ if(!do_after_mob(user, target, 20 SECONDS) || !target.equip_to_slot_if_possible(wrapping, SLOT_WEAR_SUIT, TRUE, TRUE))
+ user.visible_message("[user] fails to wrap [target] inside of [wrapping]!", "You fail to wrap [target] inside of [wrapping].")
+ return FALSE
+
+ user.visible_message("[user] successfully [target] inside of [wrapping]!", "You successfully wrap [target] inside of [wrapping].")
+ return TRUE
+
+/obj/item/clothing/suit/straight_jacket/web
+ name = "web bindings"
+ desc = "A mesh of sticky web that binds whoever is stuck inside of it"
+ icon = 'GainStation13/icons/obj/clothing/web.dmi'
+ alternate_worn_icon = 'GainStation13/icons/mob/web.dmi'
+ icon_state = "web_bindings"
+ item_state = "web_bindings"
+ breakouttime = 600 //1 minute is reasonable.
+ equip_delay_other = 0
+ equip_delay_self = 0
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/suit/straight_jacket/web/equipped(mob/user, slot)
+ . = ..()
+ if((user.get_item_by_slot(SLOT_WEAR_SUIT)) != src && !QDELETED(src))
+ qdel(src)
+
+/obj/structure/spider/cocoon/quirk
+ max_integrity = 20
+
+/datum/action/innate/make_web
+ name = "weave"
+ desc = "spins a sticky web."
+ icon_icon = 'icons/effects/effects.dmi'
+ button_icon_state = "stickyweb1"
+ background_icon_state = "bg_alien"
+
+/datum/action/innate/make_web/Activate()
+ var/turf/T = get_turf(owner)
+ owner.visible_message("[owner] begins spinning a web!", "You begin spinning a web.")
+ if(!do_after(owner, 10 SECONDS, 1, null, 1))
+ owner.visible_message("[owner] fails to spin a web!", "You fail to spin web.")
+ return FALSE
+ T.ChangeTurf(/obj/structure/spider/stickyweb)
+ owner.visible_message("[owner] spin a sticky web!", "You spin a sticky web.")
+ return TRUE
diff --git a/GainStation13/code/mobs/cakegolem.dm b/GainStation13/code/mobs/cakegolem.dm
new file mode 100644
index 0000000000..1550adf15b
--- /dev/null
+++ b/GainStation13/code/mobs/cakegolem.dm
@@ -0,0 +1,51 @@
+/mob/living/simple_animal/friendly/cakegolem //I told you I'd do it, Remie //sorry Remie -Eye
+ name = "Puffball"
+ desc = "It's a person made out of cake."
+ icon = 'GainStation13/icons/mob/cakegolem.dmi'
+ icon_state = "cakegolem"
+ icon_living = "cakegolem"
+ icon_dead = "cakegolem_dead"
+ health = 200
+ maxHealth = 200 //health buffed because you all know how people get here -Eye
+ gender = FEMALE
+ harm_intent_damage = 10
+ butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 9, \
+ /obj/item/reagent_containers/food/snacks/meat/slab = 2)
+ response_harm = "takes a bite out of"
+ attacked_sound = 'sound/items/eatfood.ogg'
+ deathmessage = "loses its false life and collapses!"
+ death_sound = "bodyfall"
+ //held_icon = "cakegolem"
+
+/mob/living/simple_animal/friendly/cakegolem/CheckParts(list/parts)
+ ..()
+ var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents
+ if(!B || !B.brainmob || !B.brainmob.mind)
+ return
+ B.brainmob.mind.transfer_to(src)
+ to_chat(src, "You are a cake person! You're a harmless cake/person hybrid that everyone loves. People can take bites out of you if they're hungry, but there is plenty of you to go around, and you regenerate health \
+ so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \
+ free cake to the station!")
+ var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Puffball.", "Name Change")
+ if(new_name)
+ to_chat(src, "Your name is now \"new_name\"!")
+ name = new_name
+
+/mob/living/simple_animal/friendly/cakegolem/Life()
+ ..()
+ if(stat)
+ return
+ if(health < maxHealth)
+ adjustBruteLoss(-5) //Fast life regen
+ for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
+ if(!D.is_decorated)
+ D.decorate_donut()
+
+/mob/living/simple_animal/friendly/cakegolem/attack_hand(mob/living/L)
+ . = ..()
+
+ //if(.) //the attack was blocked
+ //return
+ if(L.a_intent == INTENT_HARM && L.reagents && !stat)
+ L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4)
+ L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4)
diff --git a/GainStation13/code/mobs/chocoslime.dm b/GainStation13/code/mobs/chocoslime.dm
new file mode 100644
index 0000000000..cfdefadf1d
--- /dev/null
+++ b/GainStation13/code/mobs/chocoslime.dm
@@ -0,0 +1,95 @@
+/mob/living/simple_animal/hostile/feed
+ var/food_per_feeding = 5
+ var/food_fed = /datum/reagent/consumable/nutriment
+
+/mob/living/simple_animal/hostile/feed/AttackingTarget()
+ . = ..()
+ var/mob/living/carbon/L = target
+ if(L.client?.prefs?.weight_gain_weapons)
+ if(L.reagents)
+ if(!L.is_mouth_covered(head_only = 1))
+ L.reagents.add_reagent(food_fed, food_per_feeding)
+
+/mob/living/simple_animal/hostile/feed/chocolate_slime
+ name = "Chocolate slime"
+ desc = "It's a living blob of tasty chocolate!"
+ icon = 'GainStation13/icons/mob/candymonster.dmi'
+ icon_state = "a_c_slime"
+ icon_living = "a_c_slime"
+ icon_dead = "a_c_slime_dead"
+ speak_emote = list("blorbles")
+ emote_hear = list("blorbles")
+ speak_chance = 5
+ turns_per_move = 5
+ see_in_dark = 10
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/chocolatebar = 4)
+ maxHealth = 100
+ health = 100
+ obj_damage = 0
+ melee_damage_lower = 0.001
+ melee_damage_upper = 0.001
+ faction = list("slime")
+ pass_flags = PASSTABLE
+ move_to_delay = 7
+ attack_sound = 'sound/items/eatfood.ogg'
+ unique_name = 1
+ gold_core_spawnable = HOSTILE_SPAWN
+ see_in_dark = 3
+ blood_volume = 0
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
+ initial_language_holder = /datum/language_holder/slime
+// // You are not immune to vore.
+// devourable = 1
+// digestable = 1
+// feeding = 1
+
+//Creambeast - basically a bit tougher mob that has feeding ranged attacks
+/mob/living/simple_animal/hostile/feed/chocolate_slime/creambeast
+ name = "Creambeast"
+ desc = "A strange mass of thick, creamy ice cream given some sense of instinct."
+ icon_state = "icecream_monster"
+ icon_living = "icecream_monster"
+ icon_dead = "icecream_monster_dead"
+ icon_gib = "icecream_monster_dead"
+ move_to_delay = 10
+ projectiletype = /obj/item/projectile/beam/fattening/icecream
+ projectilesound = 'sound/weapons/pierce.ogg'
+ ranged = 1
+ ranged_message = "schlorps"
+ ranged_cooldown_time = 30
+ vision_range = 2
+ speed = 3
+ maxHealth = 100
+ health = 100
+ obj_damage = 0
+ vision_range = 2
+ aggro_vision_range = 9
+ turns_per_move = 5
+ blood_volume = 0
+ gold_core_spawnable = HOSTILE_SPAWN
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/icecream = 4)
+
+/obj/item/projectile/beam/fattening/icecream //might as well make use of this thing to not make ton of different variants of the same thing
+ name = "ice cream blob"
+ icon = 'GainStation13/icons/mob/candymonster.dmi'
+ icon_state = "icecream_projectile"
+ ricochets_max = 0
+ ricochet_chance = 0
+ hitsound = 'sound/weapons/tap.ogg'
+ hitsound_wall = 'sound/weapons/tap.ogg'
+ is_reflectable = FALSE
+ light_range = 0
+ var/food_per_feeding = 5
+ var/food_fed = /datum/reagent/consumable/nutriment
+ var/fullness_add = 30
+
+/obj/item/projectile/beam/fattening/icecream/on_hit(atom/target, blocked)
+ . = ..()
+ var/mob/living/carbon/L = target
+ if(L.client?.prefs?.weight_gain_weapons)
+ if(L.reagents)
+ if(!L.is_mouth_covered(head_only = 1))
+ L.reagents.add_reagent(food_fed, food_per_feeding)
+ if(HAS_TRAIT(L, TRAIT_VORACIOUS))
+ fullness_add = fullness_add * 0.67
+ L.fullness += (fullness_add)
diff --git a/GainStation13/code/mobs/races/caloritegolem.dm b/GainStation13/code/mobs/races/caloritegolem.dm
new file mode 100644
index 0000000000..761a89ca07
--- /dev/null
+++ b/GainStation13/code/mobs/races/caloritegolem.dm
@@ -0,0 +1,139 @@
+var/charges = 3
+
+/datum/species/golem/calorite //golems that heal people around them, and cook groovy food. essentially the support class of golems
+ name = "Calorite Golem"
+ id = "calorite golem"
+ prefix = "Calorite"
+ special_names = list("Callie Wright")
+ info_text = "As a Calorite Golem, you have all kinds of cool magical abilities that allow you to heal the wounded, make food more nourishing and boost people's speed! Unfortunately, you are also very flimsy, and can't dish out much damage with your hands."
+ fixed_mut_color = "ffffff"
+ limbs_id = "cal_golem" //special sprites
+ attack_verb = "bop" //they don't hit too hard, so their attack verb is fittingly pretty soft
+ armor = 25
+ punchdamagelow = 5
+ punchstunthreshold = 0 //no chance to stun
+ punchdamagehigh = 5
+ var/datum/action/innate/aura/heal
+ var/datum/action/innate/bless/boost
+ var/datum/action/innate/unburden/speed
+ var/datum/action/innate/recharge/power
+
+
+
+
+/datum/species/golem/calorite/on_species_gain(mob/living/carbon/C, datum/species/old_species)
+ ..()
+ if(ishuman(C))
+ heal = new
+ heal.Grant(C)
+ boost = new
+ boost.Grant(C)
+ speed = new
+ speed.Grant(C)
+ power = new
+ power.Grant(C)
+
+/datum/species/golem/calorite/on_species_loss(mob/living/carbon/C)
+ if(heal)
+ heal.Remove(C)
+ if(boost)
+ boost.Remove(C)
+ if(speed)
+ speed.Remove(C)
+ if(power)
+ power.Remove(C)
+ ..()
+
+/datum/action/innate/aura
+ name = "Healing Pulse"
+ desc = "Emit a healing pulse around yourself, curing the wounds of all around you."
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'GainStation13/icons/mob/action_icons.dmi'
+ button_icon_state = "healing"
+
+/datum/action/innate/unburden
+ name = "Lift Burdens"
+ desc = "Vitalise all those around you, giving them a boost of speed for a moment. The effects of this charm are more effective on those whom are heavily burdened"
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'GainStation13/icons/mob/action_icons.dmi'
+ button_icon_state = "boost"
+
+/datum/action/innate/bless
+ name = "Bless Food"
+ desc = "infuse food near you with a fraction of your power to make it more nourishing"
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'GainStation13/icons/mob/action_icons.dmi'
+ button_icon_state = "cal_bless"
+
+/datum/action/innate/recharge
+ name = "Recharge"
+ desc = "refresh and recharge your magical abilities"
+ check_flags = AB_CHECK_CONSCIOUS
+ icon_icon = 'GainStation13/icons/mob/action_icons.dmi'
+ button_icon_state = "cal_golem_sleepies"
+
+
+/datum/action/innate/recharge/Activate()
+ charges = 3
+ if(ishuman(owner))
+ to_chat(owner, "You recharge yourself with magical energy!")
+
+
+/datum/action/innate/bless/Activate()
+ if(charges != 0)
+ charges -= 1
+ if(ishuman(owner))
+ to_chat(owner, "You bless the food around you!")
+
+ for(var/obj/item/reagent_containers/food/O in view(1, owner))
+ if(!O.blessed)
+ O.reagents.add_reagent(/datum/reagent/consumable/nutriment, 10)
+ O.desc += " It faintly glows with warm, orange energy..."
+ O.blessed = 1
+ else
+ to_chat(owner, "You need to recharge...")
+
+/datum/action/innate/unburden/Activate()
+ if(charges != 0)
+ charges -= 1
+ if(ishuman(owner))
+ to_chat(owner, "You lift the burdens of those around you!")
+
+ for(var/mob/living/L in view(3, owner))
+ if(iscarbon(L))
+ if(!HAS_TRAIT(L, TRAIT_GOTTAGOFAST))
+ L.reagents.add_reagent(/datum/reagent/consumable/caloriteblessing, 5)
+
+ else
+ to_chat(owner, "You need to recharge...")
+
+
+
+
+/datum/action/innate/aura/Activate()
+ if(charges != 0)
+ charges -= 1
+ if(ishuman(owner))
+ to_chat(owner, "You heal those around you!")
+
+ for(var/mob/living/L in view(3, owner))
+ if(L.health < L.maxHealth)
+ new /obj/effect/temp_visual/heal(get_turf(L), "#375637")
+ if(iscarbon(L))
+ L.adjustBruteLoss(-3)
+ L.adjustFireLoss(-3)
+ L.adjustToxLoss(-3, forced = TRUE) //Because Slime People are people too
+ L.adjustOxyLoss(-3)
+// L.adjustStaminaLoss(-3)
+// L.adjustOrganLoss(ORGAN_SLOT_BRAIN, -3)
+ L.adjustCloneLoss(-1) //Becasue apparently clone damage is the bastion of all health
+// else if(issilicon(L))
+// L.adjustBruteLoss(-3)
+// L.adjustFireLoss(-3)
+ else if(isanimal(L))
+ var/mob/living/simple_animal/SM = L
+ SM.adjustHealth(-3, forced = TRUE)
+
+
+
+
diff --git a/GainStation13/code/mobs/slugcat.dm b/GainStation13/code/mobs/slugcat.dm
new file mode 100644
index 0000000000..1ac82e29a5
--- /dev/null
+++ b/GainStation13/code/mobs/slugcat.dm
@@ -0,0 +1,119 @@
+/mob/living/simple_animal/pet/slugcat
+ name = "slugcat"
+ desc = "It's a cat . . . Thing from another planet, maybe from another world. You think it's not dangerous, but you can't be sure. "
+ icon = 'GainStation13/icons/mob/pets.dmi'
+ icon_state = "slugcat"
+ icon_living = "slugcat"
+ icon_dead = "slugcat_dead"
+ emote_see = list("stares at the ceiling.", "shivers.")
+ speak_chance = 1
+ turns_per_move = 20
+ can_be_held = TRUE
+ see_in_dark = 6
+ ventcrawler = VENTCRAWLER_ALWAYS
+ pass_flags = PASSTABLE
+ mob_size = MOB_SIZE_SMALL
+ mob_biotypes = MOB_ORGANIC|MOB_BEAST
+ minbodytemp = 200
+ maxbodytemp = 400
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
+ unsuitable_atmos_damage = 0.5
+ animal_species = /mob/living/simple_animal/pet/slugcat
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ gold_core_spawnable = FRIENDLY_SPAWN
+ attack_sound = 'sound/effects/attackblob.ogg'
+ do_footstep = TRUE
+ gold_core_spawnable = FRIENDLY_SPAWN
+ size_multiplier = 0.5
+ obj_damage = 0
+ melee_damage_lower = 0
+ melee_damage_upper = 0
+ var/held_icon = "slugcat"
+ do_footstep = TRUE
+ //lizard food
+ devourable = 1
+ digestable = 1
+ feeding = 1
+ var/obj/item/twohanded/spear/weapon
+
+/mob/living/simple_animal/pet/slugcat/Initialize(mapload)
+ . = ..()
+ add_verb(src, /mob/living/proc/lay_down)
+
+/mob/living/simple_animal/pet/slugcat/ComponentInitialize()
+ . = ..()
+ AddElement(/datum/element/wuv, "purrs!", EMOTE_AUDIBLE, /datum/mood_event/pet_animal, "hisses!", EMOTE_AUDIBLE)
+ AddElement(/datum/element/mob_holder, held_icon)
+
+/mob/living/simple_animal/pet/slugcat/update_canmove()
+ ..()
+ if(client && stat != DEAD)
+ if (resting)
+ icon_state = "[icon_living]_rest"
+ else
+ icon_state = "[icon_living]"
+ regenerate_icons()
+
+/mob/living/simple_animal/pet/slugcat/UnarmedAttack(atom/A)
+ . = ..()
+ if(!isitem(A))
+ return
+
+ if(!weapon && istype(A, /obj/item/twohanded/spear))
+ visible_message("[src] pick up the [A].", "You pick up the [A].")
+ weapon = A
+ weapon.forceMove(src)
+ melee_damage_lower = weapon.force + weapon.force_wielded
+ melee_damage_upper = weapon.force + weapon.force_wielded
+ armour_penetration = weapon.armour_penetration
+ melee_damage_type = weapon.damtype
+ attack_sound = weapon.hitsound
+ update_icons()
+ else if(!weapon && !istype(A, /obj/item/twohanded/spear))
+ to_chat(src, "You do not know how to wield the [A]!")
+
+/mob/living/simple_animal/pet/slugcat/RangedAttack(atom/A, params)
+ . = ..()
+ if(!weapon)
+ return
+ visible_message("[src] throws the [weapon] at [A]!","You throw the [weapon] at [A]!")
+ melee_damage_lower = initial(melee_damage_lower)
+ melee_damage_upper = initial(melee_damage_upper)
+ armour_penetration = initial(armour_penetration)
+ melee_damage_type = initial(melee_damage_type)
+ attack_sound = initial(attack_sound)
+ weapon.forceMove(get_turf(src))
+ weapon.throw_at(A, weapon.throw_range, weapon.throw_speed, src)
+ weapon = null
+ update_icons()
+
+/mob/living/simple_animal/pet/slugcat/update_icons()
+ . = ..()
+ if(stat == DEAD || resting)
+ return
+ icon_state = weapon ? initial(icon_state) + "_spear" : initial(icon_state)
+
+/mob/living/simple_animal/pet/slugcat/death(gibbed)
+ if(weapon)
+ weapon.forceMove(get_turf(src))
+ weapon = null
+ update_icons()
+ . = ..()
+
+/mob/living/simple_animal/pet/slugcat/attack_ghost(mob/user)
+ if(key)
+ return
+ if(CONFIG_GET(flag/use_age_restriction_for_jobs))
+ if(!isnum(user.client.player_age))
+ return
+ if(!SSticker.mode)
+ to_chat(user, "Can't become a slugcat before the game has started.")
+ return
+ var/be_scug = alert("Become a slugcat? (Warning, You can no longer be cloned!)",,"Yes","No")
+ if(be_scug == "No" || QDELETED(src) || !isobserver(user))
+ return
+ sentience_act()
+ key = user.key
+
diff --git a/GainStation13/code/mobs/unusualtentical.dm b/GainStation13/code/mobs/unusualtentical.dm
new file mode 100644
index 0000000000..81823e601a
--- /dev/null
+++ b/GainStation13/code/mobs/unusualtentical.dm
@@ -0,0 +1,5 @@
+/obj/code/game/mobs/unusualtentical
+ name = "unusualtentical"
+ desc = "Whats this doing here?"
+ icon = "Gainstation13/icons/mob/unusualtentical.dmi"
+ icon_state = "tenticalidle"
diff --git a/GainStation13/code/modules/client/preferences/preferences.dm b/GainStation13/code/modules/client/preferences/preferences.dm
new file mode 100644
index 0000000000..d6bfb03523
--- /dev/null
+++ b/GainStation13/code/modules/client/preferences/preferences.dm
@@ -0,0 +1,101 @@
+//GS13 Preferences
+/datum/preferences
+ //Weight Gain Sources
+ ///Weight gain from food
+ var/weight_gain_food = FALSE
+ ///Weight gain from chems
+ var/weight_gain_chems = FALSE
+ ///Weight gain from items
+ var/weight_gain_items = FALSE
+ ///Weight gain from weapons
+ var/weight_gain_weapons = FALSE
+ ///Weight gain from magic
+ var/weight_gain_magic = FALSE
+ ///Weight gain from viruses
+ var/weight_gain_viruses = FALSE
+ ///Weight gain from nanites
+ var/weight_gain_nanites = FALSE
+ ///Blueberry Inflation
+ var/blueberry_inflation = FALSE
+ ///Extreme weight gain
+ var/weight_gain_extreme = FALSE
+ ///Persistant fatness
+ var/weight_gain_persistent = FALSE
+ ///Permanent weight gain
+ var/weight_gain_permanent = FALSE
+ /// At what weight will you start to get stuck in airlocks?
+ var/stuckage = FALSE
+ /// At what weight will you start to break chairs?
+ var/chair_breakage = FALSE
+ /// Are items that only affect those at high weights able to affect the player?
+ var/fatness_vulnerable = FALSE
+ /// Similar to fatness_vulnerable, but with more extreme effects such as transformation/hypno.
+ var/extreme_fatness_vulnerable = FALSE
+
+ // Helplessness, a set of prefs that make things extra tough at higher weights. If set to FALSE, they won't do anything.
+ ///What fatness level disables movement?
+ var/helplessness_no_movement = FALSE
+ ///What fatness level makes the user clumsy?
+ var/helplessness_clumsy = FALSE
+ ///What fatness level makes the user nearsighted
+ var/helplessness_nearsighted = FALSE
+ ///What fatness level makes the user's face unrecognizable.
+ var/helplessness_hidden_face = FALSE
+ ///What fatness level makes the user unable to speak?
+ var/helplessness_mute = FALSE
+
+ ///What fatness level, makes the user unable to use their arms?
+ var/helplessness_immobile_arms = FALSE
+ ///What fatness level prevents the user from wearing jumpsuits
+ var/helplessness_clothing_jumpsuit = FALSE
+ ///What fatness level prevents the user from wearing non-jumpsuit clothing
+ var/helplessness_clothing_misc = FALSE
+ ///What fatness level prevents the user from wearing anything on their back
+ var/helplessness_clothing_back = FALSE
+ ///What fatness level prevents the user from being buckled to anything?
+ var/helplessness_no_buckle = FALSE
+
+ ///Does the person wish to be involved with non-con weight gain events?
+ var/noncon_weight_gain = FALSE
+
+ //Does the person wish to be fed from bots?
+ var/bot_feeding = FALSE
+
+ ///What is the max weight that the person wishes to be? If set to FALSE, there will be no max weight
+ var/max_weight = FALSE
+
+/// Prompts the user to choose a weight and returns said weight.
+/datum/preferences/proc/chose_weight(input_text = "Choose a weight.", mob/user)
+ var/chosen_weight = FALSE
+ var/picked_weight_class = input(user,
+ input_text,
+ "Character Preference", "None") as null|anything in list(
+ "None", "Fat", "Fatter", "Very Fat", "Obese", "Morbidly Obese", "Extremely Obese", "Barely Mobile", "Immobile", "Other")
+
+ switch(picked_weight_class)
+ if("Fat")
+ chosen_weight = FATNESS_LEVEL_FATTER
+ if("Fatter")
+ chosen_weight = FATNESS_LEVEL_VERYFAT
+ if("Very Fat")
+ chosen_weight = FATNESS_LEVEL_OBESE
+ if("Obese")
+ chosen_weight = FATNESS_LEVEL_MORBIDLY_OBESE
+ if("Morbidly Obese")
+ chosen_weight = FATNESS_LEVEL_EXTREMELY_OBESE
+ if("Extremely Obese")
+ chosen_weight = FATNESS_LEVEL_BARELYMOBILE
+ if("Barely Mobile")
+ chosen_weight = FATNESS_LEVEL_IMMOBILE
+ if("Immobile")
+ chosen_weight = FATNESS_LEVEL_BLOB
+
+ if(picked_weight_class != "Other")
+ return chosen_weight
+
+ var/custom_fatness = input(user, "What fatness level (BFI) would you like to use?", "Character Preference") as null|num
+ if(isnull(custom_fatness))
+ custom_fatness = FALSE
+
+ return custom_fatness
+
\ No newline at end of file
diff --git a/GainStation13/code/modules/clothing/under/jobs/modcivilian.dm b/GainStation13/code/modules/clothing/under/jobs/modcivilian.dm
new file mode 100644
index 0000000000..19a0e1bf9e
--- /dev/null
+++ b/GainStation13/code/modules/clothing/under/jobs/modcivilian.dm
@@ -0,0 +1,156 @@
+/obj/item/clothing/under/rank/chef/modular
+ name = "cook's modular suit"
+ desc = "A suit which is given only to the most hardcore cooks in space. Now adjusts to the match the wearer's size!"
+
+ var/mob/living/carbon/U
+
+/obj/item/clothing/under/rank/chef/modular/equipped(mob/user, slot)
+ ..()
+ U = user
+
+/obj/item/clothing/under/rank/chef/modular/dropped()
+ ..()
+ U = null
+
+/obj/item/clothing/under/rank/chef/modular/jumpsuit_adjust()
+ ..()
+ worn_overlays()
+
+/obj/item/clothing/under/rank/chef/modular/worn_overlays(isinhands = FALSE)
+ if(!isinhands)
+ . = list()
+ var/obj/item/organ/O
+ var/obj/item/organ/genital/G
+ for(O in U.internal_organs)
+ if(istype(O, /obj/item/organ/genital/belly))
+ G = O
+ if(!adjusted)
+ if(G.size <= 9) //These need to be removed later, better to cap organ sizes to begin with
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "belly_[G.size]", GENITALS_UNDER_LAYER)
+ else
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "belly_9", GENITALS_UNDER_LAYER)
+ else
+ if(G.size <= 9)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "belly_[G.size]_d", GENITALS_UNDER_LAYER)
+ else
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "belly_9_d", GENITALS_UNDER_LAYER)
+ if(istype(O, /obj/item/organ/genital/anus))
+ G = O
+ if(suit_style == DIGITIGRADE_SUIT_STYLE)
+ if(G.size <= 10)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_[G.size]_l", GENITALS_FRONT_LAYER)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_[G.size]_l_NORTH", GENITALS_FRONT_LAYER)
+ else
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_10_l", GENITALS_FRONT_LAYER)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_10_l_NORTH", GENITALS_FRONT_LAYER)
+ else
+ if(G.size <= 10)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_[G.size]", GENITALS_FRONT_LAYER)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_[G.size]_NORTH", GENITALS_FRONT_LAYER)
+ else
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_10", GENITALS_FRONT_LAYER)
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "butt_10_NORTH", GENITALS_FRONT_LAYER)
+ if(istype(O, /obj/item/organ/genital/breasts))
+ G = O
+ if(G.size <= "impossible")
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "breasts_[G.size]", GENITALS_BEHIND_LAYER) //nearest
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "breasts_[G.size]_NORTH", BODY_FRONT_LAYER) //farthest
+ else
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "breasts_impossible", GENITALS_BEHIND_LAYER) //nearest
+ . += mutable_appearance('GainStation13/icons/mob/modclothes/chefmodular.dmi', "breasts_impossible_NORTH", BODY_FRONT_LAYER) //farthest
+ if(damaged_clothes)
+ . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
+ if(accessory_overlay)
+ . += accessory_overlay
+
+/obj/item/clothing/under/color/grey/modular
+ name = "grey modular jumpsuit" //change name from base clothes to distinguish them
+ desc = "A tasteful grey jumpsuit that reminds you of the good old days. Now adjusts to the match the wearer's size!" //description same as above
+
+ var/icon_location = 'GainStation13/icons/mob/modclothes/graymodular.dmi' //specify the file path where the modular overlays for those clothes are located
+ var/mob/living/carbon/U //instance a variable for keeping track of the user
+
+/obj/item/clothing/under/color/grey/modular/equipped(mob/user, slot) //whenever the clothes are in someone's inventory the clothes keep track of who that user is
+ ..()
+ U = user
+
+/obj/item/clothing/under/color/grey/modular/dropped() //whenever the clothes leave a person's inventory, they forget who held them
+ ..()
+ U = null
+
+/obj/item/clothing/under/color/grey/modular/jumpsuit_adjust() //when the user adjusts the clothes' style, rebuild the overlays
+ ..()
+ worn_overlays()
+
+/obj/item/clothing/under/color/grey/modular/worn_overlays(isinhands = FALSE)
+ if(U)
+ if(!isinhands) //make sure the clothes are being worn and aren't in someone's hands
+ . = list()
+ var/obj/item/organ/O
+ var/obj/item/organ/genital/G
+ for(O in U.internal_organs) //check the user for the organs they have
+ if(istype(O, /obj/item/organ/genital/belly)) //if that organ is a belly
+ G = O //treat that organ as a genital
+ if(!adjusted) //check the style, if it needs to be the adjusted variants
+ if(G.size <= 9) //check that the size is within accepted values, NOTE: these need to be removed later, better to cap organ sizes to begin with
+ . += mutable_appearance(icon_location, "belly_[G.size]", GENITALS_UNDER_LAYER) //add, from the clothes' icon file the overlay corresponding to that genital at that size and draw it onto the layer
+ else //if not an expected size value, bigger than the max, default to max size
+ . += mutable_appearance(icon_location, "belly_9", GENITALS_UNDER_LAYER)
+ else //use the alternative adjusted sprites
+ if(G.size <= 9)
+ . += mutable_appearance(icon_location, "belly_[G.size]_d", GENITALS_UNDER_LAYER)
+ else
+ . += mutable_appearance(icon_location, "belly_9_d", GENITALS_UNDER_LAYER)
+ if(istype(O, /obj/item/organ/genital/anus)) //if that organ is the butt
+ G = O
+ if(suit_style == DIGITIGRADE_SUIT_STYLE) //check if the suit needs to use sprites for digitigrade characters
+ if(G.size <= 10)
+ . += mutable_appearance(icon_location, "butt_[G.size]_l", GENITALS_FRONT_LAYER)
+ . += mutable_appearance(icon_location, "butt_[G.size]_l_NORTH", GENITALS_FRONT_LAYER) //to not adjust overlays every time a character turns, north-facing breasts and bellies are drawn separately, with individual icons
+ else //they'll have blank north-facing sprites in the main icon state and the north-facing will be blank on all other sides, and are drawn on different layers
+ . += mutable_appearance(icon_location, "butt_10_l", GENITALS_FRONT_LAYER)
+ . += mutable_appearance(icon_location, "butt_10_l_NORTH", GENITALS_FRONT_LAYER)
+ else //if the character is not digitigrade
+ if(G.size <= 10)
+ . += mutable_appearance(icon_location, "butt_[G.size]", GENITALS_FRONT_LAYER)
+ . += mutable_appearance(icon_location, "butt_[G.size]_NORTH", GENITALS_FRONT_LAYER)
+ else
+ . += mutable_appearance(icon_location, "butt_10", GENITALS_FRONT_LAYER)
+ . += mutable_appearance(icon_location, "butt_10_NORTH", GENITALS_FRONT_LAYER)
+ if(istype(O, /obj/item/organ/genital/breasts)) //if the organ is the breasts
+ G = O
+ if(G.size <= "o")
+ . += mutable_appearance(icon_location, "breasts_[G.size]", GENITALS_BEHIND_LAYER)
+ . += mutable_appearance(icon_location, "breasts_[G.size]_NORTH", BODY_FRONT_LAYER)
+ else
+ if(G.size == "huge")
+ . += mutable_appearance(icon_location, "breasts_huge", GENITALS_BEHIND_LAYER)
+ . += mutable_appearance(icon_location, "breasts_huge_NORTH", BODY_FRONT_LAYER)
+ else
+ if(G.size == "massive")
+ . += mutable_appearance(icon_location, "breasts_massive", GENITALS_BEHIND_LAYER)
+ . += mutable_appearance(icon_location, "breasts_massive_NORTH", BODY_FRONT_LAYER)
+ else
+ if(G.size == "giga")
+ . += mutable_appearance(icon_location, "breasts_giga", GENITALS_BEHIND_LAYER)
+ . += mutable_appearance(icon_location, "breasts_giga_NORTH", BODY_FRONT_LAYER)
+ else
+ . += mutable_appearance(icon_location, "breasts_impossible", GENITALS_BEHIND_LAYER)
+ . += mutable_appearance(icon_location, "breasts_impossible_NORTH", BODY_FRONT_LAYER)
+ if(damaged_clothes)
+ . += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
+ if(accessory_overlay)
+ . += accessory_overlay
+
+
+/obj/item/clothing/under/color/grey/modular/bra
+ name = "grey modular bra"
+ desc = "A tasteful grey bra that reminds you of the good old days. Now adjusts to the match the wearer's size!"
+ icon_location = 'GainStation13/icons/mob/modclothes/graymodular_bra.dmi'
+ icon_state = "grey"
+ item_state = "grey_bra"
+ item_color = "grey_bra"
diff --git a/GainStation13/code/modules/food_and_drinks/drinks.dm b/GainStation13/code/modules/food_and_drinks/drinks.dm
new file mode 100644
index 0000000000..626e64fbf1
--- /dev/null
+++ b/GainStation13/code/modules/food_and_drinks/drinks.dm
@@ -0,0 +1,26 @@
+////////////////////////////////////////////////////////////////////////////////
+/// GS13 Drinks
+////////////////////////////////////////////////////////////////////////////////
+
+/obj/item/reagent_containers/food/drinks/soda_cans/fizzwiz
+ name = "Fizz Wiz"
+ desc = "Unleash your inner magic!"
+ icon = 'GainStation13/icons/obj/drinks.dmi'
+ lefthand_file = 'GainStation13/icons/obj/food_lefthand.dmi'
+ righthand_file = 'GainStation13/icons/obj/food_righthand.dmi'
+ icon_state = "fizzwiz"
+ list_reagents = list(/datum/reagent/consumable/space_cola = 25, /datum/reagent/consumable/fizulphite = 15)
+ foodtype = SUGAR
+ price = 3
+
+
+/obj/item/reagent_containers/food/drinks/soda_cans/soothseltz
+ name = "Soothing Seltzer"
+ desc = "A useful drink that helps relieve a bloated stomach."
+ icon = 'GainStation13/icons/obj/drinks.dmi'
+ lefthand_file = 'GainStation13/icons/obj/food_lefthand.dmi'
+ righthand_file = 'GainStation13/icons/obj/food_righthand.dmi'
+ icon_state = "soothseltz"
+ list_reagents = list(/datum/reagent/consumable/space_cola = 25, /datum/reagent/consumable/extilphite = 15)
+ foodtype = SUGAR
+ price = 3
diff --git a/GainStation13/code/modules/food_and_drinks/food.dm b/GainStation13/code/modules/food_and_drinks/food.dm
new file mode 100644
index 0000000000..a78cd1e351
--- /dev/null
+++ b/GainStation13/code/modules/food_and_drinks/food.dm
@@ -0,0 +1,139 @@
+/obj/item/reagent_containers/food/snacks/gbburrito
+ name = "\improper GATO Gas Giant Burrito"
+ icon_state = "gbburrito"
+ desc = "More than three pounds of beans, meat, and cheese wrapped in a greasy tortilla. It's piping hot."
+ trash = null
+ list_reagents = list(/datum/reagent/consumable/nutriment = 6, /datum/reagent/consumable/flatulose = 4, /datum/reagent/consumable/sodiumchloride = 0.5)
+ filling_color = "#74291b"
+ tastes = list("refried beans","grease" = 1)
+ foodtype = MEAT
+ price = 3
+
+//these have been ported from CHOMPstation / Virgo
+/obj/item/reagent_containers/food/snacks/doner_kebab
+ name = "doner kebab"
+ icon = 'icons/obj/food/ported_meals.dmi'
+ desc = "A delicious sandwich-like food from ancient Earth. The meat is typically cooked on a vertical rotisserie."
+ icon_state = "doner_kebab"
+ trash = null
+ list_reagents = list(/datum/reagent/consumable/nutriment = 10)
+ filling_color = "#93684d"
+ tastes = list("thinly sliced meat","meat" = 1)
+ foodtype = GRAIN | VEGETABLES | MEAT | JUNKFOOD
+
+/obj/item/reagent_containers/food/snacks/lasagna
+ name = "lasagna"
+ desc = "Meaty, tomato-y, and ready to eat-y. Favorite of cats."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "lasagna"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 10)
+ filling_color = "#872020"
+ tastes = list("italian cuisine" = 1)
+ foodtype = GRAIN | VEGETABLES | MEAT
+
+/obj/item/reagent_containers/food/snacks/corndog
+ name = "corn dog"
+ desc = "A cornbread covered sausage deepfried in oil."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "corndog"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 5)
+ filling_color = "#df9745"
+ tastes = list("corn batter", "sausage" = 1)
+ foodtype = GRAIN | MEAT | JUNKFOOD
+
+/obj/item/reagent_containers/food/snacks/turkey
+ name = "turkey"
+ desc = "Tastes like chicken. It can be sliced!"
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "turkey"
+ slice_path = /obj/item/reagent_containers/food/snacks/turkey_leg
+ slices_num = 4
+ list_reagents = list(/datum/reagent/consumable/nutriment = 15)
+ filling_color = "#d4864b"
+ tastes = list("turkey" = 1)
+ foodtype = MEAT
+
+/obj/item/reagent_containers/food/snacks/turkey_leg
+ name = "turkey leg"
+ desc = "Tastes like chicken."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "turkey_slice"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 5)
+ filling_color = "#ae6941"
+ tastes = list("turkey" = 1)
+ foodtype = MEAT
+
+/obj/item/reagent_containers/food/snacks/brownies
+ name = "brownies"
+ desc = "Halfway to fudge, or halfway to cake? Who cares!"
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "brownies"
+ slice_path = /obj/item/reagent_containers/food/snacks/brownies_slice
+ slices_num = 6
+ list_reagents = list(/datum/reagent/consumable/nutriment = 30)
+ filling_color = "#392f27"
+ tastes = list("chocolate" = 1)
+ foodtype = GRAIN | SUGAR | DAIRY
+
+/obj/item/reagent_containers/food/snacks/brownies_slice
+ name = "brownie"
+ desc = "a dense, decadent chocolate brownie."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "browniesslice"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 5)
+ filling_color = "#392f27"
+ tastes = list("chocolate" = 1)
+ foodtype = GRAIN | SUGAR | DAIRY
+
+/obj/item/reagent_containers/food/snacks/brownies_cosmic
+ name = "cosmic brownies"
+ desc = "The power of cosmos likes within your hand."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "cosmicbrownies"
+ slice_path = /obj/item/reagent_containers/food/snacks/brownies_slice_cosmic
+ slices_num = 6
+ list_reagents = list(/datum/reagent/consumable/nutriment = 25, /datum/reagent/medicine/omnizine = 5)
+ filling_color = "#392f27"
+ tastes = list("chocolate" = 1)
+ foodtype = GRAIN | SUGAR | DAIRY
+
+/obj/item/reagent_containers/food/snacks/brownies_slice_cosmic
+ name = "cosmic brownie"
+ desc = "a dense, decadent and fun-looking chocolate brownie."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "cosmicbrownieslice"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/medicine/omnizine = 1)
+ filling_color = "#392f27"
+ tastes = list("chocolate" = 1)
+ foodtype = GRAIN | SUGAR | DAIRY
+
+/obj/item/reagent_containers/food/snacks/bacon_and_eggs
+ name = "bacon and eggs"
+ desc = "A staple of every breakfast."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "bacon_and_eggs"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 8)
+ filling_color = "#e9e6e3"
+ tastes = list("eggs", "bacon" = 1)
+ foodtype = BREAKFAST | MEAT
+
+/obj/item/reagent_containers/food/snacks/eggmuffin
+ name = "egg muffin"
+ desc = "A staple of every breakfast."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "eggmuffin"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 8)
+ filling_color = "#e9e6e3"
+ tastes = list("eggs", "breakfast" = 1)
+ foodtype = BREAKFAST | MEAT
+
+/obj/item/reagent_containers/food/snacks/cinammonbun
+ name = "cinammon bun"
+ desc = "Careful not to have it stolen."
+ icon = 'icons/obj/food/ported_meals.dmi'
+ icon_state = "cinammonbun"
+ list_reagents = list(/datum/reagent/consumable/nutriment = 5)
+ filling_color = "#e9e6e3"
+ tastes = list("eggs", "breakfast" = 1)
+ foodtype = GRAIN | SUGAR
+
diff --git a/GainStation13/code/modules/food_and_drinks/objects/candy_flora.dm b/GainStation13/code/modules/food_and_drinks/objects/candy_flora.dm
new file mode 100644
index 0000000000..657da5b785
--- /dev/null
+++ b/GainStation13/code/modules/food_and_drinks/objects/candy_flora.dm
@@ -0,0 +1,47 @@
+//GS13 decals - candyland related!
+//would be cool if we could use ash flora code to make these harvestable in the future - Lew
+
+
+/obj/effect/turf_decal/candy //used for baseline
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = ""
+
+/obj/effect/turf_decal/candy/redwhite
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal1"
+
+/obj/effect/turf_decal/candy/redwhite2
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal2"
+
+/obj/effect/turf_decal/candy/redwhite3
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal3"
+
+/obj/effect/turf_decal/candy/greenwhite1
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal_g1"
+
+/obj/effect/turf_decal/candy/greenwhite2
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal_g2"
+
+/obj/effect/turf_decal/candy/bluewhite1
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal_b1"
+
+/obj/effect/turf_decal/candy/purplewhite1
+ icon = 'GainStation13/icons/turf/decals_candy.dmi'
+ icon_state = "candy_decal_p1"
+
+
+/obj/structure/lollipop //ik it's not necessarily a decal but I'm lazy rn and will (hopefully) move it later
+ name = "Lollipop tree"
+ desc = "A mere snack for people larger than life."
+ max_integrity = 80
+ density = TRUE
+ pixel_x = -16
+ layer = FLY_LAYER
+ anchored = TRUE
+ icon = 'GainStation13/icons/turf/decals_large_candy.dmi'
+ icon_state = "lollipop_tree_blue"
diff --git a/GainStation13/code/modules/food_and_drinks/recipes/recipes_ported.dm b/GainStation13/code/modules/food_and_drinks/recipes/recipes_ported.dm
new file mode 100644
index 0000000000..44b3a0065b
--- /dev/null
+++ b/GainStation13/code/modules/food_and_drinks/recipes/recipes_ported.dm
@@ -0,0 +1,126 @@
+//this is a recipe file for just random shit we've ported from other servers
+//you can call me lazy if you'd like but I didn't really feel like making 10 different folders and files just to port a couple simple meals
+
+//writing down recipe categories, should be handy
+//CAT_FOOD,CAT_BREAD,CAT_BURGER,CAT_CAKE,CAT_EGG,CAT_MEAT,CAT_MISCFOOD,CAT_PASTRY,CAT_PIE,CAT_PIZZ,CAT_SALAD,CAT_SANDWICH,CAT_SOUP,CAT_SPAGHETTI,CAT_FISH,CAT_ICE
+
+
+/datum/crafting_recipe/food/doner
+ name = "Doner Kebab"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/bun = 1,
+ /obj/item/reagent_containers/food/snacks/meat/cutlet = 1,
+ /obj/item/reagent_containers/food/snacks/grown/tomato = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/doner_kebab
+ subcategory = CAT_BURGER
+
+
+/datum/crafting_recipe/food/lasagna
+ name = "Lasagna"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/boiledspaghetti = 1,
+ /obj/item/reagent_containers/food/snacks/meat/cutlet = 1,
+ /obj/item/reagent_containers/food/snacks/grown/tomato = 1,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/lasagna
+ subcategory = CAT_SPAGHETTI
+
+
+/datum/crafting_recipe/food/corndog
+ name = "Corndog"
+ reqs = list(
+ /datum/reagent/consumable/flour = 5,
+ /obj/item/reagent_containers/food/snacks/sausage = 1,
+ /datum/reagent/consumable/cooking_oil = 5
+ )
+ result = /obj/item/reagent_containers/food/snacks/corndog
+ subcategory = CAT_MEAT
+
+
+/datum/crafting_recipe/food/turkey
+ name = "Whole Turkey"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/meat/slab/chicken = 2,
+ /obj/item/reagent_containers/food/snacks/sausage = 1,
+ /obj/item/reagent_containers/food/snacks/grown/potato = 2,
+ )
+ result = /obj/item/reagent_containers/food/snacks/turkey
+ subcategory = CAT_MEAT
+
+
+/datum/crafting_recipe/food/brownies
+ name = "Brownies"
+ reqs = list(
+ /datum/reagent/consumable/flour = 5,
+ /datum/reagent/consumable/ethanol/creme_de_cacao = 10,
+ /datum/reagent/consumable/sugar = 5,
+ /obj/item/reagent_containers/food/snacks/butter = 2
+ )
+ result = /obj/item/reagent_containers/food/snacks/brownies
+ subcategory = CAT_CAKE
+
+
+/datum/crafting_recipe/food/cosmic_brownies
+ name = "Cosmic Brownies"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/brownies = 1,
+ /datum/reagent/consumable/sprinkles = 10
+ )
+ result = /obj/item/reagent_containers/food/snacks/brownies_cosmic
+ subcategory = CAT_CAKE
+
+
+/datum/crafting_recipe/food/cosmic_brownies
+ name = "Cosmic Brownies"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/brownies = 1,
+ /datum/reagent/consumable/sprinkles = 10
+ )
+ result = /obj/item/reagent_containers/food/snacks/brownies_cosmic
+ subcategory = CAT_CAKE
+
+
+/datum/crafting_recipe/food/bacon_and_eggs
+ name = "Bacon and Eggs"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/friedegg = 2,
+ /obj/item/reagent_containers/food/snacks/meat/bacon = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/bacon_and_eggs
+ subcategory = CAT_EGG
+
+
+/datum/crafting_recipe/food/egg_muffin
+ name = "Egg muffin"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/friedegg = 1,
+ /obj/item/reagent_containers/food/snacks/muffin = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/eggmuffin
+ subcategory = CAT_EGG
+
+
+/datum/crafting_recipe/food/cinnamon_roll
+ name = "Cinnamon roll"
+ reqs = list(
+ /datum/reagent/consumable/sugar = 3,
+ /datum/reagent/consumable/vanilla = 2,
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/cinammonbun
+ subcategory = CAT_PASTRY
+
+//GS Food
+
+/datum/crafting_recipe/food/lavaland_stew
+ name = "Lavaland Stew"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_leaf = 1,
+ /obj/item/reagent_containers/food/snacks/grown/ash_flora/mushroom_stem = 1,
+ /obj/item/reagent_containers/food/snacks/grown/ash_flora/cactus_fruit = 2,
+ /obj/item/reagent_containers/glass/bowl/mushroom_bowl = 1
+ )
+ result = /obj/item/reagent_containers/food/snacks/soup/lavaland_stew
+ subcategory = CAT_SOUP
diff --git a/GainStation13/code/modules/food_and_drinks/recipes_bigpizza.dm b/GainStation13/code/modules/food_and_drinks/recipes_bigpizza.dm
new file mode 100644
index 0000000000..b80420a1b8
--- /dev/null
+++ b/GainStation13/code/modules/food_and_drinks/recipes_bigpizza.dm
@@ -0,0 +1,93 @@
+
+// see code/module/crafting/table.dm
+
+////////////////////////////////////////////////PIZZA!!!////////////////////////////////////////////////
+
+//GS13 - this has been ported from CHOMP/Virgo, but I've decided to adjust the recipe a bit
+// there's both the recipe and the defines for the pizza itself here
+
+/obj/item/reagent_containers/food/snacks/pizza/framewrecker
+ name = "Framewrecker Pizza"
+ desc = "You feel your arteries clogging just by merely looking at this monster. Is this even real, or a mere hallucination?"
+ icon = 'icons/obj/food/food64x64.dmi'
+ icon_state = "theonepizza"
+ pixel_x = -16
+ pixel_y = -16
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ bonus_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5)
+ list_reagents = list(/datum/reagent/consumable/nutriment = 200, /datum/reagent/consumable/tomatojuice = 6, /datum/reagent/consumable/nutriment/vitamin = 20)
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1, "overwhelming surge of calories" = 10)
+ foodtype = GRAIN | VEGETABLES | DAIRY | MEAT | JUNKFOOD | ANTITOXIC
+
+ var/slicelist = list(/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/mushroom,
+ /obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/veggie,
+ /obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/cheese,
+ /obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/pineapple,
+ /obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/meat)
+
+
+
+//slices
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker
+ name = "Framewrecker Pizza Slice"
+ desc = "This mere slice is the size of pizza on its own!"
+ icon = 'icons/obj/food/ported_meals.dmi'
+ list_reagents = list(/datum/reagent/consumable/nutriment = 60)
+ icon_state = "big_mushroom_slice"
+ filling_color = "#FFA500"
+
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/mushroom
+ name = "Giant mushroom pizza slice"
+ icon_state = "big_mushroom_slice"
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "mushrooms" = 1, "delight" = 5)
+ foodtype = GRAIN | VEGETABLES | DAIRY | JUNKFOOD
+
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/veggie
+ name = "Giant veggie pizza slice"
+ icon_state = "big_veggie_slice"
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "veggies" = 1, "delight" = 5)
+ foodtype = GRAIN | VEGETABLES | DAIRY | JUNKFOOD
+
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/pineapple
+ name = "Giant pineapple pizza slice"
+ icon_state = "big_pineapple_slice"
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "ham" = 1, "pineapple" = 5)
+ foodtype = GRAIN | VEGETABLES | DAIRY | JUNKFOOD | FRUIT
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/meat
+ name = "Giant meat pizza slice"
+ icon_state = "big_veggie_slice"
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "meat" = 1, "delight" = 5)
+ foodtype = GRAIN | VEGETABLES | DAIRY | JUNKFOOD | MEAT
+/obj/item/reagent_containers/food/snacks/pizzaslice/framewrecker/cheese
+ name = "Giant cheese pizza slice"
+ icon_state = "big_cheese_slice"
+ tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "delight" = 5)
+ foodtype = GRAIN | VEGETABLES | DAIRY | JUNKFOOD
+
+/obj/item/reagent_containers/food/snacks/pizza/framewrecker/attackby(var/obj/item/weapon/W, var/mob/living/user)
+ if(istype(W,/obj/item/kitchen/knife))
+ user.visible_message("\The [user] starts to slowly cut through The One Pizza.", "You start to slowly cut through The One Pizza.")
+ if(!src)
+ return // We got disappeared already
+ user.visible_message("\The [user] successfully cuts The One Pizza.", "You successfully cut The One Pizza.")
+ for(var/slicetype in slicelist)
+ new slicetype(src.loc)
+ qdel(src)
+
+
+
+// recipe
+
+/datum/crafting_recipe/food/framewrecker_pizza
+ name = "Framewrecker Pizza"
+ reqs = list(
+ /obj/item/reagent_containers/food/snacks/pizzabread = 4,
+ /obj/item/reagent_containers/food/snacks/meat/cutlet = 4,
+ /obj/item/reagent_containers/food/snacks/cheesewedge = 8,
+ /obj/item/reagent_containers/food/snacks/grown/tomato = 8,
+ /obj/item/reagent_containers/food/snacks/pineappleslice = 2,
+ /obj/item/reagent_containers/food/snacks/grown/mushroom/chanterelle = 2
+ )
+ result = /obj/item/reagent_containers/food/snacks/pizza/framewrecker
+ subcategory = CAT_PIZZA
diff --git a/GainStation13/code/modules/gym/gym.dm b/GainStation13/code/modules/gym/gym.dm
new file mode 100644
index 0000000000..cf69367b4d
--- /dev/null
+++ b/GainStation13/code/modules/gym/gym.dm
@@ -0,0 +1,113 @@
+/obj/item/dumbbell
+ desc = "A weighty dumbbell, perfect for arm exercise!"
+ name = "dumbbell"
+ icon = 'GainStation13/icons/obj/dumbbell.dmi'
+ icon_state = "pen"
+ item_state = "pen"
+ throwforce = 20
+ w_class = WEIGHT_CLASS_BULKY
+ throw_speed = 2
+ throw_range = 3
+ materials = list(MAT_METAL=10)
+ pressure_resistance = 2
+ var/reps = 0
+ var/using = FALSE
+
+/obj/item/dumbbell/dropped(mob/user, silent)
+ reps = 0
+ . = ..()
+
+/obj/item/dumbbell/attack_self(mob/user)
+ . = ..()
+ if(!using)
+ using = TRUE
+ to_chat(user, "You do a rep with the [src]. YEEEEEAH!!!")
+ if(do_after(usr, CLICK_CD_RESIST-reps, 0, usr, 1))
+ if(iscarbon(user))
+ var/mob/living/carbon/U = user
+ U.adjust_fatness(-10, FATTENING_TYPE_WEIGHT_LOSS)
+ if(reps < 16)
+ reps += 0.4
+ else
+ to_chat(user, "You couldn't complete the rep. YOU'LL GET IT NEXT TIME CHAMP!!!")
+ using = FALSE
+
+/obj/machinery/treadmill
+ name = "treadmill"
+ desc = "A treadmil, for losing weight!"
+ icon = 'icons/obj/recycling.dmi'
+ icon_state = "conveyor0"
+ circuit = /obj/item/circuitboard/machine/treadmill
+
+ var/fatloss = -10
+
+/obj/machinery/treadmill/Uncross(atom/movable/AM, atom/newloc)
+ if(stat & BROKEN)
+ return ..()
+ if(!isliving(AM))
+ return ..()
+ var/mob/living/M = AM
+ if(M.throwing || M.floating || M.is_flying()) //Make sure they're not going over it
+ return ..()
+ if(AM.dir != dir) //Make sure they're going into the treadmill
+ return ..()
+ if(prob(25))
+ playsound(src, "sound/machines/tractor_running.ogg", 25, TRUE, -2) //Rumblin'
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(C.fatness > FATNESS_LEVEL_BARELYMOBILE)
+ if(prob(5))
+ visible_message(pick(list( //Really testing the poor thing, huh?
+ "\the [src] audibly strains under [C]'s weight...",
+ "\the [src] creeaaaaks under [C]'s strain..."
+ )))
+ C.adjust_fatness(fatloss, FATTENING_TYPE_WEIGHT_LOSS)
+ flick("conveyor-1", src)
+ return FALSE
+
+/obj/machinery/treadmill/RefreshParts(obj/item/O, mob/user, params)
+ for(var/obj/item/stock_parts/manipulator/M in component_parts)
+ fatloss += M.rating * -10
+
+/obj/machinery/treadmill/attackby(obj/item/O, mob/living/user, params)
+ if(default_deconstruction_screwdriver(user, "conveyor0", "conveyor0", O))
+ return TRUE
+
+ if(default_deconstruction_crowbar(O))
+ return TRUE
+
+ if(default_change_direction_wrench(O))
+ return TRUE
+
+ return ..()
+
+/obj/item/circuitboard/machine/treadmill
+ name = "Treadmill (Machine Board)"
+ build_path = /obj/machinery/autolathe
+ req_components = list(/obj/item/stock_parts/manipulator = 1)
+
+/datum/design/treadmill
+ name = "Treadmill Board"
+ id = "treadmill"
+ build_type = AUTOLATHE | PROTOLATHE
+ materials = list(MAT_METAL = 50, MAT_GLASS = 50)
+ build_path = /obj/item/circuitboard/machine/treadmill
+ category = list("inital", "Construction")
+ departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING
+
+/datum/design/dumbbell
+ name = "Dumbbell"
+ id = "dumbbell"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 2000)
+ build_path = /obj/item/dumbbell
+ category = list("initial", "Tools")
+/*
+/datum/design/treadmill
+ name = "Treadmill"
+ id = "treadmill"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 5000)
+ build_path = /obj/item/conveyor_construct/treadmill
+ category = list("initial", "Construction")
+*/
diff --git a/GainStation13/code/modules/hydroponics/grown/berries.dm b/GainStation13/code/modules/hydroponics/grown/berries.dm
new file mode 100644
index 0000000000..263262637b
--- /dev/null
+++ b/GainStation13/code/modules/hydroponics/grown/berries.dm
@@ -0,0 +1,25 @@
+/obj/item/seeds/berry/blueberry
+ name = "pack of blueberry seeds"
+ desc = "These seeds grow into blueberry bushes."
+ icon_state = "seed-blueberry"
+ species = "blueberry"
+ plantname = "Blueberry Bush"
+ product = /obj/item/reagent_containers/food/snacks/grown/berries/blueberry
+ mutatelist = list()
+ reagents_add = list(/datum/reagent/blueberry_juice = 0.1)
+ potency = 1
+ yield = 1
+ production = 10
+ rarity = 30
+
+/obj/item/reagent_containers/food/snacks/grown/berries/blueberry
+ seed = /obj/item/seeds/berry/blueberry
+ name = "bunch of blueberries"
+ desc = "Taste so good, you might turn blue!"
+ icon_state = "blueberrypile"
+ filling_color = "#5d00c7"
+ foodtype = FRUIT
+ juice_results = list(/datum/reagent/blueberry_juice = 20)
+ tastes = list("blueberry" = 1)
+ distill_reagent = null
+ wine_power = 50
diff --git a/GainStation13/code/modules/hydroponics/lipoplant.dm b/GainStation13/code/modules/hydroponics/lipoplant.dm
new file mode 100644
index 0000000000..e321f7a2d6
--- /dev/null
+++ b/GainStation13/code/modules/hydroponics/lipoplant.dm
@@ -0,0 +1,127 @@
+/obj/item/seeds/lipoplant
+ name = "pack of adipolipus"
+ desc = "These seeds grow into a foreign plant."
+ icon = 'GainStation13/icons/obj/hydroponics/lipo_seeds.dmi'
+ icon_state = "lipo_seed"
+ species = "adipolipus"
+ plantname = "Adipolipus"
+ product = /obj/item/reagent_containers/food/snacks/grown/lipofruit
+ lifespan = 30
+ potency = 20
+ maturation = 8
+ production = 5
+ yield = 1
+ growing_icon = 'GainStation13/icons/obj/hydroponics/lipo_growing.dmi'
+ icon_grow = "lipo-grow" // Uses one growth icons set for all the subtypes
+ icon_dead = "lipo-dead" // Same for the dead icon
+ icon_harvest = "lipo-harvest"
+ reagents_add = list(/datum/reagent/consumable/lipoifier = 0.05)
+
+/obj/item/reagent_containers/food/snacks/grown/lipofruit
+ seed = /obj/item/seeds/lipoplant
+ name = "lipofruit"
+ desc = "A foreign fruit with an hard shell. Perhaps something sharp could open it?"
+ icon = 'GainStation13/icons/obj/hydroponics/lipo_harvest.dmi'
+ icon_state = "lipo_nut"
+ item_state = "lipo_nut"
+ possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
+ spillable = FALSE
+ resistance_flags = ACID_PROOF
+ volume = 150 //so it won't cut reagents despite having the capacity for them
+ w_class = WEIGHT_CLASS_SMALL
+ force = 5
+ throwforce = 5
+ hitsound = 'sound/weapons/klonk.ogg'
+ attack_verb = list("klonked", "donked", "bonked")
+ distill_reagent = "creme_de_coconut"
+ var/opened = FALSE
+ sharpness = IS_BLUNT
+
+/obj/item/reagent_containers/food/snacks/grown/lipofruit/attackby(obj/item/W, mob/user, params)
+ if(!opened && W.sharpness)
+ user.show_message("You slice the fruit open!", 1)
+ opened = TRUE
+ spillable = TRUE
+ reagent_flags = OPENCONTAINER
+ ENABLE_BITFIELD(reagents.reagents_holder_flags, OPENCONTAINER)
+ icon_state = "lipo_nutcut_full"
+ desc = "A foreign fruit with an hard shell, the liquid inside looks very inviting."
+ playsound(user, W.hitsound, 50, 1, -1)
+ return
+ return ..()
+
+/obj/item/reagent_containers/food/snacks/grown/lipofruit/attack(mob/living/M, mob/user, obj/target)
+ if(!opened)
+ return
+ if(!canconsume(M, user))
+ return
+ if(!reagents || !reagents.total_volume)
+ to_chat(user, "[src] is empty!")
+ return
+
+ if(user.a_intent == INTENT_HARM && spillable)
+ var/R
+ M.visible_message("[user] splashes the contents of [src] onto [M]!",
+ "[user] splashes the contents of [src] onto [M]!")
+ if(reagents)
+ for(var/datum/reagent/A in reagents.reagent_list)
+ R += A.type + " ("
+ R += num2text(A.volume) + "),"
+ if(isturf(target) && reagents.reagent_list.len && thrownby)
+ log_combat(thrownby, target, "splashed (thrown) [english_list(reagents.reagent_list)]")
+ message_admins("[ADMIN_LOOKUPFLW(thrownby)] splashed (thrown) [english_list(reagents.reagent_list)] on [target] at [ADMIN_VERBOSEJMP(target)].")
+ reagents.reaction(M, TOUCH)
+ log_combat(user, M, "splashed", R)
+ reagents.clear_reagents()
+ else
+ if(M != user)
+ M.visible_message("[user] attempts to feed something to [M].",
+ "[user] attempts to feed something to you.")
+ if(!do_mob(user, M))
+ return
+ if(!reagents || !reagents.total_volume)
+ return // The drink might be empty after the delay, such as by spam-feeding
+ M.visible_message("[user] feeds something to [M].", "[user] feeds something to you.")
+ log_combat(user, M, "fed", reagents.log_list())
+ else
+ to_chat(user, "You swallow a gulp of [src].")
+ var/fraction = min(5/reagents.total_volume, 1)
+ reagents.reaction(M, INGEST, fraction)
+ addtimer(CALLBACK(reagents, TYPE_PROC_REF(/datum/reagents, trans_to), M, 5), 5)
+ playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
+ if(!reagents || reagents.total_volume)
+ icon_state = "lipo_nutcut_empty"
+ desc = "A foreign fruit with an hard shell."
+
+/obj/item/reagent_containers/food/snacks/grown/lipofruit/afterattack(obj/target, mob/user, proximity)
+ . = ..()
+ if((!proximity) || !check_allowed_items(target,target_self=1))
+ return
+ if(target.is_refillable()) //Something like a glass. Player probably wants to transfer TO it.
+ if(!reagents.total_volume)
+ to_chat(user, "[src] is empty!")
+ return
+ if(target.reagents.holder_full())
+ to_chat(user, "[target] is full.")
+ return
+ var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
+ to_chat(user, "You transfer [trans] unit\s of the solution to [target].")
+ else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us.
+ if(!target.reagents.total_volume)
+ to_chat(user, "[target] is empty and can't be refilled!")
+ return
+ if(reagents.holder_full())
+ to_chat(user, "[src] is full.")
+ return
+ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
+ to_chat(user, "You fill [src] with [trans] unit\s of the contents of [target].")
+ else if(reagents.total_volume)
+ if(user.a_intent == INTENT_HARM && spillable == TRUE)
+ user.visible_message("[user] splashes the contents of [src] onto [target]!", \
+ "You splash the contents of [src] onto [target].")
+ reagents.reaction(target, TOUCH)
+ reagents.clear_reagents()
+ if(reagents && reagents.total_volume && opened)
+ icon_state = "lipo_nutcut_full"
+ desc = "A foreign fruit with an hard shell, the liquid inside looks very inviting."
+
diff --git a/GainStation13/code/modules/hydroponics/munchies_weed.dm b/GainStation13/code/modules/hydroponics/munchies_weed.dm
new file mode 100644
index 0000000000..f25bd743c8
--- /dev/null
+++ b/GainStation13/code/modules/hydroponics/munchies_weed.dm
@@ -0,0 +1,53 @@
+/mob/living/carbon
+ var/nutri_mult = 1
+
+/obj/item/seeds/cannabis/munchies
+ name = "pack of munchies weed seeds"
+ desc = "These seeds grow into munchies weed."
+ icon_state = "seed-munchies"
+ species = "munchycannabis"
+ plantname = "Munchies Weed"
+ icon_grow = "munchycannabis-grow" // Uses one growth icons set for all the subtypes
+ icon_dead = "munchycannabis-dead" // Same for the dead icon
+ product = /obj/item/reagent_containers/food/snacks/grown/cannabis/munchies
+ genes = list(/datum/plant_gene/trait/repeated_harvest, /datum/plant_gene/trait/glow/orange)
+ mutatelist = list()
+ reagents_add = list(/datum/reagent/drug/space_drugs = 0.05,
+ /datum/reagent/drug/munchies = 0.10)
+ rarity = 69
+
+/obj/item/reagent_containers/food/snacks/grown/cannabis/munchies
+ seed = /obj/item/seeds/cannabis/munchies
+ name = "munchies cannabis leaf"
+ desc = "You feel hungry just looking at it."
+ icon_state = "munchycannabis"
+ wine_power = 90
+
+/datum/reagent/drug/munchies
+ name = "Appetite Stimulant"
+ value = 6
+ description = "A chemical compound that makes one mindlessly ravenous."
+ color = "#60A584"
+ pH = 9
+ metabolization_rate = REAGENTS_METABOLISM / 4
+
+/datum/reagent/drug/munchies/on_mob_add(mob/living/L, amount)
+ . = ..()
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ C.nutri_mult += 0.5
+
+/datum/reagent/drug/munchies/on_mob_delete(mob/living/L)
+ . = ..()
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ C.nutri_mult -= 0.5
+
+/datum/reagent/drug/munchies/on_mob_life(mob/living/carbon/M)
+ . = ..()
+ if(prob(10))
+ to_chat(M, "[pick("You feel a little ravenous...", "You could really go for a snack right now...", "The taste of food seems really enticing right now...", "Your belly groans, demanding food...")]")
+ if(M.fullness > 10)
+ M.fullness -= 1
+ if(M.nutrition > 150)
+ M.nutrition -= 1
diff --git a/GainStation13/code/modules/mob/living/emote.dm b/GainStation13/code/modules/mob/living/emote.dm
new file mode 100644
index 0000000000..1b4a2a2ad0
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/emote.dm
@@ -0,0 +1,100 @@
+/datum/emote/living/gurgle
+ key = "gurgle"
+ key_third_person = "gurgles"
+ message = "'s belly gurgles"
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/gurgle1.ogg'
+
+/datum/emote/living/gurgle/get_sound()
+ return get_sfx("gurgle") // Lets get any of the gurgle sounds we have set.
+
+/datum/emote/living/burp
+ key = "burp"
+ key_third_person = "burps"
+ message = "burps"
+ emote_type = EMOTE_AUDIBLE
+ var/reduction_min = 4
+ var/reduction_max = 8
+ var/noise_type = "burp"
+ var/noise_pref = BURPING_NOISES
+
+/datum/emote/living/burp/run_emote(mob/living/user, params)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ playsound_prefed(user, noise_type, noise_pref, 100, TRUE, -4)
+
+ user.reduce_fullness(rand(reduction_min,reduction_max))
+
+/datum/emote/living/burp/fart //Butt burp.
+ key = "fart"
+ key_third_person = "farts"
+ message = "farts"
+ //god hates me for this -Metha
+ noise_type = "fart"
+ noise_pref = FARTING_NOISES
+
+/datum/emote/living/burp/fart/run_emote(mob/living/user, params)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ var/obj/item/storage/book/bible/b = locate(/obj/item/storage/book/bible) in get_turf(user) //Biblefart
+ if(b)//Devine Retribution
+ var/mob/living/heretic = user //Heresy.
+ heretic.visible_message(
+ "\The [heretic] farts on \the [b], causing a violent, otherworldly ripple to echo \
+ outwards before they explode in a gorey mess of divine retribution!",
+ "You feel a deep sense of dread as you release pressure from your rear over \the [b], \
+ immediately realizing your mistake as Divine Retribution rends your form into a gorey mess.")
+ heretic.emote("scream")
+ message_admins("[ADMIN_LOOKUPFLW(heretic)] farted on a bible at [ADMIN_VERBOSEJMP(heretic)] and was gibbed.")
+ log_game("[key_name(heretic)] farted on a bible at [AREACOORD(heretic)] and was gibbed")
+ heretic.gib()
+ return //Gassy is dead
+
+/datum/emote/living/burp/belch
+ key = "belch"
+ key_third_person = "belches loudly"
+ message = "belches"
+ //god hates me for this -Metha
+ noise_type = "belch"
+ reduction_min = 6
+ reduction_max = 12
+
+/datum/emote/living/burp/fart/brap
+ key = "brap"
+ key_third_person = "braps"
+ message = ""
+ reduction_min = 6
+ reduction_max = 12
+
+/datum/emote/living/burp/fart/brap/select_message_type(var/mob/living/user)
+ return pick("farts loudly!", "cuts a fat one!", "rips absolute ass!")
+
+/datum/emote/living/burp/fart/goon // Fart but it's funny !
+ key = "goonfart"
+ key_third_person = "goonfarts"
+ noise_type = 'goon/sound/voice/farts/fart4.ogg'
+
+//Shhh... It's a secret! Don't tell or I'll steal your legs
+/datum/emote/living/burunyu
+ key = "burunyu"
+ key_third_person = "burunyues"
+ message = "emits a strange feline sound"
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/funnycat.ogg'
+
+/datum/emote/living/bellyrub
+ key = "bellyrub"
+ key_third_person = "bellyrubs"
+ message = "rubs their belly"
+ emote_type = EMOTE_VISIBLE
+
+/datum/emote/living/bellyrub/run_emote(mob/living/user, params)
+ . = ..()
+ if(!.)
+ return FALSE
+
+ user.reduce_fullness(rand(4,16), FALSE)
diff --git a/GainStation13/code/modules/mob/living/emote_modular.dm b/GainStation13/code/modules/mob/living/emote_modular.dm
new file mode 100644
index 0000000000..f8ddbcd3b5
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/emote_modular.dm
@@ -0,0 +1,4 @@
+// This is a file for emotes that have been rewritten to be more modular. Such as varying based on species or whathave you. May move this later or something.
+
+
+//I was going to put screams in here but I overhauled it in a different more austistic way
diff --git a/GainStation13/code/modules/mob/living/emote_ported.dm b/GainStation13/code/modules/mob/living/emote_ported.dm
new file mode 100644
index 0000000000..77c401b652
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/emote_ported.dm
@@ -0,0 +1,239 @@
+// This is an emote file for random shit we've ported. Im just copying the style recipes_ported.dm did, yell at me if im wrong later.
+// It said it was lazy but personally I think this might be a better way of organizing otherwise unique content that we're porting
+// for ourselves. -Reo
+
+// I found this tacked onto the bottom of code/modules/mob/living/emote.dm. No //code add: notice or anything. Moving it here,
+// since it seems to all be ported emotes. -Reo
+/*
+//Carl wuz here
+//FUCK YOU CARL SUCK MY BALLS YOU WHORE
+/datum/emote/living/tesh_sneeze
+ key = "tesh_sneeze"
+ key_third_person = "sneezes"
+ message = "sneezes."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/tesh_sneeze/can_run_emote(mob/living/user, status_check = TRUE)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ return !C.silent
+
+/datum/emote/living/tesh_sneeze/run_emote(mob/user, params)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(!C.mind || C.mind.miming)//no cute sneezing for you.
+ return
+ if(ishumanbasic(C))
+ playsound(C, pick('hyperstation/sound/voice/emotes/tesh_sneeze1.ogg', 'hyperstation/sound/voice/emotes/tesh_sneeze1b.ogg'), 50, 1)
+ if(is_species(user, /datum/species/avian))//This is required(related to subtypes), otherwise it doesn't play the noises. Sometimes. Always sometimes. Just how it be.
+ playsound(C, pick('hyperstation/sound/voice/emotes/tesh_sneeze1.ogg', 'hyperstation/sound/voice/emotes/tesh_sneeze1b.ogg'), 50, 1)
+ if(is_species(user, /datum/species/mammal))//Just because the avian subspecies doesn't have proper sprites. Some people can't use it.
+ playsound(C, pick('hyperstation/sound/voice/emotes/tesh_sneeze1.ogg', 'hyperstation/sound/voice/emotes/tesh_sneeze1b.ogg'), 50, 1)
+
+/datum/emote/living/racc
+ key = "racc_chitter"
+ key_third_person = "chitters"
+ message = "chitters."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/racc/can_run_emote(mob/living/user, status_check = TRUE)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ return !C.silent
+
+/datum/emote/living/racc/run_emote(mob/user, params)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(!C.mind || C.mind.miming)
+ return
+ if(ishumanbasic(C))
+ playsound(C, pick('hyperstation/sound/voice/emotes/racc_chitter_1.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_2.ogg',\
+ 'hyperstation/sound/voice/emotes/racc_chitter_3.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_4.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_5.ogg',\
+ 'hyperstation/sound/voice/emotes/racc_chitter_6.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_7.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_8.ogg'), 50, 1)
+ if(is_species(user, /datum/species/mammal))
+ playsound(C, pick('hyperstation/sound/voice/emotes/racc_chitter_1.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_2.ogg',\
+ 'hyperstation/sound/voice/emotes/racc_chitter_3.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_4.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_5.ogg',\
+ 'hyperstation/sound/voice/emotes/racc_chitter_6.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_7.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_8.ogg'), 50, 1)
+
+/datum/emote/living/bat
+ key = "bat_chitter"
+ key_third_person = "chitters"
+ message = "chitters."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/bat/can_run_emote(mob/living/user, status_check = TRUE)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ return !C.silent
+
+/datum/emote/living/bat/run_emote(mob/user, params)
+ . = ..()
+ if(. && iscarbon(user))
+ var/mob/living/carbon/C = user
+ if(!C.mind || C.mind.miming)
+ return
+ if(ishumanbasic(C))
+ playsound(C, pick('hyperstation/sound/voice/emotes/bat_c1.ogg', 'hyperstation/sound/voice/emotes/bat_c2.ogg', 'hyperstation/sound/voice/emotes/bat_c3.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c4.ogg', 'hyperstation/sound/voice/emotes/bat_c5.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c6.ogg', 'hyperstation/sound/voice/emotes/bat_c7.ogg', 'hyperstation/sound/voice/emotes/bat_c8.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c9.ogg'), 50, 1)
+ if(is_species(user, /datum/species/mammal))
+ playsound(C, pick('hyperstation/sound/voice/emotes/bat_c1.ogg', 'hyperstation/sound/voice/emotes/bat_c2.ogg', 'hyperstation/sound/voice/emotes/bat_c3.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c4.ogg', 'hyperstation/sound/voice/emotes/bat_c5.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c6.ogg', 'hyperstation/sound/voice/emotes/bat_c7.ogg', 'hyperstation/sound/voice/emotes/bat_c8.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c9.ogg'), 50, 1)
+ if(is_species(user, /datum/species/avian))//this and mammal should be considered the same AAAAAAAAAAAA
+ playsound(C, pick('hyperstation/sound/voice/emotes/bat_c1.ogg', 'hyperstation/sound/voice/emotes/bat_c2.ogg', 'hyperstation/sound/voice/emotes/bat_c3.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c4.ogg', 'hyperstation/sound/voice/emotes/bat_c5.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c6.ogg', 'hyperstation/sound/voice/emotes/bat_c7.ogg', 'hyperstation/sound/voice/emotes/bat_c8.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c9.ogg'), 50, 1)
+*/
+//End of the random emotes I found in mob/living
+
+
+//Rewrites of the above start.
+/datum/emote/living/carbon/racc
+ key = "racc_chitter"
+ key_third_person = "raccchitters"
+ message = "chitters."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/carbon/racc/get_sound()
+ return pick('hyperstation/sound/voice/emotes/racc_chitter_1.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_2.ogg',\
+ 'hyperstation/sound/voice/emotes/racc_chitter_3.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_4.ogg', \
+ 'hyperstation/sound/voice/emotes/racc_chitter_5.ogg','hyperstation/sound/voice/emotes/racc_chitter_6.ogg', \
+ 'hyperstation/sound/voice/emotes/racc_chitter_7.ogg', 'hyperstation/sound/voice/emotes/racc_chitter_8.ogg')
+
+/datum/emote/living/carbon/bat
+ key = "bat_chitter"
+ key_third_person = "bat_chitters"
+ message = "chitters."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/carbon/bat/get_sound()
+ return pick('hyperstation/sound/voice/emotes/bat_c1.ogg', 'hyperstation/sound/voice/emotes/bat_c2.ogg', \
+ 'hyperstation/sound/voice/emotes/bat_c3.ogg', 'hyperstation/sound/voice/emotes/bat_c4.ogg', \
+ 'hyperstation/sound/voice/emotes/bat_c5.ogg','hyperstation/sound/voice/emotes/bat_c6.ogg', \
+ 'hyperstation/sound/voice/emotes/bat_c7.ogg', 'hyperstation/sound/voice/emotes/bat_c8.ogg',\
+ 'hyperstation/sound/voice/emotes/bat_c9.ogg')
+
+//Rewrites of the above end.
+
+//Ported from Vorestation
+/datum/emote/living/carbon/teshsqueak
+ key = "teshsurprise" //Originally, It was just "surprised" but I dont think that's very telling of a teshari emote.
+ key_third_person = "teshsurprised"
+ message = "chirps in surprise!"
+ message_param = "chirps in surprise at %t!"
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/teshari/teshsqueak.ogg' // Copyright CC BY 3.0 InspectorJ (freesound.org) for the source audio.
+
+/datum/emote/living/carbon/teshchirp
+ key = "tchirp"
+ key_third_person = "tchirps"
+ message = "chirps!"
+ message_param = "chirps at %t!"
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/teshari/teshchirp.ogg' // Copyright Sampling+ 1.0 Incarnidine (freesound.org) for the source audio.
+
+/datum/emote/living/carbon/teshtrill
+ key = "trill"
+ key_third_person = "trills"
+ message = "trills."
+ message_param = "trills at %t."
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/teshari/teshtrill.ogg' // Copyright CC BY-NC 3.0 Arnaud Coutancier (freesound.org) for the source audio.
+
+/datum/emote/living/sneeze/teshsneeze //Replace this with a modular species/tongue based sneeze system later. Also piggybacking on normal sneezes
+ key = "teshsneeze"
+ key_third_person = "teshsneezes"
+ message = "sneezes."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/sneeze/teshsneeze/get_sound()
+ return pick('GainStation13/sound/voice/teshari/tesharisneeze.ogg', 'GainStation13/sound/voice/teshari/tesharisneezeb.ogg')
+
+/datum/emote/living/cough/teshcough //Same as above. Replace with a modular system later.
+ key = "teshcough"
+ key_third_person = "teshcoughs"
+ message = "coughs."
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/cough/teshcough/get_sound()
+ return pick('GainStation13/sound/voice/teshari/tesharicougha.ogg', 'GainStation13/sound/voice/teshari/tesharicoughb.ogg')
+
+/datum/emote/living/carbon/teshscream
+ key = "teshscream"
+ key_third_person = "teshscreams"
+ message = "screams!"
+ message_param = "screams at %t!"
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/teshari/teshscream.ogg'
+
+/datum/emote/living/prbt
+ key = "prbt"
+ key_third_person = "prbts"
+ message = "prbts."
+ message_param = "prbts at %t."
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/emotes/prbt.ogg'
+
+/datum/emote/living/mlem
+ key = "mlem"
+ key_third_person = "mlems"
+ message = "mlems their tongue up over their nose. Mlem."
+
+/datum/emote/living/blep
+ key = "blep"
+ key_third_person = "bleps"
+ message = "bleps their tongue out. Blep."
+
+/datum/emote/living/teppi
+ key = "gyoh"
+ key_third_person = "gyohs"
+ message = "gyohs"
+ var/bigsound = list('GainStation13/sound/voice/teppi/gyooh1.ogg', 'GainStation13/sound/voice/teppi/gyooh2.ogg', \
+ 'GainStation13/sound/voice/teppi/gyooh3.ogg', 'GainStation13/sound/voice/teppi/gyooh4.ogg', \
+ 'GainStation13/sound/voice/teppi/gyooh5.ogg', 'GainStation13/sound/voice/teppi/gyooh6.ogg')
+ var/smolsound = list('GainStation13/sound/voice/teppi/whine1.ogg', 'GainStation13/sound/voice/teppi/whine2.ogg')
+
+/datum/emote/living/teppi/run_emote(mob/living/user, params)
+ /* //If we port teppi later, Enable this.
+ if(istype(user, /mob/living/simple_mob/vore/alienanimals/teppi))
+ if(istype(user, /mob/living/simple_mob/vore/alienanimals/teppi/baby))
+ sound = pick(smolsound)
+ else
+ sound = pick(bigsound)
+ return ..()
+ */
+ if(user.size_multiplier >= 1.5)
+ sound = pick(bigsound)
+ else
+ sound = pick(smolsound)
+ . = ..()
+
+/datum/emote/living/teppi/rumble
+ key = "rumble"
+ key_third_person = "rumbles"
+ message = "rumbles contentedly."
+ sound = 'GainStation13/sound/voice/teppi/cute_rumble.ogg'
+ bigsound = list('GainStation13/sound/voice/teppi/rumble.ogg')
+ smolsound = list('GainStation13/sound/voice/teppi/cute_rumble.ogg')
+
+//Vorestation ports end.
+
+//Ported from Chompstation
+/datum/emote/living/wawa
+ key = "wawa"
+ key_third_person = "wawas"
+ message = "wawas."
+ message_param = "wawas at %t."
+ emote_type = EMOTE_AUDIBLE
+ sound = 'GainStation13/sound/voice/emotes/wawa.ogg'
+
+//Chompstation ports end.
diff --git a/GainStation13/code/modules/mob/living/fullness.dm b/GainStation13/code/modules/mob/living/fullness.dm
new file mode 100644
index 0000000000..a21a7304cc
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/fullness.dm
@@ -0,0 +1,16 @@
+/mob/living/proc/reduce_fullness(amount, notify = TRUE) // fullness_amount should be between 5 and 20 for balance and below 80 for functionality
+ if(!ishuman(src))
+ return
+
+ if(fullness >= FULLNESS_LEVEL_BLOATED && fullness_reducion_timer + FULLNESS_REDUCTION_COOLDOWN < world.time)
+
+ fullness -= amount // Remove Fullness
+
+ if(!notify)
+ return
+
+ if(amount <= 5)
+ to_chat(src, "You felt that make some space")
+ if(amount > 5)
+ to_chat(src, "You felt that make a lot of space")
+
diff --git a/GainStation13/code/modules/mob/living/nutribot.dm b/GainStation13/code/modules/mob/living/nutribot.dm
new file mode 100644
index 0000000000..936f9d9354
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/nutribot.dm
@@ -0,0 +1,609 @@
+//nutribot
+//nutribot PATHFINDING
+//nutribot ASSEMBLY
+#define NUTRIBOT_PANIC_NONE 0
+#define NUTRIBOT_PANIC_LOW 15
+#define NUTRIBOT_PANIC_MED 35
+#define NUTRIBOT_PANIC_HIGH 55
+#define NUTRIBOT_PANIC_FUCK 70
+#define NUTRIBOT_PANIC_ENDING 90
+#define NUTRIBOT_PANIC_END 100
+
+/mob/living/simple_animal/bot/nutribot
+ name = "\improper Nutribot"
+ desc = "A little nutritional robot. He looks somewhat underwhelmed."
+ icon = 'GainStation13/icons/mob/nutribot.dmi'
+ icon_state = "nutribot0"
+ density = FALSE
+ anchored = FALSE
+ health = 20
+ maxHealth = 20
+ pass_flags = PASSMOB
+
+ status_flags = (CANPUSH | CANSTUN)
+
+ radio_key = /obj/item/encryptionkey/headset_med
+ radio_channel = RADIO_CHANNEL_SERVICE
+
+ bot_type = MED_BOT
+ model = "Nutribot"
+ bot_core_type = /obj/machinery/bot_core/nutribot
+ window_id = "auto_nutrition"
+ window_name = "Automatic Nutritional Unit v1.1"
+ data_hud_type = DATA_HUD_MEDICAL_ADVANCED
+ path_image_color = "#DDDDFF"
+
+ var/obj/item/reagent_containers/glass/reagent_glass = null //Can be set to draw from this for reagents.
+ var/skin = null //Set to "tox", "ointment" or "o2" for the other two firstaid kits.
+ var/mob/living/carbon/patient = null
+ var/mob/living/carbon/oldpatient = null
+ var/oldloc = null
+ var/last_found = 0
+ var/last_newpatient_speak = 0 //Don't spam the "HEY I'M COMING" messages
+ var/injection_amount = 15 //How much reagent do we inject at a time?
+ var/feed_threshold = 200 // The weight that people should be fed to!
+ var/use_beaker = 0 //Use reagents in beaker instead of default treatment agents.
+ var/declare_cooldown = 0 //Prevents spam of critical patient alerts.
+ var/stationary_mode = 0 //If enabled, the Nutribot will not move automatically.
+ //Setting which reagents to use to treat what by default. By id.
+ var/treatment_thin = /datum/reagent/consumable/nutriment
+ var/treatment_thirsty = /datum/reagent/water
+ var/hunger_check = NUTRITION_LEVEL_HUNGRY
+ var/shut_up = 0 //self explanatory :)
+
+ //How panicked we are about being tipped over (why would you do this?)
+ var/tipped_status = NUTRIBOT_PANIC_NONE
+ //The name we got when we were tipped
+ var/tipper_name
+ //The last time we were tipped/righted and said a voice line, to avoid spam
+ var/last_tipping_action_voice = 0
+
+
+/mob/living/simple_animal/bot/nutribot/update_icon()
+ cut_overlays()
+ if(!on)
+ icon_state = "nutribot0"
+ return
+ if(IsStun())
+ icon_state = "nutribota"
+ return
+ if(mode == BOT_HEALING)
+ icon_state = "nutribots[stationary_mode]"
+ return
+ else if(stationary_mode) //Bot has yellow light to indicate stationary mode.
+ icon_state = "nutribot2"
+ else
+ icon_state = "nutribot1"
+
+/mob/living/simple_animal/bot/nutribot/Initialize(mapload, new_skin)
+ . = ..()
+ var/datum/job/cook/J = new /datum/job/cook
+ access_card.access += J.get_access()
+ prev_access = access_card.access
+ qdel(J)
+ skin = new_skin
+ update_icon()
+
+/mob/living/simple_animal/bot/nutribot/update_canmove()
+ . = ..()
+ update_icon()
+
+/mob/living/simple_animal/bot/nutribot/bot_reset()
+ ..()
+ patient = null
+ oldpatient = null
+ oldloc = null
+ last_found = world.time
+ declare_cooldown = 0
+ update_icon()
+
+/mob/living/simple_animal/bot/nutribot/proc/soft_reset() //Allows the Nutribot to still actively perform its medical duties without being completely halted as a hard reset does.
+ path = list()
+ patient = null
+ mode = BOT_IDLE
+ last_found = world.time
+ update_icon()
+
+/mob/living/simple_animal/bot/nutribot/set_custom_texts()
+
+ text_hack = "You corrupt [name]'s reagent processor circuits."
+ text_dehack = "You reset [name]'s reagent processor circuits."
+ text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!"
+
+/mob/living/simple_animal/bot/nutribot/attack_paw(mob/user)
+ return attack_hand(user)
+
+/mob/living/simple_animal/bot/nutribot/get_controls(mob/user)
+ var/dat
+ dat += hack(user)
+ dat += showpai(user)
+ dat += "Nutritional Unit Controls v1.1
"
+ dat += "Status: [on ? "On" : "Off"]
"
+ dat += "Maintenance panel panel is [open ? "opened" : "closed"]
"
+ dat += "Beaker: "
+ if(reagent_glass)
+ dat += "Loaded \[[reagent_glass.reagents.total_volume]/[reagent_glass.reagents.maximum_volume]\]"
+ else
+ dat += "None Loaded"
+ dat += "
Behaviour controls are [locked ? "locked" : "unlocked"]
"
+ if(!locked || issilicon(user) || IsAdminGhost(user))
+
+ dat += "Feed Amount: "
+ dat += "- "
+ dat += "[injection_amount] "
+ dat += "+ "
+ dat += "
"
+
+ dat += "Reagent Source: "
+ dat += "[use_beaker ? "Loaded Beaker (When available)" : "Internal Synthesizer"]
"
+
+ dat += "Hunger Check: "
+ dat += "[(hunger_check==NUTRITION_LEVEL_HUNGRY) ? "Yes" : "No"]
"
+
+ dat += "Maximum BFI: "
+ dat += "[feed_threshold ? feed_threshold : "???"] "
+ dat += "
"
+ dat += "Disable Maximum BFI: ["Disable"]
"
+ dat += "- "
+ dat += "+ "
+ dat += "
"
+
+ dat += "The speaker switch is [shut_up ? "off" : "on"]. Toggle
"
+ dat += "Patrol Station: [auto_patrol ? "Yes" : "No"]
"
+ dat += "Stationary Mode: [stationary_mode ? "Yes" : "No"]
"
+
+ return dat
+
+/mob/living/simple_animal/bot/nutribot/Topic(href, href_list)
+ if(..())
+ return TRUE
+
+ else if(href_list["adj_inject"])
+ var/adjust_num = text2num(href_list["adj_inject"])
+ injection_amount += adjust_num
+ if(injection_amount < 5)
+ injection_amount = 5
+ if(injection_amount > 15)
+ injection_amount = 15
+
+ else if(href_list["use_beaker"])
+ use_beaker = !use_beaker
+
+ else if(href_list["eject"] && (!isnull(reagent_glass)))
+ reagent_glass.forceMove(drop_location())
+ reagent_glass = null
+
+ else if(href_list["togglevoice"])
+ shut_up = !shut_up
+
+ else if(href_list["stationary"])
+ stationary_mode = !stationary_mode
+ path = list()
+ update_icon()
+
+ else if(href_list["hunger_check"])
+ hunger_check = ((hunger_check==NUTRITION_LEVEL_HUNGRY) ? NUTRITION_LEVEL_FULL : NUTRITION_LEVEL_HUNGRY)
+
+ else if(href_list["feed_threshold"])
+ var/adjust_num = text2num(href_list["feed_threshold"])
+ feed_threshold += adjust_num
+ if(adjust_num == 1)
+ feed_threshold = 0
+ if(feed_threshold < 0)
+ feed_threshold = 0
+
+ update_controls()
+ return
+
+/mob/living/simple_animal/bot/nutribot/attackby(obj/item/W as obj, mob/user as mob, params)
+ if(istype(W, /obj/item/reagent_containers/glass))
+ . = 1 //no afterattack
+ if(locked)
+ to_chat(user, "You cannot insert a beaker because the panel is locked!")
+ return
+ if(!isnull(reagent_glass))
+ to_chat(user, "There is already a beaker loaded!")
+ return
+ if(!user.transferItemToLoc(W, src))
+ return
+
+ reagent_glass = W
+ to_chat(user, "You insert [W].")
+ show_controls(user)
+
+ else
+ var/current_health = health
+ ..()
+ if(health < current_health) //if nutribot took some damage
+ step_to(src, (get_step_away(src,user)))
+
+/mob/living/simple_animal/bot/nutribot/emag_act(mob/user)
+ ..()
+ if(emagged == 2)
+ if(user)
+ to_chat(user, "You short out [src]'s reagent synthesis circuits.")
+ audible_message("[src] buzzes oddly!")
+ flick("nutribot_spark", src)
+ playsound(src, "sparks", 75, 1)
+ if(user)
+ oldpatient = user
+
+/mob/living/simple_animal/bot/nutribot/process_scan(mob/living/carbon/human/H)
+ if(H.stat == DEAD)
+ return
+
+ if((H == oldpatient) && (world.time < last_found + 200))
+ return
+
+ if(assess_patient(H))
+ last_found = world.time
+ if((last_newpatient_speak + 300) < world.time) //Don't spam these messages!
+ var/list/messagevoice = list("Hey, [H.name]! Hold on, I'm coming." = 'sound/voice/medbot/coming.ogg',"Wait [H.name]! I want to help!" = 'sound/voice/medbot/help.ogg')
+ var/message = pick(messagevoice)
+ if(prob(2) && ISINRANGE_EX(H.getFireLoss(), 0, 20))
+ message = "Notices your minor burns*OwO what's this?"
+ messagevoice[message] = 'sound/voice/medbot/owo.ogg'
+ speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
+ last_newpatient_speak = world.time
+ return H
+ else
+ return
+
+/mob/living/simple_animal/bot/nutribot/proc/tip_over(mob/user)
+ canmove = 0
+ //mobility_flags &= ~MOBILITY_MOVE
+ playsound(src, 'sound/machines/warning-buzzer.ogg', 50)
+ user.visible_message("[user] tips over [src]!", "You tip [src] over!")
+ mode = BOT_TIPPED
+ var/matrix/mat = transform
+ transform = mat.Turn(180)
+
+/mob/living/simple_animal/bot/nutribot/proc/set_right(mob/user)
+ canmove = 1
+ //mobility_flags &= MOBILITY_MOVE
+ var/list/messagevoice
+ if(user)
+ user.visible_message("[user] sets [src] right-side up!", "You set [src] right-side up!")
+ if(user.name == tipper_name)
+ messagevoice = list("I forgive you." = 'sound/voice/medbot/forgive.ogg')
+ else
+ messagevoice = list("Thank you!" = 'sound/voice/medbot/thank_you.ogg', "You are a good person." = 'sound/voice/medbot/youre_good.ogg')
+ else
+ visible_message("[src] manages to writhe wiggle enough to right itself.")
+ messagevoice = list("Fuck you." = 'sound/voice/medbot/fuck_you.ogg', "Your behavior has been reported, have a nice day." = 'sound/voice/medbot/reported.ogg')
+
+ tipper_name = null
+ if(world.time > last_tipping_action_voice + 15 SECONDS)
+ last_tipping_action_voice = world.time
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(src, messagevoice[message], 70)
+ tipped_status = NUTRIBOT_PANIC_NONE
+ mode = BOT_IDLE
+ transform = matrix()
+
+// if someone tipped us over, check whether we should ask for help or just right ourselves eventually
+/mob/living/simple_animal/bot/nutribot/proc/handle_panic()
+ tipped_status++
+ var/list/messagevoice
+ switch(tipped_status)
+ if(NUTRIBOT_PANIC_LOW)
+ messagevoice = list("I require assistance." = 'sound/voice/medbot/i_require_asst.ogg')
+ if(NUTRIBOT_PANIC_MED)
+ messagevoice = list("Please put me back." = 'sound/voice/medbot/please_put_me_back.ogg')
+ if(NUTRIBOT_PANIC_HIGH)
+ messagevoice = list("Please, I am scared!" = 'sound/voice/medbot/please_im_scared.ogg')
+ if(NUTRIBOT_PANIC_FUCK)
+ messagevoice = list("I don't like this, I need help!" = 'sound/voice/medbot/dont_like.ogg', "This hurts, my pain is real!" = 'sound/voice/medbot/pain_is_real.ogg')
+ if(NUTRIBOT_PANIC_ENDING)
+ messagevoice = list("Is this the end?" = 'sound/voice/medbot/is_this_the_end.ogg', "Nooo!" = 'sound/voice/medbot/nooo.ogg')
+ if(NUTRIBOT_PANIC_END)
+ speak("PSYCH ALERT: Crewmember [tipper_name] recorded displaying antisocial tendencies torturing bots in [get_area(src)]. Please schedule psych evaluation.", radio_channel)
+ set_right() // strong independent nutribot
+
+ if(prob(tipped_status))
+ do_jitter_animation(tipped_status * 0.1)
+
+ if(messagevoice)
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(src, messagevoice[message], 70)
+ else if(prob(tipped_status * 0.2))
+ playsound(src, 'sound/machines/warning-buzzer.ogg', 30, extrarange=-2)
+
+/mob/living/simple_animal/bot/nutribot/examine(mob/user)
+ . = ..()
+ if(tipped_status == NUTRIBOT_PANIC_NONE)
+ return
+
+ switch(tipped_status)
+ if(NUTRIBOT_PANIC_NONE to NUTRIBOT_PANIC_LOW)
+ . += "It appears to be tipped over, and is quietly waiting for someone to set it right."
+ if(NUTRIBOT_PANIC_LOW to NUTRIBOT_PANIC_MED)
+ . += "It is tipped over and requesting help."
+ if(NUTRIBOT_PANIC_MED to NUTRIBOT_PANIC_HIGH)
+ . += "They are tipped over and appear visibly distressed." // now we humanize the nutribot as a they, not an it
+ if(NUTRIBOT_PANIC_HIGH to NUTRIBOT_PANIC_FUCK)
+ . += "They are tipped over and visibly panicking!"
+ if(NUTRIBOT_PANIC_FUCK to INFINITY)
+ . += "They are freaking out from being tipped over!"
+
+/mob/living/simple_animal/bot/nutribot/handle_automated_action()
+ if(!..())
+ return
+
+ if(mode == BOT_TIPPED)
+ handle_panic()
+ return
+
+ if(mode == BOT_HEALING)
+ return
+
+ if(IsStun())
+ oldpatient = patient
+ patient = null
+ mode = BOT_IDLE
+ return
+
+ if(frustration > 8)
+ oldpatient = patient
+ soft_reset()
+
+ if(QDELETED(patient))
+ if(!shut_up && prob(1))
+ if(emagged && prob(30))
+ var/list/i_need_scissors = list('sound/voice/medbot/fuck_you.ogg', 'sound/voice/medbot/turn_off.ogg', 'sound/voice/medbot/im_different.ogg', 'sound/voice/medbot/close.ogg', 'sound/voice/medbot/shindemashou.ogg')
+ playsound(src, pick(i_need_scissors), 70)
+ else
+ var/list/messagevoice = list("Radar, put a mask on!" = 'sound/voice/medbot/radar.ogg',"There's always a catch, and I'm the best there is." = 'sound/voice/medbot/catch.ogg',"I knew it, I should've been a plastic surgeon." = 'sound/voice/medbot/surgeon.ogg',"What kind of medbay is this? Everyone's dropping like flies." = 'sound/voice/medbot/flies.ogg',"Delicious!" = 'sound/voice/medbot/delicious.ogg', "Why are we still here? Just to suffer?" = 'sound/voice/medbot/why.ogg')
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(src, messagevoice[message], 50)
+ var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE) //If in stationary mode, scan range is limited to adjacent patients.
+ patient = scan(/mob/living/carbon/human, oldpatient, scan_range)
+ oldpatient = patient
+
+ if(patient && (get_dist(src,patient) <= 1)) //Patient is next to us, begin treatment!
+ if(mode != BOT_HEALING)
+ mode = BOT_HEALING
+ update_icon()
+ frustration = 0
+ medicate_patient(patient)
+ return
+
+ //Patient has moved away from us!
+ else if(patient && path.len && (get_dist(patient,path[path.len]) > 2))
+ path = list()
+ mode = BOT_IDLE
+ last_found = world.time
+
+ else if(stationary_mode && patient) //Since we cannot move in this mode, ignore the patient and wait for another.
+ soft_reset()
+ return
+
+ if(patient && path.len == 0 && (get_dist(src,patient) > 1))
+ path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,id=access_card)
+ mode = BOT_MOVING
+ if(!path.len) //try to get closer if you can't reach the patient directly
+ path = get_path_to(src, get_turf(patient), /turf/proc/Distance_cardinal, 0, 30,1,id=access_card)
+ if(!path.len) //Do not chase a patient we cannot reach.
+ soft_reset()
+
+ if(path.len > 0 && patient)
+ if(!bot_move(path[path.len]))
+ oldpatient = patient
+ soft_reset()
+ return
+
+ if(path.len > 8 && patient)
+ frustration++
+
+ if(auto_patrol && !stationary_mode && !patient)
+ if(mode == BOT_IDLE || mode == BOT_START_PATROL)
+ start_patrol()
+
+ if(mode == BOT_PATROL)
+ bot_patrol()
+
+ return
+
+/mob/living/simple_animal/bot/nutribot/proc/assess_patient(mob/living/carbon/C)
+ //Time to see if they need medical help!
+ if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH)))
+ return FALSE //welp too late for them!
+
+ if(!(loc == C.loc) && !(isturf(C.loc) && isturf(loc)))
+ return FALSE
+
+ if(C.suiciding)
+ return FALSE //Kevorkian school of robotic medical assistants.
+
+ if(!C?.client?.prefs.bot_feeding)
+ return FALSE
+
+ if(emagged == 2) //Everyone needs our medicine. (Our medicine is corn oil)
+ return TRUE
+
+ if(ishuman(C))
+ var/mob/living/carbon/human/H = C
+ if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing))
+ var/obj/item/clothing/CS = H.wear_suit
+ var/obj/item/clothing/CH = H.head
+ if (CS.clothing_flags & CH.clothing_flags & THICKMATERIAL)
+ return FALSE // Skip over them if they have no exposed flesh.
+
+ //if(declare_crit && C.health <= 0) //Critical condition! Call for help!
+ //declare(C)
+
+ //If they're injured, we're using a beaker, and don't have one of our WONDERCHEMS.
+ if((reagent_glass) && (use_beaker) && (C.nutrition <= hunger_check) && ((C.fatness <= feed_threshold) || (feed_threshold == 0)))
+ for(var/A in reagent_glass.reagents.reagent_list)
+ var/datum/reagent/R = A
+ if(!C.reagents.has_reagent(R.type))
+ return TRUE
+
+ //They're injured enough for it!
+
+ //nutrition check
+ if((C.nutrition <= hunger_check) && ((C.fatness <= feed_threshold) || (feed_threshold == 0)) && (!C.reagents.has_reagent(treatment_thin)))
+ return TRUE //If they're already medicated don't bother!
+
+ return FALSE
+
+/mob/living/simple_animal/bot/nutribot/attack_hand(mob/living/carbon/human/H)
+ if(H.a_intent == INTENT_DISARM && mode != BOT_TIPPED)
+ H.visible_message("[H] begins tipping over [src].", "You begin tipping over [src]...")
+
+ if(world.time > last_tipping_action_voice + 15 SECONDS)
+ last_tipping_action_voice = world.time // message for tipping happens when we start interacting, message for righting comes after finishing
+ var/list/messagevoice = list("Hey, wait..." = 'sound/voice/medbot/hey_wait.ogg',"Please don't..." = 'sound/voice/medbot/please_dont.ogg',"I trusted you..." = 'sound/voice/medbot/i_trusted_you.ogg', "Nooo..." = 'sound/voice/medbot/nooo.ogg', "Oh fuck-" = 'sound/voice/medbot/oh_fuck.ogg')
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(src, messagevoice[message], 70, FALSE)
+
+ if(do_after(H, 3 SECONDS, target=src))
+ tip_over(H)
+
+ else if(H.a_intent == INTENT_HELP && mode == BOT_TIPPED)
+ H.visible_message("[H] begins righting [src].", "You begin righting [src]...")
+ if(do_after(H, 3 SECONDS, target=src))
+ set_right(H)
+ else
+ ..()
+
+/mob/living/simple_animal/bot/nutribot/UnarmedAttack(atom/A)
+ if(iscarbon(A))
+ var/mob/living/carbon/C = A
+ patient = C
+ mode = BOT_HEALING
+ update_icon()
+ medicate_patient(C)
+ update_icon()
+ else
+ ..()
+
+/mob/living/simple_animal/bot/nutribot/examinate(atom/A as mob|obj|turf in view())
+ ..()
+ if(!is_blind(src))
+ chemscan(src, A)
+
+/mob/living/simple_animal/bot/nutribot/proc/medicate_patient(mob/living/carbon/C)
+ if(!on)
+ return
+
+ if(!istype(C))
+ oldpatient = patient
+ soft_reset()
+ return
+
+ if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH)))
+ var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/medbot/no.ogg',"Live, damnit! LIVE!" = 'sound/voice/medbot/live.ogg',"I...I've never lost a patient before. Not today, I mean." = 'sound/voice/medbot/lost.ogg')
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
+ oldpatient = patient
+ soft_reset()
+ return
+
+ var/reagent_id = null
+
+ if(emagged == 2) //Emagged! Time to poison everybody.
+ reagent_id = /datum/reagent/consumable/cornoil //evil fucking check for a string as a reagent this shit is evil. its supposed to inject corn oil AND filzulphite but ill handle that later
+
+ else
+
+ if(!reagent_id && ((feed_threshold == 0) || (C.fatness <= feed_threshold)) && (C.nutrition <= hunger_check))
+ if(!C.reagents.has_reagent(treatment_thin))
+ reagent_id = treatment_thin
+
+ //If the patient is injured but doesn't have our special reagent in them then we should give it to them first
+ if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
+ for(var/A in reagent_glass.reagents.reagent_list)
+ var/datum/reagent/R = A
+ if(!C.reagents.has_reagent(R.type))
+ reagent_id = "internal_beaker"
+ break
+
+ if(!reagent_id) //If they don't need any of that they're probably cured!
+ if((C.nutrition >= hunger_check) || (C.fatness >= feed_threshold))
+ to_chat(src, "[C] is full, or fat! Your programming prevents you from feeding anyone who is over the maximum weight, or doesn't need food!")
+ var/list/messagevoice = list("All patched up!" = 'sound/voice/medbot/patchedup.ogg',"An apple a day keeps me away." = 'sound/voice/medbot/apple.ogg',"Feel better soon!" = 'sound/voice/medbot/feelbetter.ogg')
+ var/message = pick(messagevoice)
+ speak(message)
+ playsound(loc, messagevoice[message], 50, 0)
+ bot_reset()
+ return
+ else
+ if(!emagged && check_overdose(patient,reagent_id,injection_amount))
+ soft_reset()
+ return
+ C.visible_message("[src] is trying to feed [patient]!", \
+ "[src] is trying to feed you!")
+
+ var/failed = FALSE
+ if(do_mob(src, patient, 30)) //Is C == patient? This is so confusing
+ if((get_dist(src, patient) <= 1) && (on) && assess_patient(patient))
+ if(reagent_id == "internal_beaker")
+ if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
+ var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1)
+ reagent_glass.reagents.reaction(patient, INJECT, fraction)
+ reagent_glass.reagents.trans_to(patient,injection_amount) //Inject from beaker instead.
+ else
+ patient.reagents.add_reagent(reagent_id,injection_amount)
+ C.visible_message("[src] feeds [patient] with its tube!", \
+ "[src] feeds you with its tube!")
+ else
+ failed = TRUE
+ else
+ failed = TRUE
+
+ if(failed)
+ visible_message("[src] retracts its tube.")
+ update_icon()
+ soft_reset()
+ return
+
+ reagent_id = null
+ return
+
+/mob/living/simple_animal/bot/nutribot/proc/check_overdose(mob/living/carbon/patient,reagent_id,injection_amount)
+ var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_id]
+ if(!R.overdose_threshold) //Some chems do not have an OD threshold
+ return FALSE
+ var/current_volume = patient.reagents.get_reagent_amount(reagent_id)
+ if(current_volume + injection_amount > R.overdose_threshold)
+ return TRUE
+ return FALSE
+
+/mob/living/simple_animal/bot/nutribot/explode()
+ on = FALSE
+ visible_message("[src] blows apart!")
+ var/atom/Tsec = drop_location()
+
+ new /obj/item/stack/sheet/cardboard(Tsec)
+ new /obj/item/assembly/prox_sensor(Tsec)
+ new /obj/item/stack/sheet/mineral/calorite(Tsec)
+
+ if(reagent_glass)
+ drop_part(reagent_glass, Tsec)
+
+ if(prob(50))
+ drop_part(robot_arm, Tsec)
+
+ if(emagged && prob(25))
+ playsound(loc, 'sound/voice/medbot/insult.ogg', 50, 0)
+
+ do_sparks(3, TRUE, src)
+ ..()
+
+/obj/machinery/bot_core/nutribot
+ req_one_access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_ROBOTICS)
+
+#undef NUTRIBOT_PANIC_NONE
+#undef NUTRIBOT_PANIC_LOW
+#undef NUTRIBOT_PANIC_MED
+#undef NUTRIBOT_PANIC_HIGH
+#undef NUTRIBOT_PANIC_FUCK
+#undef NUTRIBOT_PANIC_ENDING
+#undef NUTRIBOT_PANIC_END
diff --git a/GainStation13/code/modules/mob/living/species.dm b/GainStation13/code/modules/mob/living/species.dm
new file mode 100644
index 0000000000..1a6c19f90b
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/species.dm
@@ -0,0 +1,423 @@
+/datum/species/proc/handle_fatness_trait(mob/living/carbon/human/H, trait, trait_lose, trait_gain, fatness_lose, fatness_gain, chat_lose, chat_gain)
+ if(H.fatness < fatness_lose)
+ if (chat_lose)
+ to_chat(H, chat_lose)
+ if (trait)
+ REMOVE_TRAIT(H, trait, OBESITY)
+ if (trait_lose)
+ ADD_TRAIT(H, trait_lose, OBESITY)
+ update_body_size(H, -1)
+ else if(H.fatness >= fatness_gain)
+ if (chat_gain)
+ to_chat(H, chat_gain)
+ if (trait)
+ REMOVE_TRAIT(H, trait, OBESITY)
+ if (trait_gain)
+ ADD_TRAIT(H, trait_gain, OBESITY)
+ update_body_size(H, 1)
+
+/datum/species/proc/handle_helplessness(mob/living/carbon/human/fatty)
+ var/datum/preferences/preferences = fatty?.client?.prefs
+ if(!istype(preferences))
+ return FALSE
+
+ if(preferences.helplessness_no_movement)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NO_MOVE, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_no_movement)
+ to_chat(fatty, "You have become too fat to move anymore.")
+ ADD_TRAIT(fatty, TRAIT_NO_MOVE, HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_no_movement)
+ to_chat(fatty, "You have become thin enough to regain some of your mobility.")
+ REMOVE_TRAIT(fatty, TRAIT_NO_MOVE, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NO_MOVE, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_NO_MOVE, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_clumsy)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_CLUMSY, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_clumsy)
+ to_chat(fatty, "Your newfound weight has made it hard to manipulate objects.")
+ ADD_TRAIT(fatty, TRAIT_CLUMSY, HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_clumsy)
+ to_chat(fatty, "You feel like you have lost enough weight to recover your dexterity.")
+ REMOVE_TRAIT(fatty, TRAIT_CLUMSY, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_CLUMSY, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_CLUMSY, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_nearsighted)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NEARSIGHT, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_nearsighted)
+ to_chat(fatty, "Your fat makes it difficult to see the world around you. ")
+ fatty.become_nearsighted(HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_nearsighted)
+ to_chat(fatty, "You are thin enough to see your enviornment again. ")
+ fatty.cure_nearsighted(HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NEARSIGHT, HELPLESSNESS_TRAIT))
+ fatty.cure_nearsighted(HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_hidden_face)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_DISFIGURED, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_hidden_face)
+ to_chat(fatty, "You have gotten fat enough that your face is now unrecognizable. ")
+ ADD_TRAIT(fatty, TRAIT_DISFIGURED, HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_hidden_face)
+ to_chat(fatty, "You have lost enough weight to allow people to now recognize your face.")
+ REMOVE_TRAIT(fatty, TRAIT_DISFIGURED, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_DISFIGURED, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_DISFIGURED, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_mute)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_MUTE, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_mute)
+ to_chat(fatty, "Your fat makes it impossible for you to speak.")
+ ADD_TRAIT(fatty, TRAIT_MUTE, HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_mute)
+ to_chat(fatty, "You are thin enough now to be able to speak again. ")
+ REMOVE_TRAIT(fatty, TRAIT_MUTE, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_MUTE, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_MUTE, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_immobile_arms)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_PARALYSIS_L_ARM, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_immobile_arms)
+ to_chat(fatty, "Your arms are now engulfed in fat, making it impossible to move your arms. ")
+ ADD_TRAIT(fatty, TRAIT_PARALYSIS_L_ARM, HELPLESSNESS_TRAIT)
+ ADD_TRAIT(fatty, TRAIT_PARALYSIS_R_ARM, HELPLESSNESS_TRAIT)
+ fatty.update_disabled_bodyparts()
+
+ else if(fatty.fatness < preferences.helplessness_immobile_arms)
+ to_chat(fatty, "You are able to move your arms again. ")
+ REMOVE_TRAIT(fatty, TRAIT_PARALYSIS_L_ARM, HELPLESSNESS_TRAIT)
+ REMOVE_TRAIT(fatty, TRAIT_PARALYSIS_R_ARM, HELPLESSNESS_TRAIT)
+ fatty.update_disabled_bodyparts()
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_PARALYSIS_L_ARM, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_PARALYSIS_L_ARM, HELPLESSNESS_TRAIT)
+ REMOVE_TRAIT(fatty, TRAIT_PARALYSIS_R_ARM, HELPLESSNESS_TRAIT)
+ fatty.update_disabled_bodyparts()
+
+ if(preferences.helplessness_clothing_jumpsuit)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NO_JUMPSUIT, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_clothing_jumpsuit)
+ ADD_TRAIT(fatty, TRAIT_NO_JUMPSUIT, HELPLESSNESS_TRAIT)
+
+ var/obj/item/clothing/under/jumpsuit = fatty.w_uniform
+ if(istype(jumpsuit) && !istype(jumpsuit, /obj/item/clothing/under/color/grey/modular))
+ to_chat(fatty, "[jumpsuit] can no longer contain your weight!")
+ fatty.dropItemToGround(jumpsuit)
+
+ else if(fatty.fatness < preferences.helplessness_clothing_jumpsuit)
+ to_chat(fatty, "You feel thin enough to put on jumpsuits now. ")
+ REMOVE_TRAIT(fatty, TRAIT_NO_JUMPSUIT, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NO_JUMPSUIT, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_NO_JUMPSUIT, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_clothing_misc)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NO_MISC, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_clothing_misc)
+ ADD_TRAIT(fatty, TRAIT_NO_MISC, HELPLESSNESS_TRAIT)
+
+ var/obj/item/clothing/suit/worn_suit = fatty.wear_suit
+ if(istype(worn_suit))
+ to_chat(fatty, "[worn_suit] can no longer contain your weight!")
+ fatty.dropItemToGround(worn_suit)
+
+ var/obj/item/clothing/gloves/worn_gloves = fatty.gloves
+ if(istype(worn_gloves))
+ to_chat(fatty, "[worn_gloves] can no longer contain your weight!")
+ fatty.dropItemToGround(worn_gloves)
+
+ var/obj/item/clothing/shoes/worn_shoes = fatty.shoes
+ if(istype(worn_shoes))
+ to_chat(fatty, "[worn_shoes] can no longer contain your weight!")
+ fatty.dropItemToGround(worn_shoes)
+
+ else if(fatty.fatness < preferences.helplessness_clothing_misc)
+ to_chat(fatty, "You feel thin enough to put on suits, shoes, and gloves now. ")
+ REMOVE_TRAIT(fatty, TRAIT_NO_MISC, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NO_MISC, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_NO_MISC, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_clothing_back)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NO_BACKPACK, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_clothing_back)
+ ADD_TRAIT(fatty, TRAIT_NO_BACKPACK, HELPLESSNESS_TRAIT)
+ var/obj/item/back_item = fatty.back
+ if(istype(back_item))
+ to_chat(fatty, "Your weight makes it impossible for you to carry [back_item].")
+ fatty.dropItemToGround(back_item)
+
+ else if(fatty.fatness < preferences.helplessness_clothing_back)
+ to_chat(fatty, "You feel thin enough to hold items on your back now. ")
+ REMOVE_TRAIT(fatty, TRAIT_NO_BACKPACK, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NO_BACKPACK, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_NO_BACKPACK, HELPLESSNESS_TRAIT)
+
+
+ if(preferences.helplessness_no_buckle)
+ if(!HAS_TRAIT_FROM(fatty, TRAIT_NO_BUCKLE, HELPLESSNESS_TRAIT))
+ if(fatty.fatness >= preferences.helplessness_no_buckle)
+ to_chat(fatty, "You feel like you've gotten too big to fit on anything.")
+ ADD_TRAIT(fatty, TRAIT_NO_BUCKLE, HELPLESSNESS_TRAIT)
+
+ else if(fatty.fatness < preferences.helplessness_no_buckle)
+ to_chat(fatty, "You feel thin enough to sit on things again. ")
+ REMOVE_TRAIT(fatty, TRAIT_NO_BUCKLE, HELPLESSNESS_TRAIT)
+
+ else
+ if(HAS_TRAIT_FROM(fatty, TRAIT_NO_BUCKLE, HELPLESSNESS_TRAIT))
+ REMOVE_TRAIT(fatty, TRAIT_NO_BUCKLE, HELPLESSNESS_TRAIT)
+
+
+/datum/species/proc/handle_fatness(mob/living/carbon/human/H)
+ handle_helplessness(H)
+ if(HAS_TRAIT(H, TRAIT_BLOB))
+ handle_fatness_trait(
+ H,
+ TRAIT_BLOB,
+ TRAIT_IMMOBILE,
+ null,
+ FATNESS_LEVEL_BLOB,
+ INFINITY,
+ "You feel like you've regained some mobility!",
+ null)
+ return
+ if(HAS_TRAIT(H, TRAIT_IMMOBILE))
+ handle_fatness_trait(
+ H,
+ TRAIT_IMMOBILE,
+ TRAIT_BARELYMOBILE,
+ TRAIT_BLOB,
+ FATNESS_LEVEL_IMMOBILE,
+ FATNESS_LEVEL_BLOB,
+ "You feel less restrained by your fat!",
+ "You feel like you've become a mountain of fat!")
+ return
+ if(HAS_TRAIT(H, TRAIT_BARELYMOBILE))
+ handle_fatness_trait(
+ H,
+ TRAIT_BARELYMOBILE,
+ TRAIT_EXTREMELYOBESE,
+ TRAIT_IMMOBILE,
+ FATNESS_LEVEL_BARELYMOBILE,
+ FATNESS_LEVEL_IMMOBILE,
+ "You feel less restrained by your fat!",
+ "You feel belly smush against the floor!")
+ return
+ if(HAS_TRAIT(H, TRAIT_EXTREMELYOBESE))
+ handle_fatness_trait(
+ H,
+ TRAIT_EXTREMELYOBESE,
+ TRAIT_MORBIDLYOBESE,
+ TRAIT_BARELYMOBILE,
+ FATNESS_LEVEL_EXTREMELY_OBESE,
+ FATNESS_LEVEL_BARELYMOBILE,
+ "You feel less restrained by your fat!",
+ "You feel like you can barely move!")
+ return
+ if(HAS_TRAIT(H, TRAIT_MORBIDLYOBESE))
+ handle_fatness_trait(
+ H,
+ TRAIT_MORBIDLYOBESE,
+ TRAIT_OBESE,
+ TRAIT_EXTREMELYOBESE,
+ FATNESS_LEVEL_MORBIDLY_OBESE,
+ FATNESS_LEVEL_EXTREMELY_OBESE,
+ "You feel a bit less fat!",
+ "You feel your belly rest heavily on your lap!")
+ return
+ if(HAS_TRAIT(H, TRAIT_OBESE))
+ handle_fatness_trait(
+ H,
+ TRAIT_OBESE,
+ TRAIT_VERYFAT,
+ TRAIT_MORBIDLYOBESE,
+ FATNESS_LEVEL_OBESE,
+ FATNESS_LEVEL_MORBIDLY_OBESE,
+ "You feel like you've lost weight!",
+ "Your thighs begin to rub against each other.")
+ return
+ if(HAS_TRAIT(H, TRAIT_VERYFAT))
+ handle_fatness_trait(
+ H,
+ TRAIT_VERYFAT,
+ TRAIT_FATTER,
+ TRAIT_OBESE,
+ FATNESS_LEVEL_VERYFAT,
+ FATNESS_LEVEL_OBESE,
+ "You feel like you've lost weight!",
+ "You feel like you're starting to get really heavy.")
+ return
+ if(HAS_TRAIT(H, TRAIT_FATTER))
+ handle_fatness_trait(
+ H,
+ TRAIT_FATTER,
+ TRAIT_FAT,
+ TRAIT_VERYFAT,
+ FATNESS_LEVEL_FATTER,
+ FATNESS_LEVEL_VERYFAT,
+ "You feel like you've lost weight!",
+ "Your clothes creak quietly!")
+ return
+ if(HAS_TRAIT(H, TRAIT_FAT))
+ handle_fatness_trait(
+ H,
+ TRAIT_FAT,
+ null,
+ TRAIT_FATTER,
+ FATNESS_LEVEL_FAT,
+ FATNESS_LEVEL_FATTER,
+ "You feel fit again!",
+ "You feel even plumper!")
+ else
+ handle_fatness_trait(
+ H,
+ null,
+ null,
+ TRAIT_FAT,
+ 0,
+ FATNESS_LEVEL_FAT,
+ null,
+ "You suddenly feel blubbery!")
+
+/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
+ if(HAS_TRAIT(src, TRAIT_NOHUNGER))
+ return //hunger is for BABIES
+
+ handle_fatness(H) // GS13
+
+ // nutrition decrease and satiety
+ if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER))
+ // THEY HUNGER
+ var/hunger_rate = HUNGER_FACTOR
+ var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
+ if(mood && mood.sanity > SANITY_DISTURBED)
+ hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
+
+ // Whether we cap off our satiety or move it towards 0
+ if(H.satiety > MAX_SATIETY)
+ H.satiety = MAX_SATIETY
+ else if(H.satiety > 0)
+ H.satiety--
+ else if(H.satiety < -MAX_SATIETY)
+ H.satiety = -MAX_SATIETY
+ else if(H.satiety < 0)
+ H.satiety++
+ if(prob(round(-H.satiety/40)))
+ H.Jitter(5)
+ hunger_rate = 3 * HUNGER_FACTOR
+ hunger_rate *= H.physiology.hunger_mod
+ H.nutrition = max(0, H.nutrition - hunger_rate)
+
+
+ if (H.nutrition > NUTRITION_LEVEL_FULL)
+ // fatConversionRate is functionally useless. It seems under normal curcumstances, each tick only processes, at most, 1 nutrition anyway. reducing the value has no effect.
+ var/fatConversionRate = 100 //GS13 what percentage of the excess nutrition should go to fat (total nutrition to transfer can't be under 1)
+ var/nutritionThatBecomesFat = max((H.nutrition - NUTRITION_LEVEL_FULL)*(fatConversionRate / 100),1)
+ H.nutrition -= nutritionThatBecomesFat
+ H.adjust_fatness(nutritionThatBecomesFat, FATTENING_TYPE_FOOD)
+ if(H.fullness > FULLNESS_LEVEL_EMPTY)//GS13 stomach-emptying routine
+ var/ticksToEmptyStomach = 20 // GS13 how many ticks it takes to decrease the fullness by 1
+ if(HAS_TRAIT(H, TRAIT_VORACIOUS))
+ ticksToEmptyStomach = ticksToEmptyStomach * 0.5
+ H.fullness -= 1/ticksToEmptyStomach
+ if (H.fullness > FULLNESS_LEVEL_BLOATED) //GS13 overeating depends on fullness now
+ if(H.overeatduration < 5000) //capped so people don't take forever to unfat
+ H.overeatduration++
+ else
+ if(H.overeatduration > 1)
+ H.overeatduration -= 1 //doubled the unfat rate -- GS13 Nah, put it back
+
+ //metabolism change
+ if(H.nutrition > NUTRITION_LEVEL_FULL +100)
+ H.metabolism_efficiency = 1
+ else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80)
+ if(H.metabolism_efficiency != 1.25 && !HAS_TRAIT(H, TRAIT_NOHUNGER))
+ to_chat(H, "You feel vigorous.")
+ H.metabolism_efficiency = 1.25
+ else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
+ if(H.metabolism_efficiency != 0.8)
+ to_chat(H, "You feel sluggish.")
+ H.metabolism_efficiency = 0.8
+ else
+ if(H.metabolism_efficiency == 1.25)
+ to_chat(H, "You no longer feel vigorous.")
+ H.metabolism_efficiency = 1
+
+ switch(H.nutrition)
+ if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL)
+ H.clear_alert("nutrition")
+ if(NUTRITION_LEVEL_STARVING to NUTRITION_LEVEL_HUNGRY)
+ H.throw_alert("nutrition", /obj/screen/alert/hungry)
+ if(0 to NUTRITION_LEVEL_STARVING)
+ H.throw_alert("nutrition", /obj/screen/alert/starving)
+
+ switch(H.fullness)
+ if(0 to FULLNESS_LEVEL_BLOATED)
+ H.clear_alert("fullness")
+ if(FULLNESS_LEVEL_BLOATED to FULLNESS_LEVEL_BEEG)
+ H.throw_alert("fullness", /obj/screen/alert/bloated)
+ if(FULLNESS_LEVEL_BEEG to FULLNESS_LEVEL_NOMOREPLZ)
+ H.throw_alert("fullness", /obj/screen/alert/stuffed)
+ if(FULLNESS_LEVEL_NOMOREPLZ to INFINITY)
+ H.throw_alert("fullness", /obj/screen/alert/beegbelly)
+
+
+ switch(H.fatness)
+ if(FATNESS_LEVEL_BLOB to INFINITY)
+ H.throw_alert("fatness", /obj/screen/alert/blob)
+
+ if(FATNESS_LEVEL_IMMOBILE to FATNESS_LEVEL_BLOB)
+ H.throw_alert("fatness", /obj/screen/alert/immobile)
+
+ if(FATNESS_LEVEL_BARELYMOBILE to FATNESS_LEVEL_IMMOBILE)
+ H.throw_alert("fatness", /obj/screen/alert/barelymobile)
+
+ if(FATNESS_LEVEL_EXTREMELY_OBESE to FATNESS_LEVEL_BARELYMOBILE)
+ H.throw_alert("fatness", /obj/screen/alert/extremelyobese)
+
+ if(FATNESS_LEVEL_MORBIDLY_OBESE to FATNESS_LEVEL_EXTREMELY_OBESE)
+ H.throw_alert("fatness", /obj/screen/alert/morbidlyobese)
+
+ if(FATNESS_LEVEL_OBESE to FATNESS_LEVEL_MORBIDLY_OBESE)
+ H.throw_alert("fatness", /obj/screen/alert/obese)
+
+ if(FATNESS_LEVEL_VERYFAT to FATNESS_LEVEL_OBESE)
+ H.throw_alert("fatness", /obj/screen/alert/veryfat)
+
+ if(FATNESS_LEVEL_FATTER to FATNESS_LEVEL_VERYFAT)
+ H.throw_alert("fatness", /obj/screen/alert/fatter)
+
+ if(FATNESS_LEVEL_FAT to FATNESS_LEVEL_FATTER)
+ H.throw_alert("fatness", /obj/screen/alert/fat)
+
+ if(0 to FATNESS_LEVEL_FAT)
+ H.clear_alert("fatness")
diff --git a/GainStation13/code/modules/mob/living/vore/eating/trasheat_lists.dm b/GainStation13/code/modules/mob/living/vore/eating/trasheat_lists.dm
new file mode 100644
index 0000000000..26abb58533
--- /dev/null
+++ b/GainStation13/code/modules/mob/living/vore/eating/trasheat_lists.dm
@@ -0,0 +1,94 @@
+// In vorecode, they're defined at code/_helpers/global_lists_vr.dm but we dont have that path at all, and I dont think it's a very good
+// path for a global lists file when there's code/_global_vars/lists as a directory. Im just putting this here for now. -Reo
+
+//Blacklist to exclude items from object ingestion. Digestion blacklist located in digest_act_vr.dm
+var/global/list/item_vore_blacklist = list(
+ /obj/item/hand_tele,
+ //obj/item/weapon/card/id/gold/captain/spare, //Hugbox
+ /obj/item/gun,
+ /obj/item/pinpointer,
+ /obj/item/clothing/shoes/magboots,
+ /obj/item/areaeditor/blueprints,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/disk/nuclear
+ //obj/item/clothing/suit/storage/hooded/wintercoat/roiz //You fluff decrease
+ )
+
+var/global/list/edible_trash = list(
+ ///obj/item/broken_device, //Doesnt exist
+ /obj/item/clothing/neck/petcollar,
+ ///obj/item/device/communicator, // Doesnt exist
+ /obj/item/clothing/mask,
+ /obj/item/clothing/glasses,
+ /obj/item/clothing/gloves,
+ /obj/item/clothing/head,
+ /obj/item/clothing/shoes,
+ /obj/item/aicard, //Repathed from /obj/item/device/aicard
+ /obj/item/flashlight,
+ /obj/item/mmi/posibrain,
+ /obj/item/paicard,
+ /obj/item/pda,
+ /obj/item/radio/headset,
+ ///obj/item/device/starcaster_news, //Doesnt exist
+ ///obj/item/inflatable/torn, //Doesnt exist
+ /obj/item/organ,
+ /obj/item/stack/sheet/cardboard,
+ /obj/item/toy,
+ /obj/item/trash,
+ ///obj/item/weapon/digestion_remains, // No former cuties (yet?)
+ /obj/item/grown/bananapeel,
+ ///obj/item/weapon/bone, // Doesnt exist
+ /obj/item/broken_bottle,
+ /obj/item/card/emagfake,
+ /obj/item/cigbutt,
+ /obj/item/circuitboard,
+ /obj/item/clipboard,
+ /obj/item/grown/corncob,
+ /obj/item/dice,
+ /obj/item/match, //Repathed from /obj/item/weapon/flame
+ /obj/item/lighter, //Added since they dont share a path of /flame anymore.
+ /obj/item/light,
+ /obj/item/lipstick,
+ /obj/item/shard,
+ /obj/item/newspaper,
+ /obj/item/paper,
+ /obj/item/paperplane,
+ /obj/item/pen,
+ /obj/item/photo,
+ /obj/item/reagent_containers/food,
+ /obj/item/reagent_containers/rag,
+ /obj/item/soap,
+ /obj/item/stack/spacecash,
+ /obj/item/storage/box/matches,
+ ///obj/item/storage/box/wings, //Doesnt exist
+ /obj/item/storage/fancy/candle_box,
+ /obj/item/storage/fancy/cigarettes,
+ /obj/item/storage/crayons,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/storage/wallet,
+ ///obj/item/weapon/storage/vore_egg, //Doesnt exist
+ ///obj/item/weapon/bikehorn/tinytether, //Doesnt exist
+ ///obj/item/capture_crystal, //Still doesnt exist.
+ /obj/item/kitchen,
+ /obj/item/storage/box/mre,
+ ///obj/item/storage/mrebag, //Doesnt exist
+ ///obj/item/weapon/storage/fancy/crackers, //Doesnt exist
+ ///obj/item/weapon/storage/fancy/heartbox, //Doesnt exist
+ ///obj/item/pizzavoucher, //Doesnt exist. Probably should, actually
+ /obj/item/pizzabox,
+ /obj/item/seeds,
+ ///obj/item/clothing/accessory/choker, //Doesnt exist
+ /obj/item/clothing/accessory/medal,
+ /obj/item/clothing/neck/tie,
+ /obj/item/clothing/neck/scarf,
+ ///obj/item/clothing/accessory/bracelet, //Doesnt exist
+ ///obj/item/clothing/accessory/locket, //Doesnt exist
+ /obj/item/storage/book/bible,
+ /obj/item/bikehorn,
+ //obj/item/inflatable/door/torn, //Doesnt exist
+ /obj/item/reagent_containers/rag/towel, //Repath from /obj/item/towel
+ /obj/item/folder,
+ /obj/item/clipboard,
+ /obj/item/coin,
+ /obj/item/clothing/ears
+ )
diff --git a/GainStation13/code/modules/reagents/chemistry/reagents/consumable_reagents.dm b/GainStation13/code/modules/reagents/chemistry/reagents/consumable_reagents.dm
new file mode 100644
index 0000000000..7b9c651022
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/reagents/consumable_reagents.dm
@@ -0,0 +1,149 @@
+//we'll put funky non-toxic chems here
+
+//fattening chem
+/datum/reagent/consumable/lipoifier
+ name = "Lipoifier"
+ description = "A very potent chemical that causes those that ingest it to build up fat cells quickly."
+ taste_description = "lard"
+ reagent_state = LIQUID
+ color = "#e2e1b1"
+ metabolization_rate = 0.5 * REAGENTS_METABOLISM
+
+/datum/reagent/consumable/lipoifier/on_mob_life(mob/living/carbon/M)
+ M.adjust_fatness(15, FATTENING_TYPE_CHEM)
+ return ..()
+
+
+//BURPY CHEM
+
+/datum/reagent/consumable/fizulphite
+ name = "Fizulphite"
+ description = "A strange chemical that produces large amounts of gas when in contact with organic, typically fleshy environments."
+ color = "#4cffed" // rgb: 102, 99, 0
+ reagent_state = LIQUID
+ taste_description = "fizziness"
+ metabolization_rate = 2 * REAGENTS_METABOLISM
+
+/datum/reagent/consumable/fizulphite/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_chems)
+ M.burpslurring = max(M.burpslurring,50)
+ M.burpslurring += 2
+ else
+ M.burpslurring += 0
+ ..()
+
+//ANTI-BURPY CHEM
+
+/datum/reagent/consumable/extilphite
+ name = "Extilphite"
+ description = "A very useful chemical that helps soothe bloated stomachs."
+ color = "#2aed96"
+ reagent_state = LIQUID
+ taste_description = "smoothness"
+ metabolization_rate = 0.8 * REAGENTS_METABOLISM
+
+/datum/reagent/consumable/extilphite/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_chems)
+ M.burpslurring -= 3
+ else
+ M.burpslurring -= 0
+
+ if(M.fullness>10)
+ M.fullness -= 6
+ else
+ M.fullness -= 0
+ ..()
+
+//FARTY CHEM
+
+/datum/reagent/consumable/flatulose
+ name = "Flatulose"
+ description = "A sugar largely indigestible to most known organic organisms. Causes frequent flatulence."
+ color = "#634500"
+ reagent_state = LIQUID
+ taste_description = "sulfury sweetness"
+ metabolization_rate = 0.5 * REAGENTS_METABOLISM //Done by Zestyspy, Jan 2023
+
+/datum/reagent/consumable/flatulose/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_chems)
+ if(M.reagents.get_reagent_amount(/datum/reagent/consumable/flatulose) < 1)
+ to_chat(M,"You feel substantially bloated...")
+ if(M.reagents.get_reagent_amount(/datum/reagent/consumable/flatulose) > 3)
+ to_chat(M,"You feel pretty gassy...")
+ M.emote(pick("brap","fart")) // we gotta categorize this into "slob" category or something later! - GDLW2
+ ..()
+ else
+ return ..()
+
+// calorite blessing chem, used in the golem ability
+
+/datum/reagent/consumable/caloriteblessing
+ name = "Calorite blessing"
+ description = "A strange, viscous liquid derived from calorite. It is said to have physically enhancing properties surprisingly unrelated to weight gain when consumed"
+ color = "#eb6e00"
+ reagent_state = LIQUID
+ taste_description = "sweet salvation"
+ metabolization_rate = 0.5 * REAGENTS_METABOLISM
+
+/datum/reagent/consumable/caloriteblessing/on_mob_metabolize(mob/living/L)
+ ..()
+ ADD_TRAIT(L, TRAIT_GOTTAGOFAST, type)
+
+
+/datum/reagent/consumable/caloriteblessing/on_mob_end_metabolize(mob/living/L)
+ REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, type)
+ ..()
+
+
+//BLUEBERRY CHEM - ONLY CHANGES PLAYER'S COLOR AND NOTHING MORE
+
+/datum/reagent/blueberry_juice
+ name = "Blueberry Juice"
+ description = "Totally infectious."
+ reagent_state = LIQUID
+ metabolization_rate = 0.25 * REAGENTS_METABOLISM
+ color = "#0004ff"
+ var/picked_color
+ var/list/random_color_list = list("#0058db","#5d00c7","#0004ff","#0057e7")
+ taste_description = "blueberry pie"
+ var/no_mob_color = FALSE
+ value = 10 //it sells. Make that berry factory
+
+/datum/reagent/blueberry_juice/on_mob_life(mob/living/carbon/M)
+ if(M?.client)
+ if(!(M?.client?.prefs?.blueberry_inflation))
+ M.reagents.remove_reagent(/datum/reagent/blueberry_juice, volume)
+ return
+ if(!no_mob_color)
+ M.add_atom_colour(picked_color, WASHABLE_COLOUR_PRIORITY)
+ M.adjust_fatness(1, FATTENING_TYPE_CHEM)
+ ..()
+
+/datum/reagent/blueberry_juice/on_mob_add(mob/living/L, amount)
+ if(iscarbon(L))
+ var/mob/living/carbon/affected_mob = L
+ if(!affected_mob?.client || !(affected_mob?.client?.prefs?.blueberry_inflation))
+ affected_mob.reagents.remove_reagent(/datum/reagent/blueberry_juice, volume)
+ return
+ picked_color = pick(random_color_list)
+ affected_mob.hider_add(src)
+ else
+ L.reagents.remove_reagent(/datum/reagent/blueberry_juice, volume)
+ ..()
+
+/datum/reagent/blueberry_juice/on_mob_delete(mob/living/L)
+ if(!iscarbon(L))
+ return
+ var/mob/living/carbon/C = L
+ C.hider_remove(src)
+
+/datum/reagent/blueberry_juice/proc/fat_hide()
+ return (124 * (volume * volume))/1000 //123'840 600% size, about 56'000 400% size, calc was: (3 * (volume * volume))/50
+
+// /obj/item/reagent_containers/food/snacks/meat/steak/troll
+// name = "Troll steak"
+// desc = "In its sliced state it remains dormant, but once the troll meat comes in contact with stomach acids, it begins a perpetual cycle of constant regrowth and digestion. You probably shouldn't eat this."
+// var/hunger_threshold = NUTRITION_LEVEL_FULL
+// var/nutrition_amount = 20 // somewhere around 5 pounds
+// var/fullness_to_add = 10
+// var/message = "You feel fuller..." // GS13
diff --git a/GainStation13/code/modules/reagents/chemistry/reagents/dwarverndrinks.dm b/GainStation13/code/modules/reagents/chemistry/reagents/dwarverndrinks.dm
new file mode 100644
index 0000000000..22afcd02c2
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/reagents/dwarverndrinks.dm
@@ -0,0 +1,28 @@
+///GS13 drinks!
+
+/datum/reagent/consumable/ethanol/oily_oafs
+ name = "Oily oafs"
+ description = "The oily oaf. while it isn't as strong as some of the other drinks on station, Its buttery aftertaste and affordability make it a staple of any good miner's diet."
+ color = "#ffc75f"
+ boozepwr = 30
+ taste_description = "rich butter and red sugar"
+ //quality = DRINK_NICE we need to get drink quality implemented in our drink files -Eye
+ glass_icon_state = "oily_oafs"
+ glass_name = "oily oafs"
+ glass_desc = "The oily oaf. A dwarvern classic beloved by miners around the cosmos."
+ shot_glass_icon_state = "shotglassbrown"
+ pH = 4.5
+ value = 0.1
+
+/datum/reagent/consumable/ethanol/glyphid_slammer
+ name = "Glyphid slammer"
+ description = "A mixture of strong beer and energy drink. How it manages to be as strong as it is baffles scientists to this day"
+ color = "#FF8A33"
+ boozepwr = 60
+ taste_description = "Cheap booze and adventure"
+ glass_icon_state = "glyphid_slammer"
+ glass_name = "Glyphid slammer"
+ glass_desc = "A bold mixture of cheap energy drink, and even cheaper ale. Beloved by partygoers and daredevils across the galaxy. Beloathed by bugpeople"
+ shot_glass_icon_state = "shotglassbrown"
+ pH = 4.5
+ value = 0.1
\ No newline at end of file
diff --git a/GainStation13/code/modules/reagents/chemistry/reagents/fatty_drinks.dm b/GainStation13/code/modules/reagents/chemistry/reagents/fatty_drinks.dm
new file mode 100644
index 0000000000..b6cbd68a4a
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/reagents/fatty_drinks.dm
@@ -0,0 +1,159 @@
+//GS13 weight gain drinks
+
+/datum/reagent/consumable/ethanol/belly_bloats
+ name = "Belly Bloats"
+ description = "A classic of this sector that bloats the waistline. Hard to stop chugging once you start."
+ color = "#FF3333"
+ boozepwr = 25
+ taste_description = "a heavy mix of cherry and beer"
+ quality = DRINK_GOOD
+ glass_icon_state = "belly_bloats"
+ glass_name = "belly bloats"
+ glass_desc = "The perfect mix to be big and merry with."
+ shot_glass_icon_state = "shotglassbrown"
+ hydration = 3
+
+/datum/reagent/consumable/ethanol/belly_bloats/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 15 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+
+/datum/reagent/consumable/ethanol/blobby_mary
+ name = "Blobby Mary"
+ description = "A bloody mary that may make you immobile. Still wondering if it's blood or tomato juice?"
+ color = "#C2707E"
+ boozepwr = 55
+ taste_description = "tomateos and an anvil on your stomach"
+ quality = DRINK_FANTASTIC
+ glass_icon_state = "blobby_mary"
+ glass_name = "blobby mary"
+ glass_desc = "For the morbidly obese ladies and gentlemen."
+ shot_glass_icon_state = "shotglassred"
+ hydration = 4
+
+/datum/reagent/consumable/ethanol/blobby_mary/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 25 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+
+/datum/reagent/consumable/ethanol/beltbuster_mead
+ name = "Beltbuster Mead"
+ description = "Kiss sobriety and clothes goodbye."
+ color = "#664300"
+ boozepwr = 85
+ taste_description = "honey, alcohol and immobility"
+ quality = DRINK_FANTASTIC
+ glass_icon_state = "beltbuster_mead"
+ glass_name = "beltbuster mead"
+ glass_desc = "The ambrosia of the blubbery gods."
+ shot_glass_icon_state = "shotglassgold"
+ hydration = 4
+
+/datum/reagent/consumable/ethanol/beltbuster_mead/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 30 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+
+/datum/reagent/consumable/heavy_cafe
+ name = "Heavy Cafe"
+ description = "Coffee, milk, sugar and cream. For the days when you really don't want to work."
+ color = "#663300"
+ taste_description = "coffee, milk and sugar"
+ quality = DRINK_GOOD
+ glass_icon_state = "heavy_cafe"
+ glass_name = "heavy cafe"
+ glass_desc = "To enjoy slow mornings with."
+ shot_glass_icon_state = "shotglassbrown"
+ hydration = 3
+
+/datum/reagent/consumable/heavy_cafe/on_mob_life(mob/living/carbon/M)
+ M.dizziness = max(0,M.dizziness-5)
+ M.drowsyness = max(0,M.drowsyness-3)
+ M.SetSleeping(0, FALSE)
+ M.adjust_bodytemperature(5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
+ M.Jitter(5)
+ if(M.getBruteLoss() && prob(20))
+ M.heal_bodypart_damage(1,0, 0)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 15 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+
+/datum/reagent/consumable/fruits_tea
+ name = "Fruits Tea"
+ description = "Somehow this mix of fruits and tea can cause considerable bulking."
+ color = "#FFCC33"
+ taste_description = "a sweet and sour mix"
+ quality = DRINK_NICE
+ glass_icon_state = "fruits_tea"
+ glass_name = "fruits tea"
+ glass_desc = "Goes down really easy and stays there for a long time."
+ shot_glass_icon_state = "shotglassgold"
+ hydration = 4
+
+/datum/reagent/consumable/fruits_tea/on_mob_life(mob/living/carbon/M)
+ M.dizziness = max(0,M.dizziness-2)
+ M.drowsyness = max(0,M.drowsyness-1)
+ M.jitteriness = max(0,M.jitteriness-3)
+ M.AdjustSleeping(-20, FALSE)
+ if(M.getToxLoss() && prob(20))
+ M.adjustToxLoss(-1, 0)
+ M.adjust_bodytemperature(20 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 15 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+ . = 1
+
+/datum/reagent/consumable/snakebite
+ name = "Snakebite"
+ description = "Guaranteed to stop 100% of all moving."
+ color = "#00CC33"
+ taste_description = "bitter immobility"
+ quality = DRINK_VERYGOOD
+ glass_icon_state = "snakebite"
+ glass_name = "snakebite"
+ glass_desc = "Won't hurt like a real bite, but you'll still regert drinking this."
+ shot_glass_icon_state = "shotglassgreen"
+ hydration = 4
+
+/datum/reagent/consumable/snakebite/on_mob_life(mob/living/carbon/M)
+ if(M && M?.client?.prefs.weight_gain_food) // GS13
+ M.nutrition += 25 * REAGENTS_METABOLISM
+ else
+ M.nutrition += 1
+ ..()
+
+/datum/reagent/consumable/milkshake_vanilla
+ name = "Vanilla Milkshake"
+ description = "A plain vanilla milkshake. A classic."
+ color = "#DFDFDF"
+ taste_description = "creamy vanilla"
+ quality = DRINK_VERYGOOD
+ nutriment_factor = 6 * REAGENTS_METABOLISM
+ glass_icon_state = "milkshake_vanilla"
+ glass_name = "vanilla milkshake"
+ glass_desc = "Guess they fixed the milkshake machine after all, huh?"
+ shot_glass_icon_state = "shotglasscream"
+ hydration = 3
+
+/datum/reagent/consumable/milkshake_chocolate
+ name = "Chocolate Milkshake"
+ description = "It's like chocolate milk, but for even cooler kids."
+ color = "#7D4E29"
+ taste_description = "creamy chocolate"
+ quality = DRINK_VERYGOOD
+ nutriment_factor = 8 * REAGENTS_METABOLISM
+ glass_icon_state = "milkshake_chocolate"
+ glass_name = "chocolate milkshake"
+ glass_desc = "Nothing better than cream AND cocoa!"
+ shot_glass_icon_state = "shotglassbrown"
+ hydration = 3
\ No newline at end of file
diff --git a/GainStation13/code/modules/reagents/chemistry/reagents/fermi_fat.dm b/GainStation13/code/modules/reagents/chemistry/reagents/fermi_fat.dm
new file mode 100644
index 0000000000..2e4968752a
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/reagents/fermi_fat.dm
@@ -0,0 +1,196 @@
+//Reagent
+/datum/reagent/fermi_fat
+ name = "Galbanic Compound"
+ description = "A chemical compound derived from lipoifier. Massively increases adipose mass and parts of it become impossible to shed through normal means."
+ color = "#E70C0C"
+ taste_description = "hunger"
+ pH = 7
+ overdose_threshold = 50
+ metabolization_rate = REAGENTS_METABOLISM / 4
+ can_synth = FALSE //DO NOT MAKE THIS SNYTHESIZABLE, THESE CHEMS ARE SUPPOSED TO NOT BE USED COMMONLY
+
+ overdose_threshold = 50
+ addiction_threshold = 100
+ addiction_stage1_end = 10
+ addiction_stage2_end = 30
+ addiction_stage3_end = 60
+ addiction_stage4_end = 100
+
+ var/addiction_mults = 0
+
+//Reaction
+/datum/chemical_reaction/fermi_fat
+ name = "FermiFat"
+ id = /datum/reagent/fermi_fat
+ mix_message = "the reaction appears to swell!"
+ required_reagents = list(/datum/reagent/consumable/lipoifier = 0.1, /datum/reagent/medicine/pen_acid = 0.1, /datum/reagent/iron = 0.1)
+ results = list(/datum/reagent/fermi_fat = 0.2)
+ required_temp = 1
+ OptimalTempMin = 700 // Lower area of bell curve for determining heat based rate reactions
+ OptimalTempMax = 740 // Upper end for above
+ ExplodeTemp = 755 // Temperature at which reaction explodes
+ OptimalpHMin = 2 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
+ OptimalpHMax = 3.5 // Higest value for above
+ ReactpHLim = 1 // How far out pH wil react, giving impurity place (Exponential phase)
+ CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
+ CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
+ CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value)
+ ThermicConstant = -10 // Temperature change per 1u produced
+ HIonRelease = 0.02 // pH change per 1u reaction (inverse for some reason)
+ RateUpLim = 2 // Optimal/max rate possible if all conditions are perfect
+ FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
+ FermiExplode = FALSE // If the chemical explodes in a special way
+ PurityMin = 0.1
+
+//When added
+/datum/reagent/fermi_fat/on_mob_add(mob/living/carbon/M)
+ . = ..()
+ if(iscarbon(M))
+ log_game("[M] ckey: [M.key] has ingested fermifat.")
+
+//Effects
+/datum/reagent/fermi_fat/on_mob_life(mob/living/carbon/M)
+ if(!iscarbon(M))
+ return..()
+ M.adjust_fatness(30, FATTENING_TYPE_CHEM)
+ M.adjust_perma(1, FATTENING_TYPE_CHEM)
+ ..()
+ . = 1
+
+//While overdosed
+/datum/reagent/fermi_fat/overdose_process(mob/living/M)
+ if(!iscarbon(M))
+ return..()
+ var/mob/living/carbon/C = M
+ C.adjust_fatness(20, FATTENING_TYPE_CHEM)
+ C.adjust_perma(1, FATTENING_TYPE_CHEM)
+ ..()
+
+/datum/reagent/fermi_fat/overdose_start(mob/living/M)
+ to_chat(M, "You took too much [name]! Your body is growing out of control!")
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/overdose, name)
+ return
+
+/datum/reagent/fermi_fat/addiction_act_stage1(mob/living/M)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_light, name)
+ if(prob(30))
+ var/add_text = pick("You feel pretty hungry.", "You think of [name].", "Your look around for food.", "[name] wasn't so bad.")
+ to_chat(M, "[add_text]")
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.adjust_fatness(1, FATTENING_TYPE_CHEM)
+ C.fullness = max(0, C.fullness-1)
+ C.nutrition = max(0, C.nutrition-1)
+ if(addiction_mults < 1)
+ C.nutri_mult += 0.5
+ C.weight_gain_rate += 0.25
+ addiction_mults = 1
+ return
+
+/datum/reagent/fermi_fat/addiction_act_stage2(mob/living/M)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_medium, name)
+ if(prob(30))
+ var/add_text = pick("You are very hungry.", "You could go for some [name].", "Your mouth waters.", "Is there any [name] around?")
+ to_chat(M, "[add_text]")
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.adjust_fatness(2, FATTENING_TYPE_CHEM)
+ C.fullness = max(0, C.fullness-2)
+ C.nutrition = max(0, C.nutrition-2)
+ if(addiction_mults < 2)
+ C.nutri_mult += 0.5
+ C.weight_gain_rate += 0.25
+ addiction_mults = 2
+ return
+
+/datum/reagent/fermi_fat/addiction_act_stage3(mob/living/M)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_severe, name)
+ if(prob(30))
+ var/add_text = pick("You are starving!", "You need some [name]!", "Your stomach growls loudly!.", "You can't stop thinking about [name]")
+ to_chat(M, "[add_text]")
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.adjust_fatness(3, FATTENING_TYPE_CHEM)
+ C.fullness = max(0, C.fullness-3)
+ C.nutrition = max(0, C.nutrition-3)
+ if(addiction_mults < 3)
+ C.nutri_mult += 0.5
+ C.weight_gain_rate += 0.25
+ addiction_mults = 3
+ return
+
+/datum/reagent/fermi_fat/addiction_act_stage4(mob/living/M)
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/withdrawal_critical, name)
+ if(prob(30))
+ var/add_text = pick("You are ravenous!!", "You need [name] NOW!!", "You'd eat ANYTHING!!", "Where is the [name]?!", "Hungry, hungry, so HUNGRY!!", "More, you need more!!")
+ to_chat(M, "[add_text]")
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.adjust_fatness(4, FATTENING_TYPE_CHEM)
+ C.fullness = max(0, C.fullness-4)
+ C.nutrition = max(0, C.nutrition-4)
+ if(addiction_mults < 4)
+ C.nutri_mult += 0.5
+ C.weight_gain_rate += 0.25
+ addiction_mults = 4
+ return
+
+/datum/reagent/fermi_fat/proc/addiction_remove(mob/living/carbon/C)
+ if(addiction_mults > 0)
+ C.nutri_mult = max(1, 0.5 * addiction_mults)
+ C.weight_gain_rate = max(0,11, 0.25 * addiction_mults)
+ return
+
+//Reagent
+/datum/reagent/fermi_slim
+ name = "Macerinic Solution"
+ description = "A solution with unparalleled obesity-solving properties. One of the few things known to be capable of removing galbanic fat."
+ color = "#3b0ce7"
+ taste_description = "thinness"
+ pH = 7
+ metabolization_rate = REAGENTS_METABOLISM / 4
+ can_synth = FALSE
+
+ overdose_threshold = 50
+
+//Reaction
+/datum/chemical_reaction/fermi_slim
+ name = "FermiSlim"
+ id = /datum/reagent/fermi_slim
+ mix_message = "the reaction seems to become thinner!"
+ required_reagents = list(/datum/reagent/medicine/lipolicide = 0.1, /datum/reagent/ammonia = 0.1, /datum/reagent/oxygen = 0.1)
+ results = list(/datum/reagent/fermi_slim = 0.2)
+ required_temp = 1
+ OptimalTempMin = 600 // Lower area of bell curve for determining heat based rate reactions
+ OptimalTempMax = 650 // Upper end for above
+ ExplodeTemp = 700 // Temperature at which reaction explodes
+ OptimalpHMin = 10 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
+ OptimalpHMax = 11.5 // Higest value for above
+ ReactpHLim = 1 // How far out pH wil react, giving impurity place (Exponential phase)
+ CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
+ CurveSharpT = 4 // How sharp the temperature exponential curve is (to the power of value)
+ CurveSharppH = 4 // How sharp the pH exponential curve is (to the power of value)
+ ThermicConstant = -10 // Temperature change per 1u produced
+ HIonRelease = -0.02 // pH change per 1u reaction (inverse for some reason)
+ RateUpLim = 2 // Optimal/max rate possible if all conditions are perfect
+ FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
+ FermiExplode = FALSE // If the chemical explodes in a special way
+ PurityMin = 0.1
+
+//Effects
+/datum/reagent/fermi_slim/on_mob_life(mob/living/carbon/M)
+ if(!iscarbon(M))
+ return..()
+ M.adjust_fatness(-50, FATTENING_TYPE_WEIGHT_LOSS)
+ M.adjust_perma(-5, FATTENING_TYPE_WEIGHT_LOSS)
+ ..()
+ . = 1
+
+/datum/reagent/fermi_slim/overdose_process(mob/living/M)
+ if(!iscarbon(M))
+ return..()
+ var/mob/living/carbon/C = M
+ C.fullness = max(0, C.fullness-5)
+ C.nutrition = max(0, C.nutrition-5)
+ C.weight_loss_rate = min(5, C.weight_loss_rate+0.01)
+ ..()
diff --git a/GainStation13/code/modules/reagents/chemistry/recipes/ROCKANDSTONEdrinks.dm b/GainStation13/code/modules/reagents/chemistry/recipes/ROCKANDSTONEdrinks.dm
new file mode 100644
index 0000000000..19765b2b3c
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/recipes/ROCKANDSTONEdrinks.dm
@@ -0,0 +1,14 @@
+//DRG drinks
+
+
+/datum/chemical_reaction/oily_oafs
+ name = "Oily oafs"
+ id = /datum/reagent/consumable/ethanol/oily_oafs
+ results = list(/datum/reagent/consumable/ethanol/oily_oafs = 2)
+ required_reagents = list(/datum/reagent/consumable/ethanol/beer = 1, /datum/reagent/consumable/cream = 1)
+
+/datum/chemical_reaction/glyphid_slammer
+ name = "Glyphid slammer"
+ id = /datum/reagent/consumable/ethanol/glyphid_slammer
+ results = list(/datum/reagent/consumable/ethanol/glyphid_slammer = 2)
+ required_reagents = list(/datum/reagent/consumable/pwr_game = 1, /datum/reagent/consumable/ethanol/beer = 1)
\ No newline at end of file
diff --git a/GainStation13/code/modules/reagents/chemistry/recipes/fatchem.dm b/GainStation13/code/modules/reagents/chemistry/recipes/fatchem.dm
new file mode 100644
index 0000000000..8523b97448
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/recipes/fatchem.dm
@@ -0,0 +1,29 @@
+//GS13 - fat chems
+
+//WG chem
+/datum/chemical_reaction/lipoifier
+ name = "lipoifier"
+ id = /datum/reagent/consumable/lipoifier
+ results = list(/datum/reagent/consumable/lipoifier = 3)
+ required_reagents = list(/datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/cornoil = 1, /datum/reagent/medicine/synthflesh = 1)
+
+//BURP CHEM
+/datum/chemical_reaction/fizulphite
+ name = "fizulphite"
+ id = /datum/reagent/consumable/fizulphite
+ results = list(/datum/reagent/consumable/fizulphite = 5)
+ required_reagents = list(/datum/reagent/consumable/sugar = 1, /datum/reagent/nitrogen = 1, /datum/reagent/oxygen = 3)
+
+//ANTI-BURP / ANTI-FULLNESS CHEM
+/datum/chemical_reaction/extilphite
+ name = "extilphite"
+ id = /datum/reagent/consumable/extilphite
+ results = list(/datum/reagent/consumable/extilphite = 5)
+ required_reagents = list(/datum/reagent/consumable/sugar = 1, /datum/reagent/hydrogen = 2, /datum/reagent/carbon = 2)
+
+// brap chem
+/datum/chemical_reaction/flatulose
+ name = "flatulose"
+ id = /datum/reagent/consumable/flatulose
+ results = list(/datum/reagent/consumable/flatulose = 3)
+ required_reagents = list(/datum/reagent/consumable/sugar = 1, /datum/reagent/toxin/bad_food = 1, /datum/reagent/consumable/cream = 1)
diff --git a/GainStation13/code/modules/reagents/chemistry/recipes/fatdrinks.dm b/GainStation13/code/modules/reagents/chemistry/recipes/fatdrinks.dm
new file mode 100644
index 0000000000..12cd73aa0c
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/recipes/fatdrinks.dm
@@ -0,0 +1,55 @@
+//GS13 drink recipes
+
+/datum/chemical_reaction/belly_bloats
+ name = "Belly Bloats"
+ id = /datum/reagent/consumable/ethanol/belly_bloats
+ results = list(/datum/reagent/consumable/ethanol/belly_bloats = 2)
+ required_reagents = list(/datum/reagent/consumable/gibbfloats = 1, /datum/reagent/consumable/ethanol/beer = 1)
+
+/datum/chemical_reaction/blobby_mary
+ name = "Blobby Mary"
+ id = /datum/reagent/consumable/ethanol/blobby_mary
+ results = list(/datum/reagent/consumable/ethanol/blobby_mary = 3)
+ required_reagents = list(/datum/reagent/consumable/tomatojuice = 1, /datum/reagent/consumable/ethanol/vodka = 1, /datum/reagent/consumable/lipoifier = 1)
+
+/datum/chemical_reaction/beltbuster_mead
+ name = "Beltbuster Mead"
+ id = /datum/reagent/consumable/ethanol/beltbuster_mead
+ results = list(/datum/reagent/consumable/ethanol/beltbuster_mead = 4)
+ required_reagents = list(/datum/reagent/consumable/ethanol/mead = 1, /datum/reagent/consumable/ethanol = 1, /datum/reagent/consumable/cream = 1, /datum/reagent/consumable/lipoifier = 1)
+
+/datum/chemical_reaction/heavy_cafe1
+ name = "Heavy Cafe"
+ id = /datum/reagent/consumable/heavy_cafe
+ results = list(/datum/reagent/consumable/heavy_cafe = 3)
+ required_reagents = list(/datum/reagent/consumable/cafe_latte = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/cream = 1)
+
+/datum/chemical_reaction/heavy_cafe2
+ name = "Heavy Cafe"
+ id = /datum/reagent/consumable/heavy_cafe
+ results = list(/datum/reagent/consumable/heavy_cafe = 3)
+ required_reagents = list(/datum/reagent/consumable/soy_latte = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/consumable/cream = 1)
+
+/datum/chemical_reaction/fruits_tea
+ name = "Fruits Tea"
+ id = /datum/reagent/consumable/fruits_tea
+ results = list(/datum/reagent/consumable/fruits_tea = 3)
+ required_reagents = list(/datum/reagent/consumable/berryjuice = 1, /datum/reagent/consumable/lemonjuice = 1, /datum/reagent/consumable/tea = 1)
+
+/datum/chemical_reaction/snakebite
+ name = "Snakebite"
+ id = /datum/reagent/consumable/snakebite
+ results = list(/datum/reagent/consumable/snakebite = 3)
+ required_reagents = list(/datum/reagent/toxin = 1, /datum/reagent/consumable/limejuice = 1, /datum/reagent/consumable/lipoifier = 1)
+
+/datum/chemical_reaction/milkshake_vanilla
+ name = "Vanilla Milkshake"
+ id = /datum/reagent/consumable/milkshake_vanilla
+ results = list(/datum/reagent/consumable/milkshake_vanilla = 3)
+ required_reagents = list(/datum/reagent/consumable/milk = 1, /datum/reagent/consumable/cream = 1, /datum/reagent/consumable/vanilla = 1)
+
+/datum/chemical_reaction/milkshake_chocolate
+ name = "Chocolate Milkshake"
+ id = /datum/reagent/consumable/milkshake_chocolate
+ results = list(/datum/reagent/consumable/milkshake_chocolate = 3)
+ required_reagents = list(/datum/reagent/consumable/milk/chocolate_milk = 1, /datum/reagent/consumable/cream = 1, /datum/reagent/consumable/coco = 1)
\ No newline at end of file
diff --git a/GainStation13/code/modules/reagents/reagent_containers/barrel_tank.dm b/GainStation13/code/modules/reagents/reagent_containers/barrel_tank.dm
new file mode 100644
index 0000000000..d53437ac60
--- /dev/null
+++ b/GainStation13/code/modules/reagents/reagent_containers/barrel_tank.dm
@@ -0,0 +1,79 @@
+//chug tank
+/obj/item/reagent_containers/barrel_tank
+ name = "barrel tank"
+ desc = "A wooden barrely with straps and a tube attached. One can only wonder what it's for."
+ icon = 'GainStation13/icons/obj/barrel_tank.dmi'
+ icon_state = "barrel_tank"
+ item_state = "barrel_tank"
+ w_class = WEIGHT_CLASS_BULKY
+ slot_flags = ITEM_SLOT_BACK
+ reagent_flags = REFILLABLE | TRANSPARENT
+ actions_types = list(/datum/action/item_action/toggle_tube)
+
+ var/mob/living/carbon/U = null
+ var/transfer_amount = 1
+
+ amount_per_transfer_from_this = 0
+ possible_transfer_amounts = list(0)
+ volume = 500
+ spillable = FALSE
+ splashable = FALSE
+
+/obj/item/reagent_containers/barrel_tank/ui_action_click(mob/user)
+ toggle_tube(user)
+
+/obj/item/reagent_containers/barrel_tank/proc/toggle_tube(mob/living/user)
+ if(!istype(user))
+ return
+ if(user.get_item_by_slot(user.getBackSlot()) != src)
+ to_chat(user, "The barrel must be worn properly to use!")
+ return
+ if(user.incapacitated())
+ return
+
+ if(!U)
+ to_chat(user, "You put the barrel's tube in your mouth.")
+ U = user
+ START_PROCESSING(SSobj, src)
+ else
+ to_chat(user, "You remove the barrel's tube from your mouth.")
+ U = null
+
+/obj/item/reagent_containers/barrel_tank/verb/toggle_tube_verb()
+ set name = "Toggle Tube"
+ set category = "Object"
+ toggle_tube(usr)
+
+/obj/item/reagent_containers/barrel_tank/equipped(mob/user, slot)
+ ..()
+ if(slot != SLOT_BACK && U != null)
+ to_chat(user, "The barrel's tube slips out of your mouth!")
+ U = null
+
+/obj/item/reagent_containers/barrel_tank/dropped(mob/user)
+ ..()
+ U = null
+
+/obj/item/reagent_containers/barrel_tank/process()
+ if(U == null)
+ return PROCESS_KILL
+
+ if(reagents.total_volume)
+ var/fraction = min(1/reagents.total_volume, 1)
+ reagents.reaction(U, INGEST, fraction, FALSE)
+ reagents.trans_to(U, transfer_amount, 2)
+ else
+ to_chat(U, "The barrel is empty!")
+ U = null
+
+/obj/item/reagent_containers/barrel_tank/attack_self(mob/user)
+ if(reagents.total_volume > 0)
+ to_chat(user, "You empty [src] of all reagents.")
+ reagents.clear_reagents()
+
+/datum/crafting_recipe/barrel_tank
+ name = "Barrel tank"
+ result = /obj/item/reagent_containers/barrel_tank
+ tools = list(TOOL_CROWBAR)
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 20)
+ category = CAT_CLOTHING
diff --git a/GainStation13/code/modules/research/designs/autolathe.dm b/GainStation13/code/modules/research/designs/autolathe.dm
new file mode 100644
index 0000000000..0232b44ad7
--- /dev/null
+++ b/GainStation13/code/modules/research/designs/autolathe.dm
@@ -0,0 +1,7 @@
+/datum/design/infrared_emitter
+ name = "Fatness Infrared Emitter"
+ id = "fatness_infrared_emitter"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 1000, MAT_GLASS = 500)
+ build_path = /obj/item/assembly/infra/fat
+ category = list("initial", "Misc")
diff --git a/GainStation13/code/modules/research/designs/nutri_designs.dm b/GainStation13/code/modules/research/designs/nutri_designs.dm
new file mode 100644
index 0000000000..bd9319cfd7
--- /dev/null
+++ b/GainStation13/code/modules/research/designs/nutri_designs.dm
@@ -0,0 +1,251 @@
+/////////////////////////////////////////
+///GS13 designs / nutri designs
+/////////////////////////////////////////
+
+
+//nutritech weapons
+/datum/design/fatoray_weak
+ name = "Basic Fatoray"
+ id = "fatoray_weak"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 8000, MAT_GLASS = 6000, MAT_CALORITE = 10000)
+ construction_time = 75
+ build_path = /obj/item/gun/energy/fatoray/weak
+ category = list("Weapons")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY
+
+/datum/design/fatoray_cannon_weak
+ name = "Basic Cannonshot Fatoray"
+ id = "fatoray_cannon_weak"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 10000, MAT_GLASS = 8000, MAT_CALORITE = 20000)
+ construction_time = 200
+ build_path = /obj/item/gun/energy/fatoray/cannon_weak
+ category = list("Weapons")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY
+
+/datum/design/alter_ray_metabolism
+ name = "AL-T-Ray: Metabolism"
+ id = "alter_ray_metabolism"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 10000, MAT_GLASS = 8000, MAT_CALORITE = 26000)
+ construction_time = 200
+ build_path = /obj/item/gun/energy/laser/alter_ray/gainrate
+ category = list("Weapons")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY
+
+
+/datum/design/alter_ray_reverser
+ name = "AL-T-Ray: Reverser"
+ id = "alter_ray_reverser"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 10000, MAT_GLASS = 8000, MAT_CALORITE = 26000)
+ construction_time = 200
+ build_path = /obj/item/gun/energy/laser/alter_ray/noloss
+ category = list("Weapons")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY
+
+//nutritech tools
+/datum/design/calorite_collar
+ name = "Calorite Collar"
+ desc = "A collar that amplifies caloric intake of the wearer."
+ id = "calorite_collar"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 1000, MAT_CALORITE = 4000)
+ construction_time = 75
+ build_path = /obj/item/clothing/neck/petcollar/calorite
+ category = list("Equipment", "Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_ALL
+
+/datum/design/cyberimp_nutriment_turbo
+ name = "Nutriment Pump Implant TURBO"
+ desc = "This implant was meant to prevent people from going hungry, but due to a flaw in its designs, it permanently produces a small amount of nutriment overtime."
+ id = "ci-nutrimentturbo"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 100
+ materials = list(MAT_METAL = 800, MAT_GLASS = 800, MAT_GOLD = 750, MAT_URANIUM = 1000)
+ build_path = /obj/item/organ/cyberimp/chest/nutriment/turbo
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/cyberimp_fat_mobility
+ name = "Mobility Nanite Core"
+ desc = "This implant contains nanites that reinforce leg muscles, allowing for unimpeded movement at extreme weights."
+ id = "ci-fatmobility"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 100
+ materials = list(MAT_METAL = 800, MAT_GLASS = 800, MAT_GOLD = 750, MAT_URANIUM = 1000)
+ build_path = /obj/item/organ/cyberimp/chest/mobility
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/bluespace_belt
+ name = "Bluespace Belt"
+ desc = "A belt made using bluespace technology. The power of space and time, used to hide the fact you are fat."
+ id = "bluespace_belt"
+ build_type = PROTOLATHE
+ construction_time = 100
+ materials = list(MAT_SILVER = 4000, MAT_GOLD = 4000, MAT_BLUESPACE = 2000, )
+ build_path = /obj/item/bluespace_belt
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/cookie_synthesizer
+ name = "Cookie Synthesizer"
+ desc = "A self-charging miraculous device that's able to produce cookies."
+ id = "cookie_synthesizer"
+ build_type = PROTOLATHE
+ construction_time = 100
+ materials = list(MAT_SILVER = 4000, MAT_URANIUM = 1000, MAT_BLUESPACE = 1000, MAT_CALORITE = 2000)
+ build_path = /obj/item/cookiesynth
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SERVICE
+
+//these are made in mech fabricator
+/datum/design/borg_cookie_synthesizer
+ name = "Cyborg Upgrade (Cookie Synthesizer)"
+ id = "borg_upgrade_cookiesynthesizer"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/cookiesynth
+ materials = list(MAT_METAL=10000, MAT_GOLD=1500, MAT_URANIUM=250, MAT_PLASMA=1500)
+ construction_time = 100
+ category = list("Cyborg Upgrade Modules")
+
+/datum/design/borg_fatoray
+ name = "Cyborg Upgrade (Fatoray)"
+ id = "borg_upgrade_fatoray"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/fatoray
+ materials = list(MAT_METAL = 8000, MAT_GLASS = 6000, MAT_CALORITE = 10000)
+ construction_time = 100
+ category = list("Cyborg Upgrade Modules")
+
+/datum/design/borg_feedtube
+ name = "Cyborg Upgrade (Feeding Tube)"
+ id = "borg_upgrade_feedingtube"
+ build_type = MECHFAB
+ build_path = /obj/item/borg/upgrade/feedtube
+ materials = list(MAT_METAL = 8000, MAT_GLASS = 6000, MAT_CALORITE = 10000)
+ construction_time = 100
+ category = list("Cyborg Upgrade Modules")
+
+//todo: make a seperate file for extra borg modules
+
+/obj/item/borg/upgrade/cookiesynth
+ name = "cyborg cookie synthesizer"
+ desc = "An extra module that allows cyborgs to dispense cookies."
+ icon_state = "cyborg_upgrade3"
+
+/obj/item/borg/upgrade/cookiesynth/action(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if(.)
+ var/obj/item/cookiesynth/S = new(R.module)
+ R.module.basic_modules += S
+ R.module.add_module(S, FALSE, TRUE)
+
+/obj/item/borg/upgrade/cookiesynth/deactivate(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if (.)
+ var/obj/item/cookiesynth/S = locate() in R.module
+ R.module.remove_module(S, TRUE)
+
+
+/obj/item/gun/energy/fatoray/weak/cyborg
+ name = "cyborg fatoray"
+ desc = "An integrated fatoray for cyborg use."
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_weak"
+ can_charge = FALSE
+ selfcharge = EGUN_SELFCHARGE_BORG
+ cell_type = /obj/item/stock_parts/cell/secborg
+ charge_delay = 5
+
+/obj/item/borg/upgrade/fatoray
+ name = "cyborg fatoray module"
+ desc = "An extra module that allows cyborgs to use fatoray weapons."
+ icon_state = "cyborg_upgrade3"
+
+/obj/item/borg/upgrade/fatoray/action(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if(.)
+ var/obj/item/gun/energy/fatoray/weak/cyborg/S = new(R.module)
+ R.module.basic_modules += S
+ R.module.add_module(S, FALSE, TRUE)
+
+/obj/item/borg/upgrade/fatoray/deactivate(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if (.)
+ var/obj/item/gun/energy/fatoray/weak/cyborg/S = locate() in R.module
+ R.module.remove_module(S, TRUE)
+
+
+
+//cyborg regen feeding tube
+
+/obj/item/reagent_containers/borghypo/feeding_tube
+ name = "cyborg feeding tube"
+ desc = "A feeding tube module for a cyborg."
+ icon = 'GainStation13/icons/obj/feeding_tube.dmi'
+ icon_state = "borg_tube"
+ possible_transfer_amounts = list(5,10,20)
+ charge_cost = 20
+ recharge_time = 3
+ accepts_reagent_upgrades = FALSE
+ reagent_ids = list(/datum/reagent/consumable/cream, /datum/reagent/consumable/milk, /datum/reagent/consumable/nutriment)
+ var/starttime = 0
+ var/chemtoadd = 5
+
+/obj/item/reagent_containers/borghypo/feeding_tube/attack(mob/living/carbon/M, mob/user)
+ var/datum/reagents/R = reagent_list[mode]
+ if(!R.total_volume)
+ to_chat(user, "The injector is empty.")
+ return
+ if(!istype(M))
+ return
+ if(R.total_volume && M.can_inject(user, 1, user.zone_selected,bypass_protection))
+
+ if(M == user.pulling && ishuman(user.pulling))
+ starttime = world.time
+ while(starttime + 300 > world.time && in_range(user, M))
+ if(do_mob(user, M, 10, 0, 1))
+ M.reagents.add_reagent(/datum/reagent/consumable/nutriment, chemtoadd)
+ M.visible_message("[user] pumps some liquid in [M]!","[user] pumps some liquid in you!")
+ else
+ to_chat(M, "You feel the cyborg's feeding tube pour liquid down your throat!")
+ to_chat(user, "You feed [M] with the integrated feeding tube.")
+ visible_message("The cyborg's feeding tube pours liquid down [M]'s throat!")
+ var/fraction = min(amount_per_transfer_from_this/R.total_volume, 1)
+ R.reaction(M, INJECT, fraction)
+ if(M.reagents)
+ var/trans = R.trans_to(M, amount_per_transfer_from_this)
+ to_chat(user, "[trans] unit\s injected. [R.total_volume] unit\s remaining.")
+
+/obj/item/reagent_containers/borghypo/feeding_tube/regenerate_reagents()
+ if(iscyborg(src.loc))
+ var/mob/living/silicon/robot/R = src.loc
+ if(R && R.cell)
+ for(var/i in modes) //Lots of reagents in this one, so it's best to regenrate them all at once to keep it from being tedious.
+ var/valueofi = modes[i]
+ var/datum/reagents/RG = reagent_list[valueofi]
+ if(RG.total_volume < RG.maximum_volume)
+ R.cell.use(charge_cost)
+ RG.add_reagent(reagent_ids[valueofi], 5)
+
+
+/obj/item/borg/upgrade/feedtube
+ name = "cyborg feeding tube module"
+ desc = "An extra module that allows cyborgs to use an integrated feeding tube along with a synthesizer."
+ icon_state = "cyborg_upgrade3"
+
+/obj/item/borg/upgrade/feedtube/action(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if(.)
+ var/obj/item/reagent_containers/borghypo/feeding_tube/S = new(R.module)
+ R.module.basic_modules += S
+ R.module.add_module(S, FALSE, TRUE)
+
+/obj/item/borg/upgrade/feedtube/deactivate(mob/living/silicon/robot/R, user = usr)
+ . = ..()
+ if (.)
+ var/obj/item/reagent_containers/borghypo/feeding_tube/S = locate() in R.module
+ R.module.remove_module(S, TRUE)
diff --git a/GainStation13/code/modules/research/nanites/nanite_programs/fattening.dm b/GainStation13/code/modules/research/nanites/nanite_programs/fattening.dm
new file mode 100644
index 0000000000..e020989e3b
--- /dev/null
+++ b/GainStation13/code/modules/research/nanites/nanite_programs/fattening.dm
@@ -0,0 +1,161 @@
+/datum/nanite_rule/fatness
+ name = "BFI"
+ desc = "Checks the host's BFI."
+
+ var/threshold = 50
+ var/above = TRUE
+
+/datum/nanite_rule/fatness/check_rule()
+ if(iscarbon(program.host_mob))
+ var/mob/living/carbon/C = program.host_mob
+ var/BFI = C.fatness_real
+ if(above)
+ if(BFI >= threshold)
+ return TRUE
+ else
+ if(BFI < threshold)
+ return TRUE
+ return FALSE
+ else
+ return FALSE
+
+/datum/nanite_rule/fatness/display()
+ return "[name] [above ? ">" : "<"] [threshold]"
+
+/datum/nanite_program/sensor/fat_sensor
+ name = "BFI Sensor"
+ desc = "The nanites receive a signal when the host's BFI is below or exceeds a certain amount."
+ can_rule = TRUE
+ var/spent = FALSE
+
+/datum/nanite_program/sensor/fat_sensor/register_extra_settings()
+ . = ..()
+ extra_settings[NES_FATNESS] = new /datum/nanite_extra_setting/number(0, 0, 3440, "BFI")
+ extra_settings[NES_DIRECTION] = new /datum/nanite_extra_setting/boolean(TRUE, "Above", "Below")
+
+/datum/nanite_program/sensor/fat_sensor/check_event()
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ var/datum/nanite_extra_setting/level = extra_settings[NES_FATNESS]
+ var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
+ var/detected = FALSE
+ if(direction.get_value())
+ if(C.fatness >= level.get_value())
+ detected = TRUE
+ else
+ if(C.fatness < level.get_value())
+ detected = TRUE
+
+ if(detected)
+ if(!spent)
+ spent = TRUE
+ return TRUE
+ return FALSE
+ else
+ spent = FALSE
+ return FALSE
+ return FALSE
+
+/datum/nanite_program/sensor/fat_sensor/make_rule(datum/nanite_program/target)
+ var/datum/nanite_rule/fatness/rule = new(target)
+ var/datum/nanite_extra_setting/direction = extra_settings[NES_DIRECTION]
+ var/datum/nanite_extra_setting/level = extra_settings[NES_FATNESS]
+ rule.above = direction.get_value()
+ rule.threshold = level.get_value()
+ return rule
+
+/datum/design/nanites/fat_sensor
+ name = "BFI Sensor"
+ desc = "The nanites boost can detect the host's BFI."
+ id = "fat_sensor_nanites"
+ program_type = /datum/nanite_program/sensor/fat_sensor
+ category = list("Sensor Nanites")
+
+/datum/nanite_program/fat_adjuster
+ name = "BFI Regulator"
+ desc = "The nanites act on the host's adipose tissues, removing or adding based on the specified preference. Nanites consumed are equal to value added/lost"
+ use_rate = 0
+ rogue_types = list(/datum/nanite_program/necrotic)
+
+/datum/nanite_program/fat_adjuster/register_extra_settings()
+ . = ..()
+ extra_settings[NES_FATNESS] = new /datum/nanite_extra_setting/number(0, -10, 10, "BFI")
+
+/datum/nanite_program/fat_adjuster/check_conditions()
+ var/datum/nanite_extra_setting/BFI = extra_settings[NES_FATNESS]
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ if(BFI.get_value() < 0)
+ if(C.fatness_real <= 0)
+ return FALSE
+ else
+ return FALSE
+ return ..()
+
+/datum/nanite_program/fat_adjuster/active_effect()
+ var/datum/nanite_extra_setting/BFI = extra_settings[NES_FATNESS]
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ if(BFI.get_value() > 0)
+ if(consume_nanites(BFI.get_value()))
+ C.adjust_fatness(BFI.get_value(), FATTENING_TYPE_NANITES)
+ else
+ if(consume_nanites(-(BFI.get_value())))
+ C.adjust_fatness(BFI.get_value(), FATTENING_TYPE_WEIGHT_LOSS)
+
+/datum/design/nanites/fat_adjuster
+ name = "BFI Regulator"
+ desc = "The nanites adjust the host's BFI."
+ id = "fat_adjuster_nanites"
+ program_type = /datum/nanite_program/fat_adjuster
+ category = list("Medical Nanites")
+
+/datum/nanite_program/fat_converter
+ name = "Adipose Conversion"
+ desc = "Nanites learn to convert excess body mass to replicate."
+ rogue_types = list(/datum/nanite_program/necrotic)
+
+/datum/nanite_program/fat_converter/check_conditions()
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ if(C.fatness_real <= 0 || nanites.nanite_volume >= nanites.max_nanites)
+ return FALSE
+ else
+ return FALSE
+ return ..()
+
+/datum/nanite_program/fat_converter/active_effect()
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ if(C.fatness_real > 0 && nanites.nanite_volume < nanites.max_nanites)
+ nanites.adjust_nanites(src, min(round(C.fatness_real), 5))
+ C.adjust_fatness(-(min(round(C.fatness_real), 5)), FATTENING_TYPE_WEIGHT_LOSS)
+
+/datum/design/nanites/fat_converter
+ name = "Adipose Conversion"
+ desc = "The nanites use fat to replicate quickly."
+ id = "fat_converter_nanites"
+ program_type = /datum/nanite_program/fat_converter
+ category = list("Medical Nanites")
+
+/datum/nanite_program/bwomf
+ name = "B.W.O.M.F." //Body Widening Operation for Mass Fattening
+ desc = "Nanites remains on standy-by, massively increasing the host's mass on trigger.."
+ unique = FALSE
+ can_trigger = TRUE
+ trigger_cost = 50
+ trigger_cooldown = 50
+ rogue_types = list(/datum/nanite_program/toxic)
+
+/datum/nanite_program/bwomf/on_trigger(comm_message)
+ if(iscarbon(host_mob))
+ var/mob/living/carbon/C = host_mob
+ C.adjust_fatness(100, FATTENING_TYPE_NANITES)
+ to_chat(C, "[pick("Your belly expands quickly!", "Fat envelops you further!", "Lard grows all over you!")]")
+
+/datum/design/nanites/bwomf
+ name = "B.W.O.M.F."
+ desc = "Massively increase host's mass on trigger."
+ id = "bwomf_nanites"
+ program_type = /datum/nanite_program/bwomf
+ category = list("Medical Nanites")
diff --git a/GainStation13/code/modules/research/techweb/nutritech_nodes.dm b/GainStation13/code/modules/research/techweb/nutritech_nodes.dm
new file mode 100644
index 0000000000..4873ad3274
--- /dev/null
+++ b/GainStation13/code/modules/research/techweb/nutritech_nodes.dm
@@ -0,0 +1,23 @@
+/////////////// GS13 - NUTRITIONAL TECHNOLOGY
+
+/datum/techweb_node/nutritech_tools
+ id = "nutritech_tools"
+ display_name = "Nutri-Tech Tools"
+ description = "Ending world hunger was never made easier!"
+ prereq_ids = list("biotech", "adv_engi")
+ design_ids = list("calorite_collar", "ci-nutrimentturbo", "bluespace_belt", "adipoelectric_transformer", "cookie_synthesizer", "borg_upgrade_cookiesynthesizer", "borg_upgrade_feedingtube", "ci-fatmobility")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
+ boost_item_paths = list(/obj/item/gun/energy/fatoray, /obj/item/gun/energy/fatoray/cannon, /obj/item/trash/fatoray_scrap1, /obj/item/trash/fatoray_scrap2)
+ export_price = 5000
+ hidden = TRUE
+
+/datum/techweb_node/nutritech_weapons
+ id = "nutritech_weapons"
+ display_name = "Nutri-Tech Weapons"
+ description = "Ever wanted to reach your daily caloric intake in just 5 seconds?"
+ prereq_ids = list("biotech", "adv_engi")
+ design_ids = list("fatoray_weak", "fatoray_cannon_weak", "alter_ray_metabolism", "alter_ray_reverser", "borg_upgrade_fatoray", "bwomf_nanites")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ boost_item_paths = list(/obj/item/gun/energy/fatoray, /obj/item/gun/energy/fatoray/cannon, /obj/item/trash/fatoray_scrap1, /obj/item/trash/fatoray_scrap2)
+ export_price = 10000
+ hidden = TRUE
diff --git a/GainStation13/code/modules/surgery/organs/augments.dm b/GainStation13/code/modules/surgery/organs/augments.dm
new file mode 100644
index 0000000000..9059f14d58
--- /dev/null
+++ b/GainStation13/code/modules/surgery/organs/augments.dm
@@ -0,0 +1,25 @@
+//GS13 - implants and similar
+
+/obj/item/organ/cyberimp/chest/nutriment/turbo
+ name = "Nutriment pump implant TURBO"
+ desc = "This implant was meant to prevent people from going hungry, but due to a flaw in its designs, it permanently produces a small amount of nutriment overtime."
+ icon_state = "chest_implant"
+ implant_color = "#006607"
+ nutrition_amount = 20 //somewhere around 5 pounds
+ hunger_threshold = NUTRITION_LEVEL_FULL
+ poison_amount = 10
+ message = "" //no message cuz spam is annoying
+
+/obj/item/organ/cyberimp/chest/mobility
+ name = "Mobility Nanite Core"
+ desc = "This implant contains nanites that reinforce leg muscles, allowing for unimpeded movement at extreme weights."
+ icon_state = "chest_implant"
+ implant_color = "#9034db"
+
+/obj/item/organ/cyberimp/chest/mobility/Insert(mob/living/carbon/M, special = 0)
+ ..()
+ ADD_TRAIT(M, TRAIT_NO_FAT_SLOWDOWN, src)
+
+/obj/item/organ/cyberimp/chest/mobility/Remove(mob/living/carbon/M, special = 0)
+ REMOVE_TRAIT(M, TRAIT_NO_FAT_SLOWDOWN, src)
+ ..()
diff --git a/GainStation13/code/modules/vending/gatocola.dm b/GainStation13/code/modules/vending/gatocola.dm
new file mode 100644
index 0000000000..a484830ebb
--- /dev/null
+++ b/GainStation13/code/modules/vending/gatocola.dm
@@ -0,0 +1,29 @@
+/obj/machinery/vending/gato
+ name = "GATO Vending Machine"
+ desc = "A GATO branded cola machine, a cute little cat is plastered onto it."
+ icon = 'icons/obj/vending.dmi'
+ icon_state = "cola_black"
+ product_slogans = "Meow~, time for some cola!"
+ vend_reply = "Meow~ Meow~"
+ products = list(
+ /obj/item/reagent_containers/food/drinks/beer = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/cola = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/starkist = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/space_up = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/pwr_game = 10,
+ )
+ contraband = list(
+ /obj/item/organ/ears/cat = 2,
+ )
+ premium = list(
+ /obj/item/reagent_containers/food/drinks/soda_cans/air = 20,
+ /obj/item/reagent_containers/food/drinks/soda_cans/fizzwiz = 5,
+ /obj/item/reagent_containers/food/drinks/soda_cans/soothseltz = 8,
+ )
+
+ refill_canister = /obj/item/vending_refill/mealdor
+
+/obj/item/vending_refill/mealdor
+ machine_name = "Meal Vendor Refill"
+ icon_state = "refill_mealdor"
diff --git a/GainStation13/code/modules/vending/mealdor.dm b/GainStation13/code/modules/vending/mealdor.dm
new file mode 100644
index 0000000000..a355f1089e
--- /dev/null
+++ b/GainStation13/code/modules/vending/mealdor.dm
@@ -0,0 +1,54 @@
+/obj/machinery/vending/mealdor
+ name = "Meal Vendor"
+ desc = "The vending machine used by starving people. Looks like they've changed the shell, it looks cuter."
+ icon = 'icons/obj/vending.dmi'
+ icon_state = "mealdor"
+ product_slogans = "Are you hungry? Eat some of my food!;Be sure to eat one of our tasty treats!;Was that your stomach? Go ahead, get some food!"
+ vend_reply = "Enjoy your meal."
+ products = list(
+
+ /obj/item/reagent_containers/food/snacks/store/cake/cheese = 10,
+ /obj/item/reagent_containers/food/snacks/store/cake/pumpkinspice = 10,
+ /obj/item/reagent_containers/food/snacks/store/cake/pound_cake = 8,
+ /obj/item/reagent_containers/food/snacks/cakeslice/bsvc = 5,
+ /obj/item/reagent_containers/food/snacks/cakeslice/bscc = 5,
+// /obj/item/reagent_containers/food/snacks/donut/purefat = 10,
+ /obj/item/reagent_containers/food/snacks/fries = 10,
+ /obj/item/reagent_containers/food/snacks/donut = 20,
+ /obj/item/reagent_containers/food/snacks/candiedapple = 7,
+ /obj/item/reagent_containers/food/snacks/burrito = 8,
+ /obj/item/reagent_containers/food/snacks/enchiladas = 10,
+ /obj/item/reagent_containers/food/snacks/spaghetti = 20,
+ /obj/item/reagent_containers/food/snacks/kebab/rat = 7,
+ /obj/item/reagent_containers/food/snacks/kebab/rat/double = 6,
+ /obj/item/reagent_containers/food/snacks/meatballspaghetti = 10,
+ /obj/item/reagent_containers/food/drinks/bottle/orangejuice = 10,
+ /obj/item/reagent_containers/food/drinks/bottle/pineapplejuice = 10,
+ /obj/item/reagent_containers/food/drinks/bottle/strawberryjuice = 10,
+ /obj/item/reagent_containers/food/drinks/beer = 10,
+ /obj/item/reagent_containers/food/drinks/soda_cans/cola = 10,
+ /obj/item/reagent_containers/food/snacks/pizza/margherita = 10,
+ /obj/item/reagent_containers/food/snacks/butterdog = 12,
+ /obj/item/reagent_containers/food/snacks/burger/plain = 20,
+ /obj/item/reagent_containers/food/snacks/burger/bearger = 10,
+ /obj/item/reagent_containers/food/snacks/pie/plump_pie = 8,
+ /obj/item/reagent_containers/food/snacks/dough = 20
+ )
+ contraband = list(
+ /obj/item/clothing/mask/fakemoustache = 5,
+ /obj/item/clothing/head/chefhat = 5,
+ /obj/item/reagent_containers/food/snacks/cookie = 10,
+ /obj/item/reagent_containers/food/snacks/salad/fruit = 15,
+ /obj/item/reagent_containers/food/snacks/salad = 20,
+ /obj/item/reagent_containers/food/snacks/salad/hellcobb = 10,
+ /obj/item/clothing/under/cowkini = 5,
+ /obj/item/reagent_containers/food/snacks/blueberry_gum = 5
+ )
+ premium = list(
+ /obj/item/reagent_containers/food/drinks/soda_cans/air = 3,
+ /obj/item/reagent_containers/food/snacks/donut/chaos = 3,
+ /obj/item/clothing/mask/cowmask/gag = 2,
+ /obj/item/clothing/mask/pig/gag = 2
+ )
+
+ refill_canister = /obj/item/vending_refill/mealdor
diff --git a/GainStation13/code/obj/items/bluespace_belt.dm b/GainStation13/code/obj/items/bluespace_belt.dm
new file mode 100644
index 0000000000..c551b18e4e
--- /dev/null
+++ b/GainStation13/code/obj/items/bluespace_belt.dm
@@ -0,0 +1,34 @@
+/obj/item/bluespace_belt
+ name = "bluespace belt"
+ desc = "A belt made using bluespace technology. The power of space and time, used to hide the fact you are fat."
+ icon = 'GainStation13/icons/obj/clothing/bluespace_belt.dmi'
+ icon_state = "bluespace_belt"
+ item_state = "bluespace_belt"
+ slot_flags = ITEM_SLOT_BELT
+ equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
+ drop_sound = 'sound/items/handling/toolbelt_drop.ogg'
+ pickup_sound = 'sound/items/handling/toolbelt_pickup.ogg'
+
+/obj/item/bluespace_belt/equipped(mob/user, slot)
+ ..()
+ if(!iscarbon(user))
+ return
+ var/mob/living/carbon/U = user
+ if(slot == SLOT_BELT)
+ to_chat(U, "You put the belt around your waist and your mass begins to shrink...")
+ U.hider_add(src)
+ else
+ to_chat(user, "The belt is opened, letting your mass flow out!")
+ U.hider_remove(src)
+
+/obj/item/bluespace_belt/dropped(mob/user)
+ ..()
+ if(!iscarbon(user))
+ return
+ var/mob/living/carbon/U = user
+ to_chat(U, "The belt is opened, letting your mass flow out!")
+ U.hider_remove(src)
+
+/obj/item/bluespace_belt/proc/fat_hide(var/mob/living/carbon/user)
+ return -(user.fatness_real - 1)
+
diff --git a/GainStation13/code/obj/items/circuits.dm b/GainStation13/code/obj/items/circuits.dm
new file mode 100644
index 0000000000..48d17cc50d
--- /dev/null
+++ b/GainStation13/code/obj/items/circuits.dm
@@ -0,0 +1,30 @@
+/obj/item/integrated_circuit/input/fat_scanner
+ name = "integrated body fat analyzer"
+ desc = "A very small version of the common medical analyser adjusted to scan a target's weight."
+ icon_state = "medscan"
+ complexity = 4
+ inputs = list("target" = IC_PINTYPE_REF)
+ outputs = list(
+ "weight (pounds)" = IC_PINTYPE_NUMBER,
+ "weight (BFI)" = IC_PINTYPE_NUMBER
+ )
+ activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT)
+ spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH
+ power_draw_per_use = 40
+
+/obj/item/integrated_circuit/input/fat_scanner/do_work()
+ var/mob/living/carbon/fatty = get_pin_data_as_type(IC_INPUT, 1, /mob/living)
+ if(!istype(fatty)) //Invalid input
+ return
+ if(!fatty.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range.
+ return
+
+ var/weight_in_pounds = fatty.calculate_weight_in_pounds()
+ var/weight_in_fatness = fatty.fatness
+
+ set_pin_data(IC_OUTPUT, 1, weight_in_pounds)
+ set_pin_data(IC_OUTPUT, 2, weight_in_fatness)
+
+ push_data()
+ activate_pin(2)
+
diff --git a/GainStation13/code/obj/items/holy.dm b/GainStation13/code/obj/items/holy.dm
new file mode 100644
index 0000000000..c7571bb601
--- /dev/null
+++ b/GainStation13/code/obj/items/holy.dm
@@ -0,0 +1,93 @@
+/obj/item/nullrod/attack(mob/target, mob/living/user)
+ . = ..()
+ if(iscarbon(target))
+ var/mob/living/carbon/T = target
+ for(var/hider in T.fat_hiders)
+ if(isitem(hider))
+ var/obj/item/O = hider
+ T.dropItemToGround(O)
+ if(T.cursed_fat == 1)
+ T.cursed_fat = 0
+ T.fattening_steps_left = 0
+
+/obj/item/storage/book/bible/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE)
+ . = ..()
+ if(iscarbon(M))
+ var/mob/living/carbon/T = M
+ for(var/hider in T.fat_hiders)
+ if(isitem(hider))
+ var/obj/item/O = hider
+ T.dropItemToGround(O)
+ if(T.cursed_fat == 1)
+ T.cursed_fat = 0
+ T.fattening_steps_left = 0
+
+/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
+ . = ..()
+ for(var/hider in M.fat_hiders)
+ if(isitem(hider))
+ var/obj/item/O = hider
+ M.dropItemToGround(O)
+ if(M.cursed_fat == 1)
+ M.cursed_fat = 0
+ M.fattening_steps_left = 0
+
+/obj/item/nullrod/dream_breaker
+ name = "dream breaker"
+ desc = "A cross-shaped weapon emitting a faint, dream-like light. Its blows will wake any dreamer."
+ icon = 'GainStation13/icons/obj/dreambreaker.dmi'
+ icon_state = "dreambreaker"
+ item_state = "dreambreaker"
+ lefthand_file = 'GainStation13/icons/obj/dreambreaker_left.dmi'
+ righthand_file = 'GainStation13/icons/obj/dreambreaker_right.dmi'
+
+ actions_types = list(/datum/action/item_action/db_slide)
+ var/slidedistance = 2
+ var/slidespeed = 3
+ var/stamina_cost = 34
+
+ force = 20
+ throwforce = 25
+ throw_range = 10
+ throw_speed = 2
+ var/click_delay = 2
+
+ slot_flags = ITEM_SLOT_BACK
+ sharpness = IS_BLUNT
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("smashed", "whacked", "smacked", "bonked")
+ hitsound = "swing_hit"
+
+ var/l_range = 3
+ var/l_power = 0.8
+ light_color = "#FFCC66"
+
+/obj/item/nullrod/dream_breaker/Initialize(mapload)
+ . = ..()
+ set_light(l_range, l_power, light_color)
+
+/obj/item/nullrod/dream_breaker/attack(mob/living/target, mob/living/user)
+ . = ..()
+ user.changeNext_move(CLICK_CD_MELEE * click_delay)
+
+/obj/item/nullrod/dream_breaker/ui_action_click(mob/user, action)
+ if(!isliving(user))
+ return
+
+ var/atom/target = get_edge_target_turf(user, user.dir) //gets the user's direction
+ user.resting = TRUE
+ if(user:getStaminaLoss() < 100)
+ if (user.throw_at(target, slidedistance, slidespeed, spin = FALSE, diagonals_first = TRUE))
+ user:adjustStaminaLoss(stamina_cost) //reduce stamina loss by 0.3 per tick, 6 per 2 seconds
+ user.visible_message("[usr] slides forward!")
+ user.resting = FALSE
+ else
+ to_chat(user, "Something prevents you from sliding forward!")
+ else
+ to_chat(user, "You fall down when attempting to slide!")
+
+/datum/action/item_action/db_slide
+ name = "Dream Breaker Slide"
+ desc = "Use dream-like atheletics to slide forward, but don't wear yourself out!."
+ icon_icon = 'GainStation13/icons/obj/dreambreaker.dmi'
+ button_icon_state = "dreambreaker"
diff --git a/GainStation13/code/obj/items/minor_items.dm b/GainStation13/code/obj/items/minor_items.dm
new file mode 100644
index 0000000000..1f399acfed
--- /dev/null
+++ b/GainStation13/code/obj/items/minor_items.dm
@@ -0,0 +1,171 @@
+/////GS13 - miscellanous items. If it's a small item, a container or something
+/////then it should land here, instead of making a seperate .dm file
+
+//fatoray research scraps (maintloot)
+
+/obj/item/trash/fatoray_scrap1
+ name = "raygun scraps"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_scrap1"
+ desc = "Small parts that seemingly once belonged to some sort of a raygun."
+
+/obj/item/trash/fatoray_scrap2
+ name = "raygun scraps"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_scrap2"
+ desc = "Small parts that seemingly once belonged to some sort of a raygun."
+
+// GS13 fatty liquid beakers defs, for admin stuff and mapping junk
+
+/obj/item/reagent_containers/glass/beaker/lipoifier
+ list_reagents = list(/datum/reagent/consumable/lipoifier = 50)
+
+/obj/item/reagent_containers/glass/beaker/cornoil
+ list_reagents = list(/datum/reagent/consumable/cornoil = 50)
+
+/obj/item/reagent_containers/glass/beaker/blueberry_juice
+ list_reagents = list(/datum/reagent/blueberry_juice = 50)
+
+/obj/item/reagent_containers/glass/beaker/fizulphite
+ list_reagents = list(/datum/reagent/consumable/fizulphite = 50)
+
+/obj/item/reagent_containers/glass/beaker/extilphite
+ list_reagents = list(/datum/reagent/consumable/extilphite = 50)
+
+/obj/item/reagent_containers/glass/beaker/calorite_blessing
+ list_reagents = list(/datum/reagent/consumable/caloriteblessing = 50)
+
+/obj/item/reagent_containers/glass/beaker/flatulose
+ list_reagents = list(/datum/reagent/consumable/flatulose = 50)
+
+//blueberry gum snack
+
+/obj/item/reagent_containers/food/snacks/blueberry_gum
+ name = "blueberry gum"
+ icon = 'GainStation13/icons/obj/gum.dmi'
+ icon_state = "gum_wrapped"
+ desc = "Doesn't cause anything more than some discoloration... probably."
+ trash = /obj/item/trash/blueberry_gum
+ list_reagents = list(/datum/reagent/blueberry_juice = 50)
+ bitesize = 5
+ filling_color = "#001aff"
+ tastes = list("blueberry gum" = 1)
+ foodtype = FRUIT
+ price = 5
+
+//blueberry gum trash
+
+/obj/item/trash/blueberry_gum
+ name = "chewed gum"
+ icon = 'GainStation13/icons/obj/gum.dmi'
+ icon_state = "gum_chewed"
+
+// nutriment pump turbo
+
+/obj/item/autosurgeon/nutripump_turbo
+ desc = "A single use autosurgeon that contains a turbo version of the nutriment pump. A screwdriver can be used to remove it, but implants can't be placed back in."
+ uses = 1
+ starting_organ = /obj/item/organ/cyberimp/chest/nutriment/turbo
+
+/obj/item/autosurgeon/fat_mobility
+ desc = "A single use autosurgeon that contains a mobility nanite core. A screwdriver can be used to remove it, but implants can't be placed back in."
+ uses = 1
+ starting_organ = /obj/item/organ/cyberimp/chest/mobility
+
+//fast food restaurant - closed / open signs
+/obj/item/holosign_creator/restaurant
+ name = "Holosign Projector - Restaurant Adverts"
+ desc = "A holo-sign maker, used for placing signs that advertises the local fast food restaurant."
+ icon = 'GainStation13/icons/obj/holosign.dmi'
+ icon_state = "holo_fastfood"
+ holosign_type = /obj/structure/holosign/restaurant
+ creation_time = 0
+ max_signs = 6
+
+/obj/item/holosign_creator/closed
+ name = "Holosign Projector - Closing Sign"
+ desc = "A holo-sign maker, used for placing signs that inform people of a location being closed off."
+ icon = 'GainStation13/icons/obj/holosign.dmi'
+ icon_state = "holo_closed"
+ holosign_type = /obj/structure/holosign/barrier/closed
+ creation_time = 0
+ max_signs = 6
+
+//holosigns used by the holosign creators
+/obj/structure/holosign/restaurant
+ name = "The Restaurant is OPEN! Come visit!"
+ desc = "A holographic projector that displays a sign advertising the nearby Fast Food Restaurant."
+ icon = 'GainStation13/icons/obj/holosign.dmi'
+ icon_state = "holosign_ad"
+
+/obj/structure/holosign/barrier/closed
+ name = "This Location is Closed!"
+ desc = "A short holographic barrier used to close off areas. Can be passed by walking."
+ icon = 'GainStation13/icons/obj/holosign.dmi'
+ icon_state = "holosign_closed"
+
+//ID for fastfood wagies so they can use the tele
+/obj/item/card/id/silver/restaurant
+ name = "silver identification card"
+ desc = "A silver ID, given to the GATO's fast food restaurant workers. Doesn't grant much besides teleporter access."
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_TELEPORTER)
+
+//gato decal, should be moved elsewhere tbh
+/obj/effect/decal/big_gato //96x96 px sprite
+ name = "GATO"
+ desc = "Your employer! Probably."
+ icon = 'GainStation13/icons/turf/96x96.dmi'
+ icon_state = "gato"
+ layer = ABOVE_OPEN_TURF_LAYER
+ pixel_x = -32
+ pixel_y = -32
+
+/obj/effect/decal/medium_gato //64x64 px sprite
+ name = "GATO"
+ desc = "Your employer! Probably."
+ icon = 'GainStation13/icons/turf/64x64.dmi'
+ icon_state = "gato"
+ layer = ABOVE_OPEN_TURF_LAYER
+ pixel_y = -16
+ pixel_x = -16
+
+
+//collar voice modulators, based on cow/pig masks
+
+/obj/item/clothing/mask/pig/gag //this one only lets you say "oink" and similar
+ name = "Voice modulator - pig"
+ desc = "A small gag, used to silence people in a rather 'original' way."
+ icon_state = "ballgag"
+ item_state = "ballgag"
+ flags_inv = HIDEFACE
+ clothing_flags = VOICEBOX_TOGGLABLE
+ w_class = WEIGHT_CLASS_SMALL
+ modifies_speech = TRUE
+
+/obj/item/clothing/mask/cowmask/gag //this one only lets you say "moo" and similar
+ name = "Voice modulator - cow"
+ desc = "A small gag, used to silence people in a rather 'original' way."
+ icon = 'icons/obj/clothing/masks.dmi'
+ icon_state = "ballgag"
+ item_state = "ballgag"
+ flags_inv = HIDEFACE
+
+/obj/item/service_sign
+ name = "service sign"
+ desc = "A sign that reads 'closed'"
+ icon = 'GainStation13/icons/obj/service_sign.dmi'
+ icon_state = "sign_closed"
+
+/obj/item/service_sign/attack_self()
+ if(icon_state == "sign_closed")
+ icon_state = "sign_open"
+ desc = "A sign that reads 'open'"
+ else
+ icon_state = "sign_closed"
+ desc = "A sign that reads 'closed'"
+
+/obj/item/trash/odd_disk
+ name = "odd disk"
+ icon = 'icons/obj/module.dmi'
+ icon_state = "datadisk0"
+ desc = "A dusty disk, desconstruction will be needed to recover data."
diff --git a/GainStation13/code/obj/items/pride_pins.dm b/GainStation13/code/obj/items/pride_pins.dm
new file mode 100644
index 0000000000..40e2a050fd
--- /dev/null
+++ b/GainStation13/code/obj/items/pride_pins.dm
@@ -0,0 +1,47 @@
+/obj/item/clothing/accessory/pride_pin
+ name = "pride pin"
+ desc = "A pride pin."
+ icon_state = "pride"
+ item_color = "pride"
+
+/obj/item/clothing/accessory/pride_pin/bi
+ name = "bisexual pride pin"
+ desc = "A bisexual pride pin."
+ icon_state = "pride_bi"
+ item_color = "pride_bi"
+
+/obj/item/clothing/accessory/pride_pin/trans
+ name = "transgender pride pin"
+ desc = "A transgender pride pin."
+ icon_state = "pride_trans"
+ item_color = "pride_trans"
+
+/obj/item/clothing/accessory/pride_pin/ace
+ name = "asexual pride pin"
+ desc = "A asexual pride pin."
+ icon_state = "pride_ace"
+ item_color = "pride_ace"
+
+/obj/item/clothing/accessory/pride_pin/enby
+ name = "non-binary pride pin"
+ desc = "A non-binary pride pin."
+ icon_state = "pride_enby"
+ item_color = "pride_enby"
+
+/obj/item/clothing/accessory/pride_pin/pan
+ name = "pansexual pride pin"
+ desc = "A pansexual pride pin."
+ icon_state = "pride_pan"
+ item_color = "pride_pan"
+
+/obj/item/clothing/accessory/pride_pin/lesbian
+ name = "lesbian pride pin"
+ desc = "A lesbian pride pin."
+ icon_state = "pride_lesbian"
+ item_color = "pride_lesbian"
+
+/obj/item/clothing/accessory/pride_pin/intersex
+ name = "intersex pride pin"
+ desc = "A intersex pride pin."
+ icon_state = "pride_intersex"
+ item_color = "pride_intersex"
diff --git a/GainStation13/code/obj/items/sensors/weight_infared.dm b/GainStation13/code/obj/items/sensors/weight_infared.dm
new file mode 100644
index 0000000000..b5883cfd51
--- /dev/null
+++ b/GainStation13/code/obj/items/sensors/weight_infared.dm
@@ -0,0 +1,79 @@
+/obj/item/assembly/infra/fat
+ name = "fatness infrared emitter"
+ desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted. This one checks if the person tripping it is above or below a certain level of fatness."
+
+ var/fatness_to_trigger = 0
+ var/trigger_below = FALSE
+
+/obj/item/assembly/infra/fat/examine(mob/user)
+ . = ..()
+ . += "The infrared trigger is set to trigger when the target is [trigger_below?"above":"below"] being [get_fatness_level_name(fatness_to_trigger)]."
+
+/obj/item/assembly/infra/fat/ui_interact(mob/user)//TODO: change this this to the wire control panel
+ if(!is_secured(user))
+ return
+
+ user.set_machine(src)
+ var/dat = "Fatness Infrared Laser"
+ dat += "
Status: [on ? "On" : "Off"]"
+ dat += "
Visibility: [visible ? "Visible" : "Invisible"]"
+ dat += "
Fatness level to trigger:[get_fatness_level_name(fatness_to_trigger)]"
+ dat += "
Trigger above or below the target fatness level:[trigger_below ? "Below" : "Above"]"
+ dat += "
Refresh"
+ dat += "
Close"
+ user << browse(dat, "window=infra")
+ onclose(user, "infra")
+ return
+
+/obj/item/assembly/infra/fat/Topic(href, href_list)
+ ..()
+ if(href_list["trigger_below"])
+ trigger_below = !(trigger_below)
+ update_icon()
+ refreshBeam()
+ if(href_list["fatness_to_trigger"])
+ var/fatness_type = input(usr,
+ "What level of fatness do you wish to alert above/under at?",
+ src, "None") as null|anything in list(
+ "None", "Fat", "Fatter", "Very Fat", "Obese", "Morbidly Obese", "Extremely Obese", "Barely Mobile", "Immobile", "Blob")
+ if(!fatness_type)
+ return
+
+ var/fatness_amount = 0
+ switch(fatness_type)
+ if("Fat")
+ fatness_amount = FATNESS_LEVEL_FAT
+ if("Fatter")
+ fatness_amount = FATNESS_LEVEL_FATTER
+ if("Very Fat")
+ fatness_amount = FATNESS_LEVEL_VERYFAT
+ if("Obese")
+ fatness_amount = FATNESS_LEVEL_OBESE
+ if("Morbidly Obese")
+ fatness_amount = FATNESS_LEVEL_MORBIDLY_OBESE
+ if("Extremely Obese")
+ fatness_amount = FATNESS_LEVEL_EXTREMELY_OBESE
+ if("Barely Mobile")
+ fatness_amount = FATNESS_LEVEL_BARELYMOBILE
+ if("Immobile")
+ fatness_amount = FATNESS_LEVEL_IMMOBILE
+ if("Blob")
+ fatness_amount = FATNESS_LEVEL_BLOB
+
+ fatness_to_trigger = fatness_amount
+ update_icon()
+ refreshBeam()
+
+/obj/item/assembly/infra/fat/trigger_beam(atom/movable/AM, turf/location)
+ var/mob/living/carbon/crossed_fatty = AM
+ if(!istype(crossed_fatty))
+ return FALSE
+
+ if(trigger_below && (crossed_fatty.fatness >= fatness_to_trigger))
+ return FALSE
+
+ if(!trigger_below && (crossed_fatty.fatness < fatness_to_trigger))
+ return FALSE
+
+ return ..() // I love using inheritence so much.
+
diff --git a/GainStation13/code/obj/structure/airlock.dm b/GainStation13/code/obj/structure/airlock.dm
new file mode 100644
index 0000000000..54ec3e29a2
--- /dev/null
+++ b/GainStation13/code/obj/structure/airlock.dm
@@ -0,0 +1,37 @@
+/obj/machinery/door
+ var/fatness_to_check = 0
+
+ var/check_fatness = FALSE
+ var/check_fatness_below = FALSE
+
+/obj/machinery/door/proc/change_fatness_to_check(mob/user)
+ var/fatness_type = input(usr,
+ "What level of fatness do you wish to alert above/under at?",
+ src, "None") as null|anything in list(
+ "None", "Fat", "Fatter", "Very Fat", "Obese", "Morbidly Obese", "Extremely Obese", "Barely Mobile", "Immobile", "Blob")
+ if(!fatness_type)
+ return FALSE
+
+ var/fatness_amount = 0
+ switch(fatness_type)
+ if("Fat")
+ fatness_amount = FATNESS_LEVEL_FAT
+ if("Fatter")
+ fatness_amount = FATNESS_LEVEL_FATTER
+ if("Very Fat")
+ fatness_amount = FATNESS_LEVEL_VERYFAT
+ if("Obese")
+ fatness_amount = FATNESS_LEVEL_OBESE
+ if("Morbidly Obese")
+ fatness_amount = FATNESS_LEVEL_MORBIDLY_OBESE
+ if("Extremely Obese")
+ fatness_amount = FATNESS_LEVEL_EXTREMELY_OBESE
+ if("Barely Mobile")
+ fatness_amount = FATNESS_LEVEL_BARELYMOBILE
+ if("Immobile")
+ fatness_amount = FATNESS_LEVEL_IMMOBILE
+ if("Blob")
+ fatness_amount = FATNESS_LEVEL_BLOB
+
+ fatness_to_check = fatness_amount
+ return TRUE
diff --git a/GainStation13/code/obj/structure/calorite_doors.dm b/GainStation13/code/obj/structure/calorite_doors.dm
new file mode 100644
index 0000000000..b228257b29
--- /dev/null
+++ b/GainStation13/code/obj/structure/calorite_doors.dm
@@ -0,0 +1,18 @@
+/obj/structure/mineral_door/calorite //GS13
+ name = "calorite door"
+ icon = 'GainStation13/icons/obj/structure/calorite_door.dmi'
+ icon_state = "calorite"
+ sheetType = /obj/item/stack/sheet/mineral/calorite
+ max_integrity = 200
+ light_range = 1
+ // Sets it open by default
+ state = TRUE
+ density = FALSE
+
+// If you ever want to make any door like this, just simply add the component like this :3
+/obj/structure/mineral_door/calorite/Initialize(mapload)
+ . = ..()
+ AddComponent(/datum/component/fattening_door)
+
+ update_icon() // Updates the sprite when spawned in cause it's closed by default.
+
diff --git a/GainStation13/code/obj/structure/candylight.dm b/GainStation13/code/obj/structure/candylight.dm
new file mode 100644
index 0000000000..220b70733b
--- /dev/null
+++ b/GainStation13/code/obj/structure/candylight.dm
@@ -0,0 +1,9 @@
+/obj/structure/tree/candylight //GS13
+ name = "Peppermint Light"
+ desc = "A light source that's made out of a peppermint tree."
+ icon = 'GainStation13/icons/obj/gslight.dmi'
+ icon_state = "candylight"
+ max_integrity = 500
+ light_color = "#a5cfc5" //testing out my copy cat skills. -Metussi
+ light_range = 3
+ anchored = 1
diff --git a/GainStation13/code/obj/structure/fountain.dm b/GainStation13/code/obj/structure/fountain.dm
new file mode 100644
index 0000000000..b76232486c
--- /dev/null
+++ b/GainStation13/code/obj/structure/fountain.dm
@@ -0,0 +1,43 @@
+
+/obj/structure/cursedfatfountain
+ name = "Strange fountain"
+ desc = "An odd fountain, sparking with foreign magic."
+ icon = 'GainStation13/icons/obj/cursed_fountain.dmi'
+ icon_state = "full"
+ anchored = TRUE
+ density = TRUE
+ var/curse_given = 0
+
+/mob/living
+ var/cursed_fat = 0 //decides whether the user is cursed at all (also makes for a fun admin switch)
+ var/fattening_steps_left = 0 //decides on the lenght of the curse
+
+/obj/structure/cursedfatfountain/attack_hand(mob/living/user)
+ . = ..()
+ if(.)
+ return
+ if(curse_given == 1)
+ to_chat(user, "The fountain has dried up.")
+ icon_state = "empty"
+ return
+ if (ishuman(user) && user.has_dna())
+ user.cursed_fat = 1
+ user.fattening_steps_left += 2000
+ icon_state = "empty"
+ to_chat(user, "The glittering orange liquid disappears instantly as you touch it. You feel a strange, warm sensation inside, growing stronger the more you move...")
+ curse_given = 1
+
+// /obj/structure/cursedfatfountain/update_icon()
+// if(last_process + time_between_uses > world.time)
+// icon_state = "full"
+// else
+// icon_state = "empty"
+
+/mob/living/carbon/Move(NewLoc, direct)
+ . = ..()
+ if(cursed_fat == 1)
+ fattening_steps_left -= 1
+ adjust_fatness(20, FATTENING_TYPE_MAGIC)
+
+ if(fattening_steps_left <= 0)
+ cursed_fat = 0
diff --git a/GainStation13/code/obj/structure/gsstatues.dm b/GainStation13/code/obj/structure/gsstatues.dm
new file mode 100644
index 0000000000..6b87a96416
--- /dev/null
+++ b/GainStation13/code/obj/structure/gsstatues.dm
@@ -0,0 +1,6 @@
+/obj/structure/statue/fatso
+ name = "statue of a forgotten god"
+ desc = "A statue of a long forgotten god, at least on earth."
+ icon = 'GainStation13/icons/obj/structure/statues.dmi'
+ icon_state = "fattha_statue"
+ anchored = TRUE
\ No newline at end of file
diff --git a/GainStation13/code/obj/structure/scale.dm b/GainStation13/code/obj/structure/scale.dm
new file mode 100644
index 0000000000..1ef881d23f
--- /dev/null
+++ b/GainStation13/code/obj/structure/scale.dm
@@ -0,0 +1,81 @@
+/obj/structure/scale
+ name = "weighing scale"
+ desc = "You can weigh yourself with this."
+ icon = 'GainStation13/icons/obj/scale.dmi'
+ icon_state = "scale"
+ anchored = TRUE
+ resistance_flags = NONE
+ max_integrity = 250
+ integrity_failure = 25
+ var/buildstacktype = /obj/item/stack/sheet/metal
+ var/buildstackamount = 3
+ layer = OBJ_LAYER
+ //stores the weight of the last person to step on in Lbs
+ var/lastreading = 0
+ //the conversion ratio for how much a point of fatness weighs on a 6' person
+ var/fatnessToWeight = 0.25
+
+/obj/structure/scale/deconstruct()
+ // If we have materials, and don't have the NOCONSTRUCT flag
+ if(buildstacktype && (!(flags_1 & NODECONSTRUCT_1)))
+ new buildstacktype(loc,buildstackamount)
+ ..()
+
+/obj/structure/scale/attackby(obj/item/W, mob/user, params)
+ if(W.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1))
+ W.play_tool_sound(src)
+ deconstruct()
+ else if(istype(W, /obj/item/assembly/shock_kit))
+ if(!user.temporarilyRemoveItemFromInventory(W))
+ return
+ var/obj/item/assembly/shock_kit/SK = W
+ var/obj/structure/chair/e_chair/E = new /obj/structure/chair/e_chair(src.loc)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ E.setDir(dir)
+ E.part = SK
+ SK.forceMove(E)
+ SK.master = E
+ qdel(src)
+ else
+ return ..()
+
+/obj/structure/scale/examine(mob/user)
+ . = ..()
+ . += "Its last reading was: [src.lastreading]Lbs"
+ . += "It's held together by a couple of bolts."
+
+/obj/structure/scale/proc/weighEffect(mob/living/carbon/human/fatty)
+ to_chat(fatty, "You weigh yourself.")
+ to_chat(fatty, "The numbers on the screen tick up and eventually settle on:")
+ //The appearance of the numbers changes with the fat level of the character
+ if (HAS_TRAIT(fatty, TRAIT_BLOB))
+ to_chat(fatty, "[round(src.lastreading/2000, 0.01)]TONS!!!")
+
+ else if (HAS_TRAIT(fatty, TRAIT_IMMOBILE))
+ to_chat(fatty, "[src.lastreading]Lbs!")
+
+ else if(HAS_TRAIT(fatty, TRAIT_OBESE) || HAS_TRAIT(fatty, TRAIT_MORBIDLYOBESE))
+ to_chat(fatty, "[src.lastreading]Lbs!")
+
+ else
+ to_chat(fatty, "[src.lastreading]Lbs.")
+
+ visible_message("The numbers on the screen read out: [fatty] has a BFI of [fatty.fatness].")
+
+/obj/structure/scale/Crossed(AM as mob|obj)
+ if(isturf(loc))
+ //need to be sure the thing that just crossed the scale is human
+ if(ishuman(AM))
+ var/mob/living/carbon/human/HM = AM
+ if(!(HM.movement_type & FLYING))
+ weighperson(HM)
+
+/obj/structure/scale/proc/weighperson(mob/living/carbon/human/fatty)
+ src.lastreading = fatty.calculate_weight_in_pounds()
+ weighEffect(fatty)
+ visible_message("[fatty] weighs themselves.")
+ visible_message("The numbers on the screen settle on: [src.lastreading]Lbs.")
+ visible_message("The numbers on the screen read out: [fatty] has a BFI of [fatty.fatness].")
+
+/mob/living/carbon/proc/calculate_weight_in_pounds()
+ return round((140 + (fatness*FATNESS_TO_WEIGHT_RATIO))*(size_multiplier**2)*((dna.features["taur"] != "None") ? 2.5: 1))
diff --git a/GainStation13/code/obj/weapons/alter_rays.dm b/GainStation13/code/obj/weapons/alter_rays.dm
new file mode 100644
index 0000000000..76245e1bec
--- /dev/null
+++ b/GainStation13/code/obj/weapons/alter_rays.dm
@@ -0,0 +1,171 @@
+/////GS13 - rayguns for metabolism and breasts/ass manipulation
+
+//this is pretty wonky code, but ig it works
+
+/obj/item/gun/energy/laser/alter_ray
+ name = "alter-ray"
+ icon = 'icons/obj/guns/energy.dmi'
+ icon_state = "lasernew"
+ desc = "This weapon is capable of altering one's body capabilities."
+ item_state = null
+ selfcharge = EGUN_SELFCHARGE
+ charge_delay = 5
+ ammo_x_offset = 2
+ clumsy_check = 1
+
+/obj/item/gun/energy/laser/alter_ray/gainrate
+ name = "AL-T-Ray: Metabolism"
+ desc = "This weapon is capable of altering one's body capabilities. This model appears to be capable of altering one's weight gain and loss rate by 10%."
+ ammo_type = list(/obj/item/ammo_casing/energy/laser/gainrate_decrease, /obj/item/ammo_casing/energy/laser/gainrate_increase, /obj/item/ammo_casing/energy/laser/lossrate_decrease, /obj/item/ammo_casing/energy/laser/lossrate_increase)
+
+
+// /obj/item/gun/energy/laser/alter_ray/assbreasts //genius name, I know
+// name = "AL-T-Ray: Voluptousness"
+// desc = "This weapon is capable of altering one's body capabilities. This model appears to be capable of altering the size's of one's breasts or buttocks."
+// ammo_type = list(/obj/item/ammo_casing/energy/laser/shrinkray, /obj/item/ammo_casing/energy/laser/growthray)
+
+
+/obj/item/projectile/alter_ray
+ name = "sizeray beam"
+ icon_state = "omnilaser"
+ hitsound = null
+ damage = 0
+ damage_type = STAMINA
+ flag = "laser"
+ pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ ricochets_max = 50
+ ricochet_chance = 80
+ is_reflectable = TRUE
+ var/ratechange_amount = 0.1
+
+
+//projectile biz
+
+/obj/item/projectile/alter_ray/gainrate_decrease
+ icon_state="bluelaser"
+
+/obj/item/projectile/alter_ray/gainrate_increase
+ icon_state="laser"
+
+/obj/item/projectile/alter_ray/lossrate_decrease
+ icon_state="bluelaser"
+
+/obj/item/projectile/alter_ray/lossrate_increase
+ icon_state="laser"
+
+// /obj/item/projectile/alter_ray/breast_decrease
+// icon_state="bluelaser"
+
+// /obj/item/projectile/alter_ray/breast_increase
+// icon_state="laser"
+
+// /obj/item/projectile/alter_ray/butt_decrease
+// icon_state="bluelaser"
+
+// /obj/item/projectile/alter_ray/butt_increase
+// icon_state="laser"
+
+//laser hitting / changing code
+
+//wg rate increase
+/obj/item/projectile/alter_ray/gainrate_increase/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+
+ if(iscarbon(gainer))
+ if(gainer.weight_gain_rate <= 3)
+ gainer.weight_gain_rate += ratechange_amount
+ return TRUE
+ return FALSE
+
+ return FALSE
+
+
+//wg rate decrease
+/obj/item/projectile/alter_ray/gainrate_decrease/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+
+ if(iscarbon(gainer))
+ if(gainer.weight_gain_rate >= 0.11)
+ gainer.weight_gain_rate -= ratechange_amount
+ return TRUE
+ if(gainer.weight_gain_rate <= 0.1)
+ return FALSE
+
+ return FALSE
+
+//wl rate increase
+/obj/item/projectile/alter_ray/lossrate_increase/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+
+ if(iscarbon(gainer))
+ if(gainer.weight_loss_rate <= 3)
+ gainer.weight_loss_rate += ratechange_amount
+ return TRUE
+ return FALSE
+
+ return FALSE
+
+//wl rate decrease
+/obj/item/projectile/alter_ray/lossrate_decrease/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+
+ if(iscarbon(gainer))
+ if(gainer.weight_loss_rate >= 0.11)
+ gainer.weight_loss_rate -= ratechange_amount
+ return TRUE
+ if(gainer.weight_loss_rate <= 0.1)
+ return FALSE
+
+ return FALSE
+
+//ammo casings - these are needed to allow guns to switch between firing modes
+/obj/item/ammo_casing/energy/laser/gainrate_increase
+ projectile_type = /obj/item/projectile/alter_ray/gainrate_increase
+ select_name = "Weight Gain Increase"
+
+/obj/item/ammo_casing/energy/laser/gainrate_decrease
+ projectile_type = /obj/item/projectile/alter_ray/gainrate_decrease
+ select_name = "Weight Gain Decrease"
+
+/obj/item/ammo_casing/energy/laser/lossrate_increase
+ projectile_type = /obj/item/projectile/alter_ray/lossrate_increase
+ select_name = "Weight Loss Increase"
+
+/obj/item/ammo_casing/energy/laser/lossrate_decrease
+ projectile_type = /obj/item/projectile/alter_ray/lossrate_decrease
+ select_name = "Weight Loss Decrease"
+
+
+
+//ALTRay for making someone gain from weight loss
+
+/obj/item/gun/energy/laser/alter_ray/noloss
+ name = "AL-T-Ray: Reverser"
+ desc = "This weapon is capable of altering one's body capabilities. This one reverse's ones body functions, to make it so weight loss results in weight gain."
+ ammo_type = list(/obj/item/ammo_casing/energy/laser/lossrate_reverse)
+
+/obj/item/ammo_casing/energy/laser/lossrate_reverse
+ projectile_type = /obj/item/projectile/alter_ray/lossrate_reverse
+ select_name = "Weight Loss Reverse"
+
+/obj/item/projectile/alter_ray/lossrate_reverse
+ ratechange_amount = -2
+ icon_state="laser"
+
+/obj/item/projectile/alter_ray/lossrate_reverse/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+
+ if(iscarbon(gainer))
+ gainer.weight_loss_rate = ratechange_amount
+ return TRUE
+
diff --git a/GainStation13/code/obj/weapons/fatbeam.dm b/GainStation13/code/obj/weapons/fatbeam.dm
new file mode 100644
index 0000000000..1b01381f4a
--- /dev/null
+++ b/GainStation13/code/obj/weapons/fatbeam.dm
@@ -0,0 +1,126 @@
+/obj/item/gun/fatbeam // GS13
+ name = "Fatbeam Gun"
+ desc = "Apparently used to treat malnourished patients from a safe distance... But we all know what it will truly be used for."
+ icon = 'icons/obj/fatbeam.dmi'
+ icon_state = "fatbeam"
+ item_state = "fatbeam"
+ w_class = WEIGHT_CLASS_NORMAL
+
+ var/mob/living/current_target
+ var/last_check = 0
+ var/check_delay = 10 //Check los as often as possible, max resolution is SSobj tick though
+ var/max_range = 8
+ var/active = 0
+ var/datum/beam/current_beam = null
+ var/mounted = 0 //Denotes if this is a handheld or mounted version
+
+ weapon_weight = WEAPON_MEDIUM
+
+/obj/item/gun/fatbeam/Initialize(mapload)
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
+/obj/item/gun/fatbeam/Destroy(mob/user)
+ STOP_PROCESSING(SSobj, src)
+ LoseTarget()
+ return ..()
+
+/obj/item/gun/fatbeam/dropped(mob/user)
+ ..()
+ LoseTarget()
+
+/obj/item/gun/fatbeam/equipped(mob/user)
+ ..()
+ LoseTarget()
+
+/obj/item/gun/fatbeam/proc/LoseTarget()
+ if(active)
+ qdel(current_beam)
+ current_beam = null
+ active = 0
+ on_beam_release(current_target)
+ current_target = null
+
+/obj/item/gun/fatbeam/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
+ if(isliving(user))
+ add_fingerprint(user)
+
+ if(current_target)
+ LoseTarget()
+ if(!isliving(target))
+ return
+
+ current_target = target
+ active = TRUE
+ current_beam = new(user,current_target,time=6000,beam_icon_state="fatbeam",btype=/obj/effect/ebeam/medical)
+ INVOKE_ASYNC(current_beam, TYPE_PROC_REF(/datum/beam,Start))
+
+ SSblackbox.record_feedback("tally", "gun_fired", 1, type)
+
+/obj/item/gun/fatbeam/process()
+
+ var/source = loc
+ if(!mounted && !isliving(source))
+ LoseTarget()
+ return
+
+ if(!current_target)
+ LoseTarget()
+ return
+
+ if(world.time <= last_check+check_delay)
+ return
+
+ last_check = world.time
+
+ if(get_dist(source, current_target)>max_range || !los_check(source, current_target))
+ LoseTarget()
+ if(isliving(source))
+ to_chat(source, "You lose control of the beam!")
+ return
+
+ if(current_target)
+ on_beam_tick(current_target)
+
+/obj/item/gun/fatbeam/proc/los_check(atom/movable/user, mob/target)
+ var/turf/user_turf = user.loc
+ if(mounted)
+ user_turf = get_turf(user)
+ else if(!istype(user_turf))
+ return FALSE
+ var/obj/dummy = new(user_turf)
+ dummy.pass_flags |= PASSTABLE|PASSGLASS|PASSGRILLE //Grille/Glass so it can be used through common windows
+ for(var/turf/turf in getline(user_turf,target))
+ if(mounted && turf == user_turf)
+ continue //Mechs are dense and thus fail the check
+ if(turf.density)
+ qdel(dummy)
+ return FALSE
+ for(var/atom/movable/AM in turf)
+ if(!AM.CanPass(dummy,turf,1))
+ qdel(dummy)
+ return FALSE
+ for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams!
+ if(B.owner.origin != current_beam.origin)
+ explosion(B.loc,0,1,3,4)
+ qdel(dummy)
+ return FALSE
+ qdel(dummy)
+ return TRUE
+
+/obj/item/gun/fatbeam/proc/on_beam_hit(var/mob/living/target)
+ return
+
+/obj/item/gun/fatbeam/proc/on_beam_tick(var/mob/living/target)
+ if(target.health != target.maxHealth)
+ new /obj/effect/temp_visual/heal(get_turf(target), "#fabb62")
+ if(target?.client?.prefs?.weight_gain_weapons)
+ target.nutrition += 50
+ return
+
+/obj/item/gun/fatbeam/proc/on_beam_release(var/mob/living/target)
+ return
+
+/obj/effect/ebeam/medical
+ name = "fattening beam"
+
diff --git a/GainStation13/code/obj/weapons/fatoray.dm b/GainStation13/code/obj/weapons/fatoray.dm
new file mode 100644
index 0000000000..77aaf31356
--- /dev/null
+++ b/GainStation13/code/obj/weapons/fatoray.dm
@@ -0,0 +1,142 @@
+/////GS13 - fattening rayguns and ranged weapons
+
+///The base fatoray
+/obj/item/gun/energy/fatoray
+ name = "Fatoray"
+ desc = "An energy gun that fattens up anyone it hits."
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ lefthand_file = 'GainStation13/icons/obj/guns_lefthand.dmi'
+ righthand_file = 'GainStation13/icons/obj/guns_righthand.dmi'
+ icon_state = "fatoray"
+ item_state = "fatoray"
+ pin = /obj/item/firing_pin
+ fire_sound = 'sound/weapons/plasma_cutter.ogg'
+ ammo_type = list(/obj/item/ammo_casing/energy/fattening)
+
+/obj/item/ammo_casing/energy/fattening
+ name = "fattening weapon lens"
+ select_name = "fatten"
+ projectile_type = /obj/item/projectile/beam/fattening
+
+///The base projectile used by the fatoray
+/obj/item/projectile/beam/fattening
+ name = "fat energy"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "ray"
+ ricochets_max = 50
+ ricochet_chance = 80
+ hitsound = 'sound/weapons/sear.ogg'
+ hitsound_wall = 'sound/weapons/effects/searwall.ogg'
+ damage = 0
+ eyeblur = 0
+ damage_type = BURN
+ flag = "energy"
+ light_range = 2
+ light_color = LIGHT_COLOR_ORANGE
+ ///How much fat is added to the target mob?
+ var/fat_added = 100
+
+
+
+////// Fatoray - cannon variant, strong but can be charged
+
+/obj/item/gun/energy/fatoray/cannon
+ name = "Fatoray Cannon"
+ desc = "An energy gun that fattens up anyone it hits. This version functions as a glass cannon of some sorts. It cannot be recharged."
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_cannon"
+ recoil = 3
+ can_charge = 0
+ slowdown = 1
+ pin = /obj/item/firing_pin
+ // charge_sections = 3
+ weapon_weight = WEAPON_HEAVY
+ ammo_type = list(/obj/item/ammo_casing/energy/fattening/cannon)
+
+
+/obj/item/ammo_casing/energy/fattening/cannon
+ name = "one-shot fattening weapon lens"
+ select_name = "fatten"
+ e_cost = 100
+ projectile_type = /obj/item/projectile/beam/fattening/cannon
+
+/obj/item/projectile/beam/fattening/cannon
+ name = "fat energy"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "cannon_ray"
+ ///How much fat is added to the target mob?
+ fat_added = 1000
+
+
+
+////////////////////////////////////////////////////////////////////
+////////FATORAYS THAT CAN BE MADE BY LATHES OR RESEARCHED///////////
+////////////////////////////////////////////////////////////////////
+
+///Weaker version of fatoray
+/obj/item/gun/energy/fatoray/weak
+ name = "Basic Fatoray"
+ desc = "An energy gun that fattens up anyone it hits. This version is considerably weaker than its original counterpart, the technology behind it seemingly still not perfected."
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_weak"
+ pin = /obj/item/firing_pin
+ ammo_type = list(/obj/item/ammo_casing/energy/fattening/weak)
+
+/obj/item/ammo_casing/energy/fattening/weak
+ name = "budget fattening weapon lens"
+ select_name = "fatten"
+ projectile_type = /obj/item/projectile/beam/fattening/weak
+
+///The base projectile used by the fatoray
+/obj/item/projectile/beam/fattening/weak
+ name = "fat energy"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "ray"
+ ///How much fat is added to the target mob?
+ fat_added = 50
+
+///////////////////////////////////////////////////
+
+///Single shot glass cannon fatoray
+/obj/item/gun/energy/fatoray/cannon_weak
+ name = "Basic Fatoray Cannon"
+ desc = "An energy gun that fattens up anyone it hits. This version functions as a glass cannon of some sorts. It cannot be recharged."
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "fatoray_cannon_weak"
+ can_charge = 0
+ recoil = 3
+ slowdown = 1
+ pin = /obj/item/firing_pin
+ // charge_sections = 3
+ weapon_weight = WEAPON_HEAVY
+ ammo_type = list(/obj/item/ammo_casing/energy/fattening/cannon_weak)
+
+/obj/item/ammo_casing/energy/fattening/cannon_weak
+ name = "one-shot fattening weapon lens"
+ select_name = "fatten"
+ e_cost = 300
+ projectile_type = /obj/item/projectile/beam/fattening/cannon_weak
+
+/obj/item/projectile/beam/fattening/cannon_weak
+ name = "fat energy"
+ icon = 'GainStation13/icons/obj/fatoray.dmi'
+ icon_state = "cannon_ray"
+ ///How much fat is added to the target mob?
+ fat_added = 500
+
+///////////////////////////////////////
+//////PROJECTILE MECHANICS/////////////
+///////////////////////////////////////
+
+
+/obj/item/projectile/beam/fattening/on_hit(atom/target, blocked)
+ . = ..()
+
+ var/mob/living/carbon/gainer = target
+ if(!iscarbon(gainer))
+ return FALSE
+
+ if(!gainer.adjust_fatness(fat_added, FATTENING_TYPE_WEAPON))
+ return FALSE
+
+ return TRUE
diff --git a/GainStation13/code/obj/weapons/feeder_ebow.dm b/GainStation13/code/obj/weapons/feeder_ebow.dm
new file mode 100644
index 0000000000..7ade7a20c3
--- /dev/null
+++ b/GainStation13/code/obj/weapons/feeder_ebow.dm
@@ -0,0 +1,25 @@
+/obj/item/gun/energy/kinetic_accelerator/crossbow/feeder
+ name = "feeder's mini energy crossbow"
+ desc = "a modified version of the standard mini energy crossbow, designed to fatten up a target while incapacitating them."
+ icon_state = "crossbow_halloween"
+ item_state = "crossbow"
+ ammo_type = list(/obj/item/ammo_casing/energy/bolt/fattening)
+
+/obj/item/ammo_casing/energy/bolt/fattening
+ projectile_type = /obj/item/projectile/energy/bolt/fattening
+
+/obj/item/projectile/energy/bolt/fattening
+ damage = 0
+
+/obj/item/projectile/energy/bolt/fattening/Initialize(mapload)
+ . = ..()
+
+/obj/item/projectile/energy/bolt/fattening/on_hit(atom/target, blocked)
+ . = ..()
+ var/mob/living/carbon/target_mob = target
+ if(!istype(target_mob) || (blocked == 100))
+ return
+
+ target_mob.reagents.add_reagent(/datum/reagent/consumable/lipoifier, 2)
+
+
diff --git a/GainStation13/code/structures/trapped_items.dm b/GainStation13/code/structures/trapped_items.dm
new file mode 100644
index 0000000000..24572a7baf
--- /dev/null
+++ b/GainStation13/code/structures/trapped_items.dm
@@ -0,0 +1,39 @@
+/obj/structure/fat_mirror
+ name = "mirror" //Exact same text. Good luck.
+ desc = "Mirror mirror on the wall, who's the most robust of them all?"
+ icon = 'icons/obj/watercloset.dmi'
+ icon_state = "mirror"
+ density = FALSE
+ anchored = TRUE
+ /// Does the item delete itself after being "used?"
+ var/single_use = TRUE
+
+/obj/structure/fat_mirror/attack_hand(mob/user)
+ . = ..()
+ if(.)
+ return
+
+ var/mob/living/carbon/looker = user
+ if(!istype(looker) || !Adjacent(looker))
+ return
+
+ make_fat(looker)
+ return TRUE
+
+/obj/structure/fat_mirror/proc/make_fat(mob/living/carbon/looker)
+ if(!istype(looker) || !looker.check_weight_prefs(FATTENING_TYPE_MAGIC))
+ return FALSE
+
+ var/fat_to_add = looker.fatness_until_next_level()
+ if(!fat_to_add)
+ fat_to_add = FATNESS_LEVEL_BLOB // If someone is a blob, just add the amount of fatness needed to be a blob in the first place.
+
+ fat_to_add += 25 // a little buffer so they don't instantly burn it off.
+ looker.adjust_fatness(fat_to_add, FATTENING_TYPE_MAGIC, TRUE)
+ to_chat(looker, span_warning("Taking a look in the mirror, you look fatter than you remeber being."))
+
+ if(single_use)
+ visible_message(span_warning("[src] shatters into pieces."))
+ qdel(src)
+
+
diff --git a/GainStation13/icons/mob/AI.dmi b/GainStation13/icons/mob/AI.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..947a021d51cc4e49d8290e353883699e1b3217ce
GIT binary patch
literal 15045
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
I75?-80DJ4xu>b%7
literal 0
HcmV?d00001
diff --git a/GainStation13/icons/mob/accessories.dmi b/GainStation13/icons/mob/accessories.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..295111c736e900a77f3bbe07e71fa3352ec63f9d
GIT binary patch
literal 506
zcmVfFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM
z;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3K9+J+UNTiHkEOv#1!Phl?|*UtCu11BqdXiuV>9t#{ezlxCxY)*G6UGr^#$ukmbgPl|P2m2?Gi?h;z>
z{aLz5{FT-;0dg)FT&_587I1wlUjaE6c>Voko~FlOwS5hMoDICbRFAV%+xLK+-EZFA
w4?{oV-2h_5_Sa~;Ngfxu&A$}6-5o#X2{I--@b#1Cy#N3J07*qoM6N<$f{z2#-2eap
literal 0
HcmV?d00001
diff --git a/GainStation13/icons/mob/action_icons.dmi b/GainStation13/icons/mob/action_icons.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..1c761599cdc99b82339146503e71ffa7fa4910ac
GIT binary patch
literal 729
zcmV;~0w(>5P)uvzGB^>`WC)i~G|NsC0npCxUPXDZO$zA~7-rnly=>Muc|91d=kN+Gy
z|EjkCnyCCMNB=fa|F%{Dvn&|k00001bW%=J06^y0W&i*Hk9t&CbVOxyV{&P5bZKvH
z004NLQ&wq9#3$vX78es#nUtSjTtbw2
z>G?USx$(t0si_5-sW=T*R&e!m0s9RA*kVEG>F=Jg0004`NklXx1&Q<^!yIX7=zOV{B2`=xS%0DW%=8Nhz2
z?u5Pvf{g!I4ci20nwFyg^hi7n?;Iei0gFuZ(RRE$4>Gk*tDkrxlFPvm=p$Em;wngv
z63PLL=Mu2oQsMrXK>Klbl=;N~cKjWP5#XD;2Bm;-b&t{Z3FvECs%QN_N2AfxjNjl_
zPN=`610|erLt7`(c?JJ^MpZ+QEUm@5a0*#+DW&<#HncB#e+Mku6HKNTFZWIv`k8yDUY=U7sMBF2~
zNRFUnG{GK_T;&Bc?G%=fyi8eTuXC9{^+HMebFZ{Kfqtp}>-+TyMvNho6mp@v00000
LNkvXXu0mjf`gTQ`
literal 0
HcmV?d00001
diff --git a/GainStation13/icons/mob/blueberry.dmi b/GainStation13/icons/mob/blueberry.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..a07147ab1d2ce6f94d32d9cdfc00c8ebd0ea21c3
GIT binary patch
literal 7026
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
0Myjf0JIm<09gS4A^+F_{{R580RPax
zhv5KV+|j7!+^^WnotyyS;McRvxqR;K?&8|Dh5*Cr;k$7FrLeHD?d|OV(i^1!0JH!A
z4V7kR00001bW%=J06^y0W&i*Hd3sb>bVOxyV{&P5bZKvH004NLQ&w-(0Dd}I)?0^6O1S3gA
zK~z|U?U?O)+aL^uE6N($Y;8hgrY&Wk_kWK&l5iSqY}ZNqZ|vEe1pB-o2{_)(&HuKp
z5z#gMwD`Ppw{v%(-_7((_gp`2@ZQhdA^o4G`^nucKEJ`A$vcAZp%CWA=Qq=Ua6c~)
z+`}T^)7%t7@SeO6lYkP!X@E{)CJ92A);GemzU6o>%g_({cdFY-44s=C0?}NZ28>Tf
zh%vSl0{Om8OhO{KMQH9V!5LtvZ$~02IPZAw%qA(^9
z0Cxh}H4`1kYJ{v#8URV3HTl#AxUH>)F+ucga=7gMh#>uF$aAm{BLX=ExI!4zQj|xq
zNXQ4B1HSEI)i3ph3j3l(B%dgb0M7@v)gbTvuvlX!08nHdU=sM&Re(;$^x81Wt_I+@
zZ8{vba-S}SnxFvEbtWr~8UUxUcarFPe0;0{ge4LIIK+~wK^9_4UgaMP!lzULl8noL
z^`14r_?89$4}cPEAkVHM#BWIx{9T&z)3;dnlS(t1BISLJ@uCi{`G{`F7>W}C5L}KVbXGEbAptNXsQ%{kqWR=gZNQfR
zW_-bjn0ku-{(KI45SoKNHMc4UX
z?s&}%#IIX;V@VR}WaaPrHIK^d(@O`BA@a<*k8GtKZcC-y@2(lGpXO&)`&l0OXX-
zBUfV_Zf+|#)BZmgoEmU@g&7DoF)IM(=pTBA-@a{UfQz>3vWIb%-FCa=r~%=xoy9B;
of8pNC;$*vg@%JCsKEU7q1Hr{b?z5%9n*aa+07*qoM6N<$f~V@5^#A|>
literal 0
HcmV?d00001
diff --git a/GainStation13/icons/mob/candymonster.dmi b/GainStation13/icons/mob/candymonster.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..c3e1d964e414bfe5a7c8899d397eb8cdc1f1f0f6
GIT binary patch
literal 1402
zcmV-=1%>*FP)C0000mP)t-sz`(#0
z2>>`704WpzPb~{15db6-03HtjFBbr{ot4hKw)5uUq>O}?eRZ9MeZauL&rAyK00001
zbW%=J06^y0W&i*HyLwbubVOxyV{&P5bZKvH004NLm66X1!Y~ZR&+Su`?K;H$xq6We
z*}=U+scm$Tc9XU!zP;T9r?82VOTLg_zL3OhTkYzGmHV1r!8+_awqeC;P00z~4T;UT1v;F3Fy1|munS{G_5B}Xd^40*s5XmKB?B%iRucP#(F-ock2S0L0p
zozD3D){YXS1!1`9JLkd91I4smmW;7H;ZNU-?av@R>V?CkG-g#(j<0$EIZc1FuJ;jL
z000CrNklwJ=R@>0Ut5tt
z%Rf#MgJSq|0rCt10ppL%@FxO@DI=_F44i~yM5-)d0uJH|Ebf$*_hi6Fn1
z>j#qmehr8_f%5yy3IeDfM1QtE5Y9mNJ1AlMPxXVV3IeDf403(IufN3$pua4?@UTbq
z15_U{W{HEaF0>UG0aEq~>IcYwpzAnJ1A80E`8}#1+^7#Y1@S84mO$2lEHOj%1Du}I
zF%+*OHwC!@SpcdZKmmuFXfdQEp93)fOy5CzuH$>`cn)lt04YGF08gI;th5;oP*7Gd
zN&$EMnf}|gSX>2C{toL0gH#_lJ_h|x@Xw-R9SZq7tRD>5^#N_t4p7!&2z~k)y
z2Wkrl)&8h}00?Re5U_v%2&xMZsDOY7Y6}psfB*=p3lOM)fC#D!5U7BF2&xMZSplI~
z>`)-^|CIvm(}+_DNC5mHsBEwo5X$@=5I}!Kp9&|m*vkA}CcyrHALZ|W;BNje3&?Qd
z2Lw0s|7)Q99TD8i|5G$(i-7zc65PrE_ueeb0tNXyB)F0PCw@Pjsf`8y;4{yV=m{-K^7wIF||t4JV_{mE*!bAE7caWpXby9NSf|J}N#{ZyPYQvQCn
z2ZBpG(jKk5#&y}^
zeL@XD{$6W8=u4kA3fNnPcgWH8o={q_)Iy#!*AN-DxtCi;LMF0Q*07*qo
IM6N<$f{o3KkN^Mx
literal 0
HcmV?d00001
diff --git a/GainStation13/icons/mob/ghoster.dmi b/GainStation13/icons/mob/ghoster.dmi
new file mode 100644
index 0000000000000000000000000000000000000000..658ed91a6dc504e47d8c25978d632eec3b2b2373
GIT binary patch
literal 1261
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