diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 9fb15b860fc..761a54f1e17 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -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" @@ -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" diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index a8e4d99fb85..47ba67088f2 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -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" diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 56afaa9acb7..fde0e074146 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -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 diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 416824fdfed..15e233a439e 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -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, /mob/living/carbon/xenomorph/predalien, /mob/living/carbon/xenomorph/boiler, /mob/living/carbon/xenomorph/boiler/primordial, diff --git a/code/datums/keybinding/xeno.dm b/code/datums/keybinding/xeno.dm index bbc16c25300..64c8ba0617f 100644 --- a/code/datums/keybinding/xeno.dm +++ b/code/datums/keybinding/xeno.dm @@ -691,6 +691,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" diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 8e82abff5f5..7458a65f568 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -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" diff --git a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm index b268f4f68a4..53598549119 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/abilities_praetorian.dm @@ -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) + +// *************************************** +// *********** 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() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm index 056b30b5ed5..40e71ead945 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/castedatum_praetorian.dm @@ -88,3 +88,60 @@ /datum/action/ability/xeno_action/pheromones/emit_warding, /datum/action/ability/xeno_action/pheromones/emit_frenzy, ) + +/datum/xeno_caste/praetorian/dancer + caste_type_path = /mob/living/carbon/xenomorph/praetorian/dancer + base_caste_type_path = /mob/living/carbon/xenomorph/praetorian + upgrade_name = "" + caste_name = "Praetorian" + display_name = "Dancer" + upgrade = XENO_UPGRADE_BASETYPE + caste_desc = "A giant melee monster. It looks pretty strong." + + // +2 melee damage + melee_damage = 25 + + // Loses some common armor (-5) for more speed (-0.3). + speed = -0.8 + soft_armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 45, BOMB = 10, BIO = 40, FIRE = 15, ACID = 40) + + // Loses ranged spit abilities for close combat combo abilities. + actions = list( + /datum/action/ability/xeno_action/xeno_resting, + /datum/action/ability/xeno_action/watch_xeno, + /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/xeno_action/place_acidwell, + /datum/action/ability/activable/xeno/corrosive_acid, + /datum/action/ability/xeno_action/dodge, + /datum/action/ability/activable/xeno/impale, + /datum/action/ability/activable/xeno/tail_trip, + /datum/action/ability/xeno_action/pheromones, + /datum/action/ability/xeno_action/pheromones/emit_recovery, + /datum/action/ability/xeno_action/pheromones/emit_warding, + /datum/action/ability/xeno_action/pheromones/emit_frenzy, + ) + +/datum/xeno_caste/praetorian/dancer/normal + upgrade = XENO_UPGRADE_NORMAL + +/datum/xeno_caste/praetorian/dancer/primordial + upgrade_name = "Primordial" + caste_desc = "An aberrant creature extremely proficient with its body and tail. Keep your distance if you don't wish to be finessed." + upgrade = XENO_UPGRADE_PRIMO + primordial_message = "With a flick of our tail, we dance through the shadows, striking with lethal precision." + + actions = list( + /datum/action/ability/xeno_action/xeno_resting, + /datum/action/ability/xeno_action/watch_xeno, + /datum/action/ability/activable/xeno/psydrain, + /datum/action/ability/xeno_action/place_acidwell, + /datum/action/ability/activable/xeno/corrosive_acid, + /datum/action/ability/xeno_action/dodge, + /datum/action/ability/activable/xeno/impale, + /datum/action/ability/activable/xeno/tail_trip, + /datum/action/ability/activable/xeno/charge/acid_dash, // No unique primordial ability at the moment. Replace eventually with something cooler! + /datum/action/ability/xeno_action/pheromones, + /datum/action/ability/xeno_action/pheromones/emit_recovery, + /datum/action/ability/xeno_action/pheromones/emit_warding, + /datum/action/ability/xeno_action/pheromones/emit_frenzy, + ) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/praetorian.dm b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/praetorian.dm index dfb2512a031..843689e7b66 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/praetorian/praetorian.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/praetorian/praetorian.dm @@ -21,3 +21,17 @@ /datum/xenomorph_skin/praetorian, ) +/mob/living/carbon/xenomorph/praetorian/dancer + icon = 'icons/Xeno/castes/praetorian/dancer.dmi' + caste_base_type = /datum/xeno_caste/praetorian/dancer + skins = null + +/mob/living/carbon/xenomorph/praetorian/dancer/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_XENOMORPH_POSTATTACK_LIVING, PROC_REF(on_postattack)) + +/// Applies the dancer mark status effect to those that they slash and damage. +/mob/living/carbon/xenomorph/praetorian/dancer/proc/on_postattack(mob/living/source, mob/living/target, damage) + SIGNAL_HANDLER + target.apply_status_effect(STATUS_EFFECT_DANCER_TAGGED, 4 SECONDS) + diff --git a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm index 5c99bc33589..22fc5d035fb 100644 --- a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm +++ b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm @@ -148,6 +148,9 @@ /mob/living/carbon/xenomorph/praetorian/primordial upgrade = XENO_UPGRADE_PRIMO +/mob/living/carbon/xenomorph/praetorian/dancer/primordial + upgrade = XENO_UPGRADE_PRIMO + //----PRAETORIAN END----// //================// //----RAVAGER START----// diff --git a/icons/Xeno/actions.dmi b/icons/Xeno/actions.dmi index d1dd26d3cbc..32bd468a7b7 100644 Binary files a/icons/Xeno/actions.dmi and b/icons/Xeno/actions.dmi differ diff --git a/icons/Xeno/castes/praetorian/dancer.dmi b/icons/Xeno/castes/praetorian/dancer.dmi new file mode 100644 index 00000000000..2a9b4d52bb1 Binary files /dev/null and b/icons/Xeno/castes/praetorian/dancer.dmi differ