diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index e5425573b4..d6746ff1a6 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -1,3 +1,5 @@
+#define MEDAL_PREFIX "Bubblegum"
+
/*
BUBBLEGUM
@@ -7,15 +9,15 @@ Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
-It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target.
-If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it.
-If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood.
-At half health, it will either charge three times or warp, then charge, instead of doing a single charge.
+It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming.
+Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target.
+To make this possible, it sprays streams of blood at random.
+From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress.
-When Bubblegum dies, it leaves behind a H.E.C.K. mining suit as well as a chest that can contain three things:
- 1. A bottle that, when activated, drives everyone nearby into a frenzy
- 2. A contract that marks for death the chosen target
- 3. A spellblade that can slice off limbs at range
+When Bubblegum dies, it leaves behind a chest that can contain three things:
+ 1. A spellblade that can slice off limbs at range
+ 2. A bottle that, when activated, drives everyone nearby into a frenzy
+ 3. A contract that marks for death the chosen target
Difficulty: Hard
@@ -44,8 +46,7 @@ Difficulty: Hard
del_on_death = 1
crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher)
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
- blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
- var/charging = FALSE
+ var/charging = 0
medal_type = BOSS_MEDAL_BUBBLEGUM
score_type = BUBBLEGUM_SCORE
deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... "
@@ -57,54 +58,33 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
-/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
- . = ..()
- if(. > 0 && prob(25))
- var/obj/effect/decal/cleanable/blood/gibs/bubblegum/B = new /obj/effect/decal/cleanable/blood/gibs/bubblegum(loc)
- if(prob(40))
- step(B, pick(GLOB.cardinals))
- else
- B.setDir(pick(GLOB.cardinals))
-
-/obj/effect/decal/cleanable/blood/gibs/bubblegum
- name = "thick blood"
- desc = "Thick, splattered blood."
- random_icon_states = list("gib3", "gib5", "gib6")
- bloodiness = 20
-
-/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in()
- return TRUE
-
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
- move_to_delay = CLAMP((health/maxHealth) * 10, 5, 10)
+ move_to_delay = CLAMP(round((health/maxHealth) * 10), 5, 10)
/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire()
- anger_modifier = CLAMP(((maxHealth - health)/60),0,20)
+ anger_modifier = CLAMP(((maxHealth - health)/50),0,20)
if(charging)
return
ranged_cooldown = world.time + ranged_cooldown_time
- var/warped = FALSE
- if(!try_bloodattack())
- INVOKE_ASYNC(src, .proc/blood_spray)
- warped = blood_warp()
- if(warped && prob(100 - anger_modifier))
- return
+ blood_warp()
- if(prob(90 - anger_modifier) || slaughterlings())
- if(health > maxHealth * 0.5)
+ if(prob(25))
+ INVOKE_ASYNC(src, .proc/blood_spray)
+
+ else if(prob(5+anger_modifier/2))
+ slaughterlings()
+ else
+ if(health > maxHealth/2 && !client)
INVOKE_ASYNC(src, .proc/charge)
else
- if(prob(70) || warped)
- INVOKE_ASYNC(src, .proc/charge, 2)
- else
- INVOKE_ASYNC(src, .proc/warp_charge)
+ INVOKE_ASYNC(src, .proc/triple_charge)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize()
. = ..()
- for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_living_list)
+ for(var/mob/living/simple_animal/hostile/megafauna/bubblegum/B in GLOB.mob_list)
if(B != src)
return INITIALIZE_HINT_QDEL //There can be only one
var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new
@@ -118,56 +98,53 @@ Difficulty: Hard
if(.)
SSshuttle.shuttle_purchase_requirements_met |= "bubblegum"
-/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon)
- if(!charging)
- ..()
+/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A)
+ if(charging)
+ return
+ ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget()
- if(!charging)
- return ..()
+ if(charging)
+ return
+ ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance)
- if(!charging)
- ..()
+ if(charging)
+ return
+ ..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
+ if(!stat)
+ playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
- new /obj/effect/temp_visual/decoy/fading(loc,src)
+ new/obj/effect/temp_visual/decoy/fading(loc,src)
DestroySurroundings()
. = ..()
- if(!stat && .)
- playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
DestroySurroundings()
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge()
- blood_warp()
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge()
+ charge()
+ sleep(10)
+ charge()
+ sleep(10)
charge()
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge(bonus_charges)
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
var/turf/T = get_turf(target)
if(!T || T == loc)
return
- new /obj/effect/temp_visual/dragon_swoop/bubblegum(T)
- charging = TRUE
+ new /obj/effect/temp_visual/dragon_swoop(T)
+ charging = 1
DestroySurroundings()
walk(src, 0)
setDir(get_dir(src, T))
var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(loc,src)
- animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 3)
- sleep(3)
- throw_at(T, get_dist(src, T), 1, src, 0, callback = CALLBACK(src, .charge_end, bonus_charges))
-
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge_end(bonus_charges, list/effects_to_destroy)
- charging = FALSE
- try_bloodattack()
- if(target)
- if(bonus_charges)
- bonus_charges--
- charge(bonus_charges)
- else
- Goto(target, move_to_delay, minimum_distance)
- SetRecoveryTime(MEGAFAUNA_DEFAULT_RECOVERY_TIME)
+ animate(D, alpha = 0, color = "#FF0000", transform = matrix()*2, time = 5)
+ sleep(5)
+ throw_at(T, get_dist(src, T), 1, src, 0)
+ charging = 0
+ Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Collide(atom/A)
@@ -191,142 +168,20 @@ Difficulty: Hard
var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
L.throw_at(throwtarget, 3)
- charging = FALSE
+ charging = 0
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood()
- var/list/targets = ListTargets()
- . = list()
- for(var/mob/living/L in targets)
- var/list/bloodpool = get_pools(get_turf(L), 0)
- if(bloodpool.len && (!faction_check_mob(L) || L.stat == DEAD))
- . += L
-
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
- var/list/targets = get_mobs_on_blood()
- if(targets.len)
- INVOKE_ASYNC(src, .proc/bloodattack, targets, prob(50))
-
- return TRUE
- return FALSE
-
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets, handedness)
- var/mob/living/target_one = pick_n_take(targets)
- var/turf/target_one_turf = get_turf(target_one)
- var/mob/living/target_two
- if(targets.len)
- target_two = pick_n_take(targets)
- var/turf/target_two_turf = get_turf(target_two)
- if(target_two.stat != CONSCIOUS || prob(10))
- bloodgrab(target_two_turf, handedness)
- else
- bloodsmack(target_two_turf, handedness)
-
- if(target_one)
- var/list/pools = get_pools(get_turf(target_one), 0)
- if(pools.len)
- target_one_turf = get_turf(target_one)
- if(target_one_turf)
- if(target_one.stat != CONSCIOUS || prob(10))
- bloodgrab(target_one_turf, !handedness)
- else
- bloodsmack(target_one_turf, !handedness)
-
- if(!target_two && target_one)
- var/list/poolstwo = get_pools(get_turf(target_one), 0)
- if(poolstwo.len)
- target_one_turf = get_turf(target_one)
- if(target_one_turf)
- if(target_one.stat != CONSCIOUS || prob(10))
- bloodgrab(target_one_turf, handedness)
- else
- bloodsmack(target_one_turf, handedness)
-
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T, handedness)
- if(handedness)
- new /obj/effect/temp_visual/bubblegum_hands/rightsmack(T)
- else
- new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T)
- sleep(2.5)
- for(var/mob/living/L in T)
- if(!faction_check_mob(L))
- to_chat(L, "[src] rends you!")
- playsound(T, attack_sound, 100, 1, -1)
- var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG))
- L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
- sleep(3)
-
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness)
- if(handedness)
- new /obj/effect/temp_visual/bubblegum_hands/rightpaw(T)
- new /obj/effect/temp_visual/bubblegum_hands/rightthumb(T)
- else
- new /obj/effect/temp_visual/bubblegum_hands/leftpaw(T)
- new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T)
- sleep(6)
- for(var/mob/living/L in T)
- if(!faction_check_mob(L))
- to_chat(L, "[src] drags you through the blood!")
- playsound(T, 'sound/magic/enter_blood.ogg', 100, 1, -1)
- var/turf/targetturf = get_step(src, dir)
- L.forceMove(targetturf)
- playsound(targetturf, 'sound/magic/exit_blood.ogg', 100, 1, -1)
- if(L.stat != CONSCIOUS)
- addtimer(CALLBACK(src, .proc/devour, L), 2)
- sleep(1)
-
-/obj/effect/temp_visual/dragon_swoop/bubblegum
- duration = 10
-
-/obj/effect/temp_visual/bubblegum_hands
- icon = 'icons/effects/bubblegum.dmi'
- duration = 9
-
-/obj/effect/temp_visual/bubblegum_hands/rightthumb
- icon_state = "rightthumbgrab"
-
-/obj/effect/temp_visual/bubblegum_hands/leftthumb
- icon_state = "leftthumbgrab"
-
-/obj/effect/temp_visual/bubblegum_hands/rightpaw
- icon_state = "rightpawgrab"
- layer = BELOW_MOB_LAYER
-
-/obj/effect/temp_visual/bubblegum_hands/leftpaw
- icon_state = "leftpawgrab"
- layer = BELOW_MOB_LAYER
-
-/obj/effect/temp_visual/bubblegum_hands/rightsmack
- icon_state = "rightsmack"
-
-/obj/effect/temp_visual/bubblegum_hands/leftsmack
- icon_state = "leftsmack"
-
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
- if(Adjacent(target))
- return FALSE
- var/list/can_jaunt = get_pools(get_turf(src), 1)
- if(!can_jaunt.len)
- return FALSE
-
- var/list/pools = get_pools(get_turf(target), 2)
- var/list/pools_to_remove = get_pools(get_turf(target), 1)
- pools -= pools_to_remove
- if(!pools.len)
- return FALSE
-
- var/obj/effect/temp_visual/decoy/DA = new /obj/effect/temp_visual/decoy(loc,src)
- DA.color = "#FF0000"
- var/oldtransform = DA.transform
- DA.transform = matrix()*2
- animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 3)
- sleep(3)
- qdel(DA)
-
var/obj/effect/decal/cleanable/blood/found_bloodpool
- pools = get_pools(get_turf(target), 2)
- pools_to_remove = get_pools(get_turf(target), 1)
- pools -= pools_to_remove
+ var/list/pools = list()
+ var/can_jaunt = FALSE
+ for(var/obj/effect/decal/cleanable/blood/nearby in view(src,2))
+ can_jaunt = TRUE
+ break
+ if(!can_jaunt)
+ return
+ for(var/obj/effect/decal/cleanable/blood/nearby in view(get_turf(target),2))
+ pools += nearby
if(pools.len)
shuffle_inplace(pools)
found_bloodpool = pick(pools)
@@ -336,51 +191,30 @@ Difficulty: Hard
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
visible_message("And springs back out!")
- return TRUE
- return FALSE
-/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
- . = list()
- for(var/obj/effect/decal/cleanable/nearby in view(T, range))
- if(nearby.can_bloodcrawl_in())
- . += nearby
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray()
visible_message("[src] sprays a stream of gore!")
- var/range = 6 + round(anger_modifier * 0.4)
+ var/turf/E = get_edge_target_turf(src, src.dir)
+ var/range = 10
var/turf/previousturf = get_turf(src)
- var/turf/J = previousturf
- var/targetdir = get_dir(src, target)
- if(target.loc == loc)
- targetdir = dir
- face_atom(target)
- new /obj/effect/decal/cleanable/blood/bubblegum(J)
- for(var/i in 1 to range)
- J = get_step(previousturf, targetdir)
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J))
- playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1)
- if(!J || !previousturf.atmos_adjacent_turfs || !previousturf.atmos_adjacent_turfs[J])
+ for(var/turf/J in getline(src,E))
+ if(!range)
break
- new /obj/effect/decal/cleanable/blood/bubblegum(J)
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(previousturf, get_dir(previousturf, J))
+ if(!previousturf.CanAtmosPass(J))
+ break
+ playsound(J,'sound/effects/splat.ogg', 100, 1, -1)
+ new /obj/effect/decal/cleanable/blood(J)
+ range--
previousturf = J
sleep(1)
-/obj/effect/decal/cleanable/blood/bubblegum
- bloodiness = 0
-
-/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in()
- return TRUE
-
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings()
visible_message("[src] summons a shoal of slaughterlings!")
- var/max_amount = 6
- for(var/H in get_pools(get_turf(src), 1))
- if(!max_amount)
- break
- max_amount--
- var/obj/effect/decal/cleanable/blood/B = H
- new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(B.loc)
- return max_amount
+ for(var/obj/effect/decal/cleanable/blood/H in range(src, 10))
+ if(prob(25))
+ new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter(H.loc)
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/slaughter
name = "slaughterling"
@@ -398,3 +232,5 @@ Difficulty: Hard
if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum))
return 1
return 0
+
+#undef MEDAL_PREFIX
\ No newline at end of file