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

Praetorian dancer strain #699

Merged
merged 12 commits into from
Dec 14, 2024
Merged
5 changes: 5 additions & 0 deletions code/__DEFINES/dcs/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@
#define COMSIG_XENOABILITY_CORROSIVE_ACID "xenoability_corrosive_acid"
#define COMSIG_XENOABILITY_SPRAY_ACID "xenoability_spray_acid"
#define COMSIG_XENOABILITY_DASH "xenoability_dash"
#define COMSIG_XENOABILITY_ACID_DASH "xenoability_acid_dash"
#define COMSIG_XENOABILITY_SHORT_SPRAY_ACID "xenoability_short_spray_acid"
#define COMSIG_XENOABILITY_XENO_SPIT "xenoability_xeno_spit"
#define COMSIG_XENOABILITY_HIDE "xenoability_hide"
Expand All @@ -751,6 +752,10 @@
#define COMSIG_XENOABILITY_MINION_BEHAVIOUR "xenoability_minion_behavior"
#define COMSIG_XENOABILITY_SILENCE "xenoability_silence"

#define COMSIG_XENOABILITY_DODGE "xenoability_dodge"
#define COMSIG_XENOABILITY_IMPALE "xenoability_impale"
#define COMSIG_XENOABILITY_TAIL_TRIP "xenoability_tail_trip"

#define COMSIG_XENOABILITY_TOXIC_SPIT "xenoability_toxic_spit"
#define COMSIG_XENOABILITY_TOXIC_SLASH "xenoability_toxic_slash"
#define COMSIG_XENOABILITY_DRAIN_STING "xenoability_drain_sting"
Expand Down
1 change: 1 addition & 0 deletions code/__DEFINES/movespeed_modification.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#define MOVESPEED_ID_FORTIFY "FORTIFY"
#define MOVESPEED_ID_WARRIOR_AGILITY "WARRIOR_AGILITY"
#define MOVESPEED_ID_FRENZY_AURA "FRENZY_AURA"
#define MOVESPEED_ID_PRAETORIAN_DANCER_DODGE_SPEED "PRAETORIAN_DANCER_DODGE_SPEED"
#define MOVESPEED_ID_XENO_HEMODILE "XENO_HEMODILE"
#define MOVESPEED_ID_RAVAGER_RAGE "RAVAGER_RAGE"
#define MOVESPEED_ID_BULL_ACID_CHARGE "BULL_ACID_CHARGE"
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/status_effects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@

#define STATUS_EFFECT_INTOXICATED /datum/status_effect/stacking/intoxicated //Damage over time

#define STATUS_EFFECT_DANCER_TAGGED /datum/status_effect/incapacitating/dancer_tagged //Additional damage/effects by Praetorian Dancer's abilities

