diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index 4ca06dd8aae..e37ab4bde2b 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -57,8 +57,11 @@ /datum/mood_event/exercise description = "Working out releases those endorphins!" - mood_change = 2 - timeout = 5 MINUTES + mood_change = 1 + +/datum/mood_event/exercise/add_effects(fitness_level) + mood_change = fitness_level // the more fit you are, the more you like to work out + return ..() /datum/mood_event/pet_animal description = "Animals are adorable! I can't stop petting them!" diff --git a/code/datums/skills/fitness.dm b/code/datums/skills/fitness.dm index a7c49a481ac..c306548303e 100644 --- a/code/datums/skills/fitness.dm +++ b/code/datums/skills/fitness.dm @@ -3,17 +3,21 @@ title = "Fitness" desc = "Twinkle twinkle little star, hit the gym and lift the bar." /// The skill value modifier effects the max duration that is possible for /datum/status_effect/exercised - modifiers = list(SKILL_VALUE_MODIFIER = list(2 MINUTES, 3 MINUTES, 4 MINUTES, 5 MINUTES, 6 MINUTES, 7 MINUTES, 10 MINUTES)) + modifiers = list(SKILL_VALUE_MODIFIER = list(1 MINUTES, 1.5 MINUTES, 2 MINUTES, 2.5 MINUTES, 3 MINUTES, 3.5 MINUTES, 5 MINUTES)) + /// How much bigger your mob becomes per level (these effects don't stack together) + var/static/size_boost = list(0, 1/16, 1/8, 3/16, 2/8, 3/8, 4/8) // skill_item_path - your mob sprite gets bigger to showoff so we don't get a special item /datum/skill/fitness/level_gained(datum/mind/mind, new_level, old_level, silent) . = ..() - var/size_boost = (new_level == SKILL_LEVEL_LEGENDARY) ? 0.25 : 0.05 - var/gym_size = RESIZE_DEFAULT_SIZE + size_boost - mind.current.update_transform(gym_size) + var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level] + var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level] + + mind.current.update_transform(new_gym_size / old_gym_size) /datum/skill/fitness/level_lost(datum/mind/mind, new_level, old_level, silent) . = ..() - var/size_boost = (new_level == SKILL_LEVEL_LEGENDARY) ? 0.25 : 0.05 - var/gym_size = RESIZE_DEFAULT_SIZE + size_boost - mind.current.update_transform(RESIZE_DEFAULT_SIZE / gym_size) + var/old_gym_size = RESIZE_DEFAULT_SIZE + size_boost[old_level] + var/new_gym_size = RESIZE_DEFAULT_SIZE + size_boost[new_level] + + mind.current.update_transform(new_gym_size / old_gym_size) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 10b3370bbf3..6cd180ab597 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -162,31 +162,33 @@ /datum/status_effect/exercised id = "Exercised" - duration = 30 SECONDS + duration = 15 SECONDS status_type = STATUS_EFFECT_REFRESH // New effects will add to total duration alert_type = null processing_speed = STATUS_EFFECT_NORMAL_PROCESS alert_type = /atom/movable/screen/alert/status_effect/exercised /// Having any of these reagents in your system extends the duration var/static/list/supplementary_reagents_bonus = list( - /datum/reagent/consumable/ethanol/protein_blend = 30 SECONDS, // protein shakes are very robust - /datum/reagent/inverse/oxandrolone = 25 SECONDS, - /datum/reagent/consumable/eggwhite = 20 SECONDS, - /datum/reagent/consumable/eggyolk = 15 SECONDS, - /datum/reagent/consumable/nutriment/protein = 15 SECONDS, - /datum/reagent/consumable/nutriment/vitamin = 10 SECONDS, - /datum/reagent/consumable/rice = 10 SECONDS, - /datum/reagent/consumable/milk = 10 SECONDS, - /datum/reagent/consumable/soymilk = 5 SECONDS, // darn vegans! - /datum/reagent/consumable/nutraslop = 5 SECONDS, // prison food to bulk up with + /datum/reagent/consumable/ethanol/protein_blend = 10 SECONDS, // protein shakes are very robust + /datum/reagent/inverse/oxandrolone = 8 SECONDS, + /datum/reagent/consumable/nutriment/protein = 5 SECONDS, + /datum/reagent/consumable/nutriment/vitamin = 4 SECONDS, + /datum/reagent/consumable/milk = 4 SECONDS, + /datum/reagent/consumable/rice = 3 SECONDS, + // keep in mind you can eat a raw egg to acquire both these reagents at the same time + /datum/reagent/consumable/eggwhite = 3 SECONDS, + /datum/reagent/consumable/eggyolk = 2 SECONDS, + // weak workout food + /datum/reagent/consumable/nutraslop = 2 SECONDS, // prison food to bulk up with + /datum/reagent/consumable/soymilk = 1 SECONDS, // darn vegans! // time for the bad stuff - /datum/reagent/consumable/sugar = -5 SECONDS, - /datum/reagent/consumable/monkey_energy = -5 SECONDS, - /datum/reagent/consumable/nutriment/fat = -5 SECONDS, + /datum/reagent/consumable/sugar = -1 SECONDS, + /datum/reagent/consumable/monkey_energy = -1 SECONDS, // the marketing was a lie + /datum/reagent/consumable/nutriment/fat = -1 SECONDS, ) /datum/status_effect/exercised/proc/workout_duration(mob/living/new_owner, bonus_time) - if(!bonus_time || !new_owner.mind) + if(!bonus_time || !new_owner.mind || !iscarbon(new_owner)) return 0 SECONDS var/modifier = 1 @@ -207,7 +209,7 @@ if(new_owner.reagents.has_reagent(workout_reagent)) food_boost += supplementary_reagents_bonus[workout_reagent] - var/skill_level_boost = (new_owner.mind.get_skill_level(/datum/skill/fitness) - 1) * 5 SECONDS + var/skill_level_boost = (new_owner.mind.get_skill_level(/datum/skill/fitness) - 1) * 2 SECONDS bonus_time = (bonus_time + food_boost + skill_level_boost) * modifier var/exhaustion_limit = new_owner.mind.get_skill_modifier(/datum/skill/fitness, SKILL_VALUE_MODIFIER) + world.time @@ -219,15 +221,21 @@ return bonus_time -/datum/status_effect/exercised/tick(seconds_between_ticks) - owner.reagents.metabolize(owner, seconds_between_ticks * SSMOBS_DT, 0) // doubles the metabolization rate - /datum/status_effect/exercised/on_creation(mob/living/new_owner, bonus_time) duration += workout_duration(new_owner, bonus_time) return ..() /datum/status_effect/exercised/refresh(mob/living/new_owner, bonus_time) duration += workout_duration(new_owner, bonus_time) + new_owner.clear_mood_event("exercise") // we need to reset the old mood event in case our fitness skill changes + new_owner.add_mood_event("exercise", /datum/mood_event/exercise, new_owner.mind.get_skill_level(/datum/skill/fitness)) + +/datum/status_effect/exercised/on_apply() + owner.add_mood_event("exercise", /datum/mood_event/exercise, owner.mind.get_skill_level(/datum/skill/fitness)) + return ..() + +/datum/status_effect/exercised/on_remove() + owner.clear_mood_event("exercise") /atom/movable/screen/alert/status_effect/exercised name = "Exercise" diff --git a/code/game/objects/structures/gym/punching_bag.dm b/code/game/objects/structures/gym/punching_bag.dm index 9219153d026..9c67bd89cfc 100644 --- a/code/game/objects/structures/gym/punching_bag.dm +++ b/code/game/objects/structures/gym/punching_bag.dm @@ -51,8 +51,9 @@ if(istype(boxing_gloves)) stamina_exhaustion = 2 + if(!iscarbon(user)) + return user.adjustStaminaLoss(stamina_exhaustion) - user.add_mood_event("exercise", /datum/mood_event/exercise) user.mind?.adjust_experience(/datum/skill/fitness, 0.1) user.apply_status_effect(/datum/status_effect/exercised) diff --git a/code/game/objects/structures/gym/weight_machine.dm b/code/game/objects/structures/gym/weight_machine.dm index 56b96e5bbd8..055c9788c95 100644 --- a/code/game/objects/structures/gym/weight_machine.dm +++ b/code/game/objects/structures/gym/weight_machine.dm @@ -1,5 +1,5 @@ #define WORKOUT_XP 5 -#define EXERCISE_STATUS_DURATION 20 SECONDS +#define EXERCISE_STATUS_DURATION 15 SECONDS #define SAFE_DRUNK_LEVEL 39 /obj/structure/weightmachine @@ -22,6 +22,9 @@ ///message when drunk user fails to use the machine var/drunk_message = "You try for a new record and pull through! Through a muscle that is." + // the total reps you can do before you hit stamcrit based on fitness level + var/static/list/total_workout_reps = list(3, 4, 4, 5, 6, 6, 7) + ///List of messages picked when using the machine. var/static/list/more_weight = list( "pushing it to the limit!", @@ -127,12 +130,12 @@ else user.balloon_alert(user, pick(finished_message)) - user.adjust_nutrition(-3) // feel the burn - user.add_mood_event("exercise", /datum/mood_event/exercise) + user.adjust_nutrition(-5) // feel the burn - // remember the real xp gain is from sleeping after working out - user.mind.adjust_experience(/datum/skill/fitness, WORKOUT_XP) - user.apply_status_effect(/datum/status_effect/exercised, EXERCISE_STATUS_DURATION) + if(iscarbon(user)) + // remember the real xp gain is from sleeping after working out + user.mind.adjust_experience(/datum/skill/fitness, WORKOUT_XP) + user.apply_status_effect(/datum/status_effect/exercised, EXERCISE_STATUS_DURATION) end_workout() @@ -141,6 +144,9 @@ STOP_PROCESSING(SSobj, src) icon_state = initial(icon_state) +/// roughly 8 seconds for 1 workout rep +#define WORKOUT_LENGTH 8 + /obj/structure/weightmachine/process(seconds_per_tick) if(!has_buckled_mobs()) end_workout() @@ -149,15 +155,22 @@ flick_overlay_view(workout, 0.8 SECONDS) flick("[base_icon_state]-u", src) var/mob/living/user = buckled_mobs[1] - animate(user, pixel_y = pixel_shift_y, time = 4) + animate(user, pixel_y = pixel_shift_y, time = WORKOUT_LENGTH * 0.5) playsound(user, 'sound/machines/creak.ogg', 60, TRUE) - animate(pixel_y = user.base_pixel_y, time = 4) + animate(pixel_y = user.base_pixel_y, time = WORKOUT_LENGTH * 0.5) - var/stamina_exhaustion = 5 - (user.mind.get_skill_level(/datum/skill/fitness) * 0.5) + if(!iscarbon(user) || isnull(user.mind)) + return TRUE + // the amount of workouts you can do before you hit stamcrit + var/workout_reps = total_workout_reps[user.mind.get_skill_level(/datum/skill/fitness)] + // total stamina drain of 1 workout calculated based on the workout length + var/stamina_exhaustion = FLOOR(user.maxHealth / workout_reps / WORKOUT_LENGTH, 0.1) user.adjustStaminaLoss(stamina_exhaustion * seconds_per_tick) return TRUE +#undef WORKOUT_LENGTH + /** * Weight lifter subtype */ diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 4af52b7f3ed..a073122ad6b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -792,7 +792,6 @@ if(hud_used?.spacesuit) hud_used.spacesuit.icon_state = "spacesuit_[cell_state]" - /mob/living/carbon/set_health(new_value) . = ..() if(. > hardcrit_threshold) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 6bfbc97b731..ce4f93d99c1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -890,12 +890,19 @@ return var/carrydelay = 5 SECONDS //if you have latex you are faster at grabbing - var/skills_space = "" //cobby told me to do this + var/skills_space + var/fitness_level = mind.get_skill_level(/datum/skill/fitness) - 1 if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY)) - carrydelay = 3 SECONDS - skills_space = " very quickly" + carrydelay -= 2 SECONDS else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY)) - carrydelay = 4 SECONDS + carrydelay -= 1 SECONDS + + // can remove up to 2 seconds at legendary + carrydelay -= fitness_level * (1/3) SECONDS + + if(carrydelay <= 3 SECONDS) + skills_space = " very quickly" + else if(carrydelay <= 4 SECONDS) skills_space = " quickly" visible_message(span_notice("[src] starts[skills_space] lifting [target] onto [p_their()] back..."), diff --git a/strings/tips.txt b/strings/tips.txt index df4e9e3e195..2a777f28304 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -252,6 +252,7 @@ When hacking doors, cutting and mending a "test light wire" will restore power t When in doubt about technical issues, clear your cache (byond launcher > cogwheel > preferences > game prefs), update your BYOND, and relog. When placing floor tiles in space, you don't need to place down lattice if there is a piece of plating nearby. Where the space map levels connect is randomized every round, but are otherwise kept consistent within rounds. Remember that they are not necessarily bidirectional! +Working out improves your fitness which increases your size and faster times to fireman carry. Remember that a quality diet and sleep are essential! You can catch thrown items by toggling on your throw mode with an empty hand active. You can change the control scheme by pressing tab. One is WASD, the other is the arrow keys. Keep in mind that hotkeys are also changed with this. You can cheat games by baking dice in microwaves to make them loaded. Cards can be seen with x-ray vision or be marked with either a pen or crayon to gain an edge.