diff --git a/GainStation13/code/mechanics/fatness.dm b/GainStation13/code/mechanics/fatness.dm
index f2d3a65e..69041e12 100644
--- a/GainStation13/code/mechanics/fatness.dm
+++ b/GainStation13/code/mechanics/fatness.dm
@@ -23,8 +23,9 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
*
* * 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)
+/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
@@ -33,10 +34,11 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
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
+ 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.
@@ -172,3 +174,34 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
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/structures/trapped_items.dm b/GainStation13/code/structures/trapped_items.dm
new file mode 100644
index 00000000..24572a7b
--- /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/code/__DEFINES/span.dm b/code/__DEFINES/span.dm
new file mode 100644
index 00000000..0447e87f
--- /dev/null
+++ b/code/__DEFINES/span.dm
@@ -0,0 +1,141 @@
+// Sorted alphabetically
+#define span_abductor(str) ("" + str + "")
+#define span_admin(str) ("" + str + "")
+#define span_adminhelp(str) ("" + str + "")
+#define span_adminnotice(str) ("" + str + "")
+#define span_adminobserverooc(str) ("" + str + "")
+#define span_adminooc(str) ("" + str + "")
+#define span_adminsay(str) ("" + str + "")
+#define span_aiprivradio(str) ("" + str + "")
+#define span_alert(str) ("" + str + "")
+#define span_alertalien(str) ("" + str + "")
+#define span_alertsyndie(str) ("" + str + "")
+#define span_alertwarning(str) ("" + str + "")
+#define span_alien(str) ("" + str + "")
+#define span_announce(str) ("" + str + "")
+#define span_announcement_header(str) ("")
+#define span_average(str) ("" + str + "")
+#define span_bigicon(str) ("" + str + "")
+#define span_binarysay(str) ("" + str + "")
+#define span_blob(str) ("" + str + "")
+#define span_blobannounce(str) ("" + str + "")
+#define span_blue(str) ("" + str + "")
+#define span_blueteamradio(str) ("" + str + "")
+#define span_bold(str) ("" + str + "")
+#define span_boldannounce(str) ("" + str + "")
+#define span_bolddanger(str) ("" + str + "")
+#define span_bolditalic(str) ("" + str + "")
+#define span_boldnicegreen(str) ("" + str + "")
+#define span_boldnotice(str) ("" + str + "")
+#define span_boldwarning(str) ("" + str + "")
+#define span_boldbig(str) ("" + str + "")
+#define span_centcomradio(str) ("" + str + "")
+#define span_changeling(str) ("" + str + "")
+#define span_clown(str) ("" + str + "")
+#define span_colossus(str) ("" + str + "")
+#define span_command_headset(str) ("" + str + "")
+#define span_comradio(str) ("" + str + "")
+#define span_cult(str) ("" + str + "")
+#define span_cult_bold(str) ("" + str + "")
+#define span_cult_bold_italic(str) ("" + str + "")
+#define span_cult_italic(str) ("" + str + "")
+#define span_cult_large(str) ("" + str + "")
+#define span_danger(str) ("" + str + "")
+#define span_deadsay(str) ("" + str + "")
+#define span_deconversion_message(str) ("" + str + "")
+#define span_drone(str) ("" + str + "")
+#define span_engradio(str) ("" + str + "")
+#define span_extremelybig(str) ("" + str + "")
+#define span_game_say(str) ("" + str + "")
+#define span_ghostalert(str) ("" + str + "")
+#define span_green(str) ("" + str + "")
+#define span_greenannounce(str) ("" + str + "")
+#define span_greenteamradio(str) ("" + str + "")
+#define span_greentext(str) ("" + str + "")
+#define span_grey(str) ("" + str + "")
+#define span_header(str) ("")
+#define span_hear(str) ("" + str + "")
+#define span_hidden(str) ("" + str + "")
+#define span_hierophant(str) ("" + str + "")
+#define span_hierophant_warning(str) ("" + str + "")
+#define span_highlight(str) ("" + str + "")
+#define span_his_grace(str) ("" + str + "")
+#define span_holoparasite(str) ("" + str + "")
+#define span_boldholoparasite(str) ("" + str + "")
+#define span_hypnophrase(str) ("" + str + "")
+#define span_icon(str) ("" + str + "")
+#define span_info(str) ("" + str + "")
+#define span_infoplain(str) ("" + str + "")
+#define span_interface(str) ("" + str + "")
+#define span_linkify(str) ("" + str + "")
+#define span_looc(str) ("" + str + "")
+#define span_major_announcement_text(str) ("" + str + "")
+#define span_major_announcement_title(str) ("" + str + "")
+#define span_medal(str) ("" + str + "")
+#define span_medradio(str) ("" + str + "")
+#define span_memo(str) ("" + str + "")
+#define span_memoedit(str) ("" + str + "")
+#define span_message(str) ("" + str + "")
+#define span_mind_control(str) ("" + str + "")
+#define span_minorannounce(str) ("" + str + "")
+#define span_minoralert(str) ("" + str + "")
+#define span_monkey(str) ("" + str + "")
+#define span_name(str) ("" + str + "")
+#define span_narsie(str) ("" + str + "")
+#define span_narsiesmall(str) ("" + str + "")
+#define span_nicegreen(str) ("" + str + "")
+#define span_notice(str) ("" + str + "")
+#define span_noticealien(str) ("" + str + "")
+#define span_ooc(str) ("" + str + "")
+#define span_ooc_announcement_text(str) ("" + str + "")
+#define span_papyrus(str) ("" + str + "")
+#define span_phobia(str) ("" + str + "")
+#define span_prefix(str) ("" + str + "")
+#define span_priorityalert(str) ("" + str + "")
+#define span_priorityannounce(str) ("" + str + "")
+#define span_prioritytitle(str) ("" + str + "")
+#define span_purple(str) ("" + str + "")
+#define span_radio(str) ("" + str + "")
+#define span_reallybig(str) ("" + str + "")
+#define span_red(str) ("" + str + "")
+#define span_redteamradio(str) ("" + str + "")
+#define span_redtext(str) ("" + str + "")
+#define span_resonate(str) ("" + str + "")
+#define span_revenbignotice(str) ("" + str + "")
+#define span_revenboldnotice(str) ("" + str + "")
+#define span_revendanger(str) ("" + str + "")
+#define span_revenminor(str) ("" + str + "")
+#define span_revennotice(str) ("" + str + "")
+#define span_revenwarning(str) ("" + str + "")
+#define span_robot(str) ("" + str + "")
+#define span_rose(str) ("" + str + "")
+#define span_sans(str) ("" + str + "")
+#define span_sciradio(str) ("" + str + "")
+#define span_secradio(str) ("" + str + "")
+#define span_servradio(str) ("" + str + "")
+#define span_singing(str) ("" + str + "")
+#define span_slime(str) ("" + str + "")
+#define span_small(str) ("" + str + "")
+#define span_smallnotice(str) ("" + str + "")
+#define span_smallnoticeital(str) ("" + str + "")
+#define span_spiderbroodmother(str) ("" + str + "")
+#define span_spiderscout(str) ("" + str + "")
+#define span_spiderbreacher(str) ("" + str + "")
+#define span_subheader_announcement_text(str) ("")
+#define span_suicide(str) ("" + str + "")
+#define span_suppradio(str) ("" + str + "")
+#define span_syndradio(str) ("" + str + "")
+#define span_tape_recorder(str) ("" + str + "")
+#define span_tinynotice(str) ("" + str + "")
+#define span_tinynoticeital(str) ("" + str + "")
+#define span_unconscious(str) ("" + str + "")
+#define span_userdanger(str) ("" + str + "")
+#define span_warning(str) ("" + str + "")
+#define span_yell(str) ("" + str + "")
+#define span_yellowteamradio(str) ("" + str + "")
+
+// Spans that use embedded tgui components:
+// Sorted alphabetically
+#define span_tooltip(tip, main_text) ("" + main_text + "")
diff --git a/tgstation.dme b/tgstation.dme
index 369210fa..69aeac64 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -98,6 +98,7 @@
#include "code\__DEFINES\sight.dm"
#include "code\__DEFINES\sound.dm"
#include "code\__DEFINES\spaceman_dmm.dm"
+#include "code\__DEFINES\span.dm"
#include "code\__DEFINES\stat.dm"
#include "code\__DEFINES\stat_tracking.dm"
#include "code\__DEFINES\status_effects.dm"
@@ -3159,6 +3160,7 @@
#include "GainStation13\code\obj\weapons\alter_rays.dm"
#include "GainStation13\code\obj\weapons\fatbeam.dm"
#include "GainStation13\code\obj\weapons\fatoray.dm"
+#include "GainStation13\code\structures\trapped_items.dm"
#include "GainStation13\icons\obj\vairous_weapons.dm"
#include "hyperstation\code\__DEFINES\economy.dm"
#include "hyperstation\code\__DEFINES\wendigo.dm"