#define STATUS_EFFECT_REPAIR_MODE /datum/status_effect/incapacitating/repair_mode //affected is blinded and stunned, but heals over time
///damage and sunder over time
#define STATUS_EFFECT_MELTING /datum/status_effect/stacking/melting
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/lists/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ GLOBAL_LIST_INIT(all_xeno_types, list(
/mob/living/carbon/xenomorph/ravager/primordial,
/mob/living/carbon/xenomorph/praetorian,
/mob/living/carbon/xenomorph/praetorian/primordial,
/mob/living/carbon/xenomorph/praetorian/dancer,
/mob/living/carbon/xenomorph/praetorian/dancer/primordial,
mister-onion marked this conversation as resolved.
Show resolved Hide resolved
/mob/living/carbon/xenomorph/predalien,
/mob/living/carbon/xenomorph/boiler,
/mob/living/carbon/xenomorph/boiler/primordial,
Expand Down
27 changes: 27 additions & 0 deletions code/datums/keybinding/xeno.dm
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,33 @@
keybind_signal = COMSIG_XENOABILITY_DASH
hotkey_keys = list("E")

/datum/keybinding/xeno/acid_dash
name = "acid_dash"
full_name = "Praetorian: Acid Dash"
description = "Quickly dash, leaving acid in your path and knocking down the first marine hit. Has reset potential."
keybind_signal = COMSIG_XENOABILITY_ACID_DASH
hotkey_keys = list("E")

/datum/keybinding/xeno/dodge
name = "Dodge"
full_name = "Praetorian: Dodge"
description = "Gain a speed boost upon activation and the ability to pass through mobs. Enemies automatically receive bump attacks when passed."
keybind_signal = COMSIG_XENOABILITY_DODGE
hotkey_keys = list("Q")

/datum/keybinding/xeno/impale
name = "Impale"
full_name = "Praetorian: Impale"
description = "Impale a marine next to you with your tail for moderate damage. Marked enemies are impaled twice."
keybind_signal = COMSIG_XENOABILITY_IMPALE
hotkey_keys = list("Z")

/datum/keybinding/xeno/tail_trip
name = "Tail Trip"
full_name = "Praetorian: Tail Trip"
description = "Target a marine within two tiles of you to disorient and slows them. Marked enemies receive stronger debuffs and are stunned for a second."
keybind_signal = COMSIG_XENOABILITY_TAIL_TRIP
hotkey_keys = list("R")
/datum/keybinding/xeno/screech
name = "screech"
full_name = "Queen: Screech"
Expand Down
6 changes: 6 additions & 0 deletions code/datums/status_effects/debuffs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -863,3 +863,9 @@
/datum/status_effect/incapacitating/spider_venom/on_remove()
owner.remove_movespeed_modifier(MOVESPEED_ID_SPIDER_VENOM)
return ..()

// ***************************************
// *********** Dancer Tagged
// ***************************************
/datum/status_effect/incapacitating/dancer_tagged
id = "dancer_tagged"
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,274 @@ GLOBAL_LIST_INIT(acid_spray_hit, typecacheof(list(/obj/structure/barricade, /obj
if(!A)
continue
A.acid_spray_act(owner)

// ***************************************
// *********** Acid dash
// ***************************************
/datum/action/ability/activable/xeno/charge/acid_dash
name = "Acid Dash"
desc = "Instantly dash, tackling the first marine in your path. If you manage to tackle someone, gain another weaker cast of the ability."
ability_cost = 250
cooldown_duration = 30 SECONDS
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_ACID_DASH,
)
charge_range = PRAE_CHARGEDISTANCE
///Can we use the ability again
var/recast_available = FALSE
///Is this the recast
var/recast = FALSE
///The last tile we dashed through, used when swapping with a human
var/turf/last_turf

/datum/action/ability/activable/xeno/charge/acid_dash/use_ability(atom/A)
if(!A)
return
var/mob/living/carbon/xenomorph/xeno_owner = owner

RegisterSignal(xeno_owner, COMSIG_XENO_OBJ_THROW_HIT, PROC_REF(obj_hit))
RegisterSignal(xeno_owner, COMSIG_MOVABLE_POST_THROW, PROC_REF(charge_complete))
RegisterSignal(xeno_owner, COMSIG_XENOMORPH_LEAP_BUMP, PROC_REF(mob_hit))
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(acid_steps)) //We drop acid on every tile we pass through

xeno_owner.visible_message(span_danger("[xeno_owner] slides towards \the [A]!"), \
span_danger("We dash towards \the [A], spraying acid down our path!") )
xeno_owner.emote("roar")
xeno_owner.xeno_flags |= XENO_LEAPING //This has to come before throw_at, which checks impact. So we don't do end-charge specials when thrown
succeed_activate()

last_turf = get_turf(owner)
owner.pass_flags = PASS_LOW_STRUCTURE|PASS_DEFENSIVE_STRUCTURE|PASS_FIRE
owner.throw_at(A, charge_range, 2, owner)

/datum/action/ability/activable/xeno/charge/acid_dash/mob_hit(datum/source, mob/living/living_target)
. = TRUE
if(living_target.stat || isxeno(living_target) || !(iscarbon(living_target))) //we leap past xenos
return
recast_available = TRUE
var/mob/living/carbon/carbon_victim = living_target
carbon_victim.ParalyzeNoChain(0.5 SECONDS)

to_chat(carbon_victim, span_highdanger("The [owner] tackles us, sending us behind them!"))
owner.visible_message(span_xenodanger("\The [owner] tackles [carbon_victim], swapping location with them!"), \
span_xenodanger("We push [carbon_victim] in our acid trail!"), visible_message_flags = COMBAT_MESSAGE)

/datum/action/ability/activable/xeno/charge/acid_dash/charge_complete()
. = ..()
var/mob/living/carbon/xenomorph/xeno_owner = owner
if(recast_available)
addtimer(CALLBACK(src, PROC_REF(charge_complete)), 2 SECONDS) //Delayed recursive call, this time you won't gain a recast so it will go on cooldown in 2 SECONDS.
recast = TRUE
else
recast = FALSE
add_cooldown()
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
xeno_owner.pass_flags = initial(xeno_owner.pass_flags)
recast_available = FALSE

///Drops an acid puddle on the current owner's tile, will do 0 damage if the owner has no acid_spray_damage
/datum/action/ability/activable/xeno/charge/acid_dash/proc/acid_steps(atom/A, atom/OldLoc, Dir, Forced)
SIGNAL_HANDLER
last_turf = OldLoc
var/mob/living/carbon/xenomorph/xeno_owner = owner
new /obj/effect/xenomorph/spray(get_turf(xeno_owner), 5 SECONDS, xeno_owner.xeno_caste.acid_spray_damage) //Add a modifier here to buff the damage if needed
for(var/obj/O in get_turf(xeno_owner))
O.acid_spray_act(xeno_owner)

mister-onion marked this conversation as resolved.
Show resolved Hide resolved
// ***************************************
// *********** Dodge
// ***************************************
/datum/action/ability/xeno_action/dodge
name = "Dodge"
action_icon_state = "dodge"
action_icon = 'icons/Xeno/actions.dmi'
desc = "Gain a speed boost upon activation and the ability to pass through mobs. Enemies automatically receive bump attacks when passed."
ability_cost = 100
cooldown_duration = 12 SECONDS
use_state_flags = ABILITY_USE_BUSY
keybind_flags = ABILITY_KEYBIND_USE_ABILITY
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_DODGE,
)
/// The increase of speed when ability is active.
var/speed_buff = -0.4
/// How long the ability will last?
var/duration = 6 SECONDS

/datum/action/ability/xeno_action/dodge/action_activate(atom/A)
owner.balloon_alert(owner, "Dodge ready!")

owner.add_movespeed_modifier(MOVESPEED_ID_PRAETORIAN_DANCER_DODGE_SPEED, TRUE, 0, NONE, TRUE, speed_buff)
owner.allow_pass_flags |= (PASS_MOB|PASS_XENO)
owner.pass_flags |= (PASS_MOB|PASS_XENO)
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
addtimer(CALLBACK(src, PROC_REF(remove_effects)), duration)

succeed_activate()
add_cooldown()

/// Automatically bumps living non-xenos if bump attacks are on.
/datum/action/ability/xeno_action/dodge/proc/on_move(datum/source)
if(owner.stat == DEAD)
return FALSE
var/datum/action/bump_attack_toggle/bump_attack_action = owner.actions_by_path[/datum/action/bump_attack_toggle]
if(bump_attack_action == null || bump_attack_action.attacking) // Bump attacks are off if attacking is true, apparently.
return FALSE
if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_BUMP_ATTACK) || owner.next_move > world.time)
return FALSE

