From 6f22e91968be211466bfb67575af220836f765c8 Mon Sep 17 00:00:00 2001 From: Venuska1117 Date: Sat, 8 Aug 2026 12:00:12 +0200 Subject: [PATCH 1/4] Boiler Changes --- code/__DEFINES/traits.dm | 6 +- code/__DEFINES/xeno.dm | 4 + .../xenomorph/abilities/general_powers.dm | 33 ++--- .../carbon/xenomorph/abilities/xeno_action.dm | 3 - .../living/carbon/xenomorph/castes/Boiler.dm | 137 ++---------------- 5 files changed, 37 insertions(+), 146 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 3df635790a5e2..40f43002bedb1 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -258,7 +258,7 @@ /// If the mob won't drop items held in face slot when downed #define TRAIT_IRON_TEETH "t_iron_teeth" -// -- ability traits -- +// -- general ability traits -- /// Xenos with this trait cannot have plasma transferred to them #define TRAIT_ABILITY_NO_PLASMA_TRANSFER "t_ability_no_plasma_transfer" /// Shows that the xeno queen is on ovi @@ -267,6 +267,10 @@ #define TRAIT_ABILITY_BURROWED "t_ability_burrowed" /// Xenos with this trait can toggle long sight while resting. #define TRAIT_ABILITY_SIGHT_IGNORE_REST "t_ability_sight_ignore_rest" + + +// -- specific ability traits -- +#define TRAIT_ABILITY_BOMBARD "t_ability_bombard" /// Used by shielder to check stance. #define TRAIT_ABILITY_ENCLOSED_PLATES "t_ability_enclosed_plates" /// Used by shielder for reflective plates. diff --git a/code/__DEFINES/xeno.dm b/code/__DEFINES/xeno.dm index 9af7e845818b7..6de428a457565 100644 --- a/code/__DEFINES/xeno.dm +++ b/code/__DEFINES/xeno.dm @@ -799,3 +799,7 @@ #define FACEHUGGER_JUMP_RANGE 1 // dont really want them to hug you immediately as you break down a corner or a door when a carrier stacks them on a tile #define EGG_JUMP_RANGE 2 // This is for egg huggers, they are supposed to be scary and leap at people yes. #define CARRIER_HUGGER_THROW_RANGE 6 + +// defines below should only be used in ability actions. +#define XENO_ACTION_CHECK(X) if(!X.check_state() || !action_cooldown_check() || !check_plasma_owner(src.plasma_cost)) return +#define XENO_ACTION_CHECK_USE_PLASMA(X) if(!X.check_state() || !action_cooldown_check() || !check_and_use_plasma_owner(src.plasma_cost)) return diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index ce73fa67c851e..8e189788b330c 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -911,52 +911,48 @@ return FALSE return TRUE -/datum/action/xeno_action/activable/xeno_spit/use_ability(atom/atom) +/datum/action/xeno_action/activable/xeno_spit/use_ability(atom/target_atom) var/mob/living/carbon/xenomorph/xeno = owner - var/spit_target = aim_turf ? get_turf(atom) : atom - if(!xeno.check_state()) - return + var/spit_target = aim_turf ? get_turf(target_atom) : target_atom - if(spitting) - to_chat(src, SPAN_WARNING("We are already preparing a spit!")) + if(HAS_TRAIT(xeno, TRAIT_ABILITY_BOMBARD)) + to_chat(xeno, SPAN_WARNING("We are already preparing a spit!")) return if(!isturf(xeno.loc)) - to_chat(src, SPAN_WARNING("We can't spit from here!")) + to_chat(xeno, SPAN_WARNING("We can't spit from here!")) return if(!action_cooldown_check()) - to_chat(src, SPAN_WARNING("We must wait for our spit glands to refill.")) + to_chat(xeno, SPAN_WARNING("We must wait for our spit glands to refill.")) return var/turf/current_turf = get_turf(xeno) - if(!current_turf) return - if (!check_plasma_owner()) - return + XENO_ACTION_CHECK(xeno) if(xeno.ammo.spit_windup) - spitting = TRUE + ADD_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) if(xeno.ammo.pre_spit_warn) playsound(xeno.loc,"alien_drool", 55, 1) to_chat(xeno, SPAN_WARNING("We begin to prepare a large spit!")) xeno.visible_message(SPAN_WARNING("[xeno] prepares to spit a massive glob!"), SPAN_WARNING("We begin to spit [xeno.ammo.name]!")) - if (!do_after(xeno, xeno.ammo.spit_windup, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + if(!do_after(xeno, xeno.ammo.spit_windup, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) to_chat(xeno, SPAN_XENODANGER("We decide to cancel our spit.")) - spitting = FALSE + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) return plasma_cost = xeno.ammo.spit_cost if(!check_and_use_plasma_owner()) - spitting = FALSE + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) return - xeno.visible_message(SPAN_XENOWARNING("[xeno] spits at [atom]!"), + xeno.visible_message(SPAN_XENOWARNING("[xeno] spits at [target_atom]!"), - SPAN_XENOWARNING("We spit [xeno.ammo.name] at [atom]!") ) + SPAN_XENOWARNING("We spit [xeno.ammo.name] at [target_atom]!") ) playsound(xeno.loc, sound_to_play, 25, 1) var/obj/projectile/proj = new (current_turf, create_cause_data(xeno.ammo.name, xeno)) @@ -965,8 +961,7 @@ proj.def_zone = xeno.get_limbzone_target() proj.fire_at(spit_target, xeno, xeno, xeno.ammo.max_range, xeno.ammo.shell_speed) - spitting = FALSE - + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) SEND_SIGNAL(xeno, COMSIG_XENO_POST_SPIT) apply_cooldown() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm index d2cd1e6615566..5ea9d9a32566b 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm @@ -485,6 +485,3 @@ /datum/action/xeno_action/proc/on_deselect(mob/user) return - -#define XENO_ACTION_CHECK(X) if(!X.check_state() || !action_cooldown_check() || !check_plasma_owner(src.plasma_cost)) return -#define XENO_ACTION_CHECK_USE_PLASMA(X) if(!X.check_state() || !action_cooldown_check() || !check_and_use_plasma_owner(src.plasma_cost)) return diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm index 22537e74a943b..97579461284d5 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm @@ -98,118 +98,13 @@ name = "Base Boiler Behavior Delegate" -/datum/action/xeno_action/activable/acid_lance/use_ability(atom/affected_atom) - var/mob/living/carbon/xenomorph/xeno = owner - - if (!istype(xeno) || !xeno.check_state()) - return - - if (!activated_once && !action_cooldown_check()) - return - - if(!affected_atom || affected_atom.layer >= FLY_LAYER || !isturf(xeno.loc)) - return - - if (!activated_once) - // Start our 'charging' - - if (!check_and_use_plasma_owner()) - return - - xeno.create_empower() - xeno.visible_message(SPAN_XENODANGER("[xeno] starts to gather its acid for a massive blast!"), SPAN_XENODANGER("We start to gather our acid for a massive blast!")) - activated_once = TRUE - stack() - addtimer(CALLBACK(src, PROC_REF(timeout)), max_stacks*stack_time + time_after_max_before_end) - apply_cooldown() - return ..() - - else - activated_once = FALSE - var/range = base_range + stacks*range_per_stack - var/damage = base_damage + stacks*damage_per_stack - var/turfs_visited = 0 - for (var/turf/turf in get_line(get_turf(xeno), affected_atom)) - if(turf.density || turf.opacity) - break - - var/should_stop = FALSE - for(var/obj/structure/structure in turf) - if(istype(structure, /obj/structure/window/framed)) - var/obj/structure/window/framed/window_frame = structure - if(!window_frame.unslashable) - window_frame.deconstruct(disassembled = FALSE) - - if(structure.opacity) - should_stop = TRUE - break - - if (should_stop) - break - - if (turfs_visited >= range) - break - - turfs_visited++ - - new /obj/effect/xenomorph/acid_damage_delay(turf, damage, 7, FALSE, "You are blasted with a stream of high-velocity acid!", xeno) - - xeno.visible_message(SPAN_XENODANGER("[xeno] fires a massive blast of acid at [affected_atom]!"), SPAN_XENODANGER("We fire a massive blast of acid at [affected_atom]!")) - remove_stack_effects("We feel our speed return to normal!") - return TRUE - -/datum/action/xeno_action/activable/acid_lance/proc/stack() - var/mob/living/carbon/xenomorph/xeno = owner - if (!istype(xeno)) - return - - if (!activated_once) - return - - stacks = min(max_stacks, stacks + 1) - if (stacks != max_stacks) - xeno.speed_modifier += movespeed_per_stack - movespeed_nerf_applied += movespeed_per_stack - xeno.recalculate_speed() - addtimer(CALLBACK(src, PROC_REF(stack)), stack_time) - return - else - to_chat(xeno, SPAN_XENOHIGHDANGER("We have charged our acid lance to maximum!")) - return - -/datum/action/xeno_action/activable/acid_lance/proc/remove_stack_effects(message = null) - var/mob/living/carbon/xenomorph/xeno = owner - - if (!istype(xeno)) - return - - if (stacks <= 0) - return - - if (message) - to_chat(xeno, SPAN_XENODANGER(message)) - - stacks = 0 - xeno.speed_modifier -= movespeed_nerf_applied - movespeed_nerf_applied = 0 - xeno.recalculate_speed() - -/datum/action/xeno_action/activable/acid_lance/proc/timeout() - if (activated_once) - activated_once = FALSE - remove_stack_effects("We have waited too long and can no longer use our acid lance!") - - -/datum/action/xeno_action/activable/acid_lance/action_cooldown_check() - return (activated_once || ..()) - /datum/action/xeno_action/activable/xeno_spit/bombard/use_ability(atom/affected_atom) . = ..() - var/mob/living/carbon/xenomorph/xeno = owner + var/mob/living/carbon/xenomorph/bombard_user = owner if(!action_cooldown_check()) // activate c/d only if we already spit - for (var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) - if (!istype(xeno_action)) + for(var/action_type in action_types_to_cd) + var/datum/action/xeno_action/xeno_action = get_action(bombard_user, action_type) + if(!istype(xeno_action)) continue xeno_action.apply_cooldown_override(cooldown_duration) @@ -218,21 +113,17 @@ /datum/action/xeno_action/onclick/acid_shroud/use_ability(atom/affected_atom) var/datum/effect_system/smoke_spread/xeno_acid/spicy_gas var/mob/living/carbon/xenomorph/xeno = owner - if (!isxeno(owner)) + if(!isxeno(owner)) return - if (!action_cooldown_check()) - return - - if (!xeno.check_state()) - return + XENO_ACTION_CHECK(xeno) if(sound_play) playsound(xeno,"acid_strike", 35, 1) sound_play = FALSE addtimer(VARSET_CALLBACK(src, sound_play, TRUE), 2 SECONDS) - if (!do_after(xeno, xeno.ammo.spit_windup/6.5, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE, numticks = 2)) /// 0.7 seconds + if(!do_after(xeno, xeno.ammo.spit_windup / 6.5, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE, numticks = 2)) /// 0.7 seconds to_chat(xeno, SPAN_XENODANGER("We decide to cancel our gas shroud.")) return @@ -249,9 +140,9 @@ spicy_gas.start() to_chat(xeno, SPAN_XENOHIGHDANGER("We dump our acid through our pores, creating a shroud of gas!")) - for (var/action_type in action_types_to_cd) + for(var/action_type in action_types_to_cd) var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) - if (!istype(xeno_action)) + if(!istype(xeno_action)) continue xeno_action.apply_cooldown_override(cooldown_duration) @@ -264,21 +155,21 @@ apply_cooldown() /datum/action/xeno_action/activable/tail_stab/boiler/use_ability(atom/affected_atom) - var/mob/living/carbon/xenomorph/stabbing_xeno = owner + var/mob/living/carbon/xenomorph/xeno = owner var/target = ..() if(iscarbon(target)) var/mob/living/carbon/carbon_target = target - if(stabbing_xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas/acid]) + if(xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas/acid]) carbon_target.reagents.add_reagent("molecularacid", 6) carbon_target.reagents.set_source_mob(owner, /datum/reagent/toxin/molecular_acid) - else if(stabbing_xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas]) + else if(xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas]) var/datum/effects/neurotoxin/neuro_effect = locate() in carbon_target.effects_list if(!neuro_effect) neuro_effect = new(carbon_target, owner) neuro_effect.duration += 20 - to_chat(carbon_target,SPAN_HIGHDANGER("You are injected with something from [stabbing_xeno]'s tailstab!")) + to_chat(carbon_target,SPAN_HIGHDANGER("You are injected with something from [xeno]'s tailstab!")) else - CRASH("Globber has unknown ammo [stabbing_xeno.ammo]! Oh no!") + CRASH("Globber has unknown ammo [xeno.ammo]! Oh no!") return TRUE #define ACID_COST_BOILER 200 // ACID_COST_LEVEL_3 From 2124c23f3c4e5d8fd41912c46d5c6a2abb9dcbaf Mon Sep 17 00:00:00 2001 From: Venuska1117 Date: Sat, 8 Aug 2026 12:03:47 +0200 Subject: [PATCH 2/4] oops --- .../carbon/xenomorph/abilities/general_powers.dm | 8 ++++---- .../mob/living/carbon/xenomorph/castes/Boiler.dm | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 8e189788b330c..7ac71067c72d8 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -934,7 +934,7 @@ XENO_ACTION_CHECK(xeno) if(xeno.ammo.spit_windup) - ADD_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) + ADD_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("bombard")) if(xeno.ammo.pre_spit_warn) playsound(xeno.loc,"alien_drool", 55, 1) to_chat(xeno, SPAN_WARNING("We begin to prepare a large spit!")) @@ -942,12 +942,12 @@ SPAN_WARNING("We begin to spit [xeno.ammo.name]!")) if(!do_after(xeno, xeno.ammo.spit_windup, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) to_chat(xeno, SPAN_XENODANGER("We decide to cancel our spit.")) - REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("bombard")) return plasma_cost = xeno.ammo.spit_cost if(!check_and_use_plasma_owner()) - REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("bombard")) return xeno.visible_message(SPAN_XENOWARNING("[xeno] spits at [target_atom]!"), @@ -961,7 +961,7 @@ proj.def_zone = xeno.get_limbzone_target() proj.fire_at(spit_target, xeno, xeno, xeno.ammo.max_range, xeno.ammo.shell_speed) - REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("spitting")) + REMOVE_TRAIT(xeno, TRAIT_ABILITY_BOMBARD, TRAIT_SOURCE_ABILITY("bombard")) SEND_SIGNAL(xeno, COMSIG_XENO_POST_SPIT) apply_cooldown() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm index 97579461284d5..154ba0fcf50fd 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm @@ -155,21 +155,21 @@ apply_cooldown() /datum/action/xeno_action/activable/tail_stab/boiler/use_ability(atom/affected_atom) - var/mob/living/carbon/xenomorph/xeno = owner + var/mob/living/carbon/xenomorph/stabbing_xeno = owner var/target = ..() if(iscarbon(target)) var/mob/living/carbon/carbon_target = target - if(xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas/acid]) + if(stabbing_xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas/acid]) carbon_target.reagents.add_reagent("molecularacid", 6) carbon_target.reagents.set_source_mob(owner, /datum/reagent/toxin/molecular_acid) - else if(xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas]) + else if(stabbing_xeno.ammo == GLOB.ammo_list[/datum/ammo/xeno/boiler_gas]) var/datum/effects/neurotoxin/neuro_effect = locate() in carbon_target.effects_list if(!neuro_effect) neuro_effect = new(carbon_target, owner) neuro_effect.duration += 20 - to_chat(carbon_target,SPAN_HIGHDANGER("You are injected with something from [xeno]'s tailstab!")) + to_chat(carbon_target,SPAN_HIGHDANGER("You are injected with something from [stabbing_xeno]'s tailstab!")) else - CRASH("Globber has unknown ammo [xeno.ammo]! Oh no!") + CRASH("Globber has unknown ammo [stabbing_xeno.ammo]! Oh no!") return TRUE #define ACID_COST_BOILER 200 // ACID_COST_LEVEL_3 From c8a1747d74f4c4b1fee492dbc7b3eb5e811dffed Mon Sep 17 00:00:00 2001 From: Venuska1117 Date: Sat, 8 Aug 2026 12:05:38 +0200 Subject: [PATCH 3/4] .. --- code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm index 154ba0fcf50fd..90c35a68dfd6b 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm @@ -100,10 +100,10 @@ /datum/action/xeno_action/activable/xeno_spit/bombard/use_ability(atom/affected_atom) . = ..() - var/mob/living/carbon/xenomorph/bombard_user = owner + var/mob/living/carbon/xenomorph/xeno = owner if(!action_cooldown_check()) // activate c/d only if we already spit for(var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_action(bombard_user, action_type) + var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) if(!istype(xeno_action)) continue From cfca87f53f6881ddc1dac348221bc2613766f119 Mon Sep 17 00:00:00 2001 From: Venuska1117 Date: Sat, 8 Aug 2026 12:06:56 +0200 Subject: [PATCH 4/4] forgot that too --- .../mob/living/carbon/xenomorph/abilities/general_abilities.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm index aa48705322421..e1915596bf7b3 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm @@ -462,7 +462,6 @@ ability_uses_acid_overlay = TRUE /// Var that keeps track of in-progress wind-up spits like Bombard to prevent spitting multiple spits at the same time - var/spitting = FALSE var/sound_to_play = "acid_spit" var/aim_turf = FALSE