Merge pull request #13015 from silicons/combat_rework_experimental
Combat v4: Redesigning Stamina, Sprint, Combat mode
This commit is contained in:
@@ -191,8 +191,8 @@
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
|
||||
return
|
||||
|
||||
adjustStaminaLossBuffered(STAM_COST_THROW_MOB * ((throwable_mob.mob_size+1)**2))// throwing an entire person shall be very tiring
|
||||
if(!UseStaminaBuffer(STAM_COST_THROW_MOB * ((throwable_mob.mob_size+1)**2), TRUE))
|
||||
return
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
if(start_T && end_T)
|
||||
@@ -206,7 +206,8 @@
|
||||
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
|
||||
return
|
||||
|
||||
adjustStaminaLossBuffered(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST))
|
||||
if(!UseStaminaBuffer(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST), warn = TRUE))
|
||||
return
|
||||
|
||||
if(thrown_thing)
|
||||
var/power_throw = 0
|
||||
@@ -594,15 +595,23 @@
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit)
|
||||
|
||||
/mob/living/carbon/update_stamina()
|
||||
var/stam = getStaminaLoss()
|
||||
if(stam > DAMAGE_PRECISION)
|
||||
var/total_health = (maxHealth - stam)
|
||||
if(total_health <= crit_threshold && !stat)
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
KnockToFloor(TRUE)
|
||||
update_health_hud()
|
||||
|
||||
var/total_health = getStaminaLoss()
|
||||
if(total_health)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && total_health >= STAMINA_CRIT && !stat)
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
set_resting(TRUE, FALSE, FALSE)
|
||||
SEND_SIGNAL(src, COMSIG_DISABLE_COMBAT_MODE)
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_HARD_STAMCRIT)
|
||||
filters += CIT_FILTER_STAMINACRIT
|
||||
update_mobility()
|
||||
if((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && total_health <= STAMINA_CRIT)
|
||||
to_chat(src, "<span class='notice'>You don't feel nearly as exhausted anymore.</span>")
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_HARD_STAMCRIT)
|
||||
filters -= CIT_FILTER_STAMINACRIT
|
||||
update_mobility()
|
||||
UpdateStaminaBuffer()
|
||||
update_health_hud()
|
||||
|
||||
/mob/living/carbon/update_sight()
|
||||
if(!client)
|
||||
return
|
||||
|
||||
@@ -805,7 +805,7 @@
|
||||
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
|
||||
|
||||
hud_used.staminas?.update_icon_state()
|
||||
hud_used.staminabuffer?.update_icon_state()
|
||||
hud_used.staminabuffer?.mark_dirty()
|
||||
|
||||
/mob/living/carbon/human/fully_heal(admin_revive = FALSE)
|
||||
if(admin_revive)
|
||||
@@ -1044,10 +1044,9 @@
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
|
||||
return
|
||||
var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay
|
||||
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment
|
||||
var/scaling = maxHealth / 100
|
||||
var/health_deficiency = (((maxHealth / scaling) + stambufferinfluence) - (health / scaling) + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
var/health_deficiency = ((maxHealth / scaling) - (health / scaling) + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
if(health_deficiency >= 40)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
buckle_lying = FALSE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
/// Enable stamina combat
|
||||
combat_flags = COMBAT_FLAGS_DEFAULT | COMBAT_FLAG_UNARMED_PARRY
|
||||
combat_flags = COMBAT_FLAGS_STAMINA_COMBAT | COMBAT_FLAG_UNARMED_PARRY
|
||||
status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER
|
||||
has_field_of_vision = FALSE //Handled by species.
|
||||
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI
|
||||
if(!SSI)
|
||||
SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase)
|
||||
. -= SSI.config_entry_value
|
||||
if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
@@ -61,7 +56,11 @@
|
||||
HM.on_move(NewLoc)
|
||||
if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_MOVE|MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && (!pulledby || (pulledby.pulledby == src)))
|
||||
if(!HAS_TRAIT(src, TRAIT_FREESPRINT))
|
||||
doSprintLossTiles(1)
|
||||
var/datum/movespeed_modifier/equipment_speedmod/MM = get_movespeed_modifier_datum(/datum/movespeed_modifier/equipment_speedmod)
|
||||
var/amount = 1
|
||||
if(MM?.multiplicative_slowdown >= 1)
|
||||
amount *= (1 + (6 - (3 / MM.multiplicative_slowdown)))
|
||||
doSprintLossTiles(amount)
|
||||
if((oldpseudoheight - pseudo_z_axis) >= 8)
|
||||
to_chat(src, "<span class='warning'>You trip off of the elevated surface!</span>")
|
||||
for(var/obj/item/I in held_items)
|
||||
|
||||
@@ -1364,9 +1364,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(!(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK))
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount
|
||||
user.adjustStaminaLossBuffered(1.5)
|
||||
else
|
||||
user.adjustStaminaLossBuffered(3.5)
|
||||
if(!user.UseStaminaBuffer(1.5, warn = TRUE))
|
||||
return
|
||||
else if(!user.UseStaminaBuffer(3.5, warn = TRUE))
|
||||
return
|
||||
|
||||
if(attacker_style && attacker_style.harm_act(user,target))
|
||||
return TRUE
|
||||
@@ -1505,6 +1506,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return FALSE
|
||||
|
||||
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
|
||||
if(!user.UseStaminaBuffer(3, warn = TRUE))
|
||||
return
|
||||
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
|
||||
|
||||
target.visible_message(\
|
||||
@@ -1512,7 +1515,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
"<span class='notice'>[user] slaps you in the face! </span>",\
|
||||
"You hear a slap.", target = user, target_message = "<span class='notice'>You slap [user == target ? "yourself" : "\the [target]"] in the face! </span>")
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_FACE_SLAP)
|
||||
user.adjustStaminaLossBuffered(3)
|
||||
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
|
||||
stop_wagging_tail(target)
|
||||
return FALSE
|
||||
@@ -1520,8 +1522,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
|
||||
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
|
||||
return FALSE
|
||||
if(!user.UseStaminaBuffer(3, warn = TRUE))
|
||||
return FALSE
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_ASS_SLAP)
|
||||
user.adjustStaminaLossBuffered(3)
|
||||
target.adjust_arousal(20,maso = TRUE)
|
||||
if (ishuman(target) && HAS_TRAIT(target, TRAIT_MASO) && target.has_dna() && prob(10))
|
||||
target.mob_climax(forced_climax=TRUE)
|
||||
@@ -1539,9 +1542,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes disarmspam cause staminaloss, pugilists can do it almost effortlessly
|
||||
user.adjustStaminaLossBuffered(1)
|
||||
if(!user.UseStaminaBuffer(1, warn = TRUE))
|
||||
return
|
||||
else
|
||||
user.adjustStaminaLossBuffered(3)
|
||||
if(!user.UseStaminaBuffer(1, warn = TRUE))
|
||||
return
|
||||
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
return TRUE
|
||||
@@ -1777,9 +1782,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
to_chat(user, "<span class='notice'>You can only force yourself up if you're on the ground.</span>")
|
||||
return
|
||||
if(!user.UseStaminaBuffer(STAMINA_COST_SHOVE_UP, TRUE))
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] forces [p_them()]self up to [p_their()] feet!</span>", "<span class='notice'>You force yourself up to your feet!</span>")
|
||||
user.set_resting(FALSE, TRUE)
|
||||
user.adjustStaminaLossBuffered(user.stambuffer) //Rewards good stamina management by making it easier to instantly get up from resting
|
||||
playsound(user, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
@@ -1798,8 +1804,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else
|
||||
if(user == target)
|
||||
return
|
||||
if(!user.UseStaminaBuffer(4, warn = TRUE))
|
||||
return
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
|
||||
user.adjustStaminaLossBuffered(4)
|
||||
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
|
||||
|
||||
if(target.w_uniform)
|
||||
|
||||
@@ -502,19 +502,14 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
if(getStaminaLoss() && !SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)) //CIT CHANGE - prevents stamina regen while combat mode is active
|
||||
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? STAM_RECOVERY_STAM_CRIT : STAM_RECOVERY_RESTING) : STAM_RECOVERY_NORMAL)
|
||||
var/combat_mode = SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE)
|
||||
if(getStaminaLoss() && !HAS_TRAIT(src, TRAIT_NO_STAMINA_REGENERATION))
|
||||
adjustStaminaLoss((!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? STAM_RECOVERY_STAM_CRIT : STAM_RECOVERY_RESTING) : STAM_RECOVERY_NORMAL) * (combat_mode? 0.25 : 1))
|
||||
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && incomingstammult != 1)
|
||||
incomingstammult = max(0.01, incomingstammult)
|
||||
incomingstammult = min(1, incomingstammult*2)
|
||||
|
||||
//CIT CHANGES START HERE. STAMINA BUFFER STUFF
|
||||
if(bufferedstam && world.time > stambufferregentime)
|
||||
var/drainrate = max((bufferedstam*(bufferedstam/(5)))*0.1,1)
|
||||
bufferedstam = max(bufferedstam - drainrate, 0)
|
||||
//END OF CIT CHANGES
|
||||
|
||||
var/restingpwr = 1 + 4 * !CHECK_MOBILITY(src, MOBILITY_STAND)
|
||||
|
||||
//Dizziness
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
|
||||
diag_hud.add_to_hud(src)
|
||||
faction += "[REF(src)]"
|
||||
stamina_buffer = INFINITY
|
||||
UpdateStaminaBuffer()
|
||||
GLOB.mob_living_list += src
|
||||
|
||||
/mob/living/prepare_huds()
|
||||
@@ -1257,7 +1259,7 @@
|
||||
SetUnconscious(clamp_unconscious_to)
|
||||
HealAllImmobilityUpTo(clamp_immobility_to)
|
||||
adjustStaminaLoss(min(0, -stamina_boost))
|
||||
adjustStaminaLossBuffered(min(0, -stamina_buffer_boost))
|
||||
RechargeStaminaBuffer(stamina_buffer_boost) // this MUST GO AFTER ADJUSTSTAMINALOSS.
|
||||
if(scale_stamina_loss_recovery)
|
||||
adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0))
|
||||
if(put_on_feet)
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
active_block_item = null
|
||||
REMOVE_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_BLOCK_TRAIT)
|
||||
REMOVE_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT)
|
||||
REMOVE_TRAIT(src, TRAIT_NO_STAMINA_BUFFER_REGENERATION, ACTIVE_BLOCK_TRAIT)
|
||||
REMOVE_TRAIT(src, TRAIT_NO_STAMINA_REGENERATION, ACTIVE_BLOCK_TRAIT)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/active_block)
|
||||
var/datum/block_parry_data/data = I.get_block_parry_data()
|
||||
DelayNextAction(data.block_end_click_cd_add)
|
||||
@@ -27,6 +29,10 @@
|
||||
ADD_TRAIT(src, TRAIT_MOBILITY_NOUSE, ACTIVE_BLOCK_TRAIT) //probably should be something else at some point
|
||||
if(data.block_lock_sprinting)
|
||||
ADD_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT)
|
||||
if(data.block_no_stamina_regeneration)
|
||||
ADD_TRAIT(src, TRAIT_NO_STAMINA_REGENERATION, ACTIVE_BLOCK_TRAIT)
|
||||
if(data.block_no_stambuffer_regeneration)
|
||||
ADD_TRAIT(src, TRAIT_NO_STAMINA_BUFFER_REGENERATION, ACTIVE_BLOCK_TRAIT)
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/active_block, multiplicative_slowdown = data.block_slowdown)
|
||||
active_block_effect_start()
|
||||
return TRUE
|
||||
@@ -192,7 +198,7 @@
|
||||
var/held_index = C.get_held_index_of_item(src)
|
||||
var/obj/item/bodypart/BP = C.hand_bodyparts[held_index]
|
||||
if(!BP?.body_zone)
|
||||
return C.adjustStaminaLossBuffered(stamina_amount) //nah
|
||||
return C.adjustStaminaLoss(stamina_amount) //nah
|
||||
var/zone = BP.body_zone
|
||||
var/stamina_to_zone = data.block_stamina_limb_ratio * stamina_amount
|
||||
var/stamina_to_chest = stamina_amount - stamina_to_zone
|
||||
@@ -200,9 +206,9 @@
|
||||
stamina_to_chest -= stamina_buffered
|
||||
C.apply_damage(stamina_to_zone, STAMINA, zone)
|
||||
C.apply_damage(stamina_to_chest, STAMINA, BODY_ZONE_CHEST)
|
||||
C.adjustStaminaLossBuffered(stamina_buffered)
|
||||
C.adjustStaminaLoss(stamina_buffered)
|
||||
else
|
||||
owner.adjustStaminaLossBuffered(stamina_amount)
|
||||
owner.adjustStaminaLoss(stamina_amount)
|
||||
|
||||
/obj/item/proc/on_active_block(mob/living/owner, atom/object, damage, damage_blocked, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return, override_direction)
|
||||
return
|
||||
|
||||
@@ -68,12 +68,13 @@
|
||||
// can always implement it later, whatever.
|
||||
if((data.parry_respect_clickdelay && !CheckActionCooldown()) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
to_chat(src, "<span class='warning'>You are not ready to parry (again)!</span>")
|
||||
return
|
||||
return FALSE
|
||||
// Point of no return, make sure everything is set.
|
||||
parrying = method
|
||||
if(method == ITEM_PARRY)
|
||||
active_parry_item = using_item
|
||||
adjustStaminaLossBuffered(data.parry_stamina_cost)
|
||||
if(!UseStaminaBuffer(data.parry_stamina_cost, TRUE))
|
||||
return FALSE
|
||||
parry_start_time = world.time
|
||||
successful_parries = list()
|
||||
addtimer(CALLBACK(src, .proc/end_parry_sequence), full_parry_duration)
|
||||
|
||||
@@ -74,8 +74,12 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/// Ratio of stamina incurred by chest (so after [block_stamina_limb_ratio] runs) that is buffered.
|
||||
var/block_stamina_buffer_ratio = 1
|
||||
|
||||
/// Stamina dealt directly via adjustStaminaLossBuffered() per SECOND of block.
|
||||
/// Stamina dealt directly via UseStaminaBuffer() per SECOND of block.
|
||||
var/block_stamina_cost_per_second = 1.5
|
||||
/// Prevent stamina buffer regeneration while block?
|
||||
var/block_no_stambuffer_regeneration = TRUE
|
||||
/// Prevent stamina regeneration while block?
|
||||
var/block_no_stamina_regeneration = FALSE
|
||||
|
||||
/// Bitfield for attack types that we can block while down. This will work in any direction.
|
||||
var/block_resting_attack_types_anydir = ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED | ATTACK_TYPE_TACKLE
|
||||
@@ -307,7 +311,7 @@ GLOBAL_LIST_EMPTY(block_parry_data)
|
||||
/mob/living/proc/handle_block_parry(seconds = 1)
|
||||
if(combat_flags & COMBAT_FLAG_ACTIVE_BLOCKING)
|
||||
var/datum/block_parry_data/data = return_block_parry_datum(active_block_item.block_parry_data)
|
||||
adjustStaminaLossBuffered(data.block_stamina_cost_per_second * seconds)
|
||||
UseStaminaBuffer(data.block_stamina_cost_per_second * seconds)
|
||||
|
||||
/mob/living/on_item_dropped(obj/item/I)
|
||||
if(I == active_block_item)
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
|
||||
|
||||
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
|
||||
var/timeofdeath = 0
|
||||
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
@@ -148,9 +149,6 @@
|
||||
var/combatmessagecooldown = 0
|
||||
|
||||
var/incomingstammult = 1
|
||||
var/bufferedstam = 0
|
||||
var/stambuffer = 20
|
||||
var/stambufferregentime
|
||||
|
||||
//Sprint buffer---
|
||||
var/sprint_buffer = 42 //Tiles
|
||||
@@ -159,3 +157,13 @@
|
||||
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
|
||||
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
|
||||
//---End
|
||||
|
||||
// Stamina Buffer---
|
||||
/// Our stamina buffer
|
||||
var/stamina_buffer
|
||||
/// Stamina buffer regen modifier
|
||||
var/stamina_buffer_regen_mod = 1
|
||||
/// Last time stamina buffer regen was done
|
||||
var/stamina_buffer_regen_last = 0
|
||||
/// Last time we used stamina buffer
|
||||
var/stamina_buffer_last_use = 0
|
||||
|
||||
@@ -176,4 +176,6 @@
|
||||
else
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/limbless)
|
||||
|
||||
update_movespeed()
|
||||
|
||||
return mobility_flags
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
add_movespeed_modifier(/datum/movespeed_modifier/sprinting)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
@@ -36,6 +37,7 @@
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) || (combat_flags & COMBAT_FLAG_SPRINT_FORCED))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/sprinting)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
|
||||
@@ -1132,10 +1132,6 @@
|
||||
bellyup = 1
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_health = 1)
|
||||
if(istype(cell))
|
||||
cell.charge -= amount * 5
|
||||
|
||||
/mob/living/silicon/robot/verb/viewmanifest()
|
||||
set category = "Robot Commands"
|
||||
set name = "View Crew Manifest"
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Attempts to use an amount of stamina from our stamina buffer.
|
||||
* Does not use anything if we don't have enough.
|
||||
*
|
||||
* Returns TRUE or FALSE based on if we have it.
|
||||
*/
|
||||
/mob/living/proc/UseStaminaBuffer(amount, warn = FALSE, considered_action = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_STAMINA_BUFFER))
|
||||
return TRUE
|
||||
if(stamina_buffer < amount)
|
||||
var/stamina_health = getStaminaLoss()
|
||||
if(stamina_health > STAMINA_NO_OVERDRAW_THRESHOLD)
|
||||
if(warn)
|
||||
to_chat(src, "<span class='warning'>You do not have enough action stamina to do that!</span>")
|
||||
return FALSE
|
||||
adjustStaminaLoss(amount * CONFIG_GET(number/stamina_combat/overdraw_penalty_factor))
|
||||
else
|
||||
stamina_buffer -= amount
|
||||
if(considered_action)
|
||||
stamina_buffer_last_use = world.time
|
||||
UpdateStaminaBuffer()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Updates our stamina buffer amount.
|
||||
*/
|
||||
/mob/living/proc/UpdateStaminaBuffer(updating_hud = TRUE)
|
||||
var/time = world.time - stamina_buffer_regen_last
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/buffer_max, buffer_max)
|
||||
stamina_buffer_regen_last = world.time
|
||||
if((stamina_buffer >= buffer_max) || !(combat_flags & COMBAT_FLAG_STAMINA_BUFFER))
|
||||
stamina_buffer = buffer_max
|
||||
return
|
||||
else if(!time || HAS_TRAIT(src, TRAIT_NO_STAMINA_BUFFER_REGENERATION))
|
||||
return
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/out_of_combat_timer, out_of_combat_timer)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/base_regeneration, base_regeneration)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/combat_regeneration, combat_regeneration)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/percent_regeneration_out_of_combat, percent_regeneration_out_of_combat)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_delay, post_action_penalty_delay)
|
||||
CONFIG_CACHE_ENTRY_AND_FETCH_VALUE(number/stamina_combat/post_action_penalty_factor, post_action_penalty_factor)
|
||||
var/base_regen = (SEND_SIGNAL(src, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))? base_regeneration : combat_regeneration
|
||||
var/time_since_last_action = world.time - stamina_buffer_last_use
|
||||
var/action_penalty = ((time_since_last_action) < (post_action_penalty_delay * 10))? post_action_penalty_factor : 1
|
||||
var/out_of_combat_bonus = (time_since_last_action < (out_of_combat_timer * 10))? 0 : ((buffer_max * percent_regeneration_out_of_combat * 0.01))
|
||||
var/regen = ((base_regen * action_penalty) + out_of_combat_bonus) * time * 0.1 * stamina_buffer_regen_mod
|
||||
stamina_buffer += min((buffer_max - stamina_buffer), regen)
|
||||
if(updating_hud)
|
||||
hud_used?.staminabuffer?.mark_dirty()
|
||||
|
||||
/**
|
||||
* Boosts our stamina buffer by this much.
|
||||
*/
|
||||
/mob/living/proc/RechargeStaminaBuffer(amount)
|
||||
stamina_buffer += abs(amount)
|
||||
UpdateStaminaBuffer()
|
||||
@@ -38,6 +38,12 @@ Key procs
|
||||
|
||||
/// Multiplicative slowdown
|
||||
var/multiplicative_slowdown = 0
|
||||
/// Next two variables depend on this: Should we do advanced calculations?
|
||||
var/complex_calculation = FALSE
|
||||
/// Absolute max tiles we can boost to
|
||||
var/absolute_max_tiles_per_second
|
||||
/// Max tiles per second we can boost
|
||||
var/max_tiles_per_second_boost
|
||||
|
||||
/// Movetypes this applies to
|
||||
var/movetypes = ALL
|
||||
@@ -53,6 +59,16 @@ Key procs
|
||||
if(!id)
|
||||
id = "[type]" //We turn the path into a string.
|
||||
|
||||
/**
|
||||
* Returns new multiplicative movespeed after modification.
|
||||
*/
|
||||
/datum/movespeed_modifier/proc/apply_multiplicative(existing, mob/target)
|
||||
if(!complex_calculation || (multiplicative_slowdown > 0)) // we aren't limiting how much things can slowdown.. yet.
|
||||
return existing + multiplicative_slowdown
|
||||
var/current_tiles = 10 / max(existing, world.tick_lag)
|
||||
var/minimum_speed = 10 / min(current_tiles + max_tiles_per_second_boost, max(current_tiles, absolute_max_tiles_per_second))
|
||||
return max(minimum_speed, existing + multiplicative_slowdown)
|
||||
|
||||
GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
|
||||
/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO!
|
||||
@@ -171,13 +187,15 @@ GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
/// Set or update the global movespeed config on a mob
|
||||
/mob/proc/update_config_movespeed()
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod, multiplicative_slowdown = get_config_multiplicative_speed())
|
||||
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod_floating, multiplicative_slowdown = get_config_multiplicative_speed(TRUE))
|
||||
|
||||
/// Get the global config movespeed of a mob by type
|
||||
/mob/proc/get_config_multiplicative_speed()
|
||||
if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type])
|
||||
/mob/proc/get_config_multiplicative_speed(floating = FALSE)
|
||||
var/list/read = floating? GLOB.mob_config_movespeed_type_lookup_floating : GLOB.mob_config_movespeed_type_lookup
|
||||
if(!islist(read) || !read[type])
|
||||
return 0
|
||||
else
|
||||
return GLOB.mob_config_movespeed_type_lookup[type]
|
||||
return read[type]
|
||||
|
||||
/// Go through the list of movespeed modifiers and calculate a final movespeed. ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
|
||||
/mob/proc/update_movespeed()
|
||||
@@ -198,7 +216,7 @@ GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
conflict_tracker[conflict] = amt
|
||||
else
|
||||
continue
|
||||
. += amt
|
||||
. = M.apply_multiplicative(., src)
|
||||
var/old = cached_multiplicative_slowdown // CITAEDL EDIT - To make things a bit less jarring, when in situations where
|
||||
// your delay decreases, "give" the delay back to the client
|
||||
cached_multiplicative_slowdown = .
|
||||
@@ -220,6 +238,13 @@ GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
var/datum/movespeed_modifier/M = movespeed_modification[id]
|
||||
. += M.multiplicative_slowdown
|
||||
|
||||
/**
|
||||
* Gets the movespeed modifier datum of a modifier on a mob. Returns null if not found.
|
||||
* DANGER: IT IS UP TO THE PERSON USING THIS TO MAKE SURE THE MODIFIER IS NOT MODIFIED IF IT HAPPENS TO BE GLOBAL/CACHED.
|
||||
*/
|
||||
/mob/proc/get_movespeed_modifier_datum(id)
|
||||
return movespeed_modification[id]
|
||||
|
||||
/// Checks if a move speed modifier is valid and not missing any data
|
||||
/proc/movespeed_data_null_check(datum/movespeed_modifier/M) //Determines if a data list is not meaningful and should be discarded.
|
||||
. = TRUE
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/datum/movespeed_modifier/jetpack
|
||||
conflicts_with = MOVE_CONFLICT_JETPACK
|
||||
movetypes = FLOATING
|
||||
multiplicative_slowdown = -1
|
||||
|
||||
/datum/movespeed_modifier/jetpack/cybernetic
|
||||
multiplicative_slowdown = -0.5
|
||||
multiplicative_slowdown = -1.25
|
||||
|
||||
/datum/movespeed_modifier/jetpack/fullspeed
|
||||
multiplicative_slowdown = -2
|
||||
multiplicative_slowdown = -1.5
|
||||
|
||||
/datum/movespeed_modifier/die_of_fate
|
||||
multiplicative_slowdown = 1
|
||||
|
||||
@@ -111,6 +111,12 @@
|
||||
|
||||
/datum/movespeed_modifier/mob_config_speedmod
|
||||
variable = TRUE
|
||||
blacklisted_movetypes = FLOATING
|
||||
flags = IGNORE_NOSLOW
|
||||
|
||||
/datum/movespeed_modifier/mob_config_speedmod_floating
|
||||
variable = TRUE
|
||||
movetypes = FLOATING
|
||||
flags = IGNORE_NOSLOW
|
||||
|
||||
/datum/movespeed_modifier/liver_cirrhosis
|
||||
@@ -120,3 +126,30 @@
|
||||
/datum/movespeed_modifier/active_block
|
||||
variable = TRUE
|
||||
flags = IGNORE_NOSLOW
|
||||
|
||||
/datum/movespeed_modifier/sprinting
|
||||
flags = IGNORE_NOSLOW
|
||||
blacklisted_movetypes = FLOATING
|
||||
priority = 100
|
||||
|
||||
/// for speed reasons this is sorta copypasty.
|
||||
/datum/movespeed_modifier/sprinting/apply_multiplicative(existing, mob/target)
|
||||
. = existing
|
||||
if(target.m_intent != MOVE_INTENT_RUN)
|
||||
return
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!(L.mobility_flags & MOBILITY_STAND))
|
||||
return
|
||||
var/static/datum/config_entry/number/movedelay/sprint_max_tiles_increase/SMTI
|
||||
if(!SMTI)
|
||||
SMTI = CONFIG_GET_ENTRY(number/movedelay/sprint_max_tiles_increase)
|
||||
var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI
|
||||
if(!SSI)
|
||||
SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase)
|
||||
var/static/datum/config_entry/number/movedelay/sprint_absolute_max_tiles/SAMT
|
||||
if(!SAMT)
|
||||
SAMT = CONFIG_GET_ENTRY(number/movedelay/sprint_absolute_max_tiles)
|
||||
var/current_tiles = 10 / max(existing, world.tick_lag)
|
||||
var/minimum_speed = 10 / min(max(SAMT.config_entry_value, current_tiles), current_tiles + SMTI.config_entry_value)
|
||||
. = min(., max(minimum_speed, existing - SSI.config_entry_value))
|
||||
|
||||
@@ -154,8 +154,8 @@
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
|
||||
if(stam_cost) //CIT CHANGE - makes gun recoil cause staminaloss
|
||||
var/safe_cost = clamp(stam_cost, 0, STAMINA_NEAR_CRIT - user.getStaminaLoss())*(firing && burst_size >= 2 ? 1/burst_size : 1)
|
||||
user.adjustStaminaLossBuffered(safe_cost) //CIT CHANGE - ditto
|
||||
var/safe_cost = clamp(stam_cost, 0, user.stamina_buffer)*(firing && burst_size >= 2 ? 1/burst_size : 1)
|
||||
user.UseStaminaBuffer(safe_cost)
|
||||
|
||||
if(suppressed)
|
||||
playsound(user, fire_sound, 10, 1)
|
||||
@@ -590,6 +590,9 @@
|
||||
update_icon()
|
||||
|
||||
/obj/item/gun/proc/getinaccuracy(mob/living/user, bonus_spread, stamloss)
|
||||
return 0 // Replacement TBD: Exponential curved aim instability system.
|
||||
|
||||
/*
|
||||
if(inaccuracy_modifier == 0)
|
||||
return bonus_spread
|
||||
var/base_inaccuracy = weapon_weight * 25 * inaccuracy_modifier
|
||||
@@ -612,6 +615,7 @@
|
||||
if(mult < 0) //accurate weapons should provide a proper bonus with negative inaccuracy. the opposite is true too.
|
||||
mult *= 1/inaccuracy_modifier
|
||||
return max(bonus_spread + (base_inaccuracy * mult), 0) //no negative spread.
|
||||
*/
|
||||
|
||||
/obj/item/gun/proc/getstamcost(mob/living/carbon/user)
|
||||
. = recoil
|
||||
|
||||
@@ -44,10 +44,9 @@
|
||||
if(HAS_TRAIT(user, TRAIT_FAST_PUMP))
|
||||
recentpump = world.time + 2
|
||||
else
|
||||
if(!user.UseStaminaBuffer(2, warn = TRUE))
|
||||
return
|
||||
recentpump = world.time + 10
|
||||
if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina.
|
||||
user.adjustStaminaLossBuffered(2) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added
|
||||
return
|
||||
|
||||
/obj/item/gun/ballistic/shotgun/blow_up(mob/user)
|
||||
. = 0
|
||||
|
||||
Reference in New Issue
Block a user