var/turf/current_turf = get_turf(owner)
for(var/mob/living/living_mob in current_turf)
if(living_mob.stat == DEAD)
continue
if(isxeno(living_mob))
var/mob/living/carbon/xenomorph/xenomorph_mob = living_mob
if(owner.issamexenohive(xenomorph_mob))
continue
owner.Bump(living_mob)
return

/// Removes the movespeed modifier and various pass_flags that was given by the dodge ability.
/datum/action/ability/xeno_action/dodge/proc/remove_effects()
owner.balloon_alert(owner, "Dodge inactive!")

owner.remove_movespeed_modifier(MOVESPEED_ID_PRAETORIAN_DANCER_DODGE_SPEED)
owner.allow_pass_flags &= ~(PASS_MOB|PASS_XENO)
owner.pass_flags &= ~(PASS_MOB|PASS_XENO)
UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)

// ***************************************
// *********** Impale
// ***************************************
/datum/action/ability/activable/xeno/impale
name = "Impale"
action_icon_state = "impale"
desc = "Impale a marine next to you with your tail for moderate damage. Marked enemies are impaled twice."
ability_cost = 100
cooldown_duration = 8 SECONDS
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_IMPALE,
)
target_flags = ABILITY_MOB_TARGET

/datum/action/ability/activable/xeno/impale/can_use_ability(atom/A, silent = FALSE, override_flags)
. = ..()
if(!.)
return FALSE
if(!iscarbon(A))
if(!silent)
A.balloon_alert(owner, "cannot impale")
return FALSE
if(isxeno(A))
var/mob/living/carbon/xenomorph/xenomorph_target = A
if(owner.issamexenohive(xenomorph_target))
A.balloon_alert(owner, "cannot impale ally")
return FALSE
var/mob/living/carbon/carbon_target = A
if(!owner.Adjacent(carbon_target))
carbon_target.balloon_alert(owner, "too far")
return FALSE
if(carbon_target.stat == DEAD)
carbon_target.balloon_alert(owner, "already dead")
return FALSE

