mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 05:00:55 +01:00
Reworks bileworms into artillery-like enemies (#96159)
## About The Pull Request Bileworms now attack by firing a barrage of arcing projectiles at their target, one guaranteed to hit their turf and the rest spread around them. Bileworms fire 5 shots and vileworms fire 7 at a faster rate. The projectiles themselves deal 20/25 burn damage and scale with MELEE armor (as ACID is mostly for atom armor and not mob) on mobs and ACID on objects. Bileworms now have a short jump animation before they burrow, during which they can be stunned by getting shot or hit (only damaging projectiles count, so you need to melee with your crusher if you want to stop a burrow). Doing so prevents them from attacking for 2.4 seconds, after which they burrow back underground without an animation (as to avoid chainstunning) They will not burrow immediatelly after firing, now only repositioning if their target is 3 or less tiles away from them or if they have been hit by an attack. Their health has been increased to 110/175 to compensate for them now being able to be stunned, as those are above important breakpoints for damage, making them require 1 more swing after backstab/1 more shot to kill respectively. When attacking NODE drones bileworms will have 30% less spread, making them a priority target to take out during vent defense, but not as dangerous as brimdemons or legions. https://github.com/user-attachments/assets/9d11959f-c90b-4fd5-b93f-bc514237e9bf Full video of 7 bileworm/5 vileworm fights with better visuals and no compression can be seen here: https://streamable.com/6thbmm (Both underground firing and dead sprite issues have been fixed after the recording) Worm jumping sprite/animation by ArcaneMusic, edited by me ## Why It's Good For The Game Bileworms are not fun to fight for both PKA and PKC users, there is no counterplay to their burrowing, and they are not engaging during vent defense. This should address all of these issues, and make them more fun to fight. ## Changelog 🆑 SmArtKar, ArcaneMusic balance: Bileworms now fire arcing shots instead of cross patterns, and can be stunned by hitting them during the burrow animation. Their health has been slightly buffed to compensate. /🆑
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
icon_living = "bileworm"
|
||||
icon_dead = "bileworm_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BUG|MOB_MINING
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
maxHealth = 110
|
||||
health = 110
|
||||
verb_say = "spittles"
|
||||
verb_ask = "spittles questioningly"
|
||||
verb_exclaim = "splutters and gurgles"
|
||||
@@ -30,10 +30,16 @@
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/bileworm
|
||||
|
||||
///which action this mob will be given, subtypes have different attacks
|
||||
var/attack_action_path = /datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm
|
||||
///which, if at all, mob this evolves into at the 30 min mark
|
||||
/// Which action this mob will be given, subtypes have different attacks
|
||||
var/attack_action_path = /datum/action/cooldown/mob_cooldown/bileworm_spew
|
||||
/// Which, if at all, mob this evolves into at the 30 min mark
|
||||
var/evolve_path = /mob/living/basic/mining/bileworm/vileworm
|
||||
/// Emissive icon_state
|
||||
var/emissive_state = "bileworm_e"
|
||||
/// Icon file used for the jumping animation
|
||||
var/icon_jump = 'icons/mob/simple/lavaland/bileworm_jump.dmi'
|
||||
/// Are we currently in the middle of a jump?
|
||||
var/jumping = FALSE
|
||||
|
||||
/mob/living/basic/mining/bileworm/Initialize(mapload)
|
||||
. = ..()
|
||||
@@ -42,11 +48,7 @@
|
||||
if(ispath(evolve_path))
|
||||
AddComponent(/datum/component/evolutionary_leap, 30 MINUTES, evolve_path)
|
||||
AddElement(/datum/element/content_barfer)
|
||||
|
||||
//setup mob abilities
|
||||
|
||||
//well, one of them has to start on infinite cooldown
|
||||
var/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/spew_bile = new(src)
|
||||
var/datum/action/cooldown/mob_cooldown/spew_bile = new attack_action_path(src)
|
||||
spew_bile.Grant(src)
|
||||
spew_bile.StartCooldownSelf(INFINITY)
|
||||
ai_controller?.set_blackboard_key(BB_BILEWORM_SPEW_BILE, spew_bile)
|
||||
@@ -61,5 +63,10 @@
|
||||
|
||||
/mob/living/basic/mining/bileworm/update_overlays()
|
||||
. = ..()
|
||||
if (stat != DEAD)
|
||||
. += emissive_appearance(icon, "[icon_living]_e", src)
|
||||
if (stat != DEAD && !jumping)
|
||||
. += emissive_appearance(icon, emissive_state, src)
|
||||
|
||||
/mob/living/basic/mining/bileworm/on_attacked(datum/source, atom/attacker, attack_flags)
|
||||
. = ..()
|
||||
if (!(attack_flags & (ATTACKER_STAMINA_ATTACK | ATTACKER_SHOVING)))
|
||||
ai_controller?.set_blackboard_key(BB_BILEWORM_SCARED, TRUE)
|
||||
|
||||
@@ -2,21 +2,70 @@
|
||||
name = "Resurface"
|
||||
desc = "Burrow underground, and then move to a new location near your target. Must spew bile to refresh."
|
||||
shared_cooldown = MOB_SHARED_COOLDOWN_1 | MOB_SHARED_COOLDOWN_2
|
||||
/// Damage tracker var for bileworms
|
||||
var/jump_damaged = FALSE
|
||||
/// How long does the jump take to perform?
|
||||
var/jump_length = 1 SECONDS
|
||||
/// How long do we get stunned for if we fail a jump?
|
||||
var/jump_stun = 2.4 SECONDS
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/Grant(mob/granted_to)
|
||||
. = ..()
|
||||
owner?.AddElement(/datum/element/relay_attackers)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/Activate(atom/target_atom)
|
||||
StartCooldownSelf(INFINITY)
|
||||
StartCooldownOthers(INFINITY)
|
||||
burrow(owner, target_atom)
|
||||
//spew now off cooldown shortly
|
||||
StartCooldownOthers(1.5 SECONDS)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/burrow(mob/living/burrower, atom/target)
|
||||
/// Amount of frames in the jump animation
|
||||
#define BILEWORM_JUMP_FRAMES 14
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/burrow(mob/living/burrower, atom/target, force = FALSE)
|
||||
var/turf/unburrow_turf = get_unburrow_turf(burrower, target)
|
||||
if(!unburrow_turf) // means all the turfs nearby are station turfs or something, not lavaland
|
||||
if (!unburrow_turf) // means all the turfs nearby are station turfs or something, not lavaland
|
||||
to_chat(burrower, span_warning("Couldn't burrow anywhere near the target!"))
|
||||
if(burrower.ai_controller?.ai_status == AI_STATUS_ON)
|
||||
//this is a valid reason to give up on a target
|
||||
burrower.ai_controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET)
|
||||
return
|
||||
|
||||
if (istype(burrower, /mob/living/basic/mining/bileworm) && !force)
|
||||
var/mob/living/basic/mining/bileworm/worm = burrower
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(worm))
|
||||
var/old_icon_state = worm.icon_state
|
||||
worm.icon_state = null
|
||||
// Get rid of the base emissive
|
||||
worm.jumping = TRUE
|
||||
worm.update_appearance(UPDATE_OVERLAYS)
|
||||
var/atom/movable/visual = worm.flick_overlay_view(mutable_appearance(worm.icon_jump, "[worm.icon_living]_jump_1"), jump_length)
|
||||
visual.vis_flags |= VIS_INHERIT_ID // So you can attack it
|
||||
var/atom/movable/emissive_visual = worm.flick_overlay_view(emissive_appearance(worm.icon_jump, "[worm.emissive_state]_jump_1", worm), jump_length)
|
||||
// We have to manually animate these to get around BYOND icon_state animations happening in world time and not per-object
|
||||
for (var/i in 2 to BILEWORM_JUMP_FRAMES)
|
||||
animate(visual, time = jump_length / BILEWORM_JUMP_FRAMES, icon_state = "[worm.icon_living]_jump_[i]", flags = ANIMATION_CONTINUE)
|
||||
animate(emissive_visual, time = jump_length / BILEWORM_JUMP_FRAMES, icon_state = "[worm.emissive_state]_jump_[i]", flags = ANIMATION_CONTINUE)
|
||||
jump_damaged = FALSE
|
||||
RegisterSignal(worm, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked))
|
||||
// Not in an if check direclty to reduce duplicate code
|
||||
var/jump_result = do_after(worm, jump_length, worm, hidden = TRUE, extra_checks = CALLBACK(src, PROC_REF(damage_check)))
|
||||
UnregisterSignal(worm, COMSIG_ATOM_WAS_ATTACKED)
|
||||
if (worm.icon_state == null)
|
||||
worm.icon_state = old_icon_state
|
||||
worm.jumping = FALSE
|
||||
worm.update_appearance(UPDATE_OVERLAYS)
|
||||
if (!jump_result && jump_stun)
|
||||
if (!QDELETED(visual))
|
||||
QDEL_NULL(visual)
|
||||
QDEL_NULL(emissive_visual)
|
||||
worm.flick_overlay_view(mutable_appearance('icons/effects/effects.dmi', "dazed"), jump_stun)
|
||||
worm.Stun(jump_stun)
|
||||
addtimer(CALLBACK(src, PROC_REF(burrow_again), burrower, target), jump_stun)
|
||||
return
|
||||
|
||||
burrower.ai_controller?.set_blackboard_key(BB_BILEWORM_SCARED, FALSE)
|
||||
playsound(burrower, 'sound/effects/break_stone.ogg', 50, TRUE)
|
||||
new /obj/effect/temp_visual/mook_dust(get_turf(burrower))
|
||||
ADD_TRAIT(burrower, TRAIT_GODMODE, REF(src))
|
||||
@@ -29,59 +78,189 @@
|
||||
REMOVE_TRAIT(burrower, TRAIT_GODMODE, REF(src))
|
||||
burrower.RemoveInvisibility(type)
|
||||
|
||||
#undef BILEWORM_JUMP_FRAMES
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/burrow_again(mob/living/burrower, atom/target)
|
||||
if (!QDELETED(burrower) && !burrower.stat)
|
||||
// Burrow immediatelly after being stunned out of the first jump to avoid chainstuns
|
||||
burrow(burrower, target, force = TRUE)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/on_attacked(datum/source, atom/attacker, attack_flags)
|
||||
SIGNAL_HANDLER
|
||||
if (!(attack_flags & (ATTACKER_STAMINA_ATTACK | ATTACKER_SHOVING)) && jump_stun)
|
||||
jump_damaged = TRUE
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/damage_check()
|
||||
return !jump_damaged
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/resurface/proc/get_unburrow_turf(mob/living/burrower, atom/target)
|
||||
//we want the worm to try guaranteeing a hit on a living target if it thinks it can
|
||||
var/cardinal_only = FALSE
|
||||
|
||||
if(isliving(target))
|
||||
var/mob/living/living_target = target
|
||||
if(living_target.stat >= UNCONSCIOUS)
|
||||
cardinal_only = TRUE
|
||||
|
||||
var/list/potential_turfs = shuffle(oview(5, target))//get in view, shuffle
|
||||
var/list/fallback_turfs = list()
|
||||
for(var/turf/open/misc/chosen_one in potential_turfs)//first turf that counts as ground
|
||||
if(cardinal_only && !(get_dir(chosen_one, target) in GLOB.cardinals))
|
||||
fallback_turfs.Add(chosen_one)
|
||||
continue
|
||||
var/list/potential_turfs = shuffle(oview(5, target)) // get in view, shuffle
|
||||
for(var/turf/open/misc/chosen_one in potential_turfs) // first turf that counts as ground
|
||||
return chosen_one
|
||||
//even if a worm can't execute someone in crit, it should not fail if it has SOMETHING to move to.
|
||||
if(fallback_turfs.len)
|
||||
return pick(fallback_turfs)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm
|
||||
/datum/action/cooldown/mob_cooldown/bileworm_spew
|
||||
name = "Spew Bile"
|
||||
desc = "Spews bile everywhere. Must resurface after use to refresh."
|
||||
projectile_type = /obj/projectile/bileworm_acid
|
||||
projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg'
|
||||
desc = "Spew a barrage of bile globs."
|
||||
shared_cooldown = MOB_SHARED_COOLDOWN_1 | MOB_SHARED_COOLDOWN_2
|
||||
cooldown_time = 3 SECONDS
|
||||
/// Sound played when firing a projectile
|
||||
var/projectile_sound = 'sound/mobs/non-humanoids/bileworm/bileworm_spit.ogg'
|
||||
/// How many additional projectiles to shoot around the target?
|
||||
var/additional_shots = 4
|
||||
/// Delay between each shot
|
||||
var/shot_delay = 0.15 SECONDS
|
||||
/// Effect to spawn
|
||||
var/obj/effect/bileworm_acid/acid_type = /obj/effect/bileworm_acid
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/Activate(atom/target_atom)
|
||||
/datum/action/cooldown/mob_cooldown/bileworm_spew/Activate(atom/target_atom)
|
||||
StartCooldownSelf(INFINITY)
|
||||
attack_sequence(owner, target_atom)
|
||||
//resurface now off cooldown shortly
|
||||
StartCooldownOthers(2.5 SECONDS)
|
||||
StartCooldownSelf()
|
||||
// Resurface now off cooldown shortly
|
||||
StartCooldownOthers(2 SECONDS) // Enough time for a mark + detonation combo, or 3 shots with a PKA
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/attack_sequence(mob/living/firer, atom/target)
|
||||
fire_in_directions(firer, target, GLOB.cardinals)
|
||||
SLEEP_CHECK_DEATH(0.5 SECONDS, firer)
|
||||
fire_in_directions(firer, target, GLOB.diagonals)
|
||||
/datum/action/cooldown/mob_cooldown/bileworm_spew/proc/attack_sequence(mob/living/firer, atom/target)
|
||||
new acid_type(firer, target)
|
||||
playsound(firer, projectile_sound, 70)
|
||||
var/list/all_dirs = GLOB.alldirs.Copy()
|
||||
var/turf/hit_turf = get_turf(target)
|
||||
// One guaranteed to hit target's turf, the rest hit randomly around them
|
||||
for (var/i in 1 to additional_shots)
|
||||
if (!length(all_dirs))
|
||||
return
|
||||
|
||||
/obj/projectile/bileworm_acid
|
||||
SLEEP_CHECK_DEATH(shot_delay, firer)
|
||||
if (hit_turf != target.loc)
|
||||
all_dirs = list(NONE) + GLOB.alldirs // Refresh potential target turfs if they've moved
|
||||
|
||||
var/turf/target_turf = null
|
||||
// NODE drones get a much more focused barrage sent at them
|
||||
if (istype(target, /mob/living/basic/node_drone) && prob(30))
|
||||
target_turf = get_turf(target)
|
||||
else
|
||||
var/target_dir = pick_n_take(all_dirs)
|
||||
target_turf = target_dir ? get_step(target, target_dir) : get_turf(target)
|
||||
|
||||
if (target_turf == firer.loc) // Don't hit ourselves
|
||||
var/target_dir = pick_n_take(all_dirs)
|
||||
target_turf = target_dir ? get_step(target, target_dir) : get_turf(target)
|
||||
|
||||
new acid_type(firer, target_turf)
|
||||
if (i % 2 == 0)
|
||||
playsound(firer, projectile_sound, 70)
|
||||
|
||||
/obj/effect/bileworm_acid
|
||||
name = "acidic bile"
|
||||
icon_state = "neurotoxin"
|
||||
hitsound = 'sound/items/weapons/sear.ogg'
|
||||
damage = 20
|
||||
speed = 0.5
|
||||
range = 20
|
||||
jitter = 3 SECONDS
|
||||
stutter = 3 SECONDS
|
||||
damage_type = BURN
|
||||
pass_flags = PASSTABLE
|
||||
icon = 'icons/obj/weapons/guns/projectiles.dmi'
|
||||
icon_state = "bile_glob"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
/// Damage dealt to all mobs in the impact turf
|
||||
var/damage = 20
|
||||
/// Tiles travelled per second at maximum range
|
||||
var/speed = 5
|
||||
/// Maximum range for our speed calculations
|
||||
var/max_range = 10
|
||||
/// Warning sign on the turf we're about to hit
|
||||
var/obj/effect/bileworm_target/target_sign = null
|
||||
|
||||
/obj/projectile/bileworm_acid/Initialize(mapload)
|
||||
/obj/effect/bileworm_acid/Initialize(mapload, atom/new_target)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/parriable_projectile)
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
if (new_target)
|
||||
fire_at(get_turf(new_target))
|
||||
|
||||
/obj/effect/bileworm_acid/Destroy(force)
|
||||
QDEL_NULL(target_sign)
|
||||
return ..()
|
||||
|
||||
/obj/effect/bileworm_acid/update_overlays()
|
||||
. = ..()
|
||||
. += emissive_appearance(icon, icon_state, src, alpha = 20, effect_type = EMISSIVE_BLOOM)
|
||||
|
||||
/obj/effect/bileworm_acid/proc/fire_at(turf/target)
|
||||
if (!istype(target))
|
||||
target = get_turf(target)
|
||||
var/turf/start = get_turf(src)
|
||||
forceMove(target) // Immediately move to the target turf so we can guarantee they can see us
|
||||
pixel_x = (start.x - target.x) * ICON_SIZE_X
|
||||
pixel_y = (start.y - target.y) * ICON_SIZE_Y
|
||||
// Because BYOND's get_dist is taxicab distance
|
||||
var/travel_dist = sqrt((start.x - target.x) ** 2 + (start.y - target.y) ** 2)
|
||||
// Slightly scale the speed with distance for fairer gameplay
|
||||
if (travel_dist < max_range)
|
||||
speed *= 0.5 + travel_dist / max_range * 0.5
|
||||
var/travel_time = travel_dist / speed * 1 SECONDS
|
||||
animate(src, pixel_x = 0, time = travel_time, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_OUT) // Not a perfect arc but looks better
|
||||
animate(src, pixel_y = 160, time = travel_time / 2, flags = ANIMATION_PARALLEL, easing = QUAD_EASING | EASE_OUT)
|
||||
animate(pixel_y = 0, time = travel_time / 2, easing = QUAD_EASING | EASE_IN)
|
||||
animate(src, transform = matrix().Turn(start.x > target.x ? -91 : 91), time = travel_time / 2, flags = ANIMATION_PARALLEL, easing = SINE_EASING | EASE_IN)
|
||||
animate(transform = matrix().Turn(start.x > target.x ? -180 : 180), time = travel_time / 2, easing = SINE_EASING | EASE_OUT)
|
||||
target_sign = new(target)
|
||||
addtimer(CALLBACK(src, PROC_REF(impact), target), travel_time)
|
||||
|
||||
/obj/effect/bileworm_acid/proc/impact(turf/target)
|
||||
var/obj/effect/abstract/particle_holder/impact_particles = new(target, /particles/bile)
|
||||
QDEL_IN(impact_particles, /particles/bile::lifespan)
|
||||
|
||||
var/hit_something = FALSE
|
||||
for (var/mob/living/victim in target)
|
||||
if(HAS_TRAIT(target, TRAIT_UNHITTABLE_BY_PROJECTILES))
|
||||
if(!HAS_TRAIT(target, TRAIT_BLOCKING_PROJECTILES) && isliving(target))
|
||||
var/mob/living/living_target = target
|
||||
living_target.block_projectile_effects()
|
||||
continue
|
||||
|
||||
// Doesn't make much sense to use melee for mobs, but its a mining mob so eeeeeh
|
||||
// Can't use acid either as its mostly for atom armor only
|
||||
var/blocked = victim.run_armor_check(null, MELEE, armour_penetration = 40, silent = TRUE)
|
||||
if (blocked >= 100)
|
||||
continue
|
||||
|
||||
hit_something = TRUE
|
||||
victim.apply_damage(damage, BURN, null, blocked, wound_bonus = CANT_WOUND)
|
||||
to_chat(victim, span_userdanger("You're hit by [src]!"))
|
||||
|
||||
for (var/obj/thing in target)
|
||||
if (!thing.uses_integrity || !thing.density)
|
||||
continue
|
||||
hit_something = TRUE
|
||||
thing.take_damage(damage, BURN, ACID, sound_effect = FALSE)
|
||||
|
||||
if (hit_something)
|
||||
playsound(target, 'sound/items/weapons/sear.ogg', 50, -1)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/bileworm_target
|
||||
icon = 'icons/mob/telegraphing/telegraph.dmi'
|
||||
icon_state = "projectile_circle"
|
||||
layer = BELOW_MOB_LAYER
|
||||
plane = GAME_PLANE
|
||||
|
||||
/obj/effect/bileworm_target/Initialize(mapload)
|
||||
. = ..()
|
||||
update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/effect/bileworm_target/update_overlays()
|
||||
. = ..()
|
||||
. += emissive_appearance(icon, icon_state, src, alpha = 90, effect_type = EMISSIVE_BLOOM)
|
||||
|
||||
/particles/bile
|
||||
icon = 'icons/effects/particles/goop.dmi'
|
||||
icon_state = list("goop_1" = 6, "goop_2" = 2, "goop_3" = 1)
|
||||
width = 100
|
||||
height = 100
|
||||
count = 10
|
||||
spawning = 10
|
||||
color = "#00ea2b80" //to get 96 alpha
|
||||
lifespan = 1.5 SECONDS
|
||||
fade = 1 SECONDS
|
||||
grow = -0.025
|
||||
gravity = list(0, 0.15)
|
||||
position = generator(GEN_SPHERE, 0, 8, NORMAL_RAND)
|
||||
spin = generator(GEN_NUM, -15, 15, NORMAL_RAND)
|
||||
velocity = generator(GEN_BOX, list(-2, 2), list(2, 4), NORMAL_RAND)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/devour
|
||||
name = "Devour"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
blackboard = list(
|
||||
BB_TARGETING_STRATEGY = /datum/targeting_strategy/basic/bileworm,
|
||||
BB_TARGET_PRIORITY_STRATEGY = /datum/target_priority_strategy/mining,
|
||||
BB_BILEWORM_FLEE_DISTANCE = 3,
|
||||
)
|
||||
|
||||
planning_subtrees = list(
|
||||
@@ -22,16 +23,12 @@
|
||||
return
|
||||
|
||||
var/datum/action/cooldown/mob_cooldown/resurface = controller.blackboard[BB_BILEWORM_RESURFACE]
|
||||
var/datum/action/cooldown/mob_cooldown/bile = controller.blackboard[BB_BILEWORM_SPEW_BILE]
|
||||
|
||||
//because one ability is always INFINITY cooldown, this actually works to check which ability should be used
|
||||
//sometimes it will try to spew bile on infinity cooldown, but that's okay because as soon as resurface is ready it will attempt that
|
||||
|
||||
if(resurface?.IsAvailable())
|
||||
if(resurface?.IsAvailable() && (controller.blackboard[BB_BILEWORM_SCARED] || get_dist(controller.pawn, controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET]) <= controller.blackboard[BB_BILEWORM_FLEE_DISTANCE]))
|
||||
controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_RESURFACE, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING
|
||||
|
||||
var/datum/action/cooldown/mob_cooldown/bile = controller.blackboard[BB_BILEWORM_SPEW_BILE]
|
||||
|
||||
if(bile?.IsAvailable())
|
||||
controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_plan_execute, BB_BILEWORM_SPEW_BILE, BB_BASIC_MOB_CURRENT_TARGET)
|
||||
return SUBTREE_RETURN_FINISH_PLANNING //focus on the fight
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "bilehorn"
|
||||
desc = "Bits of bileworm anatomy rearranged to produce wonderful music, not bile. Keeps the name though, because for an instrument, it is quite vile."
|
||||
force = 5
|
||||
icon = 'icons/mob/simple/lavaland/bileworm.dmi'
|
||||
icon = 'icons/obj/mining_zones/artefacts.dmi'
|
||||
icon_state = "bilehorn"
|
||||
allowed_instrument_ids = "bilehorn"
|
||||
inhand_icon_state = null
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
name = "bileworm skin"
|
||||
desc = "The slushy, squishy and slightly shiny skin of a postmortem bileworm."
|
||||
singular_name = "bileworm skin piece"
|
||||
icon = 'icons/mob/simple/lavaland/bileworm.dmi'
|
||||
icon = 'icons/obj/stack_objects.dmi'
|
||||
icon_state = "sheet-bileworm"
|
||||
inhand_icon_state = null
|
||||
merge_type = /obj/item/stack/sheet/animalhide/bileworm
|
||||
|
||||
@@ -4,34 +4,20 @@
|
||||
icon_state = "vileworm"
|
||||
icon_living = "vileworm"
|
||||
icon_dead = "vileworm_dead"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
maxHealth = 175
|
||||
health = 175
|
||||
|
||||
attack_action_path = /datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm
|
||||
attack_action_path = /datum/action/cooldown/mob_cooldown/bileworm_spew/corrupt
|
||||
evolve_path = null
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm
|
||||
/datum/action/cooldown/mob_cooldown/bileworm_spew/corrupt
|
||||
name = "Spew Corrupted Bile"
|
||||
desc = "Spews corrupted bile everywhere. Must resurface after use to refresh."
|
||||
projectile_type = /obj/projectile/bileworm_acid/vile
|
||||
desc = "Spew a barrage of corrupted bile globs."
|
||||
cooldown_time = 2.5 SECONDS
|
||||
acid_type = /obj/effect/bileworm_acid/corrupt
|
||||
additional_shots = 6
|
||||
shot_delay = 0.1 SECONDS
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm/Activate(atom/target_atom)
|
||||
StartCooldownSelf(INFINITY)
|
||||
attack_sequence(owner, target_atom)
|
||||
//faster than unevolved
|
||||
StartCooldownOthers(1.5 SECONDS)
|
||||
|
||||
/datum/action/cooldown/mob_cooldown/projectile_attack/dir_shots/bileworm/vileworm/attack_sequence(mob/living/firer, atom/target)
|
||||
fire_in_directions(firer, target, GLOB.cardinals)
|
||||
SLEEP_CHECK_DEATH(0.25 SECONDS, firer)
|
||||
fire_in_directions(firer, target, GLOB.diagonals)
|
||||
SLEEP_CHECK_DEATH(0.25 SECONDS, firer)
|
||||
fire_in_directions(firer, target, GLOB.cardinals)
|
||||
// surprise!
|
||||
if(prob(25))
|
||||
SLEEP_CHECK_DEATH(0.25 SECONDS, firer)
|
||||
fire_in_directions(firer, target, GLOB.diagonals)
|
||||
|
||||
/obj/projectile/bileworm_acid/vile
|
||||
name = "corrupted bile"
|
||||
icon_state = "vileworm"
|
||||
/obj/effect/bileworm_acid/corrupt
|
||||
icon_state = "corrupt_bile_glob"
|
||||
damage = 27
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
drop_mod = crusher_drop_chance,\
|
||||
drop_immediately = basic_mob_flags & DEL_ON_DEATH,\
|
||||
)
|
||||
RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(check_ashwalker_peace_violation))
|
||||
RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked))
|
||||
// We add this to ensure that mobs will actually receive the above signal, as some will lack AI
|
||||
// handling for retaliation and attack special cases
|
||||
AddElement(/datum/element/relay_attackers)
|
||||
@@ -55,9 +55,9 @@
|
||||
throw_blocked_message = throw_blocked_message,\
|
||||
)
|
||||
|
||||
/mob/living/basic/mining/proc/check_ashwalker_peace_violation(datum/source, mob/living/carbon/human/possible_ashwalker)
|
||||
/mob/living/basic/mining/proc/on_attacked(datum/source, atom/attacker, attack_flags)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!isashwalker(possible_ashwalker) || !has_faction(FACTION_ASHWALKER))
|
||||
if(!isashwalker(attacker) || !has_faction(FACTION_ASHWALKER))
|
||||
return
|
||||
remove_faction(FACTION_ASHWALKER)
|
||||
|
||||
Reference in New Issue
Block a user