mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-10 07:41:16 +01:00
0b0c5ea91e
## About The Pull Request Extends the part of the crafting unit test that ensures consistency between the total mats of the components of a recipe (or rather, the result of said recipe) and a generic instance of the same type as its result, previously only implemented on food recipes. ## Why It's Good For The Game This ensures a degree of consistency with the material composition of various objects in the game. I couldn't do it in the original PR as that one was too big already and it took months to get it merged, and have the relative bugs fixed. Currently a WIP as I slowly deal with the unit test reports. ## Changelog 🆑 refactor: Follow-up to the crafting/material refactor from months ago. All objects crafted with stacks now inherit their mat composition (not necessarily the effects and color) by default, while previously only a few things like chair, sinks and toilets did. Report any object looking or behaving weirdly as a result. fix: The material composition of ammo boxes is no longer a 1/10 of what it's supposed to be. It was a shitty hack to make it harder to recycle empty ammo boxes. Instead, they lose materials as they're emptied now. /🆑
239 lines
7.9 KiB
Plaintext
239 lines
7.9 KiB
Plaintext
#define WORKOUT_XP 5
|
|
#define EXERCISE_STATUS_DURATION 15 SECONDS
|
|
#define SAFE_DRUNK_LEVEL 39
|
|
|
|
/obj/structure/weightmachine
|
|
name = "chest press machine"
|
|
desc = "Just looking at this thing makes you feel tired."
|
|
icon = 'icons/obj/fluff/gym_equipment.dmi'
|
|
icon_state = "stacklifter"
|
|
base_icon_state = "stacklifter"
|
|
can_buckle = TRUE
|
|
density = TRUE
|
|
anchored = TRUE
|
|
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
|
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 7)
|
|
|
|
///How much we shift the user's pixel y when using the weight machine.
|
|
var/pixel_shift_z = -3
|
|
|
|
///The weight action we give to people that buckle themselves to us.
|
|
var/datum/action/push_weights/weight_action
|
|
|
|
///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!",
|
|
"going into overdrive!",
|
|
"burning with determination!",
|
|
"rising up to the challenge!",
|
|
"getting strong now!",
|
|
"getting ripped!",
|
|
)
|
|
///List of messages picked when finished using the machine.
|
|
var/static/list/finished_message = list(
|
|
"You feel stronger!",
|
|
"You feel like you can take on the world!",
|
|
"You feel robust!",
|
|
"You feel indestructible!",
|
|
)
|
|
var/static/list/finished_silicon_message = list(
|
|
"You feel nothing!",
|
|
"No pain, no gain!",
|
|
"Chassis hardness rating... Unchanged.",
|
|
"You feel the exact same. Nothing.",
|
|
)
|
|
|
|
/obj/structure/weightmachine/Initialize(mapload)
|
|
. = ..()
|
|
|
|
weight_action = new(src)
|
|
weight_action.weightpress = src
|
|
|
|
var/static/list/tool_behaviors
|
|
if(!tool_behaviors)
|
|
tool_behaviors = string_assoc_nested_list(list(
|
|
TOOL_CROWBAR = list(
|
|
SCREENTIP_CONTEXT_RMB = "Deconstruct",
|
|
),
|
|
|
|
TOOL_WRENCH = list(
|
|
SCREENTIP_CONTEXT_RMB = "Anchor",
|
|
),
|
|
))
|
|
AddElement(/datum/element/contextual_screentip_tools, tool_behaviors)
|
|
|
|
/obj/structure/weightmachine/Destroy()
|
|
QDEL_NULL(weight_action)
|
|
return ..()
|
|
|
|
/obj/structure/weightmachine/buckle_feedback(mob/living/being_buckled, mob/buckler)
|
|
if(HAS_TRAIT(being_buckled, TRAIT_RESTRAINED))
|
|
return ..()
|
|
|
|
if(being_buckled == buckler)
|
|
being_buckled.visible_message(
|
|
span_notice("[buckler] lays down on [src]."),
|
|
span_notice("You lay down on [src]."),
|
|
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
|
|
)
|
|
else
|
|
being_buckled.visible_message(
|
|
span_notice("[buckler] lays [being_buckled] down on [src]."),
|
|
span_notice("[buckler] lays you down on [src]."),
|
|
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
|
|
)
|
|
|
|
/obj/structure/weightmachine/unbuckle_feedback(mob/living/being_unbuckled, mob/unbuckler)
|
|
if(HAS_TRAIT(being_unbuckled, TRAIT_RESTRAINED))
|
|
return ..()
|
|
|
|
if(being_unbuckled == unbuckler)
|
|
being_unbuckled.visible_message(
|
|
span_notice("[unbuckler] gets up from [src]."),
|
|
span_notice("You get up from [src]."),
|
|
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
|
|
)
|
|
else
|
|
being_unbuckled.visible_message(
|
|
span_notice("[unbuckler] pulls [being_unbuckled] up from [src]."),
|
|
span_notice("[unbuckler] pulls you up from [src]."),
|
|
visible_message_flags = ALWAYS_SHOW_SELF_MESSAGE,
|
|
)
|
|
|
|
/obj/structure/weightmachine/buckle_mob(mob/living/buckled, force, check_loc)
|
|
. = ..()
|
|
weight_action.Grant(buckled)
|
|
|
|
/obj/structure/weightmachine/unbuckle_mob(mob/living/buckled_mob, force, can_fall)
|
|
. = ..()
|
|
weight_action.Remove(buckled_mob)
|
|
|
|
/obj/structure/weightmachine/wrench_act_secondary(mob/living/user, obj/item/tool)
|
|
tool.play_tool_sound(src)
|
|
balloon_alert(user, anchored ? "unsecured" : "secured")
|
|
anchored = !anchored
|
|
return TRUE
|
|
|
|
/obj/structure/weightmachine/crowbar_act_secondary(mob/living/user, obj/item/tool)
|
|
if(anchored)
|
|
balloon_alert(user, "still secured!")
|
|
return FALSE
|
|
tool.play_tool_sound(src)
|
|
balloon_alert(user, "deconstructing...")
|
|
if (!do_after(user, 10 SECONDS, target = src))
|
|
return FALSE
|
|
new /obj/item/stack/sheet/iron(get_turf(src), 5)
|
|
new /obj/item/stack/rods(get_turf(src), 2)
|
|
new /obj/item/chair(get_turf(src))
|
|
qdel(src)
|
|
return TRUE
|
|
|
|
/obj/structure/weightmachine/proc/perform_workout(mob/living/user)
|
|
if(user.nutrition <= NUTRITION_LEVEL_STARVING)
|
|
user.balloon_alert(user, "too hungry to workout!")
|
|
return
|
|
|
|
user.balloon_alert_to_viewers("[pick(more_weight)]")
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
if(do_after(user, 8 SECONDS, src) && user.has_gravity())
|
|
// with enough dedication, even clowns can overcome their handicaps
|
|
var/clumsy_chance = 30 - (user.mind.get_skill_level(/datum/skill/athletics) * 5)
|
|
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(clumsy_chance))
|
|
playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
|
|
to_chat(user, span_warning("Your hand slips, causing \the [src] to smash you!"))
|
|
user.take_bodypart_damage(rand(2, 5))
|
|
end_workout()
|
|
return
|
|
|
|
// awlways a chance for a person not to fail horribly when drunk
|
|
if(user.get_drunk_amount() > SAFE_DRUNK_LEVEL && prob(min(user.get_drunk_amount(), 99)))
|
|
playsound(src,'sound/effects/bang.ogg', 50, TRUE)
|
|
to_chat(user, span_warning(drunk_message))
|
|
user.take_bodypart_damage(rand(5, 10), wound_bonus = 10)
|
|
end_workout()
|
|
return
|
|
|
|
if(issilicon(user))
|
|
user.balloon_alert(user, pick(finished_silicon_message))
|
|
else
|
|
user.balloon_alert(user, pick(finished_message))
|
|
|
|
user.adjust_nutrition(-5) // feel the burn
|
|
|
|
if(iscarbon(user))
|
|
var/gravity_modifier = user.has_gravity() > STANDARD_GRAVITY ? 2 : 1
|
|
// remember the real xp gain is from sleeping after working out
|
|
user.mind.adjust_experience(/datum/skill/athletics, WORKOUT_XP * gravity_modifier)
|
|
user.apply_status_effect(/datum/status_effect/exercised, EXERCISE_STATUS_DURATION)
|
|
|
|
end_workout()
|
|
|
|
/obj/structure/weightmachine/proc/end_workout()
|
|
playsound(src, 'sound/machines/click.ogg', 60, TRUE)
|
|
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()
|
|
return FALSE
|
|
var/mutable_appearance/workout = mutable_appearance(icon, "[base_icon_state]-o", ABOVE_MOB_LAYER, src, appearance_flags = KEEP_APART)
|
|
workout = color_atom_overlay(workout)
|
|
flick_overlay_view(workout, 0.8 SECONDS)
|
|
flick("[base_icon_state]-u", src)
|
|
var/mob/living/user = buckled_mobs[1]
|
|
animate(user, pixel_z = pixel_shift_z, time = WORKOUT_LENGTH * 0.5, flags = ANIMATION_PARALLEL|ANIMATION_RELATIVE)
|
|
animate(pixel_z = -pixel_shift_z, time = WORKOUT_LENGTH * 0.5, flags = ANIMATION_PARALLEL)
|
|
playsound(user, 'sound/machines/creak.ogg', 60, TRUE)
|
|
|
|
if(!iscarbon(user) || isnull(user.mind))
|
|
return TRUE
|
|
|
|
var/affected_gravity = user.has_gravity()
|
|
if (!affected_gravity)
|
|
return TRUE // No weight? I could do this all day
|
|
var/gravity_modifier = affected_gravity > STANDARD_GRAVITY ? 0.75 : 1
|
|
// the amount of workouts you can do before you hit stamcrit
|
|
var/workout_reps = total_workout_reps[user.mind.get_skill_level(/datum/skill/athletics)] * gravity_modifier
|
|
// total stamina drain of 1 workout calculated based on the workout length
|
|
var/stamina_exhaustion = FLOOR(user.maxHealth / workout_reps / WORKOUT_LENGTH, 0.1)
|
|
|
|
var/obj/item/organ/cyberimp/chest/spine/potential_spine = user.get_organ_slot(ORGAN_SLOT_SPINE)
|
|
if(istype(potential_spine))
|
|
stamina_exhaustion *= potential_spine.athletics_boost_multiplier
|
|
|
|
if(HAS_TRAIT(user, TRAIT_STRENGTH)) //The strong get reductions to stamina damage taken while exercising
|
|
stamina_exhaustion *= 0.5
|
|
|
|
user.adjust_stamina_loss(stamina_exhaustion * seconds_per_tick)
|
|
|
|
return TRUE
|
|
|
|
#undef WORKOUT_LENGTH
|
|
|
|
/**
|
|
* Weight lifter subtype
|
|
*/
|
|
/obj/structure/weightmachine/weightlifter
|
|
name = "incline bench press"
|
|
icon_state = "benchpress"
|
|
base_icon_state = "benchpress"
|
|
|
|
pixel_shift_z = 5
|
|
|
|
drunk_message = "You raise the bar over you trying to balance it with one hand, keyword tried."
|
|
|
|
#undef WORKOUT_XP
|
|
#undef EXERCISE_STATUS_DURATION
|
|
#undef SAFE_DRUNK_LEVEL
|