/datum/action/ability/activable/xeno/impale/use_ability(atom/target_atom)
. = ..()

var/mob/living/carbon/xenomorph/xeno_owner = owner
if(!iscarbon(target_atom))
return
var/mob/living/carbon/living_target = target_atom
var/buffed = living_target.has_status_effect(STATUS_EFFECT_DANCER_TAGGED)
xeno_owner.visible_message(span_danger("\The [xeno_owner] violently slices [living_target] with its tail [buffed ? "twice" : ""]!"), \
span_danger("We slice [living_target] with our tail[buffed ? " twice" : ""]!"))

try_impale(living_target)
if(buffed)
xeno_owner.emote("roar")
addtimer(CALLBACK(src, PROC_REF(try_impale), living_target), 0.1 SECONDS) // A short delay for animation coolness (and also if they're dead).

succeed_activate()
add_cooldown()

/// Performs the main effect of impale ability like animating and attacking.
/datum/action/ability/activable/xeno/impale/proc/try_impale(mob/living/carbon/living_target)
var/mob/living/carbon/xenomorph/xeno_owner = owner
var/damage = (xeno_owner.xeno_caste.melee_damage * xeno_owner.xeno_melee_damage_modifier)
xeno_owner.face_atom(living_target)
xeno_owner.do_attack_animation(living_target, ATTACK_EFFECT_REDSLASH)
xeno_owner.spin(4, 1)
playsound(living_target,'sound/weapons/alien_tail_attack.ogg', 30, TRUE)
if(living_target.stat != DEAD) // If they drop dead from the first impale, keep the effects but do no damage.
living_target.apply_damage(damage, BRUTE, blocked = MELEE)

// ***************************************
// *********** Tail Trip
// ***************************************
/datum/action/ability/activable/xeno/tail_trip
name = "Tail Trip"
action_icon_state = "tail_trip"
desc = "Target a marine within two tiles of you to disorient and slows them. Marked enemies receive stronger debuffs and are stunned for a second."
ability_cost = 50
cooldown_duration = 8 SECONDS
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_TAIL_TRIP,
)
target_flags = ABILITY_MOB_TARGET

/datum/action/ability/activable/xeno/tail_trip/can_use_ability(atom/A, silent = FALSE, override_flags)
. = ..()
if(!.)
return FALSE
if(!iscarbon(A))
if(!silent)
A.balloon_alert(owner, "cannot tail trip")
return FALSE
if(isxeno(A))
var/mob/living/carbon/xenomorph/xenomorph_target = A
if(owner.issamexenohive(xenomorph_target))
A.balloon_alert(owner, "cannot tail trip ally")
return FALSE
var/mob/living/carbon/carbon_target = A
if(get_dist(owner, carbon_target) > 2)
if(!silent)
carbon_target.balloon_alert(owner, "too far")
return FALSE
if(!line_of_sight(owner, carbon_target, 2))
if(!silent)
carbon_target.balloon_alert(owner, "need line of sight")
return FALSE
if(carbon_target.stat == DEAD)
carbon_target.balloon_alert(owner, "already dead")
return FALSE
if(carbon_target.stat == UNCONSCIOUS)
carbon_target.balloon_alert(owner, "not standing")
return FALSE

/datum/action/ability/activable/xeno/tail_trip/use_ability(atom/target_atom)
. = ..()

var/mob/living/carbon/xenomorph/xeno_owner = owner
if(!iscarbon(target_atom))
return

var/mob/living/carbon/living_target = target_atom

var/damage = (xeno_owner.xeno_caste.melee_damage * xeno_owner.xeno_melee_damage_modifier)
var/buffed = living_target.has_status_effect(STATUS_EFFECT_DANCER_TAGGED)

xeno_owner.visible_message(span_danger("\The [xeno_owner] sweeps [living_target]'s legs with its tail!"), \
span_danger("We trip [living_target] with our tail!"))
shake_camera(living_target, 2, 1)
xeno_owner.face_atom(living_target)
xeno_owner.spin(4, 1)
xeno_owner.emote("tail")
playsound(living_target,'sound/weapons/alien_claw_block.ogg', 50, 1)

living_target.Paralyze(buffed ? 1 SECONDS : 0.1 SECONDS)
living_target.adjust_stagger(buffed ? 5 SECONDS : 4 SECONDS)
living_target.adjust_slowdown(buffed ? 1.2 : 0.9)
living_target.apply_damage(damage, STAMINA, updating_health = TRUE)

succeed_activate()
add_cooldown()
Loading
Loading