diff --git a/code/__DEFINES/action.dm b/code/__DEFINES/action.dm
index 6a5ec139ef806..d47fa07f02fb8 100644
--- a/code/__DEFINES/action.dm
+++ b/code/__DEFINES/action.dm
@@ -50,6 +50,8 @@
#define VREF_MUTABLE_GAS_MINE_TIMER "VREF_GASMINE_CHARGETIMER"
// extra reference for how long untill we recharge a new gas mine
#define VREF_MUTABLE_ACID_MINE_TIMER "VREF_ACIDMINE_CHARGETIMER"
+// extra reference for how many scorched earth charges we have
+#define VREF_MUTABLE_SCORCHED_EARTH "VREF_SCORCHED_EARTH"
/// Actions that toggle on click/trigger
#define ACTION_TOGGLE "toggle"
diff --git a/code/__DEFINES/dcs/signals/signals_keybindings.dm b/code/__DEFINES/dcs/signals/signals_keybindings.dm
index 506f471065f46..977d207a9a139 100644
--- a/code/__DEFINES/dcs/signals/signals_keybindings.dm
+++ b/code/__DEFINES/dcs/signals/signals_keybindings.dm
@@ -193,6 +193,7 @@
#define COMSIG_XENOABILITY_TOGGLE_CHARGE "xenoability_toggle_charge"
#define COMSIG_XENOABILITY_CRESTTOSS "xenoability_cresttoss"
#define COMSIG_XENOABILITY_ADVANCE "xenoability_advance"
+#define COMSIG_XENOABILITY_SCORCHED_EARTH "xenoability_scorched_earth"
#define COMSIG_XENOABILITY_DEVOUR "xenoability_devour"
#define COMSIG_XENOABILITY_DRAIN "xenoability_drain"
@@ -202,10 +203,6 @@
#define COMSIG_XENOABILITY_CARNAGE "xenoability_carnage"
#define COMSIG_XENOABILITY_FEAST "xenoability_feast"
-#define COMSIG_XENOABILITY_BULLCHARGE "xenoability_bullcharge"
-#define COMSIG_XENOABILITY_BULLHEADBUTT "xenoability_bullheadbutt"
-#define COMSIG_XENOABILITY_BULLGORE "xenoability_bullgore"
-
#define COMSIG_XENOABILITY_TAIL_SWEEP "xenoability_tail_sweep"
#define COMSIG_XENOABILITY_FORWARD_CHARGE "xenoability_forward_charge"
#define COMSIG_XENOABILITY_CREST_DEFENSE "xenoability_crest_defense"
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 6d913c12a28f9..15796432a9b23 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -117,7 +117,6 @@ GLOBAL_VAR_INIT(refid_filter, TYPEID(filter(type="angular_blur")))
#define isxenoqueen(A) (istype(A, /mob/living/carbon/xenomorph/queen))
#define isxenoshrike(A) (istype(A, /mob/living/carbon/xenomorph/shrike))
#define isxenodefiler(A) (istype(A, /mob/living/carbon/xenomorph/defiler))
-#define isxenobull(A) (istype(A, /mob/living/carbon/xenomorph/bull))
#define isxenohivemind(A) (istype(A, /mob/living/carbon/xenomorph/hivemind))
#define isxenowraith(A) (istype(A, /mob/living/carbon/xenomorph/wraith))
#define isxenowidow(A) (istype(A, /mob/living/carbon/xenomorph/widow))
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index a6c1075abad32..6f1ca753d0819 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -83,8 +83,6 @@ GLOBAL_LIST_INIT(all_xeno_types, list(
/mob/living/carbon/xenomorph/hivelord/primordial,
/mob/living/carbon/xenomorph/carrier,
/mob/living/carbon/xenomorph/carrier/primordial,
- /mob/living/carbon/xenomorph/bull,
- /mob/living/carbon/xenomorph/bull/primordial,
/mob/living/carbon/xenomorph/queen,
/mob/living/carbon/xenomorph/queen/primordial,
/mob/living/carbon/xenomorph/king,
@@ -109,6 +107,8 @@ GLOBAL_LIST_INIT(all_xeno_types, list(
/mob/living/carbon/xenomorph/defiler/primordial,
/mob/living/carbon/xenomorph/crusher,
/mob/living/carbon/xenomorph/crusher/primordial,
+ /mob/living/carbon/xenomorph/crusher/bull,
+ /mob/living/carbon/xenomorph/crusher/bull/primordial,
/mob/living/carbon/xenomorph/widow,
/mob/living/carbon/xenomorph/widow/primordial,
/mob/living/carbon/xenomorph/shrike,
@@ -129,7 +129,7 @@ GLOBAL_LIST_INIT(all_xeno_types, list(
))
GLOBAL_LIST_INIT(xeno_types_tier_one, list(/datum/xeno_caste/runner, /datum/xeno_caste/drone, /datum/xeno_caste/sentinel, /datum/xeno_caste/defender))
-GLOBAL_LIST_INIT(xeno_types_tier_two, list(/datum/xeno_caste/hunter, /datum/xeno_caste/warrior, /datum/xeno_caste/spitter, /datum/xeno_caste/hivelord, /datum/xeno_caste/carrier, /datum/xeno_caste/bull, /datum/xeno_caste/puppeteer, /datum/xeno_caste/pyrogen))
+GLOBAL_LIST_INIT(xeno_types_tier_two, list(/datum/xeno_caste/hunter, /datum/xeno_caste/warrior, /datum/xeno_caste/spitter, /datum/xeno_caste/hivelord, /datum/xeno_caste/carrier, /datum/xeno_caste/puppeteer, /datum/xeno_caste/pyrogen))
GLOBAL_LIST_INIT(xeno_types_tier_three, list(/datum/xeno_caste/gorger, /datum/xeno_caste/widow, /datum/xeno_caste/ravager, /datum/xeno_caste/praetorian, /datum/xeno_caste/boiler, /datum/xeno_caste/defiler, /datum/xeno_caste/crusher, /datum/xeno_caste/shrike, /datum/xeno_caste/behemoth, /datum/xeno_caste/warlock))
GLOBAL_LIST_INIT(xeno_types_tier_four, list(/datum/xeno_caste/shrike, /datum/xeno_caste/queen, /datum/xeno_caste/king))
diff --git a/code/datums/gamemodes/_game_mode.dm b/code/datums/gamemodes/_game_mode.dm
index 42300bea1b7b0..e22ce42a73c26 100644
--- a/code/datums/gamemodes/_game_mode.dm
+++ b/code/datums/gamemodes/_game_mode.dm
@@ -449,12 +449,8 @@ GLOBAL_LIST_INIT(bioscan_locations, list(
parts += "[GLOB.round_statistics.spitter_scatter_spits] number of times Spitters horked up scatter spits."
if(GLOB.round_statistics.ravager_endures)
parts += "[GLOB.round_statistics.ravager_endures] number of times Ravagers used Endure."
- if(GLOB.round_statistics.bull_crush_hit)
- parts += "[GLOB.round_statistics.bull_crush_hit] number of times Bulls crushed marines."
- if(GLOB.round_statistics.bull_gore_hit)
- parts += "[GLOB.round_statistics.bull_gore_hit] number of times Bulls gored marines."
- if(GLOB.round_statistics.bull_headbutt_hit)
- parts += "[GLOB.round_statistics.bull_headbutt_hit] number of times Bulls headbutted marines."
+ if(GLOB.round_statistics.bull_hit)
+ parts += "[GLOB.round_statistics.bull_hit] number of times Bulls charged into marines."
if(GLOB.round_statistics.hunter_marks)
parts += "[GLOB.round_statistics.hunter_marks] number of times Hunters marked a target for death."
if(GLOB.round_statistics.ravager_rages)
diff --git a/code/datums/keybinding/xeno.dm b/code/datums/keybinding/xeno.dm
index e0e97547126d5..2524a03033928 100644
--- a/code/datums/keybinding/xeno.dm
+++ b/code/datums/keybinding/xeno.dm
@@ -286,27 +286,6 @@
keybind_signal = COMSIG_XENOABILITY_HIGH_PRESSURE_SPIT
hotkey_keys = list("E")
-/datum/keybinding/xeno/plow_charge
- name = "plow_charge"
- full_name = "Bull: Plow Charge"
- description = "A charge that plows through the victims."
- keybind_signal = COMSIG_XENOABILITY_BULLCHARGE
- hotkey_keys = list("Q")
-
-/datum/keybinding/xeno/headbutt_charge
- name = "headbutt_charge"
- full_name = "Bull: Headbutt Charge"
- description = "A charge that tosses the victim forward or backwards, depending on intent."
- keybind_signal = COMSIG_XENOABILITY_BULLHEADBUTT
- hotkey_keys = list("F")
-
-/datum/keybinding/xeno/gore_charge
- name = "gore_charge"
- full_name = "Bull: Gore Charge"
- description = "A charge that gores the victim."
- keybind_signal = COMSIG_XENOABILITY_BULLGORE
- hotkey_keys = list("R")
-
/datum/keybinding/xeno/throw_hugger
name = "throw_hugger"
full_name = "Carrier: Throw Hugger"
@@ -383,6 +362,13 @@
keybind_signal = COMSIG_XENOABILITY_ADVANCE
hotkey_keys = list("F")
+/datum/keybinding/xeno/scorched_earth
+ name = "Scorched Earth"
+ full_name = "Bull: Scorched Earth"
+ description = "When activated, gain three charges of Scorched Earth. These can be used to dash towards a targeted location, leaving damaging trails of plasma behind."
+ keybind_signal = COMSIG_XENOABILITY_SCORCHED_EARTH
+ hotkey_keys = list("F")
+
/datum/keybinding/xeno/forward_charge
name = "forward charge"
full_name = "Defender: Forward charge"
diff --git a/code/datums/round_statistics.dm b/code/datums/round_statistics.dm
index 801cfe38ac7b4..6e4a5cc66d462 100644
--- a/code/datums/round_statistics.dm
+++ b/code/datums/round_statistics.dm
@@ -37,7 +37,6 @@ GLOBAL_DATUM_INIT(round_statistics, /datum/round_statistics, new)
var/trap_holes = 0
var/boiler_acid_smokes = 0
var/boiler_neuro_smokes = 0
- var/crusher_stomps = 0
var/crusher_stomp_victims = 0
var/praetorian_acid_sprays = 0
var/praetorian_spray_direct_hits = 0
@@ -79,9 +78,7 @@ GLOBAL_DATUM_INIT(round_statistics, /datum/round_statistics, new)
var/spitter_acid_sprays = 0
var/spitter_scatter_spits = 0
var/wraith_phase_shifts = 0
- var/bull_crush_hit = 0
- var/bull_gore_hit = 0
- var/bull_headbutt_hit = 0
+ var/bull_hit = 0
var/ravager_endures = 0
var/hunter_marks = 0
var/hunter_silence_targets = 0
diff --git a/code/modules/admin/panels/player_panel.dm b/code/modules/admin/panels/player_panel.dm
index e1d47311647ac..4ac6238ff62ea 100644
--- a/code/modules/admin/panels/player_panel.dm
+++ b/code/modules/admin/panels/player_panel.dm
@@ -458,7 +458,6 @@ ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_BAN, "Show Player Panel", mob/
Defender |
Alien Tier 2:
Hunter |
- Bull |
Warrior |
Spitter |
Hivelord |
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index f237ede72d9e4..e9853dcd56c92 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -408,8 +408,6 @@ Status: [status ? status : "Unknown"] | Damage: [health ? health : "None"]
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/drone, location, null, delmob)
if("sentinel")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/sentinel, location, null, delmob)
- if("bull")
- newmob = M.change_mob_type(/mob/living/carbon/xenomorph/bull, location, null, delmob)
if("hunter")
newmob = M.change_mob_type(/mob/living/carbon/xenomorph/hunter, location, null, delmob)
if("carrier")
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
index 75ab0a64d2e31..d43bcda296146 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/behemoth/castedatum_behemoth.dm
@@ -29,7 +29,7 @@
// *** Evolution *** //
upgrade_threshold = TIER_THREE_THRESHOLD
- deevolves_to = /datum/xeno_caste/bull
+ deevolves_to = /datum/xeno_caste/warrior
// *** Flags *** //
caste_flags = CASTE_EVOLUTION_ALLOWED|CASTE_IS_STRONG|CASTE_STAGGER_RESISTANT
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/bull/abilities_bull.dm b/code/modules/mob/living/carbon/xenomorph/castes/bull/abilities_bull.dm
deleted file mode 100644
index 82e60f4d51a76..0000000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/bull/abilities_bull.dm
+++ /dev/null
@@ -1,38 +0,0 @@
-// ***************************************
-// *********** Bull charge types
-// ***************************************
-
-/datum/action/ability/activable/xeno/bull_charge
- name = "Plow Charge"
- action_icon_state = "bull_charge"
- action_icon = 'icons/Xeno/actions/bull.dmi'
- desc = "When you hit a host, knock them out of your way while continuing your charge undeterred. The force of your charge also disarms them."
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BULLCHARGE,
- )
- var/new_charge_type = CHARGE_BULL
-
-
-/datum/action/ability/activable/xeno/bull_charge/on_selection()
- SEND_SIGNAL(owner, COMSIG_XENOACTION_TOGGLECHARGETYPE, new_charge_type)
-
-
-/datum/action/ability/activable/xeno/bull_charge/headbutt
- name = "Headbutt Charge"
- action_icon_state = "bull_headbutt"
- action_icon = 'icons/Xeno/actions/bull.dmi'
- desc = "When you hit a host, stops your charge while headbutting them, flinging them in the air and stunning them for some time."
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BULLHEADBUTT,
- )
- new_charge_type = CHARGE_BULL_HEADBUTT
-
-/datum/action/ability/activable/xeno/bull_charge/gore
- name = "Gore Charge"
- action_icon_state = "bull_gore"
- action_icon = 'icons/Xeno/actions/bull.dmi'
- desc = "When you hit a host, stops your charge while piercing and injecting them with Ozelomelyn."
- keybinding_signals = list(
- KEYBINDING_NORMAL = COMSIG_XENOABILITY_BULLGORE,
- )
- new_charge_type = CHARGE_BULL_GORE
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/bull/bull.dm b/code/modules/mob/living/carbon/xenomorph/castes/bull/bull.dm
deleted file mode 100644
index 4bd4249bd7fc4..0000000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/bull/bull.dm
+++ /dev/null
@@ -1,28 +0,0 @@
-/mob/living/carbon/xenomorph/bull
- caste_base_type = /datum/xeno_caste/bull
- name = "Bull"
- desc = "A bright red alien with a matching temper."
- icon = 'icons/Xeno/castes/bull.dmi'
- icon_state = "Bull Walking"
- bubble_icon = "alienleft"
- health = 160
- maxHealth = 160
- plasma_stored = 200
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_NORMAL
-
- pixel_x = -16
- pixel_y = -3
-
-
-/mob/living/carbon/xenomorph/bull/handle_special_state()
- if(is_charging >= CHARGE_ON)
- icon_state = "[xeno_caste.caste_name][(xeno_flags & XENO_ROUNY) ? " rouny" : ""] Charging"
- return TRUE
- return FALSE
-
-
-/mob/living/carbon/xenomorph/bull/handle_special_wound_states(severity)
- . = ..()
- if(is_charging >= CHARGE_ON)
- return "wounded_charging_[severity]"
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm b/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm
deleted file mode 100644
index b97855384c6d7..0000000000000
--- a/code/modules/mob/living/carbon/xenomorph/castes/bull/castedatum_bull.dm
+++ /dev/null
@@ -1,63 +0,0 @@
-/datum/xeno_caste/bull
- caste_name = "Bull"
- display_name = "Bull"
- upgrade_name = ""
- caste_desc = "A well defended hit-and-runner."
- base_strain_type = /mob/living/carbon/xenomorph/bull
- caste_type_path = /mob/living/carbon/xenomorph/bull
- tier = XENO_TIER_TWO
- upgrade = XENO_UPGRADE_BASETYPE
- wound_type = "bull" //used to match appropriate wound overlays
-
- // *** Melee Attacks *** //
- melee_damage = 24
-
- // *** Speed *** //
- speed = -0.8
-
- // *** Plasma *** //
- plasma_max = 340 //High plasma is need for charging
- plasma_gain = 24
-
- // *** Health *** //
- max_health = 450
-
- // *** Sunder *** //
- sunder_multiplier = 0.9
-
- // *** Evolution *** //
- evolution_threshold = 225
- upgrade_threshold = TIER_TWO_THRESHOLD
-
- deevolves_to = /datum/xeno_caste/runner
-
- // *** Flags *** //
- caste_flags = CASTE_EVOLUTION_ALLOWED
- can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER
- caste_traits = null
-
- // *** Defense *** //
- soft_armor = list(MELEE = 50, BULLET = 55, LASER = 55, ENERGY = 55, BOMB = 20, BIO = 35, FIRE = 50, ACID = 35)
-
- // *** Minimap Icon *** //
- minimap_icon = "bull"
-
- 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/ready_charge/bull_charge,
- /datum/action/ability/activable/xeno/bull_charge,
- /datum/action/ability/activable/xeno/bull_charge/headbutt,
- /datum/action/ability/activable/xeno/bull_charge/gore,
- /datum/action/ability/xeno_action/toggle_long_range/bull,
- )
-
-/datum/xeno_caste/bull/normal
- upgrade = XENO_UPGRADE_NORMAL
-
-/datum/xeno_caste/bull/primordial
- upgrade_name = "Primordial"
- caste_desc = "Bloodthirsty horned devil of the hive. Stay away from its path."
- primordial_message = "We are the spearhead of the hive. Run them all down."
- upgrade = XENO_UPGRADE_PRIMO
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_bull.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_bull.dm
new file mode 100644
index 0000000000000..2702321f14e0c
--- /dev/null
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_bull.dm
@@ -0,0 +1,259 @@
+// ***************************************
+// *********** Bull's Charge
+// ***************************************
+/datum/action/ability/xeno_action/ready_charge/bull_charge
+ action_icon_state = "bull_ready_charge"
+ action_icon = 'icons/Xeno/actions/bull.dmi'
+ charge_type = CHARGE_BULL
+ crush_sound = SFX_ALIEN_TAIL_ATTACK
+ speed_per_step = 0.15
+ steps_for_charge = 5
+ max_steps_buildup = 10
+ crush_living_damage = 37
+ plasma_use_multiplier = 2
+
+
+// ***************************************
+// *********** Bull's Stomp
+// ***************************************
+#define BULL_STOMP_DEBUFF 1.5 //in stacks.
+
+/datum/action/ability/activable/xeno/stomp/bull
+ name = "Bull's Stomp"
+ ability_cost = 50
+ cooldown_duration = 10 SECONDS
+ stomp_damage = 50
+ paralyze_duration = 2 SECONDS
+
+/datum/action/ability/activable/xeno/stomp/bull/use_ability(atom/A)
+ succeed_activate()
+ add_cooldown()
+ playsound(xeno_owner.loc, 'sound/effects/bang.ogg', 25, 0)
+ xeno_owner.create_stomp()
+ for(var/mob/living/living_target in range(1, xeno_owner.loc))
+ if(xeno_owner.issamexenohive(living_target) || living_target.stat == DEAD || !xeno_owner.Adjacent(living_target))
+ continue
+ var/distance = get_dist(living_target, xeno_owner)
+ var/damage = stomp_damage / max(1, distance + 1)
+ if(distance == 0)
+ GLOB.round_statistics.crusher_stomp_victims++
+ SSblackbox.record_feedback("tally", "round_statistics", 1, "crusher_stomp_victims")
+ living_target.take_overall_damage(damage, BRUTE, MELEE, updating_health = TRUE, max_limbs = 2)
+ living_target.Paralyze(paralyze_duration)
+ shake_camera(living_target, 2, 2)
+ else
+ step_away(living_target, xeno_owner, 1) //Knock away
+ living_target.take_overall_damage(damage, BRUTE, MELEE, updating_health = TRUE, max_limbs = 2)
+ living_target.do_jitter_animation(700, BULL_STOMP_DEBUFF SECONDS)
+ living_target.adjust_stagger(BULL_STOMP_DEBUFF)
+ living_target.adjust_slowdown(BULL_STOMP_DEBUFF)
+
+
+// ***************************************
+// *********** Scorched Earth
+// ***************************************
+#define SCORCHED_EARTH_RANGE 6
+#define SCORCHED_EARTH_RESET_TIME 6 SECONDS
+#define SCORCHED_EARTH_AOE_SIZE 1
+#define SCORCHED_EARTH_TRAVEL_DAMAGE 5
+#define SCORCHED_EARTH_TRAVEL_DEBUFF 4
+#define SCORCHED_EARTH_TILE_DAMAGE 15
+#define SCORCHED_EARTH_TILE_DEBUFF 1
+
+/datum/action/ability/activable/xeno/scorched_earth
+ name = "Scorched Earth"
+ action_icon_state = "scorched_earth"
+ action_icon = 'icons/Xeno/actions/crusher.dmi'
+ desc = "When activated, gain three charges of Scorched Earth. These can be used to dash towards a targeted location, leaving damaging trails of plasma behind."
+ ability_cost = 250
+ cooldown_duration = 3 MINUTES
+ target_flags = ABILITY_TURF_TARGET
+ keybinding_signals = list(
+ KEYBINDING_NORMAL = COMSIG_XENOABILITY_SCORCHED_EARTH,
+ )
+ /// Used for particles. Holds the particles instead of the mob. See particle_holder for documentation.
+ var/obj/effect/abstract/particle_holder/particle_holder
+ /// Whether this ability is active or not.
+ var/ability_active = FALSE
+ /// The current amount of charges of this ability that we have. Initial value is assumed to be the maximum.
+ var/ability_charges = 3
+ /// Timer ID. Warns the player that the ability's duration is about to end.
+ var/warning_timer
+ /// Timer ID. Grace period that this ability allows after activation. If it expires, the ability resets.
+ var/reset_timer
+
+/datum/action/ability/activable/xeno/scorched_earth/on_cooldown_finish()
+ playsound(xeno_owner, 'sound/effects/alien/new_larva.ogg', 50, 0, 1)
+ xeno_owner.balloon_alert(xeno_owner, "[initial(name)] ready")
+ return ..()
+
+/datum/action/ability/activable/xeno/scorched_earth/give_action(...)
+ . = ..()
+ var/mutable_appearance/counter_maptext = mutable_appearance(icon = null, icon_state = null, layer = ACTION_LAYER_MAPTEXT)
+ counter_maptext.pixel_x = 16
+ counter_maptext.pixel_y = -4
+ visual_references[VREF_MUTABLE_SCORCHED_EARTH] = counter_maptext
+
+/datum/action/ability/activable/xeno/scorched_earth/remove_action(...)
+ . = ..()
+ button.cut_overlay(visual_references[VREF_MUTABLE_SCORCHED_EARTH])
+ visual_references[VREF_MUTABLE_SCORCHED_EARTH] = null
+
+/datum/action/ability/activable/xeno/scorched_earth/update_button_icon()
+ if(!ability_active)
+ return ..()
+ button.cut_overlay(visual_references[VREF_MUTABLE_SCORCHED_EARTH])
+ var/mutable_appearance/number = visual_references[VREF_MUTABLE_SCORCHED_EARTH]
+ number.maptext = MAPTEXT("[ability_charges]/[initial(ability_charges)]")
+ visual_references[VREF_MUTABLE_SCORCHED_EARTH] = number
+ button.add_overlay(visual_references[VREF_MUTABLE_SCORCHED_EARTH])
+ return ..()
+
+/datum/action/ability/activable/xeno/scorched_earth/action_activate()
+ if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER) & COMPONENT_ACTION_BLOCK_TRIGGER)
+ return FALSE
+ if(!ability_active && can_use_action())
+ ability_active = TRUE
+ xeno_owner.emote("roar6")
+ ability_charges = initial(ability_charges)
+ use_state_flags |= ABILITY_IGNORE_PLASMA
+ warning_timer = addtimer(CALLBACK(xeno_owner, TYPE_PROC_REF(/mob, playsound_local), xeno_owner.loc, 'sound/voice/hiss4.ogg', 40, TRUE), SCORCHED_EARTH_RESET_TIME * 0.7, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)
+ reset_timer = addtimer(CALLBACK(src, PROC_REF(end_ability)), SCORCHED_EARTH_RESET_TIME, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)
+ particle_holder = new(xeno_owner, /particles/bull_glow)
+ particle_holder.particles.icon = xeno_owner.icon
+ adjust_particles(new_dir = xeno_owner.dir)
+ RegisterSignals(xeno_owner, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_LIVING_DO_RESIST, COMSIG_XENOMORPH_REST, COMSIG_XENOMORPH_UNREST), PROC_REF(adjust_particles))
+ RegisterSignals(xeno_owner, list(COMSIG_QDELETING, COMSIG_MOB_DEATH), PROC_REF(end_ability))
+ add_cooldown(1.5 SECONDS)
+ succeed_activate()
+ if(xeno_owner.selected_ability == src)
+ return
+ if(xeno_owner.selected_ability)
+ xeno_owner.selected_ability.deselect()
+ select()
+
+/datum/action/ability/activable/xeno/scorched_earth/use_ability(turf/turf_target)
+ . = ..()
+ xeno_owner.set_canmove(FALSE)
+ playsound(xeno_owner, 'sound/effects/alien/behemoth/landslide_enhanced_charge.ogg', 30, TRUE)
+ RegisterSignal(xeno_owner, COMSIG_MOVABLE_MOVED, PROC_REF(check_turf))
+ RegisterSignal(xeno_owner, COMSIG_MOVABLE_POST_THROW, PROC_REF(end_throw))
+ xeno_owner.throw_at(turf_target, SCORCHED_EARTH_RANGE, 3, xeno_owner)
+ ability_charges--
+ if(!ability_charges)
+ end_ability()
+ return
+ add_cooldown(1.5 SECONDS)
+ warning_timer = addtimer(CALLBACK(xeno_owner, TYPE_PROC_REF(/mob, playsound_local), xeno_owner.loc, 'sound/voice/hiss4.ogg', 40, TRUE), SCORCHED_EARTH_RESET_TIME * 0.7, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)
+ reset_timer = addtimer(CALLBACK(src, PROC_REF(end_ability)), SCORCHED_EARTH_RESET_TIME, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)
+
+/// Ends the throw, removing signals and allowing movement.
+/datum/action/ability/activable/xeno/scorched_earth/proc/end_throw()
+ SIGNAL_HANDLER
+ xeno_owner.set_canmove(TRUE)
+ UnregisterSignal(xeno_owner, list(COMSIG_MOVABLE_MOVED, COMSIG_MOVABLE_POST_THROW))
+ if(xeno_owner.throwing)
+ xeno_owner.stop_throw()
+
+/// Checks affected turfs and applies various effects to eligible contents.
+/datum/action/ability/activable/xeno/scorched_earth/proc/check_turf(datum/source, atom/old_loc, movement_dir)
+ SIGNAL_HANDLER
+ for(var/turf/affected_turf AS in RANGE_TURFS(SCORCHED_EARTH_AOE_SIZE, xeno_owner.loc))
+ if(isclosedturf(affected_turf))
+ continue
+ var/obj/fire/scorched_earth/bull_fire = locate(/obj/fire/scorched_earth) in affected_turf
+ if(!bull_fire)
+ new /obj/fire/scorched_earth(affected_turf, max(900, rand(0, 1100)), 0, "red", 0, 0, xeno_owner.hivenumber)
+ for(var/mob/living/affected_living in affected_turf)
+ if(affected_living.issamexenohive(xeno_owner) || affected_living.stat == DEAD)
+ continue
+ affected_living.take_overall_damage(SCORCHED_EARTH_TRAVEL_DAMAGE, BRUTE, MELEE, penetration = 100, max_limbs = SCORCHED_EARTH_TRAVEL_DAMAGE)
+ affected_living.adjust_stagger(SCORCHED_EARTH_TRAVEL_DEBUFF)
+ affected_living.adjust_slowdown(SCORCHED_EARTH_TRAVEL_DEBUFF)
+
+/// Adjusts particles to match the user. Alignments are hand picked, and should be remade if the King's icon ever changes.
+/datum/action/ability/activable/xeno/scorched_earth/proc/adjust_particles(datum/source, unused, new_dir)
+ SIGNAL_HANDLER
+ if(!particle_holder)
+ return
+ if(!(new_dir in GLOB.alldirs))
+ new_dir = xeno_owner.dir
+ particle_holder.particles.icon_state = "[xeno_owner.xeno_caste.caste_name] Glow [closest_cardinal_dir(new_dir)]" // This intentionally misses some states, for the record.
+ particle_holder.layer = xeno_owner.layer + 0.01
+ particle_holder.pixel_x = xeno_owner.pixel_x + 32
+ particle_holder.pixel_y = xeno_owner.pixel_y + 19
+
+/// Ends the ability.
+/datum/action/ability/activable/xeno/scorched_earth/proc/end_ability()
+ SIGNAL_HANDLER
+ ability_active = FALSE
+ use_state_flags &= ~ABILITY_IGNORE_PLASMA
+ deltimer(warning_timer)
+ deltimer(reset_timer)
+ QDEL_NULL(particle_holder)
+ UnregisterSignal(xeno_owner, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_LIVING_DO_RESIST, COMSIG_XENOMORPH_REST, COMSIG_XENOMORPH_UNREST, COMSIG_QDELETING, COMSIG_MOB_DEATH))
+ update_button_icon()
+ button.cut_overlay(visual_references[VREF_MUTABLE_SCORCHED_EARTH])
+ xeno_owner.playsound_local(xeno_owner.loc, 'sound/voice/hiss5.ogg', 40, TRUE)
+ add_cooldown()
+
+/obj/fire/scorched_earth
+ name = "Scorched Earth"
+ icon = 'icons/effects/fire.dmi'
+ icon_state = "bull"
+ light_range = 1
+ light_power = 1
+ burn_decay = 80
+ /// The hive this belongs to.
+ var/hivenumber
+
+/obj/fire/scorched_earth/Initialize(mapload, new_burn_ticks = burn_ticks, new_burn_level = burn_level, f_color, fire_stacks = 0, fire_damage = 0, _hivenumber)
+ . = ..()
+ hivenumber = _hivenumber
+
+/obj/fire/scorched_earth/update_icon_state()
+ light_color = LIGHT_COLOR_BLOOD_MAGIC
+
+/obj/fire/scorched_earth/effect_smoke(...)
+ return
+
+/obj/fire/scorched_earth/set_fire(new_burn_ticks, new_burn_level, new_flame_color, fire_stacks = 0, fire_damage = 0)
+ if(new_burn_ticks <= 0)
+ qdel(src)
+ return
+ if(new_burn_ticks)
+ burn_ticks = new_burn_ticks
+ if(new_burn_level)
+ burn_level = new_burn_level
+ update_appearance(UPDATE_ICON)
+ if((fire_stacks + fire_damage) <= 0)
+ return
+
+/obj/fire/scorched_earth/affect_atom(atom/affected)
+ if(!isliving(affected))
+ return
+ var/mob/living/affected_living = affected
+ if(affected_living.stat == DEAD)
+ return
+ if(isxeno(affected_living))
+ var/mob/living/carbon/xenomorph/affected_xeno = affected_living
+ if(affected_xeno.hivenumber == hivenumber)
+ return
+ if(affected_living.status_flags & (INCORPOREAL|GODMODE))
+ return FALSE
+ if(affected_living.pass_flags & PASS_FIRE)
+ return FALSE
+ affected_living.take_overall_damage(SCORCHED_EARTH_TILE_DAMAGE, BRUTE, MELEE, penetration = 100, max_limbs = 2)
+ affected_living.adjust_blurriness(SCORCHED_EARTH_TRAVEL_DEBUFF)
+ affected_living.adjust_stagger(SCORCHED_EARTH_TRAVEL_DEBUFF)
+ affected_living.adjust_slowdown(SCORCHED_EARTH_TRAVEL_DEBUFF)
+
+/particles/bull_glow
+ icon_state = "Bull Glow 2"
+ width = 96
+ height = 96
+ count = 1
+ spawning = 1
+ lifespan = 8
+ fadein = 4
+ fade = 4
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
index e6e8269b70f05..c9a2c5acd162e 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/abilities_crusher.dm
@@ -5,21 +5,22 @@
name = "Stomp"
action_icon_state = "stomp"
action_icon = 'icons/Xeno/actions/crusher.dmi'
- desc = "Knocks all adjacent targets away and down."
+ desc = "Stomp on the ground, dealing heavy damage to anyone under you. Adjacent targets take less damage, and are knocked back."
ability_cost = 100
cooldown_duration = 20 SECONDS
keybind_flags = ABILITY_KEYBIND_USE_ABILITY
keybinding_signals = list(
KEYBINDING_NORMAL = COMSIG_XENOABILITY_STOMP,
)
+ /// The damage dealt by this ability.
+ var/stomp_damage = 60
+ /// The duration of this ability's paralyze debuff.
+ var/paralyze_duration = 3 SECONDS
/datum/action/ability/activable/xeno/stomp/use_ability(atom/A)
succeed_activate()
add_cooldown()
- GLOB.round_statistics.crusher_stomps++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "crusher_stomps")
-
playsound(xeno_owner.loc, 'sound/effects/bang.ogg', 25, 0)
xeno_owner.visible_message(span_xenodanger("[xeno_owner] smashes into the ground!"), \
span_xenodanger("We smash into the ground!"))
@@ -29,12 +30,12 @@
if(xeno_owner.issamexenohive(M) || M.stat == DEAD || isnestedhost(M) || !xeno_owner.Adjacent(M))
continue
var/distance = get_dist(M, xeno_owner)
- var/damage = xeno_owner.xeno_caste.stomp_damage/max(1, distance + 1)
+ var/damage = stomp_damage / max(1, distance + 1)
if(distance == 0) //If we're on top of our victim, give him the full impact
GLOB.round_statistics.crusher_stomp_victims++
SSblackbox.record_feedback("tally", "round_statistics", 1, "crusher_stomp_victims")
M.take_overall_damage(damage, BRUTE, MELEE, updating_health = TRUE, max_limbs = 3)
- M.Paralyze(3 SECONDS)
+ M.Paralyze(paralyze_duration)
to_chat(M, span_userdanger("You are stomped on by [xeno_owner]!"))
shake_camera(M, 3, 3)
else
@@ -42,7 +43,7 @@
shake_camera(M, 2, 2)
to_chat(M, span_userdanger("You reel from the shockwave of [xeno_owner]'s stomp!"))
M.take_overall_damage(damage, BRUTE, MELEE, updating_health = TRUE, max_limbs = 3)
- M.Paralyze(0.5 SECONDS)
+ M.Paralyze(paralyze_duration / 6)
/datum/action/ability/activable/xeno/stomp/ai_should_start_consider()
return TRUE
@@ -72,6 +73,8 @@
KEYBINDING_NORMAL = COMSIG_XENOABILITY_CRESTTOSS,
)
target_flags = ABILITY_MOB_TARGET
+ /// How far we will fling our target
+ var/fling_distance = 6
/datum/action/ability/activable/xeno/cresttoss/on_cooldown_finish()
to_chat(xeno_owner, span_xenowarning("We can now crest toss again."))
@@ -95,7 +98,6 @@
/datum/action/ability/activable/xeno/cresttoss/use_ability(atom/movable/A)
xeno_owner.face_atom(A) //Face towards the target so we don't look silly
var/facing
- var/toss_distance = xeno_owner.xeno_caste.crest_toss_distance
var/turf/throw_origin = get_turf(xeno_owner)
var/turf/target_turf = throw_origin //throw distance is measured from the xeno itself
var/big_mob_message
@@ -110,10 +112,10 @@
if(isliving(A))
var/mob/living/L = A
if(L.mob_size >= MOB_SIZE_BIG) //Penalize toss distance for big creatures
- toss_distance = FLOOR(toss_distance * 0.5, 1)
+ fling_distance = FLOOR(fling_distance * 0.5, 1)
big_mob_message = ", struggling mightily to heft its bulk"
else if(ismecha(A))
- toss_distance = FLOOR(toss_distance * 0.5, 1)
+ fling_distance = FLOOR(fling_distance * 0.5, 1)
big_mob_message = ", struggling mightily to heft its bulk"
if(xeno_owner.a_intent == INTENT_HARM) //If we use the ability on hurt intent, we throw them in front; otherwise we throw them behind.
@@ -122,13 +124,13 @@
facing = get_dir(A, xeno_owner)
var/turf/temp
- for(var/x in 1 to toss_distance)
+ for(var/x in 1 to fling_distance)
temp = get_step(target_turf, facing)
if(!temp)
break
target_turf = temp
- xeno_owner.icon_state = "Crusher Charging" //Momentarily lower the crest for visual effect
+ xeno_owner.icon_state = "[xeno_owner.xeno_caste.caste_name] Charging" //Momentarily lower the crest for visual effect.
xeno_owner.visible_message(span_xenowarning("\The [xeno_owner] flings [A] away with its crest[big_mob_message]!"), \
span_xenowarning("We fling [A] away with our crest[big_mob_message]!"))
@@ -136,13 +138,11 @@
succeed_activate()
A.forceMove(throw_origin)
- A.throw_at(target_turf, toss_distance, 1, xeno_owner, TRUE, TRUE)
-
+ A.throw_at(target_turf, fling_distance, 1, xeno_owner, TRUE, TRUE)
//Handle the damage
if(!xeno_owner.issamexenohive(A) && isliving(A)) //Friendly xenos don't take damage.
- var/damage = toss_distance * 6
var/mob/living/L = A
- L.take_overall_damage(damage, BRUTE, MELEE, updating_health = TRUE)
+ L.take_overall_damage(fling_distance * 6, BRUTE, MELEE, updating_health = TRUE)
shake_camera(L, 2, 2)
playsound(A, pick('sound/weapons/alien_claw_block.ogg','sound/weapons/alien_bite2.ogg'), 50, 1)
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
index f587f1cfe71dc..f226d6f789dd9 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/castedatum_crusher.dm
@@ -27,7 +27,7 @@
// *** Evolution *** //
upgrade_threshold = TIER_THREE_THRESHOLD
- deevolves_to = /datum/xeno_caste/bull
+ deevolves_to = /datum/xeno_caste/warrior
// *** Flags *** //
can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER
@@ -42,10 +42,6 @@
// *** Minimap Icon *** //
minimap_icon = "crusher"
- // *** Crusher Abilities *** //
- stomp_damage = 60
- crest_toss_distance = 6
-
actions = list(
/datum/action/ability/xeno_action/xeno_resting,
/datum/action/ability/xeno_action/watch_xeno,
@@ -83,3 +79,60 @@
/datum/action/ability/activable/xeno/cresttoss,
/datum/action/ability/activable/xeno/advance,
)
+
+
+// ***************************************
+// *********** Bull
+// ***************************************
+/datum/xeno_caste/crusher/bull
+ caste_name = "Bull"
+ display_name = "Bull"
+ caste_desc = "A well defended hit-and-runner."
+ caste_type_path = /mob/living/carbon/xenomorph/crusher/bull
+ wound_type = "bull"
+
+ // *** Melee Attacks *** //
+ attack_delay = 7
+
+ // *** Speed *** //
+ speed = -0.8
+
+ // *** Health *** //
+ max_health = 400
+
+ // *** Flags *** //
+ caste_flags = CASTE_EVOLUTION_ALLOWED|CASTE_IS_STRONG
+ can_flags = CASTE_CAN_BE_QUEEN_HEALED|CASTE_CAN_BE_GIVEN_PLASMA|CASTE_CAN_BE_LEADER
+ caste_traits = list(TRAIT_STAGGERIMMUNE)
+
+ // *** Defense *** //
+ soft_armor = list(MELEE = 65, BULLET = 65, LASER = 65, ENERGY = 65, BOMB = 65, BIO = 65, FIRE = 65, ACID = 65)
+
+ 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/ready_charge/bull_charge,
+ /datum/action/ability/xeno_action/toggle_long_range/bull,
+ /datum/action/ability/activable/xeno/stomp/bull,
+ )
+
+/datum/xeno_caste/crusher/bull/normal
+ upgrade = XENO_UPGRADE_NORMAL
+
+/datum/xeno_caste/crusher/bull/primordial
+ upgrade_name = "Primordial"
+ caste_desc = "Bloodthirsty horned devil of the hive. Stay away from its path."
+ primordial_message = "We are the spearhead of the hive. Run them all down."
+ upgrade = XENO_UPGRADE_PRIMO
+
+ // *** 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/ready_charge/bull_charge,
+ /datum/action/ability/xeno_action/toggle_long_range/bull,
+ /datum/action/ability/activable/xeno/stomp/bull,
+ /datum/action/ability/activable/xeno/scorched_earth,
+ )
diff --git a/code/modules/mob/living/carbon/xenomorph/castes/crusher/crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/crusher/crusher.dm
index 74162039f312c..111e8c8d03a72 100644
--- a/code/modules/mob/living/carbon/xenomorph/castes/crusher/crusher.dm
+++ b/code/modules/mob/living/carbon/xenomorph/castes/crusher/crusher.dm
@@ -2,7 +2,7 @@
caste_base_type = /datum/xeno_caste/crusher
name = "Crusher"
desc = "A huge alien with an enormous armored head crest."
- icon = 'icons/Xeno/castes/crusher.dmi'
+ icon = 'icons/Xeno/castes/crusher/crusher.dmi'
icon_state = "Crusher Walking"
bubble_icon = "alienleft"
health = 300
@@ -46,3 +46,17 @@
/mob/living/carbon/xenomorph/crusher/resisted_against(datum/source)
user_unbuckle_mob(source, source)
+
+/mob/living/carbon/xenomorph/crusher/bull
+ caste_base_type = /datum/xeno_caste/crusher/bull
+ name = "Bull"
+ desc = "A bright red alien with a matching temper."
+ icon = 'icons/Xeno/castes/crusher/bull.dmi'
+ icon_state = "Bull Walking"
+ mob_size = MOB_SIZE_XENO
+ pixel_x = -16
+ pixel_y = -3
+
+/mob/living/carbon/xenomorph/crusher/bull/primordial
+ upgrade = XENO_UPGRADE_PRIMO
+ upgrade_stored = TIER_THREE_THRESHOLD
diff --git a/code/modules/mob/living/carbon/xenomorph/charge_crush.dm b/code/modules/mob/living/carbon/xenomorph/charge_crush.dm
index 6967a8d1962d6..6ac3e165de264 100644
--- a/code/modules/mob/living/carbon/xenomorph/charge_crush.dm
+++ b/code/modules/mob/living/carbon/xenomorph/charge_crush.dm
@@ -3,9 +3,7 @@
#define CHARGE_CRUSH (1<<0)
#define CHARGE_BULL (1<<1)
-#define CHARGE_BULL_HEADBUTT (1<<2)
-#define CHARGE_BULL_GORE (1<<3)
-#define CHARGE_BEHEMOTH (1<<4)
+#define CHARGE_BEHEMOTH (1<<2)
#define STOP_CRUSHER_ON_DEL (1<<0)
@@ -34,7 +32,6 @@
var/steps_for_charge = 7
var/max_steps_buildup = 14
var/crush_living_damage = 20
- var/next_special_attack = 0 //Little var to keep track on special attack timers.
var/plasma_use_multiplier = 1
///If this charge should keep momentum on dir change and if it can charge diagonally
var/agile_charge = FALSE
@@ -226,7 +223,7 @@
span_danger("We run [victim] over!"), null, 5)
victim.take_overall_damage(CHARGE_SPEED(src) * 10, BRUTE,MELEE, max_limbs = 3)
animation_flash_color(victim)
- if(CHARGE_BULL, CHARGE_BULL_HEADBUTT, CHARGE_BULL_GORE) //Xeno Bull
+ if(CHARGE_BULL)
if(MODULUS(valid_steps_taken, 4) == 0)
playsound(charger, SFX_ALIEN_FOOTSTEP_LARGE, 50)
if(CHARGE_BEHEMOTH)
@@ -268,8 +265,14 @@
if(charger.incapacitated() || charger.now_pushing)
return NONE
- if(charge_type & (CHARGE_BULL|CHARGE_BULL_HEADBUTT|CHARGE_BULL_GORE|CHARGE_BEHEMOTH) && !isliving(crushed))
+ if(charge_type & (CHARGE_BULL|CHARGE_BEHEMOTH) && !isliving(crushed))
do_stop_momentum()
+ if(charge_type & CHARGE_BEHEMOTH)
+ return COMPONENT_MOVABLE_PREBUMP_STOPPED
+ if(istype(crushed, /obj/structure/razorwire))
+ var/obj/structure/razorwire/crushed_wire = crushed
+ INVOKE_ASYNC(crushed_wire, TYPE_PROC_REF(/atom, post_crush_act), charger, src)
+ return COMPONENT_MOVABLE_PREBUMP_ENTANGLED
return COMPONENT_MOVABLE_PREBUMP_STOPPED
var/precrush = crushed.pre_crush_act(charger, src) //Negative values are codes. Positive ones are damage to deal.
@@ -339,54 +342,6 @@
do_stop_momentum(FALSE)
return COMPONENT_MOVABLE_PREBUMP_STOPPED
-
-/datum/action/ability/xeno_action/ready_charge/bull_charge
- action_icon_state = "bull_ready_charge"
- action_icon = 'icons/Xeno/actions/bull.dmi'
- charge_type = CHARGE_BULL
- speed_per_step = 0.15
- steps_for_charge = 5
- max_steps_buildup = 10
- crush_living_damage = 37
- plasma_use_multiplier = 2
-
-
-/datum/action/ability/xeno_action/ready_charge/bull_charge/give_action(mob/living/L)
- . = ..()
- RegisterSignal(L, COMSIG_XENOACTION_TOGGLECHARGETYPE, PROC_REF(toggle_charge_type))
-
-
-/datum/action/ability/xeno_action/ready_charge/bull_charge/remove_action(mob/living/L)
- UnregisterSignal(L, COMSIG_XENOACTION_TOGGLECHARGETYPE)
- return ..()
-
-
-/datum/action/ability/xeno_action/ready_charge/bull_charge/proc/toggle_charge_type(datum/source, new_charge_type = CHARGE_BULL)
- SIGNAL_HANDLER
- if(charge_type == new_charge_type)
- return
-
- var/mob/living/carbon/xenomorph/charger = owner
- if(charger.is_charging >= CHARGE_ON)
- do_stop_momentum()
-
- switch(new_charge_type)
- if(CHARGE_BULL)
- charge_type = CHARGE_BULL
- crush_sound = initial(crush_sound)
- to_chat(owner, span_notice("Now charging normally."))
- if(CHARGE_BULL_HEADBUTT)
- charge_type = CHARGE_BULL_HEADBUTT
- to_chat(owner, span_notice("Now headbutting on impact."))
- if(CHARGE_BULL_GORE)
- charge_type = CHARGE_BULL_GORE
- crush_sound = SFX_ALIEN_TAIL_ATTACK
- to_chat(owner, span_notice("Now goring on impact."))
-
-/datum/action/ability/xeno_action/ready_charge/bull_charge/on_xeno_upgrade()
- var/mob/living/carbon/xenomorph/X = owner
- agile_charge = (X.upgrade == XENO_UPGRADE_PRIMO)
-
/datum/action/ability/xeno_action/ready_charge/queen_charge
action_icon_state = "queen_ready_charge"
action_icon = 'icons/Xeno/actions/queen.dmi'
@@ -569,15 +524,10 @@
switch(charge_datum.charge_type)
if(CHARGE_CRUSH)
Paralyze(CHARGE_SPEED(charge_datum) * 2 SECONDS)
- if(CHARGE_BULL_HEADBUTT)
- Paralyze(CHARGE_SPEED(charge_datum) * 1.5 SECONDS)
if(CHARGE_BULL)
- Paralyze(0.2 SECONDS)
- if(CHARGE_BULL_GORE)
+ Paralyze(CHARGE_SPEED(charge_datum) * 1.5 SECONDS)
adjust_stagger(CHARGE_SPEED(charge_datum) * 1 SECONDS)
adjust_slowdown(CHARGE_SPEED(charge_datum) * 1)
- reagents.add_reagent(/datum/reagent/toxin/xeno_ozelomelyn, 10)
- playsound(charger,'sound/effects/spray3.ogg', 15, TRUE)
if(anchored)
charge_datum.do_stop_momentum(FALSE)
@@ -603,40 +553,16 @@
charger.visible_message(span_danger("[charger] rams [src]!"),
span_xenodanger("We ram [src]!"))
charge_datum.speed_down(1) //Lose one turf worth of speed.
- GLOB.round_statistics.bull_crush_hit++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "bull_crush_hit")
return PRECRUSH_PLOWED
- if(CHARGE_BULL_GORE)
- if(world.time > charge_datum.next_special_attack)
- charge_datum.next_special_attack = world.time + 2 SECONDS
- var/turf/destination = get_step(loc, charger.dir)
- if(destination)
- throw_at(destination, 1, 1, charger, FALSE)
- charger.visible_message(span_danger("[charger] gores [src]!"),
- span_xenowarning("We gore [src] and skid to a halt!"))
- GLOB.round_statistics.bull_gore_hit++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "bull_gore_hit")
-
-
- if(CHARGE_BULL_HEADBUTT)
- var/fling_dir = charger.a_intent == INTENT_HARM ? charger.dir : REVERSE_DIR(charger.dir)
- var/fling_dist = min(round(CHARGE_SPEED(charge_datum)) + 2, 3)
- var/turf/destination = loc
- var/turf/temp
-
- for(var/i in 1 to fling_dist)
- temp = get_step(destination, fling_dir)
- if(!temp)
- break
- destination = temp
- if(destination != loc)
- throw_at(destination, fling_dist, 1, charger, TRUE)
-
- charger.visible_message(span_danger("[charger] rams into [src] and flings [p_them()] away!"),
- span_xenowarning("We ram into [src] and skid to a halt!"))
- GLOB.round_statistics.bull_headbutt_hit++
- SSblackbox.record_feedback("tally", "round_statistics", 1, "bull_headbutt_hit")
+ if(CHARGE_BULL)
+ var/turf/destination = get_step(loc, charger.dir)
+ if(destination)
+ throw_at(destination, 1, 1, charger, FALSE)
+ charger.visible_message(span_danger("[charger] gores [src]!"),
+ span_xenowarning("We gore [src] and skid to a halt!"))
+ GLOB.round_statistics.bull_hit++
+ SSblackbox.record_feedback("tally", "round_statistics", 1, "bull_hit")
charge_datum.do_stop_momentum(FALSE)
return PRECRUSH_STOPPED
diff --git a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
index 5a63b86bbbdb8..13f85ade1f001 100644
--- a/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
+++ b/code/modules/mob/living/carbon/xenomorph/hive_datum.dm
@@ -1232,9 +1232,6 @@ to_chat will check for valid clients itself already so no need to double check f
/mob/living/carbon/xenomorph/boiler/Corrupted
hivenumber = XENO_HIVE_CORRUPTED
-/mob/living/carbon/xenomorph/bull/Corrupted
- hivenumber = XENO_HIVE_CORRUPTED
-
/mob/living/carbon/xenomorph/carrier/Corrupted
hivenumber = XENO_HIVE_CORRUPTED
@@ -1310,9 +1307,6 @@ to_chat will check for valid clients itself already so no need to double check f
/mob/living/carbon/xenomorph/boiler/Alpha
hivenumber = XENO_HIVE_ALPHA
-/mob/living/carbon/xenomorph/bull/Alpha
- hivenumber = XENO_HIVE_ALPHA
-
/mob/living/carbon/xenomorph/carrier/Alpha
hivenumber = XENO_HIVE_ALPHA
@@ -1385,9 +1379,6 @@ to_chat will check for valid clients itself already so no need to double check f
/mob/living/carbon/xenomorph/boiler/Beta
hivenumber = XENO_HIVE_BETA
-/mob/living/carbon/xenomorph/bull/Beta
- hivenumber = XENO_HIVE_BETA
-
/mob/living/carbon/xenomorph/carrier/Beta
hivenumber = XENO_HIVE_BETA
@@ -1460,9 +1451,6 @@ to_chat will check for valid clients itself already so no need to double check f
/mob/living/carbon/xenomorph/boiler/Zeta
hivenumber = XENO_HIVE_ZETA
-/mob/living/carbon/xenomorph/bull/Zeta
- hivenumber = XENO_HIVE_ZETA
-
/mob/living/carbon/xenomorph/carrier/Zeta
hivenumber = XENO_HIVE_ZETA
diff --git a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
index df1c0000d7b53..e090cd67644af 100644
--- a/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xeno_defines.dm
@@ -160,12 +160,6 @@
var/flay_plasma_gain = 0
var/max_puppets = 0
- // *** Crusher Abilities *** //
- ///The damage the stomp causes, counts armor
- var/stomp_damage = 0
- ///How many tiles the Crest toss ability throws the victim.
- var/crest_toss_distance = 0
-
// *** Gorger Abilities *** //
///Maximum amount of overheal that can be gained
var/overheal_max = 150
diff --git a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
index 7ecac730a6a63..5d969e6eb350c 100644
--- a/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
+++ b/code/modules/mob/living/carbon/xenomorph/xenoupgrade.dm
@@ -86,14 +86,6 @@
//-----RUNNER END-----//
//================//
-//-----BULL START-----//
-
-/mob/living/carbon/xenomorph/bull/primordial
- upgrade = XENO_UPGRADE_PRIMO
- upgrade_stored = TIER_TWO_THRESHOLD
-
-//-----BULL END-----//
-//================//
//-----DRONE START-----//
/mob/living/carbon/xenomorph/drone/primordial
diff --git a/icons/Xeno/actions/crusher.dmi b/icons/Xeno/actions/crusher.dmi
index e296ff4e8906f..bac1230904638 100644
Binary files a/icons/Xeno/actions/crusher.dmi and b/icons/Xeno/actions/crusher.dmi differ
diff --git a/icons/Xeno/castes/bull.dmi b/icons/Xeno/castes/bull.dmi
deleted file mode 100644
index 7d652e4b756de..0000000000000
Binary files a/icons/Xeno/castes/bull.dmi and /dev/null differ
diff --git a/icons/Xeno/castes/crusher/bull.dmi b/icons/Xeno/castes/crusher/bull.dmi
new file mode 100644
index 0000000000000..f0b961b11c857
Binary files /dev/null and b/icons/Xeno/castes/crusher/bull.dmi differ
diff --git a/icons/Xeno/castes/crusher.dmi b/icons/Xeno/castes/crusher/crusher.dmi
similarity index 100%
rename from icons/Xeno/castes/crusher.dmi
rename to icons/Xeno/castes/crusher/crusher.dmi
diff --git a/icons/effects/fire.dmi b/icons/effects/fire.dmi
index e68fc9f38d1cd..b7c96fcd492dd 100644
Binary files a/icons/effects/fire.dmi and b/icons/effects/fire.dmi differ
diff --git a/tgmc.dme b/tgmc.dme
index 62e02a34f0a3c..11fcd8cd63361 100644
--- a/tgmc.dme
+++ b/tgmc.dme
@@ -1853,12 +1853,10 @@ F// DM Environment file for baystation12.dme.
#include "code\modules\mob\living\carbon\xenomorph\castes\boiler\abilities_boiler.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\boiler\boiler.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\boiler\castedatum_boiler.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\bull\abilities_bull.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\bull\bull.dm"
-#include "code\modules\mob\living\carbon\xenomorph\castes\bull\castedatum_bull.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\carrier\abilities_carrier.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\carrier\carrier.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\carrier\castedatum_carrier.dm"
+#include "code\modules\mob\living\carbon\xenomorph\castes\crusher\abilities_bull.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\crusher\abilities_crusher.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\crusher\castedatum_crusher.dm"
#include "code\modules\mob\living\carbon\xenomorph\castes\crusher\crusher.dm"