From b1d61e471839f5f421b3d893829ad79dc7372b41 Mon Sep 17 00:00:00 2001 From: Joan Lung Date: Mon, 19 Sep 2016 20:49:51 -0400 Subject: [PATCH] Makes bubblegum possibly more fun/fair to fight maybe (#20552) Significantly reworked bubblegum's attacks, it now has the following attacks; Attacks through blood, done occasionally and at the end of every charge. Spray blood if it failed to attack through blood during its normal attack sequence. Warp through blood if it failed to attack through blood during its normal attack sequence. Spawn up to 6 slaughterlings, which block enemies but not it. Charge at a target. May be prefaced by a blood warp or done up to 3 times if below half health. --- .../mining/lavaland/necropolis_chests.dm | 8 +- .../hostile/megafauna/bubblegum.dm | 231 ++++++++++++++---- icons/effects/bubblegum.dmi | Bin 0 -> 13876 bytes 3 files changed, 193 insertions(+), 46 deletions(-) create mode 100644 icons/effects/bubblegum.dmi diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 02e71c0f08f..365e3ade3f6 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -704,15 +704,13 @@ /obj/structure/closet/crate/necropolis/bubblegum/New() ..() - var/loot = rand(1,4) + var/loot = rand(1,3) switch(loot) if(1) - new /obj/item/weapon/antag_spawner/slaughter_demon(src) - if(2) new /obj/item/mayhem(src) - if(3) + if(2) new /obj/item/blood_contract(src) - if(4) + if(3) new /obj/item/weapon/gun/magic/staff/spellblade(src) /obj/item/blood_contract 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 f961094c4c9..b64463f3b7c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -9,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 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. +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. When Bubblegum dies, it leaves behind a chest that can contain three things: - 1. A slaughter demon spawner - 2. A bottle that, when activated, drives everyone nearby into a frenzy - 3. A contract that marks for death the chosen target + 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 Difficulty: Hard @@ -45,6 +45,7 @@ Difficulty: Hard pixel_x = -32 del_on_death = 1 loot = list(/obj/structure/closet/crate/necropolis/bubblegum) + blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME var/charging = 0 medal_type = MEDAL_PREFIX score_type = BUBBLEGUM_SCORE @@ -57,6 +58,12 @@ 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) + if(amount > 0 && prob(33)) + var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(loc) + B.bloodiness = 20 + . = ..() + /mob/living/simple_animal/hostile/megafauna/bubblegum/Life() ..() move_to_delay = Clamp(round((health/maxHealth) * 10), 5, 10) @@ -67,18 +74,21 @@ Difficulty: Hard return ranged_cooldown = world.time + ranged_cooldown_time - blood_warp() - - if(prob(25)) + var/warped = FALSE + if(!try_bloodattack()) addtimer(src, "blood_spray", 0) + warped = blood_warp() + if(warped && prob(100 - anger_modifier)) + return - else if(prob(5+anger_modifier/2)) - slaughterlings() - else - if(health > maxHealth/2 && !client) + if(prob(90 - anger_modifier) || slaughterlings()) + if(health > maxHealth * 0.5 || client) addtimer(src, "charge", 0) else - addtimer(src, "triple_charge", 0) + if(prob(70) || warped) + addtimer(src, "triple_charge", 0) + else + addtimer(src, "warp_charge", 0) /mob/living/simple_animal/hostile/megafauna/bubblegum/New() @@ -109,20 +119,22 @@ Difficulty: Hard ..() /mob/living/simple_animal/hostile/megafauna/bubblegum/Move() - if(!stat) - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1) if(charging) PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(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() + charge() + /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() @@ -139,6 +151,7 @@ Difficulty: Hard sleep(5) throw_at(T, get_dist(src, T), 1, src, 0) charging = 0 + try_bloodattack() Goto(target, move_to_delay, minimum_distance) @@ -166,17 +179,132 @@ Difficulty: Hard 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(L)) + . += L + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack() + var/list/targets = get_mobs_on_blood() + if(targets.len) + addtimer(src, "bloodattack", 0, FALSE, targets) + + return TRUE + return FALSE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets) + 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)) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_two_turf) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_two_turf) + bloodgrab(target_two_turf) + else + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_two_turf) + bloodsmack(target_two_turf) + + var/list/pools = get_pools(get_turf(target_one), 0) + if(pools.len) + target_one_turf = get_turf(target_one) + if(target_one.stat != CONSCIOUS || prob(10)) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftpaw, target_one_turf) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftthumb, target_one_turf) + bloodgrab(target_one_turf) + else + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftsmack, target_one_turf) + bloodsmack(target_one_turf) + + if(!target_two && target_one) + pools = get_pools(get_turf(target_one), 0) + if(pools.len) + target_one_turf = get_turf(target_one) + if(target_one.stat != CONSCIOUS || prob(10)) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_one_turf) + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_one_turf) + bloodgrab(target_one_turf) + else + PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_one_turf) + bloodsmack(target_one_turf) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T) + sleep(2.5) + for(var/mob/living/L in T) + if(!faction_check(L)) + L << "[src] rends you!" + playsound(T, attack_sound, 100, 1, -1) + var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "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) + sleep(6) + for(var/mob/living/L in T) + if(!faction_check(L)) + 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(src, "devour", 2, FALSE, L) + sleep(1) + +/obj/effect/overlay/temp/bubblegum_hands + icon = 'icons/effects/bubblegum.dmi' + duration = 9 + +/obj/effect/overlay/temp/bubblegum_hands/rightthumb + icon_state = "rightthumbgrab" + +/obj/effect/overlay/temp/bubblegum_hands/leftthumb + icon_state = "leftthumbgrab" + +/obj/effect/overlay/temp/bubblegum_hands/rightpaw + icon_state = "rightpawgrab" + layer = BELOW_MOB_LAYER + +/obj/effect/overlay/temp/bubblegum_hands/leftpaw + icon_state = "leftpawgrab" + layer = BELOW_MOB_LAYER + +/obj/effect/overlay/temp/bubblegum_hands/rightsmack + icon_state = "rightsmack" + +/obj/effect/overlay/temp/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/overlay/temp/decoy/DA = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src)) + DA.color = "#FF0000" + var/oldtransform = DA.transform + DA.transform = matrix()*2 + animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 5) + sleep(5) + qdel(DA) + var/obj/effect/decal/cleanable/blood/found_bloodpool - 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 + pools = get_pools(get_turf(target), 2) + pools_to_remove = get_pools(get_turf(target), 1) + pools -= pools_to_remove if(pools.len) shuffle(pools) found_bloodpool = pick(pools) @@ -186,35 +314,56 @@ 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/blood/nearby in view(T, range)) + . += nearby /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray() visible_message("[src] sprays a stream of gore!") - var/turf/E = get_edge_target_turf(src, src.dir) - var/range = 10 + var/range = 6 + round(anger_modifier * 0.4) var/turf/previousturf = get_turf(src) - for(var/turf/J in getline(src,E)) - if(!range) - break + 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(J) + for(var/i in 1 to range) + J = get_step(previousturf, targetdir) PoolOrNew(/obj/effect/overlay/temp/dir_setting/bloodsplatter, list(previousturf, get_dir(previousturf, J))) - if(!previousturf.CanAtmosPass(J)) + playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1) + if(!J || !previousturf.CanAtmosPass(J)) break - playsound(J,'sound/effects/splat.ogg', 100, 1, -1) - new /obj/effect/decal/cleanable/blood(J) - range-- + var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(J) + B.bloodiness = 0 previousturf = J sleep(1) /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings() visible_message("[src] summons a shoal of slaughterlings!") - for(var/obj/effect/decal/cleanable/blood/H in range(src, 10)) - if(prob(25)) - new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(H.loc) + 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/blood/slaughter(B.loc) + return max_amount /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter name = "slaughterling" desc = "Though not yet strong enough to create a true physical form, it's nonetheless determined to murder you." - faction = list("mining") + density = 0 + faction = list("mining", "boss") weather_immunities = list("lava","ash") +/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter/CanPass(atom/movable/mover, turf/target, height = 0) + if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) + return 1 + return 0 + #undef MEDAL_PREFIX \ No newline at end of file diff --git a/icons/effects/bubblegum.dmi b/icons/effects/bubblegum.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a53dd7d563aa87c70ff9c6e4b08c077dba500ab8 GIT binary patch literal 13876 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