diff --git a/GainStation13/code/mechanics/fatness.dm b/GainStation13/code/mechanics/fatness.dm
index f2d3a65e..b1b58e4e 100644
--- a/GainStation13/code/mechanics/fatness.dm
+++ b/GainStation13/code/mechanics/fatness.dm
@@ -11,6 +11,8 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
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%
@@ -46,7 +48,9 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
fatness = fatness_real //Make their current fatness their real fatness
- hiders_apply() //Check and apply hiders, XWG is there too
+ hiders_apply() //Check and apply hiders
+ perma_apply() //Check and apply for permanent fat
+ xwg_resize() //Apply XWG
return TRUE
@@ -132,24 +136,52 @@ GLOBAL_LIST_INIT(uncapped_resize_areas, list(/area/bridge, /area/crew_quarters,
/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_over = min(fatness_over, (client?.prefs?.max_weight - 1)) //And make sure it's not above their preferred max
- fatness = fatness_real + fatness_over //Then, make their current fatness the sum of their real plus/minus the calculated amount
- if(client?.prefs?.weight_gain_extreme && !normalized)
- xwg_resize()
+ 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(!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()
- 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)
+ 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)
diff --git a/GainStation13/code/mechanics/permanent_fat.dm b/GainStation13/code/mechanics/permanent_fat.dm
new file mode 100644
index 00000000..74471024
--- /dev/null
+++ b/GainStation13/code/mechanics/permanent_fat.dm
@@ -0,0 +1,18 @@
+/datum/preferences/proc/perma_fat_save(character)
+ if(iscarbon(character))
+ var/mob/living/carbon/C = character
+ if(!path)
+ return 0
+ 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 0
+
+ savecharcooldown = world.time + PREF_SAVELOAD_COOLDOWN
+ var/savefile/S = new /savefile(path)
+ if(!S)
+ return 0
+ S.cd = "/character[default_slot]"
+
+ WRITE_FILE(S["permanent_fat"] , C.fatness_perma)
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 00000000..593b18d5
--- /dev/null
+++ b/GainStation13/code/modules/reagents/chemistry/reagents/fermi_fat.dm
@@ -0,0 +1,186 @@
+///datum/reagent/sizechem
+
+//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 == 0)
+ 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 <= 1)
+ 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 <= 2)
+ 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 <= 3)
+ 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
+
+/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
+
+//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 = 800 // 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_CHEM)
+ M.adjust_perma(-5, FATTENING_TYPE_CHEM)
+ ..()
+ . = 1
diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm
index 8887ae00..f3ca9244 100644
--- a/code/__HELPERS/roundend.dm
+++ b/code/__HELPERS/roundend.dm
@@ -3,6 +3,13 @@
#define POPCOUNT_SHUTTLE_ESCAPEES "shuttle_escapees" //Emergency shuttle only.
/datum/controller/subsystem/ticker/proc/gather_roundend_feedback()
+
+ //GS13 Process permanent fat
+ for(var/mob/m in GLOB.player_list)
+ if(m.client.prefs)
+ if(m.client.ckey)
+ m.client.prefs.perma_fat_save(m)
+
gather_antag_data()
record_nuke_disk_location()
var/json_file = file("[GLOB.log_directory]/round_end_data.json")
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index a3c41df0..b05aae85 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -105,6 +105,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//GS13
var/starting_weight = 0 //how thicc you wanna be at start
+ var/permanent_fat = 0 //If it isn't the consequences of your own actions
var/wg_rate = 0.5
var/wl_rate = 0.5
var/voice = "human"
@@ -2997,6 +2998,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//GS13
character.fatness = starting_weight
character.fatness_real = starting_weight
+ character.fatness_perma = permanent_fat
character.weight_gain_rate = wg_rate
character.weight_loss_rate = wl_rate
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 1e4841ed..dab7cfb7 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -392,6 +392,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["age"] >> age
S["body_size"] >> body_size
S["starting_weight"] >> starting_weight
+ S["permanent_fat"] >> permanent_fat
S["wg_rate"] >> wg_rate
S["wl_rate"] >> wl_rate
S["hair_color"] >> hair_color
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index f077adf2..50b5bfa4 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -321,6 +321,12 @@
else if(stage in R.addiction_stage4_end to INFINITY)
to_chat(C, "You feel like you've gotten over your need for [R.name].")
SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_addiction")
+
+ //GS13 on reagent addiction removal
+ if(istype(R, /datum/reagent/fermi_fat))
+ var/datum/reagent/fermi_fat/F = R
+ F.addiction_remove(C)
+
cached_addictions.Remove(R)
else
SEND_SIGNAL(C, COMSIG_CLEAR_MOOD_EVENT, "[R.type]_overdose")
diff --git a/modular_citadel/code/game/machinery/cryopod.dm b/modular_citadel/code/game/machinery/cryopod.dm
index 3ee9a1f0..d2678424 100644
--- a/modular_citadel/code/game/machinery/cryopod.dm
+++ b/modular_citadel/code/game/machinery/cryopod.dm
@@ -248,6 +248,11 @@
/obj/machinery/cryopod/proc/despawn_occupant()
var/mob/living/mob_occupant = occupant
+ //GS13 Process permanent fat
+ if(mob_occupant.client.prefs)
+ if(mob_occupant.client.ckey)
+ mob_occupant.client.prefs.perma_fat_save(mob_occupant)
+
//Update any existing objectives involving this mob.
for(var/datum/objective/O in GLOB.objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
diff --git a/tgstation.dme b/tgstation.dme
index 369210fa..e48509bb 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3103,6 +3103,7 @@
#include "GainStation13\code\mechanics\helplessness.dm"
#include "GainStation13\code\mechanics\infestation.dm"
#include "GainStation13\code\mechanics\metal_cruncher.dm"
+#include "GainStation13\code\mechanics\permanent_fat.dm"
#include "GainStation13\code\mechanics\spells.dm"
#include "GainStation13\code\mechanics\wand.dm"
#include "GainStation13\code\mechanics\water_sponge.dm"
@@ -3133,6 +3134,7 @@
#include "GainStation13\code\modules\reagents\chemistry\reagents\consumable_reagents.dm"
#include "GainStation13\code\modules\reagents\chemistry\reagents\dwarverndrinks.dm"
#include "GainStation13\code\modules\reagents\chemistry\reagents\fatty_drinks.dm"
+#include "GainStation13\code\modules\reagents\chemistry\reagents\fermi_fat.dm"
#include "GainStation13\code\modules\reagents\chemistry\recipes\fatchem.dm"
#include "GainStation13\code\modules\reagents\chemistry\recipes\fatdrinks.dm"
#include "GainStation13\code\modules\reagents\chemistry\recipes\ROCKANDSTONEdrinks.dm"