diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index 189ac6fd0b53..a1711a1d415f 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -27,6 +27,9 @@ #define FOOTSTEP_MOB_SHOE 4 #define FOOTSTEP_MOB_HUMAN 5 //Warning: Only works on /mob/living/carbon/human #define FOOTSTEP_MOB_SLIME 6 +#define FOOTSTEP_MOB_SLIME 6 +#define FOOTSTEP_OBJ_MACHINE 7 +#define FOOTSTEP_OBJ_ROBOT 8 /* diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm deleted file mode 100644 index 2e5533023ac8..000000000000 --- a/code/datums/components/footstep.dm +++ /dev/null @@ -1,125 +0,0 @@ -#define SHOULD_DISABLE_FOOTSTEPS(source) ((SSlag_switch.measures[DISABLE_FOOTSTEPS] && !(HAS_TRAIT(source, TRAIT_BYPASS_MEASURES))) || HAS_TRAIT(source, TRAIT_SILENT_FOOTSTEPS)) - -///Footstep component. Plays footsteps at parents location when it is appropriate. -/datum/component/footstep - ///How many steps the parent has taken since the last time a footstep was played. - var/steps = 0 - ///volume determines the extra volume of the footstep. This is multiplied by the base volume, should there be one. - var/volume - ///e_range stands for extra range - aka how far the sound can be heard. This is added to the base value and ignored if there isn't a base value. - var/e_range - ///footstep_type is a define which determines what kind of sounds should get chosen. - var/footstep_type - ///This can be a list OR a soundfile OR null. Determines whatever sound gets played. - var/footstep_sounds - -/datum/component/footstep/Initialize(footstep_type_ = FOOTSTEP_MOB_BAREFOOT, volume_ = 0.5, e_range_ = -8) - if(!isliving(parent)) - return COMPONENT_INCOMPATIBLE - volume = volume_ - e_range = e_range_ - footstep_type = footstep_type_ - switch(footstep_type) - if(FOOTSTEP_MOB_HUMAN) - if(!ishuman(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), PROC_REF(play_humanstep)) - return - if(FOOTSTEP_MOB_CLAW) - footstep_sounds = GLOB.clawfootstep - if(FOOTSTEP_MOB_BAREFOOT) - footstep_sounds = GLOB.barefootstep - if(FOOTSTEP_MOB_HEAVY) - footstep_sounds = GLOB.heavyfootstep - if(FOOTSTEP_MOB_SHOE) - footstep_sounds = GLOB.footstep - if(FOOTSTEP_MOB_SLIME) - footstep_sounds = 'sound/effects/footstep/slime1.ogg' - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), PROC_REF(play_simplestep)) //Note that this doesn't get called for humans. - -///Prepares a footstep. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/open -/datum/component/footstep/proc/prepare_step() - var/turf/open/T = get_turf(parent) - if(!istype(T)) - return - - var/mob/living/LM = parent - - if(!T.footstep || LM.buckled || LM.throwing || LM.movement_type & (VENTCRAWLING | FLYING) || HAS_TRAIT(LM, TRAIT_IMMOBILIZED)) - return - - if(LM.body_position == LYING_DOWN) //play crawling sound if we're lying - playsound(T, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1) - return - - if(iscarbon(LM)) - var/mob/living/carbon/C = LM - if(!C.get_bodypart(BODY_ZONE_L_LEG) && !C.get_bodypart(BODY_ZONE_R_LEG)) - return - if(C.m_intent == MOVE_INTENT_WALK) - return// stealth - steps++ - - if(steps >= 6) - steps = 0 - - if(steps % 2) - return - - if(steps != 0 && !LM.has_gravity(T)) // don't need to step as often when you hop around - return - return T - -/datum/component/footstep/proc/play_simplestep() - SIGNAL_HANDLER - - if (SHOULD_DISABLE_FOOTSTEPS(parent)) - return - - var/turf/open/T = prepare_step() - if(!T) - return - if(isfile(footstep_sounds) || istext(footstep_sounds)) - playsound(T, footstep_sounds, volume, falloff_distance = 1) - return - var/turf_footstep - switch(footstep_type) - if(FOOTSTEP_MOB_CLAW) - turf_footstep = T.clawfootstep - if(FOOTSTEP_MOB_BAREFOOT) - turf_footstep = T.barefootstep - if(FOOTSTEP_MOB_HEAVY) - turf_footstep = T.heavyfootstep - if(FOOTSTEP_MOB_SHOE) - turf_footstep = T.footstep - if(!turf_footstep) - return - playsound(T, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range, falloff_distance = 1) - -/datum/component/footstep/proc/play_humanstep() - SIGNAL_HANDLER - - if (SHOULD_DISABLE_FOOTSTEPS(parent)) - return - - var/turf/open/T = prepare_step() - if(!T) - return - var/mob/living/carbon/human/H = parent - var/feetCover = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) || (H.w_uniform && (H.w_uniform.body_parts_covered & FEET)) - - if(H.shoes || feetCover) //are we wearing shoes - playsound(T, pick(GLOB.footstep[T.footstep][1]), - GLOB.footstep[T.footstep][2] * volume, - TRUE, - GLOB.footstep[T.footstep][3] + e_range, falloff_distance = 1) - else - if(H.dna.species.special_step_sounds) - playsound(T, pick(H.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1) - else - playsound(T, pick(GLOB.barefootstep[T.barefootstep][1]), - GLOB.barefootstep[T.barefootstep][2] * volume, - TRUE, - GLOB.barefootstep[T.barefootstep][3] + e_range, falloff_distance = 1) - -#undef SHOULD_DISABLE_FOOTSTEPS diff --git a/code/datums/elements/footstep.dm b/code/datums/elements/footstep.dm new file mode 100644 index 000000000000..6d58a27270d1 --- /dev/null +++ b/code/datums/elements/footstep.dm @@ -0,0 +1,156 @@ +///Footstep element. Plays footsteps at parents location when it is appropriate. +/datum/element/footstep + element_flags = ELEMENT_DETACH|ELEMENT_BESPOKE + id_arg_index = 2 + ///A list containing living mobs and the number of steps they have taken since the last time their footsteps were played. + var/list/steps_for_living = list() + ///volume determines the extra volume of the footstep. This is multiplied by the base volume, should there be one. + var/volume + ///e_range stands for extra range - aka how far the sound can be heard. This is added to the base value and ignored if there isn't a base value. + var/e_range + ///footstep_type is a define which determines what kind of sounds should get chosen. + var/footstep_type + ///This can be a list OR a soundfile OR null. Determines whatever sound gets played. + var/footstep_sounds + ///Whether or not to add variation to the sounds played + var/sound_vary = FALSE + +/datum/element/footstep/Attach(datum/target, footstep_type = FOOTSTEP_MOB_BAREFOOT, volume = 0.5, e_range = -8, sound_vary = FALSE) + . = ..() + if(!ismovable(target)) + return ELEMENT_INCOMPATIBLE + src.volume = volume + src.e_range = e_range + src.footstep_type = footstep_type + src.sound_vary = sound_vary + switch(footstep_type) + if(FOOTSTEP_MOB_HUMAN) + if(!ishuman(target)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_humanstep)) + steps_for_living[target] = 0 + return + if(FOOTSTEP_MOB_CLAW) + footstep_sounds = GLOB.clawfootstep + if(FOOTSTEP_MOB_BAREFOOT) + footstep_sounds = GLOB.barefootstep + if(FOOTSTEP_MOB_HEAVY) + footstep_sounds = GLOB.heavyfootstep + if(FOOTSTEP_MOB_SHOE) + footstep_sounds = GLOB.footstep + if(FOOTSTEP_MOB_SLIME) + footstep_sounds = 'sound/effects/footstep/slime1.ogg' + if(FOOTSTEP_OBJ_MACHINE) + footstep_sounds = 'sound/effects/bang.ogg' + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_simplestep_machine)) + return + if(FOOTSTEP_OBJ_ROBOT) + footstep_sounds = 'sound/effects/tank_treads.ogg' + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_simplestep_machine)) + return + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(play_simplestep)) + steps_for_living[target] = 0 + +/datum/element/footstep/Detach(atom/movable/source) + UnregisterSignal(source, COMSIG_MOVABLE_MOVED) + steps_for_living -= source + return ..() + +///Prepares a footstep for living mobs. Determines if it should get played. Returns the turf it should get played on. Note that it is always a /turf/open +/datum/element/footstep/proc/prepare_step(mob/living/source) + var/turf/open/turf = get_turf(source) + if(!istype(turf)) + return + + if(!turf.footstep || source.buckled || source.throwing || source.movement_type & (VENTCRAWLING | FLYING)) + return + + if(!(source.mobility_flags & MOBILITY_STAND)) //play crawling sound if we're lying + playsound(source, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1, vary = sound_vary) + return + + if(iscarbon(source)) + var/mob/living/carbon/carbon_source = source + if(!carbon_source.get_bodypart(BODY_ZONE_L_LEG) && !carbon_source.get_bodypart(BODY_ZONE_R_LEG)) + return + + /* todo: stealth mode? + if(carbon_source.m_intent == MOVE_INTENT_WALK) + return// stealth + */ + + steps_for_living[source] += 1 + var/steps = steps_for_living[source] + + if(steps >= 6) + steps_for_living[source] = 0 + steps = 0 + + if(steps % 2) + return + + if(steps != 0 && !source.has_gravity(turf)) // don't need to step as often when you hop around + return + return turf + +/datum/element/footstep/proc/play_simplestep(mob/living/source) + SIGNAL_HANDLER + + var/turf/open/source_loc = prepare_step(source) + if(!source_loc) + return + if(isfile(footstep_sounds) || istext(footstep_sounds)) + playsound(source, footstep_sounds, volume, falloff_distance = 1, vary = sound_vary) + return + var/turf_footstep + switch(footstep_type) + if(FOOTSTEP_MOB_CLAW) + turf_footstep = source_loc.clawfootstep + if(FOOTSTEP_MOB_BAREFOOT) + turf_footstep = source_loc.barefootstep + if(FOOTSTEP_MOB_HEAVY) + turf_footstep = source_loc.heavyfootstep + if(FOOTSTEP_MOB_SHOE) + turf_footstep = source_loc.footstep + if(!turf_footstep) + return + playsound(source, pick(footstep_sounds[turf_footstep][1]), footstep_sounds[turf_footstep][2] * volume, TRUE, footstep_sounds[turf_footstep][3] + e_range, falloff_distance = 1, vary = sound_vary) + +/datum/element/footstep/proc/play_humanstep(mob/living/carbon/human/source) + SIGNAL_HANDLER + + var/volume_multiplier = 1 + var/range_adjustment = 0 + + if(HAS_TRAIT(source, TRAIT_LIGHT_STEP)) + volume_multiplier = 0.6 + range_adjustment = -2 + + var/turf/open/source_loc = prepare_step(source) + if(!source_loc) + return + + if ((source.wear_suit?.body_parts_covered | source.w_uniform?.body_parts_covered | source.shoes?.body_parts_covered) & FEET) + // we are wearing shoes + playsound(source, pick(GLOB.footstep[source_loc.footstep][1]), + GLOB.footstep[source_loc.footstep][2] * volume * volume_multiplier, + TRUE, + GLOB.footstep[source_loc.footstep][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary) + else + if(source.dna.species.special_step_sounds) + playsound(source, pick(source.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1, vary = sound_vary) + else + playsound(source, pick(GLOB.barefootstep[source_loc.barefootstep][1]), + GLOB.barefootstep[source_loc.barefootstep][2] * volume * volume_multiplier, + TRUE, + GLOB.barefootstep[source_loc.barefootstep][3] + e_range + range_adjustment, falloff_distance = 1, vary = sound_vary) + + +///Prepares a footstep for machine walking +/datum/element/footstep/proc/play_simplestep_machine(atom/movable/source) + SIGNAL_HANDLER + + var/turf/open/source_loc = get_turf(source) + if(!istype(source_loc)) + return + playsound(source, footstep_sounds, 50, falloff_distance = 1, vary = sound_vary) diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 4e88f2c4a613..3c0cf94b50ca 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -167,8 +167,8 @@ /datum/keybinding/mob/toggle_move_intent hotkey_keys = list("Alt") name = "toggle_move_intent" - full_name = "Hold to toggle move intent" - description = "Held down to cycle to the other move intent, release to cycle back" + full_name = "Hold to toggle sprint" + description = "Hold down to enable sprinting. Releasing will return you to walk." keybind_signal = COMSIG_KB_MOB_TOGGLEMOVEINTENT_DOWN /datum/keybinding/mob/toggle_move_intent/down(client/user) diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 574c35f60beb..22c3027cc2af 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -122,12 +122,6 @@ lose_text = "You start tromping around like a barbarian." medical_record_text = "Patient's dexterity belies a strong capacity for stealth." -/datum/quirk/light_step/on_spawn() - var/datum/component/footstep/C = quirk_holder.GetComponent(/datum/component/footstep) - if(C) - C.volume *= 0.6 - C.e_range -= 2 - /datum/quirk/musician name = "Musician" desc = "You can tune handheld musical instruments to play melodies that clear certain negative effects and soothe the soul." diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index dcb44af19cca..646f5656f48a 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -31,8 +31,7 @@ /mob/living/carbon/alien/humanoid/Initialize() . = ..() - AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11) - + AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW, 0.5, -11) /mob/living/carbon/alien/humanoid/show_inv(mob/user) user.set_machine(src) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 5330ee1841f6..89440a66f607 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -526,7 +526,6 @@ return embeds - /mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0) var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES) if(!eyes) //can't flash what can't see! @@ -574,7 +573,6 @@ if(prob(20)) to_chat(src, "Something bright flashes in the corner of your vision!") - /mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15) var/list/reflist = list(intensity) // Need to wrap this in a list so we can pass a reference SEND_SIGNAL(src, COMSIG_CARBON_SOUNDBANG, reflist) @@ -603,7 +601,6 @@ SEND_SOUND(src, sound('sound/weapons/flash_ring.ogg',0,1,0,250)) return effect_amount //how soundbanged we are - /mob/living/carbon/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone) if(damage_type != BRUTE && damage_type != BURN) return @@ -625,7 +622,6 @@ if(istype(ears) && !ears.deaf) . = TRUE - /mob/living/carbon/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) . = ..() if(isnull(.)) @@ -636,7 +632,6 @@ else if(getOxyLoss() <= 50) REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) - /mob/living/carbon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE) . = ..() if(isnull(.)) @@ -648,18 +643,20 @@ REMOVE_TRAIT(src, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) /mob/living/carbon/bullet_act(obj/projectile/P, def_zone, piercing_hit = FALSE) - var/mob/living/carbon/human/current_user = src //is this a good idea? who can say? var/armor = run_armor_check(def_zone, P.flag, P.armour_penetration, silent = TRUE) var/on_hit_state = P.on_hit(src, armor, piercing_hit) + if(!P.nodamage && on_hit_state != BULLET_ACT_BLOCK && !QDELETED(src)) //QDELETED literally just for the instagib rifle. Yeah. apply_damage(P.damage, P.damage_type, def_zone, armor, sharpness = TRUE) + if(P.damage-armor >= 15 && P.damage_type == BRUTE && (!armor || prob(40) || P.damage-armor >= 25)) spray_blood(get_dir(P.starting,src), (P.damage-armor)/5) - var/obj/item/bodypart/targeted_bodypart = null bleed((P.damage-armor)/2) recoil_camera(src, clamp((P.damage-armor)/4,0.5,10), clamp((P.damage-armor)/4,0.5,10), P.damage/8, P.Angle) apply_effects(P.stun, P.knockdown, P.unconscious, P.irradiate, P.slur, P.stutter, P.eyeblur, P.drowsy, armor, P.stamina, P.jitter, P.paralyze, P.immobilize) + if(P.dismemberment) check_projectile_dismemberment(P, def_zone) + return on_hit_state ? BULLET_ACT_HIT : BULLET_ACT_BLOCK diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index 7f65b79ddca1..3e9e455569e8 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -31,6 +31,17 @@ if(m_intent == MOVE_INTENT_RUN) adjust_nutrition(-(HUNGER_FACTOR/10)) + if(m_intent == MOVE_INTENT_RUN && !(movement_type & FLYING) && (mobility_flags & (MOBILITY_MOVE|MOBILITY_STAND)) && !pulledby) + drain_sprint() + if(momentum_dir & direct) + momentum_distance++ + if(!has_momentum && momentum_distance >= 4 && add_movespeed_modifier(/datum/movespeed_modifier/momentum)) + has_momentum = TRUE + else + momentum_dir = direct + momentum_distance = 0 + if(has_momentum && remove_movespeed_modifier(/datum/movespeed_modifier/momentum)) + has_momentum = FALSE /mob/living/carbon/set_usable_legs(new_value) . = ..() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 27fa569de7cd..a5ce76114ee1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -23,8 +23,10 @@ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_FACE_ACT, PROC_REF(clean_face)) AddComponent(/datum/component/personal_crafting) - AddComponent(/datum/component/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) AddComponent(/datum/component/bloodysoles/feet) + + AddElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) + GLOB.human_list += src /mob/living/carbon/human/proc/setup_human_dna() diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 755c674a107d..0b5daa91d262 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -51,7 +51,7 @@ create_dna(src) dna.initialize_dna(random_blood_type()) - AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, -6) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_BAREFOOT, 1, -6) AddComponent(/datum/component/bloodysoles/feet) /mob/living/carbon/monkey/Destroy() diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index ec7c76f5ca61..0565c6c1fc1d 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -39,7 +39,7 @@ /mob/living/simple_animal/hostile/alien/Initialize() . = ..() - AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) /mob/living/simple_animal/hostile/alien/drone name = "alien drone" diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3670e14a6405..e120bd62aefd 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -155,7 +155,7 @@ if(dextrous) AddComponent(/datum/component/personal_crafting) if(footstep_type) - AddComponent(/datum/component/footstep, footstep_type) + AddElement(/datum/element/footstep, footstep_type) /mob/living/simple_animal/Destroy() GLOB.simple_animals[AIStatus] -= src diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index cb4b76983563..05f3150b0efb 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -104,7 +104,7 @@ set_colour(new_colour) . = ..() set_nutrition(700) - AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 0) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_SLIME, 0) /mob/living/simple_animal/slime/Destroy() for (var/A in actions) diff --git a/code/modules/mob/living/sprint.dm b/code/modules/mob/living/sprint.dm new file mode 100644 index 000000000000..22a545a6f09a --- /dev/null +++ b/code/modules/mob/living/sprint.dm @@ -0,0 +1,96 @@ +/atom/movable/screen/mov_intent + var/mutable_appearance/sprint_bar + +/atom/movable/screen/mov_intent/update_overlays() + . = ..() + if(!ishuman(hud?.mymob)) + return + + if(isnull(sprint_bar)) + sprint_bar = mutable_appearance( + icon = 'icons/effects/progressbar.dmi', + icon_state = "prog_bar_100", + ) + sprint_bar.pixel_y -= 2 + + var/mob/living/carbon/human/runner = hud.mymob + sprint_bar.icon_state = "prog_bar_[round(((runner.sprint_length / runner.sprint_length_max) * 100), 5)]" + . += sprint_bar + +/datum/movespeed_modifier/momentum + movetypes = GROUND + flags = IGNORE_NOSLOW + multiplicative_slowdown = -0.1 + +/mob/living/carbon + /// If TRUE, we are being affected by run momentum + var/has_momentum = FALSE + /// Our last move direction, used for tracking momentum + var/momentum_dir = NONE + /// How many tiles we've moved in the momentum direction + var/momentum_distance = 0 + +/mob/living/carbon/human + m_intent = MOVE_INTENT_WALK + /// How many tiles left in your sprint + var/sprint_length = 100 + /// How many tiles you can sprint before spending stamina + var/sprint_length_max = 100 + /// How many tiles you get back per second + var/sprint_regen_per_second = 0.75 + +/mob/living/carbon/human/toggle_move_intent() + . = ..() + if(m_intent == MOVE_INTENT_RUN) + playsound_local(get_turf(src), 'sound/effects/sprintactivate.ogg', 75, vary = FALSE, pressure_affected = FALSE) + else + playsound_local(get_turf(src), 'sound/effects/sprintdeactivate.ogg', 75, vary = FALSE, pressure_affected = FALSE) + +/mob/living/carbon/human/Life(seconds_per_tick, times_fired) + . = ..() + if(!.) + return + if(m_intent == MOVE_INTENT_RUN || sprint_length >= sprint_length_max) + return + + adjust_sprint_left(sprint_regen_per_second * seconds_per_tick * (body_position == LYING_DOWN ? 2 : 1)) + +/mob/living/carbon/proc/adjust_sprint_left(amount) + return + +/mob/living/carbon/human/adjust_sprint_left(amount) + sprint_length = clamp(sprint_length + amount, 0, sprint_length_max) + for(var/atom/movable/screen/mov_intent/selector in hud_used?.static_inventory) + selector.update_appearance(UPDATE_OVERLAYS) + +/mob/living/carbon/proc/drain_sprint() + return + +/mob/living/carbon/human/drain_sprint() + adjust_sprint_left(-1) + // Sprinting when out of sprint will cost stamina + if(sprint_length > 0) + return + + // Okay you're gonna stamcrit yourself, slow your roll + if(getStaminaLoss() >= maxHealth * 0.9) + toggle_move_intent() + return + + adjustStaminaLoss(1) + +/mob/living/carbon/human/fully_heal(heal_flags) + . = ..() + adjust_sprint_left(INFINITY) + +// Minor stamina regeneration effects, such as stimulants, will replenish sprint capacity +/mob/living/carbon/human/adjustStaminaLoss(amount, updating_stamina, forced, required_biotype) + . = ..() + if(amount < 0 && amount >= -20) + adjust_sprint_left(amount * 0.25) + +// Entering stamina critical will drain your sprint capacity entirely +/mob/living/carbon/human/enter_stamcrit() + . = ..() + if(HAS_TRAIT_FROM(src, TRAIT_FLOORED, STAMINA)) + adjust_sprint_left(-INFINITY) diff --git a/config/game_options.txt b/config/game_options.txt index 135123b845ad..423ab5fa0e0b 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -33,7 +33,7 @@ EMOJIS ## These modify the run/walk speed of all mobs before the mob-specific modifiers are applied. RUN_DELAY 1.5 -WALK_DELAY 3 +WALK_DELAY 2.5 ## The variables below affect the movement of specific mob types. THIS AFFECTS ALL SUBTYPES OF THE TYPE YOU CHOOSE! ## Entries completely override all subtypes. Later entries have precedence over earlier entries. diff --git a/shiptest.dme b/shiptest.dme index 55ad11a800d5..d9d28ec476cd 100644 --- a/shiptest.dme +++ b/shiptest.dme @@ -503,7 +503,6 @@ #include "code\datums\components\empprotection.dm" #include "code\datums\components\explodable.dm" #include "code\datums\components\fishing_spot.dm" -#include "code\datums\components\footstep.dm" #include "code\datums\components\forensics.dm" #include "code\datums\components\fullauto.dm" #include "code\datums\components\gps.dm" @@ -665,6 +664,7 @@ #include "code\datums\elements\embed.dm" #include "code\datums\elements\empprotection.dm" #include "code\datums\elements\firestacker.dm" +#include "code\datums\elements\footstep.dm" #include "code\datums\elements\forced_gravity.dm" #include "code\datums\elements\lazy_fishing_spot.dm" #include "code\datums\elements\light_blocking.dm" @@ -2505,6 +2505,7 @@ #include "code\modules\mob\living\living_say.dm" #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm" +#include "code\modules\mob\living\sprint.dm" #include "code\modules\mob\living\status_procs.dm" #include "code\modules\mob\living\taste.dm" #include "code\modules\mob\living\ventcrawling.dm" diff --git a/sound/effects/sprintactivate.ogg b/sound/effects/sprintactivate.ogg new file mode 100644 index 000000000000..f499765dc228 Binary files /dev/null and b/sound/effects/sprintactivate.ogg differ diff --git a/sound/effects/sprintdeactivate.ogg b/sound/effects/sprintdeactivate.ogg new file mode 100644 index 000000000000..c22587ace000 Binary files /dev/null and b/sound/effects/sprintdeactivate.ogg differ diff --git a/sound/effects/tank_treads.ogg b/sound/effects/tank_treads.ogg new file mode 100644 index 000000000000..be4e0ff273be Binary files /dev/null and b/sound/effects/tank_treads.ogg differ