Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ravager Revork Episode 5: Ravager Strikes Back #155

Merged
merged 11 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,10 @@ GLOBAL_LIST_INIT(xenoupgradetiers, list(XENO_UPGRADE_BASETYPE, XENO_UPGRADE_INVA

#define RAVAGER_RAGE_DURATION 10 SECONDS
#define RAVAGER_RAGE_WARNING 0.7
#define RAVAGER_RAGE_MIN_HEALTH_THRESHOLD 0.5 //The maximum % of HP we can have to trigger Rage
#define RAVAGER_RAGE_MIN_HEALTH_THRESHOLD 0.75 //The maximum % of HP we can have to trigger Rage
#define RAVAGER_RAGE_STAGGERSTUN_IMMUNE_THRESHOLD 0.5
#define RAVAGER_RAGE_ENDURE_INCREASE_PER_SLASH 2 SECONDS //The amount of time each slash during Rage increases Endure's duration
#define RAVAGER_RAGE_HEALTH_RECOVERY_PER_SLASH 80 //Maximum amount of healing from slash during Rage
#define RAVAGER_RAGE_HEALTH_RECOVERY_PER_SLASH 60 //Maximum amount of healing from slash during Rage

//crusher defines
#define CRUSHER_STOMP_LOWER_DMG 40
Expand Down
7 changes: 0 additions & 7 deletions code/datums/keybinding/xeno.dm
Original file line number Diff line number Diff line change
Expand Up @@ -742,13 +742,6 @@
keybind_signal = COMSIG_XENOABILITY_ENDURE
hotkey_keys = list("F")

/datum/keybinding/xeno/ravager_rage
name = "ravager_rage"
full_name = "Ravager: Rage"
description = "While active, you will temporarily recover plasma and sunder and gain a bonus to speed and melee damage in proportion to the percentage of your missing health. At negative HP your ability cooldowns reset and your slash damage restores health."
keybind_signal = COMSIG_XENOABILITY_RAGE
hotkey_keys = list("Space")

/datum/keybinding/xeno/ravager_vampirism
name = "togglevampirism"
full_name = "Ravager: Toggle vampirism"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,156 +304,6 @@
return FALSE
return TRUE

// ***************************************
// *********** Rage
// ***************************************
/datum/action/ability/xeno_action/rage
name = "Rage"
action_icon_state = "rage"
desc = "Use while at 50% health or lower to gain extra slash damage, resistances and speed in proportion to your missing hit points. This bonus is increased and you regain plasma while your HP is negative."
ability_cost = 0 //We're limited by cooldowns, not plasma
cooldown_duration = 60 SECONDS
keybind_flags = ABILITY_KEYBIND_USE_ABILITY | ABILITY_IGNORE_SELECTED_ABILITY
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_RAGE,
)
///Determines the power of Rage's many effects. Power scales inversely with the Ravager's HP; min 0.25 at 50% of Max HP, max 1 while in negative HP. 0.5 and above triggers especial effects.
var/rage_power
///Determines the Plasma to remove when Rage ends
var/rage_plasma

/datum/action/ability/xeno_action/rage/on_cooldown_finish()
to_chat(owner, span_xenodanger("We are able to enter our rage once again."))
owner.playsound_local(owner, 'sound/effects/alien/newlarva.ogg', 25, 0, 1)
return ..()

/datum/action/ability/xeno_action/rage/can_use_action(atom/A, silent = FALSE, override_flags)
. = ..()
if(!.)
return FALSE

var/mob/living/carbon/xenomorph/rager = owner

if(rager.health > rager.maxHealth * RAVAGER_RAGE_MIN_HEALTH_THRESHOLD) //Need to be at 50% of max hp or lower to rage
if(!silent)
to_chat(rager, span_xenodanger("Our health isn't low enough to rage! We must take [rager.health - (rager.maxHealth * RAVAGER_RAGE_MIN_HEALTH_THRESHOLD)] more damage!"))
return FALSE


/datum/action/ability/xeno_action/rage/action_activate()
var/mob/living/carbon/xenomorph/X = owner

var/rage_threshold = X.maxHealth * (1 - RAVAGER_RAGE_MIN_HEALTH_THRESHOLD)
rage_power = max(0, (1 - ((X.health - RAVAGER_ENDURE_HP_LIMIT) / (X.maxHealth - RAVAGER_ENDURE_HP_LIMIT - rage_threshold)))) //Calculate the power of our rage; scales with difference between current and max HP

var/rage_power_radius = CEILING(rage_power * 3, 1) //Define radius of the SFX

X.visible_message(span_danger("\The [X] becomes frenzied, bellowing with a shuddering roar!"), \
span_highdanger("We bellow as our fury overtakes us! RIP AND TEAR!"))
X.do_jitter_animation(1000)

//Roar SFX; volume scales with rage
playsound(X.loc, 'sound/voice/alien/roar2.ogg', clamp(100 * rage_power, 25, 80), 0)

var/bonus_duration

var/datum/action/ability/xeno_action/endure/endure_ability = X.actions_by_path[/datum/action/ability/xeno_action/endure]
if(endure_ability.endure_duration) //Check if Endure is active
endure_ability.endure_threshold = RAVAGER_ENDURE_HP_LIMIT * (1 + rage_power) //Endure crit threshold scales with Rage Power; min -100, max -150
RegisterSignal(X, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(drain_slash))

for(var/turf/affected_tiles AS in RANGE_TURFS(rage_power_radius * 0.5, X.loc))
affected_tiles.Shake(duration = 1 SECONDS) //SFX

for(var/mob/living/affected_mob in cheap_get_humans_near(X, rage_power_radius) + cheap_get_xenos_near(X, rage_power_radius)) //Roar that applies cool SFX
if(affected_mob.stat || affected_mob == X) //We don't care about the dead/unconsious || RUTGMC EDIT
continue

shake_camera(affected_mob, 1 SECONDS, 1)
affected_mob.Shake(duration = 1 SECONDS) //SFX

X.add_filter("ravager_rage_outline", 5, outline_filter(1.5, COLOR_RED)) //Set our cool aura; also confirmation we have the buff

rage_plasma = min(X.xeno_caste.plasma_max - X.plasma_stored, X.xeno_caste.plasma_max * rage_power) //Calculate the plasma to restore (and take away later)
X.plasma_stored += rage_plasma //Regain a % of our maximum plasma scaling with rage
X.xeno_melee_damage_modifier += rage_power //Set rage melee damage bonus

X.add_movespeed_modifier(MOVESPEED_ID_RAVAGER_RAGE, TRUE, 0, NONE, TRUE, X.xeno_caste.speed * 0.5 * rage_power) //Set rage speed bonus

//Too angry to be stunned/slowed/staggered/knocked down
ADD_TRAIT(X, TRAIT_STUNIMMUNE, RAGE_TRAIT)
ADD_TRAIT(X, TRAIT_SLOWDOWNIMMUNE, RAGE_TRAIT)
ADD_TRAIT(X, TRAIT_STAGGERIMMUNE, RAGE_TRAIT)

addtimer(CALLBACK(src, PROC_REF(rage_warning), bonus_duration), (RAVAGER_RAGE_DURATION + bonus_duration) * RAVAGER_RAGE_WARNING) //Warn the ravager when rage is about to expire.
addtimer(CALLBACK(src, PROC_REF(rage_deactivate)), (RAVAGER_RAGE_DURATION + bonus_duration))

succeed_activate()
add_cooldown()

GLOB.round_statistics.ravager_rages++ //Statistics
SSblackbox.record_feedback("tally", "round_statistics", 1, "ravager_rages")

///Warns the user when his rage is about to end.
/datum/action/ability/xeno_action/rage/proc/rage_warning(bonus_duration = 0)
if(QDELETED(owner))
return
to_chat(owner,span_highdanger("Our rage begins to subside... [initial(name)] will only last for only [(RAVAGER_RAGE_DURATION + bonus_duration) * (1-RAVAGER_RAGE_WARNING) * 0.1] more seconds!"))
owner.playsound_local(owner, 'sound/voice/alien/hiss8.ogg', 50, 0, 1)

///Warns the user when his rage is about to end.
/datum/action/ability/xeno_action/rage/proc/drain_slash(datum/source, mob/living/target, damage, list/damage_mod, list/armor_mod)
SIGNAL_HANDLER
var/mob/living/rager = owner
var/brute_damage = rager.getBruteLoss()
var/burn_damage = rager.getFireLoss()
if(!brute_damage && !burn_damage) //If we have no healable damage, don't bother proceeding
return
var/health_recovery = rage_power * RAVAGER_RAGE_HEALTH_RECOVERY_PER_SLASH //Amount of health we leech per slash
var/health_modifier
if(brute_damage) //First heal Brute damage, then heal Burn damage with remainder
health_modifier = min(brute_damage, health_recovery)*-1 //Get the lower of our Brute Loss or the health we're leeching
rager.adjustBruteLoss(health_modifier)
health_recovery += health_modifier //Decrement the amount healed from our total healing pool
if(burn_damage)
health_modifier = min(burn_damage, health_recovery)*-1
rager.adjustFireLoss(health_modifier)

var/datum/action/ability/xeno_action/endure/endure_ability = rager.actions_by_path[/datum/action/ability/xeno_action/endure]
if(endure_ability.endure_duration) //Check if Endure is active
var/new_duration = min(RAVAGER_ENDURE_DURATION, (timeleft(endure_ability.endure_duration) + RAVAGER_RAGE_ENDURE_INCREASE_PER_SLASH * rage_power)) //Increment Endure duration by 2 seconds per slash at maximum rage
deltimer(endure_ability.endure_duration) //Reset timers
deltimer(endure_ability.endure_warning_duration)
endure_ability.endure_duration = addtimer(CALLBACK(endure_ability, TYPE_PROC_REF(/datum/action/ability/xeno_action/endure, endure_deactivate)), new_duration, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_OVERRIDE) //Reset Endure timers if active
if(new_duration > 3 SECONDS) //Check timing
endure_ability.endure_warning_duration = addtimer(CALLBACK(endure_ability, TYPE_PROC_REF(/datum/action/ability/xeno_action/endure, endure_warning)), new_duration - 3 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_OVERRIDE) //Reset Endure timers if active

///Called when we want to end the Rage effect
/datum/action/ability/xeno_action/rage/proc/rage_deactivate()
if(QDELETED(owner))
return
var/mob/living/carbon/xenomorph/X = owner

X.do_jitter_animation(1000)

X.remove_filter("ravager_rage_outline")
X.visible_message(span_warning("[X] seems to calm down."), \
span_highdanger("Our rage subsides and its power leaves our body, leaving us exhausted."))

X.xeno_melee_damage_modifier = initial(X.xeno_melee_damage_modifier) //Reset rage melee damage bonus
X.remove_movespeed_modifier(MOVESPEED_ID_RAVAGER_RAGE) //Reset speed
X.use_plasma(rage_plasma) //Remove the temporary Plasma

REMOVE_TRAIT(X, TRAIT_STUNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(X, TRAIT_SLOWDOWNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(X, TRAIT_STAGGERIMMUNE, RAGE_TRAIT)
UnregisterSignal(X, COMSIG_XENOMORPH_ATTACK_LIVING)

rage_power = 0
rage_plasma = 0
X.playsound_local(X, 'sound/voice/alien/hiss8.ogg', 50) //Audio cue


// ***************************************
// *********** Vampirism
// ***************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
/datum/action/ability/activable/xeno/charge,
/datum/action/ability/activable/xeno/ravage,
/datum/action/ability/xeno_action/endure,
/datum/action/ability/xeno_action/rage,
)

/datum/xeno_caste/ravager/on_caste_applied(mob/xenomorph)
Expand Down Expand Up @@ -76,6 +75,5 @@
/datum/action/ability/activable/xeno/charge,
/datum/action/ability/activable/xeno/ravage,
/datum/action/ability/xeno_action/endure,
/datum/action/ability/xeno_action/rage,
/datum/action/ability/xeno_action/vampirism,
)
83 changes: 83 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/ravager/ravager.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,94 @@
pixel_x = -16
old_x = -16
bubble_icon = "alienroyal"
var/rage_power
var/rage = FALSE
var/staggerstun_immune = FALSE
var/on_cooldown = FALSE

/mob/living/carbon/xenomorph/ravager/Initialize(mapload)
. = ..()
ADD_TRAIT(src, TRAIT_LIGHT_STEP, XENO_TRAIT)

/mob/living/carbon/xenomorph/ravager/Life()
. = ..()
if(health > maxHealth * RAVAGER_RAGE_MIN_HEALTH_THRESHOLD)
homexp13 marked this conversation as resolved.
Show resolved Hide resolved
if(!rage)
return
rage = FALSE
on_cooldown = FALSE
rage_power = 0
remove_filter("ravager_rage_outline")
xeno_melee_damage_modifier = initial(xeno_melee_damage_modifier)
remove_movespeed_modifier(MOVESPEED_ID_RAVAGER_RAGE)
REMOVE_TRAIT(src, TRAIT_STUNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(src, TRAIT_SLOWDOWNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(src, TRAIT_STAGGERIMMUNE, RAGE_TRAIT)
UnregisterSignal(src, COMSIG_XENOMORPH_ATTACK_LIVING)
playsound_local(src, 'sound/voice/alien/hiss8.ogg', 50)
balloon_alert(src, "We are rested enough")
return

var/rage_threshold = maxHealth * (1 - RAVAGER_RAGE_MIN_HEALTH_THRESHOLD)
rage_power = max(0, (1 - ((health - RAVAGER_ENDURE_HP_LIMIT) / (maxHealth - RAVAGER_ENDURE_HP_LIMIT - rage_threshold))))

add_filter("ravager_rage_outline", 5, outline_filter(rage_power, COLOR_RED))

if(!rage)
RegisterSignal(src, COMSIG_XENOMORPH_ATTACK_LIVING, PROC_REF(drain_slash))
rage = TRUE

if(!staggerstun_immune && (health <= maxHealth * RAVAGER_RAGE_STAGGERSTUN_IMMUNE_THRESHOLD))
ADD_TRAIT(src, TRAIT_STUNIMMUNE, RAGE_TRAIT)
ADD_TRAIT(src, TRAIT_SLOWDOWNIMMUNE, RAGE_TRAIT)
ADD_TRAIT(src, TRAIT_STAGGERIMMUNE, RAGE_TRAIT)
staggerstun_immune = TRUE
else if (health > maxHealth * RAVAGER_RAGE_STAGGERSTUN_IMMUNE_THRESHOLD)
REMOVE_TRAIT(src, TRAIT_STUNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(src, TRAIT_SLOWDOWNIMMUNE, RAGE_TRAIT)
REMOVE_TRAIT(src, TRAIT_STAGGERIMMUNE, RAGE_TRAIT)
Comment on lines +55 to +62
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Объедини все 3 трейта в список трейтов как это с PASSABLE тогда как я понимаю можно будет и без дополнительного вара обойтись

staggerstun_immune = FALSE

xeno_melee_damage_modifier = initial(xeno_melee_damage_modifier) + rage_power
add_movespeed_modifier(MOVESPEED_ID_RAVAGER_RAGE, TRUE, 0, NONE, TRUE, xeno_caste.speed * 0.5 * rage_power)

if((health < 0) && !on_cooldown && stat == CONSCIOUS)
playsound(loc, 'sound/voice/alien/roar2.ogg', clamp(100 * rage_power, 25, 80), 0)
balloon_alert(src, "RIP AND TEAR")
plasma_stored += xeno_caste.plasma_max
var/datum/action/ability/xeno_action/charge = actions_by_path[/datum/action/ability/activable/xeno/charge]
var/datum/action/ability/xeno_action/ravage = actions_by_path[/datum/action/ability/activable/xeno/ravage]
if(charge)
charge.clear_cooldown()
if(ravage)
ravage.clear_cooldown()
on_cooldown = TRUE

/mob/living/carbon/xenomorph/ravager/proc/drain_slash(datum/source, mob/living/target, damage, list/damage_mod, list/armor_mod)
SIGNAL_HANDLER
var/brute_damage = getBruteLoss()
var/burn_damage = getFireLoss()
if(!brute_damage && !burn_damage)
return
var/health_recovery = rage_power * RAVAGER_RAGE_HEALTH_RECOVERY_PER_SLASH
var/health_modifier
if(brute_damage)
health_modifier = min(brute_damage, health_recovery)*-1
adjustBruteLoss(health_modifier)
health_recovery += health_modifier
if(burn_damage)
health_modifier = min(burn_damage, health_recovery)*-1
Comment on lines +89 to +93
Copy link
Collaborator

@Helg2 Helg2 Aug 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
health_modifier = min(brute_damage, health_recovery)*-1
adjustBruteLoss(health_modifier)
health_recovery += health_modifier
if(burn_damage)
health_modifier = min(burn_damage, health_recovery)*-1
health_modifier = -min(brute_damage, health_recovery)
adjustBruteLoss(health_modifier)
health_recovery += health_modifier
if(burn_damage)
health_modifier = -min(burn_damage, health_recovery)

adjustFireLoss(health_modifier)

var/datum/action/ability/xeno_action/endure/endure_ability = actions_by_path[/datum/action/ability/xeno_action/endure]
if(endure_ability.endure_duration) //Check if Endure is active
var/new_duration = min(RAVAGER_ENDURE_DURATION, (timeleft(endure_ability.endure_duration) + RAVAGER_RAGE_ENDURE_INCREASE_PER_SLASH * rage_power))
deltimer(endure_ability.endure_duration) //Reset timers
deltimer(endure_ability.endure_warning_duration)
endure_ability.endure_duration = addtimer(CALLBACK(endure_ability, TYPE_PROC_REF(/datum/action/ability/xeno_action/endure, endure_deactivate)), new_duration, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_OVERRIDE)
if(new_duration > 3 SECONDS) //Check timing
endure_ability.endure_warning_duration = addtimer(CALLBACK(endure_ability, TYPE_PROC_REF(/datum/action/ability/xeno_action/endure, endure_warning)), new_duration - 3 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_OVERRIDE)

// ***************************************
// *********** Mob overrides
// ***************************************
Expand Down
Loading