From 7964c5f9c64d3c09cc52a73685e50cb5f97d5286 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Wed, 11 Sep 2019 12:09:24 -0400 Subject: [PATCH 1/3] Reworks Ash Drake, Refactors Colossus, Fixes Endless Animal Attacks --- .../mob/living/carbon/alien/alien_defense.dm | 3 +- .../mob/living/carbon/human/human_defense.dm | 11 +- code/modules/mob/living/carbon/slime/slime.dm | 3 +- code/modules/mob/living/living_defense.dm | 18 +- code/modules/mob/living/silicon/pai/pai.dm | 10 +- .../mob/living/silicon/silicon_defense.dm | 3 +- .../living/simple_animal/animal_defense.dm | 5 +- .../mob/living/simple_animal/constructs.dm | 2 +- .../hostile/megafauna/blood_drunk_miner.dm | 2 +- .../hostile/megafauna/colossus.dm | 223 +++--- .../simple_animal/hostile/megafauna/drake.dm | 655 +++++++++++++----- .../hostile/megafauna/megafauna.dm | 41 +- 12 files changed, 657 insertions(+), 319 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 5eb8f5766e4..d7881367d13 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -59,7 +59,8 @@ In all, this is a lot like the monkey code. /N return 0 /mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M) - if(..()) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) switch(M.melee_damage_type) if(BRUTE) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index ad3e459c552..99b7b339d90 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -437,16 +437,17 @@ emp_act visible_message("[M] has tried to disarm [src]!") /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M) - if(..()) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration)) - return 0 + return FALSE var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot") var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone)) + if(!affecting) + affecting = get_organ("chest") + affecting.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) - var/obj/item/organ/external/affected = src.get_organ(dam_zone) - if(affected) - affected.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data apply_damage(damage, M.melee_damage_type, affecting, armor) updatehealth("animal attack") diff --git a/code/modules/mob/living/carbon/slime/slime.dm b/code/modules/mob/living/carbon/slime/slime.dm index ddab7eae1ee..4cba9bb5a12 100644 --- a/code/modules/mob/living/carbon/slime/slime.dm +++ b/code/modules/mob/living/carbon/slime/slime.dm @@ -258,7 +258,8 @@ M.updatehealth() /mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M) - if(..()) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) attacked += 10 adjustBruteLoss(damage) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f0c3b85ece1..f624b7ab33d 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -303,17 +303,17 @@ return /mob/living/attack_animal(mob/living/simple_animal/M) + M.face_atom(src) if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0) M.custom_emote(1, "[M.friendly] [src].") - return 0 - else - if(M.attack_sound) - playsound(loc, M.attack_sound, 50, 1, 1) - M.do_attack_animation(src) - visible_message("\The [M] [M.attacktext] [src]!", \ - "\The [M] [M.attacktext] [src]!") - add_attack_logs(M, src, "Animal attacked") - return 1 + return FALSE + if(M.attack_sound) + playsound(loc, M.attack_sound, 50, 1, 1) + M.do_attack_animation(src) + visible_message("\The [M] [M.attacktext] [src]!", \ + "\The [M] [M.attacktext] [src]!") + add_attack_logs(M, src, "Animal attacked") + return TRUE /mob/living/attack_larva(mob/living/carbon/alien/larva/L) switch(L.a_intent) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 75cca0dfb54..d9f1aac2757 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -227,14 +227,8 @@ // See software.dm for Topic() /mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M) - if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0) - M.custom_emote(1, "[M.friendly] [src].") - else - M.do_attack_animation(src) - if(M.attack_sound) - playsound(loc, M.attack_sound, 50, 1, 1) - for(var/mob/O in viewers(src, null)) - O.show_message("[M] [M.attacktext] [src]!", 1) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) add_attack_logs(M, src, "Animal attacked for [damage] damage") adjustBruteLoss(damage) diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index a903b6999dc..d88faff76f6 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -20,7 +20,8 @@ return /mob/living/silicon/attack_animal(mob/living/simple_animal/M) - if(..()) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) switch(M.melee_damage_type) if(BRUTE) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 3fafd7267f2..119eb1b29c0 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -53,9 +53,10 @@ L.amount_grown = min(L.amount_grown + damage, L.max_grown) /mob/living/simple_animal/attack_animal(mob/living/simple_animal/M) - if(..()) + . = ..() + if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - attack_threshold_check(damage, M.melee_damage_type) + return attack_threshold_check(damage, M.melee_damage_type) /mob/living/simple_animal/attack_slime(mob/living/carbon/slime/M) ..() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index ea8e80d2e3c..218693b7dc3 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -80,7 +80,7 @@ else to_chat(M, "You cannot repair your own dents, as you have none!") else if(src != M) - ..() + return ..() /mob/living/simple_animal/hostile/construct/narsie_act() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index e7ad2c5fab6..701a75fd3ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -30,7 +30,7 @@ Difficulty: Medium icon = 'icons/mob/alienqueen.dmi' light_color = "#E4C7C5" speak_emote = list("roars") - speed = 1 + speed = 3 move_to_delay = 3 projectiletype = /obj/item/projectile/kinetic/miner projectilesound = 'sound/weapons/kenetic_accel.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index f275f7ce7d0..cade1489c63 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -1,4 +1,3 @@ - /* COLOSSUS @@ -31,35 +30,74 @@ Difficulty: Very Hard attack_sound = 'sound/magic/ratvar_attack.ogg' icon_state = "eva" icon_living = "eva" - icon_dead = "dragon_dead" + icon_dead = "" friendly = "stares down" icon = 'icons/mob/lavaland/96x96megafauna.dmi' speak_emote = list("roars") armour_penetration = 40 melee_damage_lower = 40 melee_damage_upper = 40 - speed = 1 + speed = 10 move_to_delay = 10 - ranged = 1 + ranged = TRUE pixel_x = -32 - del_on_death = 1 + del_on_death = TRUE internal_type = /obj/item/gps/internal/colossus medal_type = BOSS_MEDAL_COLOSSUS score_type = COLOSSUS_SCORE crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher) loot = list(/obj/structure/closet/crate/necropolis/colossus) - butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) deathmessage = "disintegrates, leaving a glowing core in its wake." death_sound = 'sound/misc/demon_dies.ogg' + attack_action_types = list(/datum/action/innate/megafauna_attack/spiral_attack, + /datum/action/innate/megafauna_attack/aoe_attack, + /datum/action/innate/megafauna_attack/shotgun, + /datum/action/innate/megafauna_attack/alternating_cardinals) -/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/L) - visible_message("[src] disintegrates [L]!") - L.dust() +/datum/action/innate/megafauna_attack/spiral_attack + name = "Spiral Shots" + icon_icon = 'icons/mob/actions/actions.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now firing in a spiral." + chosen_attack_num = 1 + +/datum/action/innate/megafauna_attack/aoe_attack + name = "All Directions" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "at_shield2" + chosen_message = "You are now firing in all directions." + chosen_attack_num = 2 + +/datum/action/innate/megafauna_attack/shotgun + name = "Shotgun Fire" + icon_icon = 'icons/obj/guns/projectile.dmi' + button_icon_state = "shotgun" + chosen_message = "You are now firing shotgun shots where you aim." + chosen_attack_num = 3 + +/datum/action/innate/megafauna_attack/alternating_cardinals + name = "Alternating Shots" + icon_icon = 'icons/obj/guns/projectile.dmi' + button_icon_state = "pistol" + chosen_message = "You are now firing in alternating cardinal directions." + chosen_attack_num = 4 /mob/living/simple_animal/hostile/megafauna/colossus/OpenFire() anger_modifier = Clamp(((maxHealth - health)/50),0,20) ranged_cooldown = world.time + 120 + if(client) + switch(chosen_attack) + if(1) + select_spiral_attack() + if(2) + random_shots() + if(3) + blast() + if(4) + alternating_dir_shots() + return + if(enrage(target)) if(move_to_delay == initial(move_to_delay)) visible_message("\"You can't dodge.\"") @@ -72,52 +110,14 @@ Difficulty: Very Hard move_to_delay = initial(move_to_delay) if(prob(20+anger_modifier)) //Major attack - telegraph() - - if(health < maxHealth/3) - double_spiral() - else - visible_message("\"Judgement.\"") - spawn(0) - spiral_shoot(rand(0, 1)) - + select_spiral_attack() else if(prob(20)) - ranged_cooldown = world.time + 30 random_shots() else if(prob(70)) - ranged_cooldown = world.time + 20 blast() else - ranged_cooldown = world.time + 40 - spawn(0) - alternating_dir_shots() - -/obj/effect/temp_visual/at_shield - name = "anti-toolbox field" - desc = "A shimmering forcefield protecting the colossus." - icon = 'icons/effects/effects.dmi' - icon_state = "at_shield2" - layer = FLY_LAYER - luminosity = 2 - duration = 8 - var/target - -/obj/effect/temp_visual/at_shield/New(new_loc, new_target) - ..() - target = new_target - spawn(0) - orbit(target, 0, FALSE, 0, 0, FALSE, TRUE) - -/mob/living/simple_animal/hostile/megafauna/colossus/bullet_act(obj/item/projectile/P) - if(!stat) - var/obj/effect/temp_visual/at_shield/AT = new /obj/effect/temp_visual/at_shield(loc, src) - var/random_x = rand(-32, 32) - AT.pixel_x += random_x - - var/random_y = rand(0, 72) - AT.pixel_y += random_y - ..() + alternating_dir_shots() /mob/living/simple_animal/hostile/megafauna/colossus/proc/enrage(mob/living/L) if(ishuman(L)) @@ -126,61 +126,33 @@ Difficulty: Very Hard . = TRUE /mob/living/simple_animal/hostile/megafauna/colossus/proc/alternating_dir_shots() + ranged_cooldown = world.time + 40 dir_shots(diagonals) - sleep(10) + SLEEP_CHECK_DEATH(10) dir_shots(cardinal) - sleep(10) + SLEEP_CHECK_DEATH(10) dir_shots(diagonals) - sleep(10) + SLEEP_CHECK_DEATH(10) dir_shots(cardinal) +/mob/living/simple_animal/hostile/megafauna/colossus/proc/select_spiral_attack() + telegraph() + if(health < maxHealth/3) + return double_spiral() + visible_message("\"Judgement.\"") + return spiral_shoot() + /mob/living/simple_animal/hostile/megafauna/colossus/proc/double_spiral() visible_message("\"Die.\"") - sleep(10) - spawn(0) - spiral_shoot() - spawn(0) - spiral_shoot(1) + SLEEP_CHECK_DEATH(10) + INVOKE_ASYNC(src, .proc/spiral_shoot, FALSE) + INVOKE_ASYNC(src, .proc/spiral_shoot, TRUE) -/mob/living/simple_animal/hostile/megafauna/colossus/proc/spiral_shoot(negative = 0, counter_start = 1) +/mob/living/simple_animal/hostile/megafauna/colossus/proc/spiral_shoot(negative = pick(TRUE, FALSE), counter_start = 8) + var/turf/start_turf = get_step(src, pick(alldirs)) var/counter = counter_start - var/turf/marker for(var/i in 1 to 80) - switch(counter) - if(1) - marker = locate(x, y - 2, z) - if(2) - marker = locate(x - 1, y - 2, z) - if(3) - marker = locate(x - 2, y - 2, z) - if(4) - marker = locate(x - 2, y - 1, z) - if(5) - marker = locate(x - 2, y, z) - if(6) - marker = locate(x - 2, y + 1, z) - if(7) - marker = locate(x - 2, y + 2, z) - if(8) - marker = locate(x - 1, y + 2, z) - if(9) - marker = locate(x, y + 2, z) - if(10) - marker = locate(x + 1, y + 2, z) - if(11) - marker = locate(x + 2, y + 2, z) - if(12) - marker = locate(x + 2, y + 1, z) - if(13) - marker = locate(x + 2, y, z) - if(14) - marker = locate(x + 2, y - 1, z) - if(15) - marker = locate(x + 2, y - 2, z) - if(16) - marker = locate(x + 1, y - 2, z) - if(negative) counter-- else @@ -189,44 +161,45 @@ Difficulty: Very Hard counter = 1 if(counter < 1) counter = 16 - shoot_projectile(marker) - playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 20, 1) - sleep(1) + shoot_projectile(start_turf, counter * 22.5) + playsound(get_turf(src), 'sound/magic/clockwork/invoke_general.ogg', 20, TRUE) + SLEEP_CHECK_DEATH(1) -/mob/living/simple_animal/hostile/megafauna/colossus/proc/shoot_projectile(turf/marker) - if(!marker || marker == loc) +/mob/living/simple_animal/hostile/megafauna/colossus/proc/shoot_projectile(turf/marker, set_angle) + if(!isnum(set_angle) && (!marker || marker == loc)) return var/turf/startloc = get_turf(src) var/obj/item/projectile/P = new /obj/item/projectile/colossus(startloc) - P.current = startloc - P.starting = startloc + P.preparePixelProjectile(marker, marker, startloc) P.firer = src - P.yo = marker.y - startloc.y - P.xo = marker.x - startloc.x if(target) P.original = target - else - P.original = marker - P.fire() + P.fire(set_angle) /mob/living/simple_animal/hostile/megafauna/colossus/proc/random_shots() + ranged_cooldown = world.time + 30 var/turf/U = get_turf(src) - playsound(U, 'sound/magic/invoke_general.ogg', 300, 1, 5) + playsound(U, 'sound/magic/clockwork/invoke_general.ogg', 300, TRUE, 5) for(var/T in RANGE_TURFS(12, U) - U) if(prob(5)) shoot_projectile(T) -/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast() - playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2) - var/turf/T = get_turf(target) - newtonian_move(get_dir(T, targets_from)) - for(var/turf/turf in range(1, T)) - shoot_projectile(turf) +/mob/living/simple_animal/hostile/megafauna/colossus/proc/blast(set_angle) + ranged_cooldown = world.time + 20 + var/turf/target_turf = get_turf(target) + playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 2) + newtonian_move(get_dir(target_turf, src)) + var/angle_to_target = Get_Angle(src, target_turf) + if(isnum(set_angle)) + angle_to_target = set_angle + var/static/list/colossus_shotgun_shot_angles = list(12.5, 7.5, 2.5, -2.5, -7.5, -12.5) + for(var/i in colossus_shotgun_shot_angles) + shoot_projectile(target_turf, angle_to_target + i) /mob/living/simple_animal/hostile/megafauna/colossus/proc/dir_shots(list/dirs) if(!islist(dirs)) dirs = alldirs.Copy() - playsound(get_turf(src), 'sound/magic/invoke_general.ogg', 200, 1, 2) + playsound(src, 'sound/magic/clockwork/invoke_general.ogg', 200, TRUE, 2) for(var/d in dirs) var/turf/E = get_step(src, d) shoot_projectile(E) @@ -234,9 +207,29 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/megafauna/colossus/proc/telegraph() for(var/mob/M in range(10,src)) if(M.client) - flash_color(M.client, rgb(200, 0, 0), 1) + flash_color(M.client, "#C80000", 1) shake_camera(M, 4, 3) - playsound(get_turf(src),'sound/magic/narsie_attack.ogg', 200, 1) + playsound(src, 'sound/magic/narsie_attack.ogg', 200, TRUE) + + +/mob/living/simple_animal/hostile/megafauna/colossus/devour(mob/living/L) + visible_message("[src] disintegrates [L]!") + L.dust() + +/obj/effect/temp_visual/at_shield + name = "anti-toolbox field" + desc = "A shimmering forcefield protecting the colossus." + icon = 'icons/effects/effects.dmi' + icon_state = "at_shield2" + layer = FLY_LAYER + light_range = 2 + duration = 8 + var/target + +/obj/effect/temp_visual/at_shield/Initialize(mapload, new_target) + . = ..() + target = new_target + INVOKE_ASYNC(src, /atom/movable/proc/orbit, target, 0, FALSE, 0, 0, FALSE, TRUE) /obj/item/projectile/colossus name ="death bolt" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 4ac58ecf0b5..ccd00514daa 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -1,3 +1,9 @@ +#define DRAKE_SWOOP_HEIGHT 270 //how high up drakes go, in pixels +#define DRAKE_SWOOP_DIRECTION_CHANGE_RANGE 5 //the range our x has to be within to not change the direction we slam from + +#define SWOOP_DAMAGEABLE 1 +#define SWOOP_INVULNERABLE 2 + /* ASH DRAKE @@ -6,10 +12,11 @@ Ash drakes spawn randomly wherever a lavaland creature is able to spawn. They ar 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. -Whenever possible, the drake will breathe fire in the four cardinal directions, igniting and heavily damaging anything caught in the blast. -It also often causes fire to rain from the sky - many nearby turfs will flash red as a fireball crashes into them, dealing damage to anything on the turfs. -The drake also utilizes its wings to fly into the sky and crash down onto a specified point. Anything on this point takes tremendous damage. +Whenever possible, the drake will breathe fire directly at it's target, igniting and heavily damaging anything caught in the blast. +It also often causes lava to pool from the ground around you - many nearby turfs will temporarily turn into lava, dealing damage to anything on the turfs. +The drake also utilizes its wings to fly into the sky, flying after its target and attempting to slam down on them. Anything near when it slams down takes huge damage. - Sometimes it will chain these swooping attacks over and over, making swiftness a necessity. + - Sometimes, it will encase its target in an arena of lava When an ash drake dies, it leaves behind a chest that can contain four things: 1. A spectral blade that allows its wielder to call ghosts to it, enhancing its power @@ -39,31 +46,358 @@ Difficulty: Medium armour_penetration = 40 melee_damage_lower = 40 melee_damage_upper = 40 - speed = 1 - move_to_delay = 10 - ranged = 1 + speed = 5 + move_to_delay = 5 + ranged = TRUE pixel_x = -16 crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher) loot = list(/obj/structure/closet/crate/necropolis/dragon) butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30) - var/swooping = 0 - var/swoop_cooldown = 0 + var/swooping = NONE + var/player_cooldown = 0 internal_type = /obj/item/gps/internal/dragon medal_type = BOSS_MEDAL_DRAKE score_type = DRAKE_SCORE deathmessage = "collapses into a pile of bones, its flesh sloughing away." death_sound = 'sound/misc/demon_dies.ogg' + attack_action_types = list(/datum/action/innate/megafauna_attack/fire_cone, + /datum/action/innate/megafauna_attack/fire_cone_meteors, + /datum/action/innate/megafauna_attack/mass_fire, + /datum/action/innate/megafauna_attack/lava_swoop) + +/datum/action/innate/megafauna_attack/fire_cone + name = "Fire Cone" + icon_icon = 'icons/obj/wizard.dmi' + button_icon_state = "fireball" + chosen_message = "You are now shooting fire at your target." + chosen_attack_num = 1 + +/datum/action/innate/megafauna_attack/fire_cone_meteors + name = "Fire Cone With Meteors" + icon_icon = 'icons/mob/actions/actions.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now shooting fire at your target and raining fire around you." + chosen_attack_num = 2 + +/datum/action/innate/megafauna_attack/mass_fire + name = "Mass Fire Attack" + icon_icon = 'icons/effects/fire.dmi' + button_icon_state = "1" + chosen_message = "You are now shooting mass fire at your target." + chosen_attack_num = 3 + +/datum/action/innate/megafauna_attack/lava_swoop + name = "Lava Swoop" + icon_icon = 'icons/effects/effects.dmi' + button_icon_state = "lavastaff_warn" + chosen_message = "You are now swooping and raining lava at your target." + chosen_attack_num = 4 + +/obj/item/gps/internal/dragon + icon_state = null + gpstag = "Fiery Signal" + desc = "Here there be dragons." + invisibility = 100 + +/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() + if(swooping) + return + + anger_modifier = Clamp(((maxHealth - health)/50),0,20) + ranged_cooldown = world.time + ranged_cooldown_time + + if(client) + switch(chosen_attack) + if(1) + fire_cone(meteors = FALSE) + if(2) + fire_cone() + if(3) + mass_fire() + if(4) + lava_swoop() + return + + if(prob(15 + anger_modifier)) + lava_swoop() + + else if(prob(10+anger_modifier)) + shoot_fire_attack() + else + fire_cone() + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/shoot_fire_attack() + if(health < maxHealth*0.5) + mass_fire() + else + fire_cone() + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain() + if(!target) + return + target.visible_message("Fire rains from the sky!") + for(var/turf/turf in range(9,get_turf(target))) + if(prob(11)) + new /obj/effect/temp_visual/target(turf) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_pools(var/amount, var/delay = 0.8) + if(!target) + return + target.visible_message("Lava starts to pool up around you!") + while(amount > 0) + if(QDELETED(target)) + break + var/turf/T = pick(RANGE_TURFS(1, target)) + new /obj/effect/temp_visual/lava_warning(T, 60) // longer reset time for the lava + amount-- + SLEEP_CHECK_DEATH(delay) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_swoop(var/amount = 30) + if(health < maxHealth * 0.5) + return swoop_attack(lava_arena = TRUE, swoop_cooldown = 60) + INVOKE_ASYNC(src, .proc/lava_pools, amount) + swoop_attack(FALSE, target, 1000) // longer cooldown until it gets reset below + SLEEP_CHECK_DEATH(0) + fire_cone() + if(health < maxHealth*0.5) + SLEEP_CHECK_DEATH(10) + fire_cone() + SLEEP_CHECK_DEATH(10) + fire_cone() + SetRecoveryTime(40) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/mass_fire(var/spiral_count = 12, var/range = 15, var/times = 3) + SLEEP_CHECK_DEATH(0) + for(var/i = 1 to times) + SetRecoveryTime(50) + playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE) + var/increment = 360 / spiral_count + for(var/j = 1 to spiral_count) + var/list/turfs = line_target(j * increment + i * increment / 2, range, src) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + SLEEP_CHECK_DEATH(25) + SetRecoveryTime(30) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/lava_arena() + if(!target) + return + target.visible_message("[src] encases you in an arena of fire!") + var/amount = 3 + var/turf/center = get_turf(target) + var/list/walled = RANGE_TURFS(3, center) - RANGE_TURFS(2, center) + var/list/drakewalls = list() + for(var/turf/T in walled) + drakewalls += new /obj/effect/temp_visual/drakewall(T) // no people with lava immunity can just run away from the attack for free + var/list/indestructible_turfs = list() + for(var/turf/T in RANGE_TURFS(2, center)) + if(istype(T, /turf/simulated/floor/indestructible)) + continue + if(!istype(T, /turf/simulated/wall/indestructible)) + T.ChangeTurf(/turf/simulated/floor/plating/asteroid/basalt/lava_land_surface) + else + indestructible_turfs += T + SLEEP_CHECK_DEATH(10) // give them a bit of time to realize what attack is actually happening + + var/list/turfs = RANGE_TURFS(2, center) + while(amount > 0) + var/list/empty = indestructible_turfs.Copy() // can't place safe turfs on turfs that weren't changed to be open + var/any_attack = 0 + for(var/turf/T in turfs) + for(var/mob/living/L in T.contents) + if(L.client) + empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield + any_attack = 1 + for(var/obj/mecha/M in T.contents) + empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty) + any_attack = 1 + if(!any_attack) + for(var/obj/effect/temp_visual/drakewall/D in drakewalls) + qdel(D) + return 0 // nothing to attack in the arena time for enraged attack if we still have a target + for(var/turf/T in turfs) + if(!(T in empty)) + new /obj/effect/temp_visual/lava_warning(T) + else if(!istype(T, /turf/simulated/wall/indestructible)) + new /obj/effect/temp_visual/lava_safe(T) + amount-- + SLEEP_CHECK_DEATH(24) + return 1 // attack finished completely + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/arena_escape_enrage() // you ran somehow / teleported away from my arena attack now i'm mad fucker + SLEEP_CHECK_DEATH(0) + SetRecoveryTime(80) + visible_message("[src] starts to glow vibrantly as its wounds close up!") + adjustBruteLoss(-250) // yeah you're gonna pay for that, don't run nerd + add_atom_colour(rgb(255, 255, 0), TEMPORARY_COLOUR_PRIORITY) + move_to_delay = move_to_delay / 2 + light_range = 10 + SLEEP_CHECK_DEATH(10) // run. + mass_fire(20, 15, 3) + move_to_delay = initial(move_to_delay) + remove_atom_colour(TEMPORARY_COLOUR_PRIORITY) + light_range = initial(light_range) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_cone(var/atom/at = target, var/meteors = TRUE) + playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE) + SLEEP_CHECK_DEATH(0) + if(prob(50) && meteors) + INVOKE_ASYNC(src, .proc/fire_rain) + var/range = 15 + var/list/turfs = list() + turfs = line_target(-40, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + turfs = line_target(0, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + turfs = line_target(40, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/line_target(var/offset, var/range, var/atom/at = target) + if(!at) + return + var/angle = Atan2(at.x - src.x, at.y - src.y) + offset + var/turf/T = get_turf(src) + for(var/i in 1 to range) + var/turf/check = locate(src.x + cos(angle) * i, src.y + sin(angle) * i, src.z) + if(!check) + break + T = check + return (getline(src, T) - get_turf(src)) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_line(var/list/turfs) + SLEEP_CHECK_DEATH(0) + dragon_fire_line(src, turfs) + +//fire line keeps going even if dragon is deleted +/proc/dragon_fire_line(var/source, var/list/turfs) + var/list/hit_list = list() + for(var/turf/T in turfs) + if(T.density) + break + new /obj/effect/hotspot(T) + T.hotspot_expose(700,50,1) + for(var/mob/living/L in T.contents) + if(L in hit_list || L == source) + continue + hit_list += L + L.adjustFireLoss(20) + to_chat(L, "You're hit by [source]'s fire breath!") + + // deals damage to mechs + for(var/obj/mecha/M in T.contents) + if(M in hit_list) + continue + hit_list += M + M.take_damage(45, BRUTE, "melee", 1) + sleep(1.5) + +/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(lava_arena = FALSE, atom/movable/manual_target, var/swoop_cooldown = 30) + if(stat || swooping) + return + if(manual_target) + target = manual_target + if(!target) + return + stop_automated_movement = TRUE + swooping |= SWOOP_DAMAGEABLE + density = FALSE + icon_state = "shadow" + visible_message("[src] swoops up high!") + + var/negative + var/initial_x = x + if(target.x < initial_x) //if the target's x is lower than ours, swoop to the left + negative = TRUE + else if(target.x > initial_x) + negative = FALSE + else if(target.x == initial_x) //if their x is the same, pick a direction + negative = prob(50) + var/obj/effect/temp_visual/dragon_flight/F = new /obj/effect/temp_visual/dragon_flight(loc, negative) + + negative = !negative //invert it for the swoop down later + + var/oldtransform = transform + alpha = 255 + animate(src, alpha = 204, transform = matrix()*0.9, time = 3, easing = BOUNCE_EASING) + for(var/i in 1 to 3) + sleep(1) + if(QDELETED(src) || stat == DEAD) //we got hit and died, rip us + qdel(F) + if(stat == DEAD) + swooping &= ~SWOOP_DAMAGEABLE + animate(src, alpha = 255, transform = oldtransform, time = 0, flags = ANIMATION_END_NOW) //reset immediately + return + animate(src, alpha = 100, transform = matrix()*0.7, time = 7) + swooping |= SWOOP_INVULNERABLE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + SLEEP_CHECK_DEATH(7) + + while(target && loc != get_turf(target)) + forceMove(get_step(src, get_dir(src, target))) + SLEEP_CHECK_DEATH(0.5) + + // Ash drake flies onto its target and rains fire down upon them + var/descentTime = 10 + var/lava_success = TRUE + if(lava_arena) + lava_success = lava_arena() + + + //ensure swoop direction continuity. + if(negative) + if(IsInRange(x, initial_x + 1, initial_x + DRAKE_SWOOP_DIRECTION_CHANGE_RANGE)) + negative = FALSE + else + if(IsInRange(x, initial_x - DRAKE_SWOOP_DIRECTION_CHANGE_RANGE, initial_x - 1)) + negative = TRUE + new /obj/effect/temp_visual/dragon_flight/end(loc, negative) + new /obj/effect/temp_visual/dragon_swoop(loc) + animate(src, alpha = 255, transform = oldtransform, descentTime) + SLEEP_CHECK_DEATH(descentTime) + swooping &= ~SWOOP_INVULNERABLE + mouse_opacity = initial(mouse_opacity) + icon_state = "dragon" + playsound(loc, 'sound/effects/meteorimpact.ogg', 200, TRUE) + for(var/mob/living/L in orange(1, src)) + if(L.stat) + visible_message("[src] slams down on [L], crushing [L.p_them()]!") + L.gib() + else + L.adjustBruteLoss(75) + if(L && !QDELETED(L)) // Some mobs are deleted on death + var/throw_dir = get_dir(src, L) + if(L.loc == loc) + throw_dir = pick(alldirs) + var/throwtarget = get_edge_target_turf(src, throw_dir) + L.throw_at(throwtarget, 3) + visible_message("[L] is thrown clear of [src]!") + for(var/obj/mecha/M in orange(1, src)) + M.take_damage(75, BRUTE, "melee", 1) + + for(var/mob/M in range(7, src)) + shake_camera(M, 15, 1) + + density = TRUE + SLEEP_CHECK_DEATH(1) + swooping &= ~SWOOP_DAMAGEABLE + SetRecoveryTime(swoop_cooldown) + if(!lava_success) + arena_escape_enrage() /mob/living/simple_animal/hostile/megafauna/dragon/ex_act(severity, target) - if(severity == 3) + if(severity == EXPLODE_LIGHT) return ..() /mob/living/simple_animal/hostile/megafauna/dragon/adjustHealth(amount, updating_health = TRUE) - if(swooping) + if(swooping & SWOOP_INVULNERABLE) return FALSE return ..() +/mob/living/simple_animal/hostile/megafauna/dragon/visible_message() + if(swooping & SWOOP_INVULNERABLE) //to suppress attack messages without overriding every single proc that could send a message saying we got hit + return + return ..() + /mob/living/simple_animal/hostile/megafauna/dragon/AttackingTarget() if(!swooping) return ..() @@ -83,181 +417,161 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/dragon/Process_Spacemove(movement_dir = 0) return 1 -/obj/effect/temp_visual/fireball - icon = 'icons/obj/wizard.dmi' - icon_state = "fireball" - name = "fireball" - desc = "Get out of the way!" - layer = 6 - randomdir = 0 - duration = 12 - pixel_z = 500 +/obj/effect/temp_visual/lava_warning + icon_state = "lavastaff_warn" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 13 -/obj/effect/temp_visual/fireball/New(loc) - ..() - animate(src, pixel_z = 0, time = 12) +/obj/effect/temp_visual/lava_warning/ex_act() + return -/obj/effect/temp_visual/target - icon = 'icons/mob/actions/actions.dmi' - icon_state = "sniper_zoom" - layer = MOB_LAYER - 0.1 - luminosity = 2 - duration = 12 +/obj/effect/temp_visual/lava_warning/Initialize(mapload, var/reset_time = 10) + . = ..() + INVOKE_ASYNC(src, .proc/fall, reset_time) + src.alpha = 63.75 + animate(src, alpha = 255, time = duration) + +/obj/effect/temp_visual/lava_warning/proc/fall(var/reset_time) + var/turf/T = get_turf(src) + playsound(T,'sound/magic/fleshtostone.ogg', 80, TRUE) + sleep(duration) + playsound(T,'sound/magic/fireball.ogg', 200, TRUE) + + for(var/mob/living/L in T.contents) + if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + continue + L.adjustFireLoss(10) + to_chat(L, "You fall directly into the pool of lava!") + + // deals damage to mechs + for(var/obj/mecha/M in T.contents) + M.take_damage(45, BRUTE, "melee", 1) + + // changes turf to lava temporarily + if(!T.density && !istype(T, /turf/simulated/floor/plating/lava)) + var/lava_turf = /turf/simulated/floor/plating/lava/smooth + var/reset_turf = T.type + T.ChangeTurf(lava_turf) + sleep(reset_time) + T.ChangeTurf(reset_turf) + +/obj/effect/temp_visual/drakewall + desc = "An ash drakes true flame." + name = "Fire Barrier" + icon = 'icons/effects/fire.dmi' + icon_state = "1" + anchored = TRUE + opacity = 0 + density = TRUE + duration = 82 + color = COLOR_DARK_ORANGE + +/obj/effect/temp_visual/drakewall/CanAtmosPass() + return !density + +/obj/effect/temp_visual/lava_safe + icon = 'icons/obj/hand_of_god_structures.dmi' + icon_state = "trap-earth" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 13 /obj/effect/temp_visual/dragon_swoop name = "certain death" desc = "Don't just stand there, move!" icon = 'icons/effects/96x96.dmi' icon_state = "landing" - layer = MOB_LAYER - 0.1 + layer = BELOW_MOB_LAYER pixel_x = -32 pixel_y = -32 color = "#FF0000" duration = 10 +/obj/effect/temp_visual/dragon_flight + icon = 'icons/mob/lavaland/64x64megafauna.dmi' + icon_state = "dragon" + layer = ABOVE_ALL_MOB_LAYER + pixel_x = -16 + duration = 10 + randomdir = FALSE + +/obj/effect/temp_visual/dragon_flight/Initialize(mapload, negative) + . = ..() + INVOKE_ASYNC(src, .proc/flight, negative) + +/obj/effect/temp_visual/dragon_flight/proc/flight(negative) + if(negative) + animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT*0.1, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING) + else + animate(src, pixel_x = DRAKE_SWOOP_HEIGHT*0.1, pixel_z = DRAKE_SWOOP_HEIGHT*0.15, time = 3, easing = BOUNCE_EASING) + sleep(3) + icon_state = "swoop" + if(negative) + animate(src, pixel_x = -DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7) + else + animate(src, pixel_x = DRAKE_SWOOP_HEIGHT, pixel_z = DRAKE_SWOOP_HEIGHT, time = 7) + +/obj/effect/temp_visual/dragon_flight/end + pixel_x = DRAKE_SWOOP_HEIGHT + pixel_z = DRAKE_SWOOP_HEIGHT + duration = 10 + +/obj/effect/temp_visual/dragon_flight/end/flight(negative) + if(negative) + pixel_x = -DRAKE_SWOOP_HEIGHT + animate(src, pixel_x = -16, pixel_z = 0, time = 5) + else + animate(src, pixel_x = -16, pixel_z = 0, time = 5) + +obj/effect/temp_visual/fireball + icon = 'icons/obj/wizard.dmi' + icon_state = "fireball" + name = "fireball" + desc = "Get out of the way!" + layer = FLY_LAYER + randomdir = FALSE + duration = 9 + pixel_z = 270 + +/obj/effect/temp_visual/fireball/Initialize() + . = ..() + animate(src, pixel_z = 0, time = duration) + +/obj/effect/temp_visual/target + icon = 'icons/mob/actions/actions.dmi' + icon_state = "sniper_zoom" + layer = BELOW_MOB_LAYER + light_range = 2 + duration = 9 + /obj/effect/temp_visual/target/ex_act() return -/obj/effect/temp_visual/target/New(loc) - ..() - spawn(0) - fall() +/obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit) + . = ..() + INVOKE_ASYNC(src, .proc/fall, flame_hit) -/obj/effect/temp_visual/target/proc/fall() +/obj/effect/temp_visual/target/proc/fall(list/flame_hit) var/turf/T = get_turf(src) - playsound(T,'sound/magic/fireball.ogg', 200, 1) + playsound(T,'sound/magic/fleshtostone.ogg', 80, TRUE) new /obj/effect/temp_visual/fireball(T) - sleep(12) - explosion(T, 0, 0, 1, 0, 0, 0, 1, 1) - -/mob/living/simple_animal/hostile/megafauna/dragon/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/50),0,20) - ranged_cooldown = world.time + ranged_cooldown_time - if(swooping) - fire_rain() - return - - if(prob(15 + anger_modifier) && !client) - if(health < maxHealth/2) - spawn(0) - swoop_attack(1) - else - fire_rain() - - else if(prob(10+anger_modifier) && !client) - if(health > maxHealth/2) - spawn(0) - swoop_attack(0) - else - spawn(0) - triple_swoop(0) - else - fire_walls() - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_rain() - visible_message("Fire rains from the sky!") - for(var/turf/turf in range(12,get_turf(src))) - if(prob(10)) - new /obj/effect/temp_visual/target(turf) - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_walls() - playsound(get_turf(src),'sound/magic/fireball.ogg', 200, 1) - - for(var/d in cardinal) - spawn(0) - fire_wall(d) - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/fire_wall(dir) - var/list/hit_things = list(src) - var/turf/E = get_edge_target_turf(src, dir) - var/range = 10 - var/turf/previousturf = get_turf(src) - for(var/turf/J in getline(src,E)) - if(!range || !previousturf.CanAtmosPass(J)) - break - range-- - new /obj/effect/hotspot(J) - J.hotspot_expose(700,50,1) - for(var/mob/living/L in J.contents - hit_things) - L.adjustFireLoss(20) + sleep(duration) + if(ismineralturf(T)) + var/turf/simulated/mineral/M = T + M.gets_drilled() + playsound(T, "explosion", 80, TRUE) + new /obj/effect/hotspot(T) + T.hotspot_expose(700, 50, 1) + for(var/mob/living/L in T.contents) + if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon)) + continue + if(islist(flame_hit) && !flame_hit[L]) + L.adjustFireLoss(40) to_chat(L, "You're hit by the drake's fire breath!") - hit_things += L - previousturf = J - sleep(1) - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/triple_swoop() - swoop_attack() - swoop_attack() - swoop_attack() - -/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target) - if(stat || swooping) - return - swoop_cooldown = world.time + 200 - var/atom/swoop_target - if(manual_target) - swoop_target = manual_target - else - swoop_target = target - stop_automated_movement = TRUE - swooping = 1 - density = 0 - icon_state = "swoop" - visible_message("[src] swoops up high!") - if(prob(50)) - animate(src, pixel_x = 500, pixel_z = 500, time = 10) - else - animate(src, pixel_x = -500, pixel_z = 500, time = 10) - sleep(30) - - var/turf/tturf - if(fire_rain) - fire_rain() - - icon_state = "dragon" - if(swoop_target && !QDELETED(swoop_target) && swoop_target.z == src.z) - tturf = get_turf(swoop_target) - else - tturf = get_turf(src) - forceMove(tturf) - new /obj/effect/temp_visual/dragon_swoop(tturf) - animate(src, pixel_x = initial(pixel_x), pixel_z = 0, time = 10) - sleep(10) - playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1) - for(var/mob/living/L in orange(1, src)) - if(L.stat) - visible_message("[src] slams down on [L], crushing [L.p_them()]!") - L.gib() + flame_hit[L] = TRUE else - L.adjustBruteLoss(75) - if(L && !QDELETED(L)) // Some mobs are deleted on death - var/throw_dir = get_dir(src, L) - if(L.loc == loc) - throw_dir = pick(alldirs) - var/throwtarget = get_edge_target_turf(src, throw_dir) - L.throw_at(throwtarget, 3) - visible_message("[L] is thrown clear of [src]!") - - for(var/mob/M in range(7, src)) - shake_camera(M, 15, 1) - - stop_automated_movement = FALSE - swooping = 0 - density = 1 - -/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A) - if(!istype(A)) - return - if(swoop_cooldown >= world.time) - to_chat(src, "You need to wait 20 seconds between swoop attacks!") - return - swoop_attack(1, A) - -/obj/item/gps/internal/dragon - icon_state = null - gpstag = "Fiery Signal" - desc = "Here there be dragons." - invisibility = 100 + L.adjustFireLoss(10) //if we've already hit them, do way less damage /mob/living/simple_animal/hostile/megafauna/dragon/lesser name = "lesser ash drake" @@ -267,9 +581,22 @@ Difficulty: Medium obj_damage = 80 melee_damage_upper = 30 melee_damage_lower = 30 + mouse_opacity = MOUSE_OPACITY_ICON damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) loot = list() crusher_loot = list() + butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) + attack_action_types = list() + +/mob/living/simple_animal/hostile/megafauna/dragon/lesser/AltClickOn(atom/movable/A) + if(!istype(A)) + return + if(player_cooldown >= world.time) + to_chat(src, "You need to wait [(player_cooldown - world.time) / 10] seconds before swooping again!") + return + swoop_attack(FALSE, A) + lava_pools(10, 2) // less pools but longer delay before spawns + player_cooldown = world.time + 200 // needs seperate cooldown or cant use fire attacks /mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype) return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 130cfb3f847..81c96135b0e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -7,11 +7,11 @@ sentience_type = SENTIENCE_BOSS environment_smash = ENVIRONMENT_SMASH_RWALLS obj_damage = 400 - luminosity = 3 + light_range = 3 faction = list("mining", "boss") weather_immunities = list("lava","ash") - flying = 1 - robust_searching = 1 + flying = TRUE + robust_searching = TRUE ranged_ignores_vision = TRUE stat_attack = DEAD atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) @@ -20,6 +20,12 @@ maxbodytemp = INFINITY vision_range = 5 aggro_vision_range = 18 + move_force = MOVE_FORCE_OVERPOWERING + move_resist = MOVE_FORCE_OVERPOWERING + pull_force = MOVE_FORCE_OVERPOWERING + mob_size = MOB_SIZE_LARGE + layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise + mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway var/list/crusher_loot var/medal_type var/score_type = BOSS_SCORE @@ -27,13 +33,9 @@ var/anger_modifier = 0 var/obj/item/gps/internal_gps var/internal_type - move_force = MOVE_FORCE_OVERPOWERING - move_resist = MOVE_FORCE_OVERPOWERING - pull_force = MOVE_FORCE_OVERPOWERING - mob_size = MOB_SIZE_LARGE - layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise - mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway + var/recovery_time = 0 var/true_spawn = TRUE // if this is a megafauna that should grant achievements, or have a gps signal + var/nest_range = 10 var/chosen_attack = 1 // chosen attack num var/list/attack_action_types = list() @@ -50,6 +52,16 @@ QDEL_NULL(internal_gps) return ..() +/mob/living/simple_animal/hostile/megafauna/Moved() + if(nest && nest.parent && get_dist(nest.parent, src) > nest_range) + var/turf/closest = get_turf(nest.parent) + for(var/i = 1 to nest_range) + closest = get_step(closest, get_dir(closest, src)) + forceMove(closest) // someone teleported out probably and the megafauna kept chasing them + target = null + return + return ..() + /mob/living/simple_animal/hostile/megafauna/can_die() return ..() && health <= 0 @@ -68,6 +80,8 @@ loot = crusher_loot /mob/living/simple_animal/hostile/megafauna/AttackingTarget() + if(recovery_time >= world.time) + return . = ..() if(. && isliving(target)) var/mob/living/L = target @@ -90,13 +104,14 @@ /mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L) if(!L) - return + return FALSE visible_message( "[src] devours [L]!", "You feast on [L], restoring your health!") - if(!is_station_level(z) && !client) //NPC monsters won't heal while on station + if(!is_station_level(z) || client) //NPC monsters won't heal while on station adjustBruteLoss(-L.maxHealth/2) L.gib() + return TRUE /mob/living/simple_animal/hostile/megafauna/ex_act(severity, target) switch(severity) @@ -109,6 +124,10 @@ if(3) adjustBruteLoss(50) +/mob/living/simple_animal/hostile/megafauna/proc/SetRecoveryTime(buffer_time) + recovery_time = world.time + buffer_time + ranged_cooldown = world.time + buffer_time + /mob/living/simple_animal/hostile/megafauna/proc/grant_achievement(medaltype, scoretype, crusher_kill) if(!medal_type || admin_spawned || !SSmedals.hub_enabled) //Don't award medals if the medal type isn't set return FALSE From 59082ff21a2d25ab30321bc7d5d573ddd68df6bf Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Wed, 11 Sep 2019 13:52:33 -0400 Subject: [PATCH 2/3] space dragonnnn --- code/datums/spells/wizard.dm | 12 +-- .../temporary_visuals/miscellaneous.dm | 4 + .../hostile/megafauna/colossus.dm | 10 +++ .../simple_animal/hostile/megafauna/drake.dm | 70 ++++++++++++++++++ icons/effects/effects.dmi | Bin 421714 -> 425706 bytes icons/mob/actions/actions.dmi | Bin 122497 -> 122968 bytes icons/mob/spacedragon.dmi | Bin 0 -> 8111 bytes 7 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 icons/mob/spacedragon.dmi diff --git a/code/datums/spells/wizard.dm b/code/datums/spells/wizard.dm index 739a03d92c5..6bcba4cd83b 100644 --- a/code/datums/spells/wizard.dm +++ b/code/datums/spells/wizard.dm @@ -383,18 +383,18 @@ name = "Repulse" desc = "This spell throws everything around the user away." charge_max = 400 - clothes_req = 1 + clothes_req = TRUE invocation = "GITTAH WEIGH" invocation_type = "shout" range = 5 cooldown_min = 150 selection_type = "view" + sound = 'sound/magic/repulse.ogg' var/maxthrow = 5 var/sparkle_path = /obj/effect/temp_visual/gravpush action_icon_state = "repulse" - sound = 'sound/magic/repulse.ogg' -/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets, mob/user = usr) +/obj/effect/proc_holder/spell/aoe_turf/repulse/cast(list/targets, mob/user = usr, stun_amt = 2) var/list/thrownatoms = list() var/atom/throwtarget var/distfromcaster @@ -411,16 +411,16 @@ throwtarget = get_edge_target_turf(user, get_dir(user, get_step_away(AM, user))) distfromcaster = get_dist(user, AM) if(distfromcaster == 0) - if(istype(AM, /mob/living)) + if(isliving(AM)) var/mob/living/M = AM M.Weaken(5) M.adjustBruteLoss(5) to_chat(M, "You're slammed into the floor by a mystical force!") else new sparkle_path(get_turf(AM), get_dir(user, AM)) //created sparkles will disappear on their own - if(istype(AM, /mob/living)) + if(isliving(AM)) var/mob/living/M = AM - M.Weaken(2) + M.Weaken(stun_amt) to_chat(M, "You're thrown back by a mystical force!") spawn(0) AM.throw_at(throwtarget, ((Clamp((maxthrow - (Clamp(distfromcaster - 2, 0, distfromcaster))), 3, maxthrow))), 1)//So stuff gets tossed around at the same time. diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index d6dbf1dddbb..f7a0962269d 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -90,6 +90,10 @@ /obj/effect/temp_visual/dir_setting/wraith/out icon_state = "phase_shift" +/obj/effect/temp_visual/dir_setting/tailsweep + icon_state = "tailsweep" + duration = 4 + /obj/effect/temp_visual/wizard name = "water" icon = 'icons/mob/mob.dmi' diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index cade1489c63..8eed750804f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -231,6 +231,16 @@ Difficulty: Very Hard target = new_target INVOKE_ASYNC(src, /atom/movable/proc/orbit, target, 0, FALSE, 0, 0, FALSE, TRUE) +/mob/living/simple_animal/hostile/megafauna/colossus/bullet_act(obj/item/projectile/P) + if(!stat) + var/obj/effect/temp_visual/at_shield/AT = new /obj/effect/temp_visual/at_shield(loc, src) + var/random_x = rand(-32, 32) + AT.pixel_x += random_x + + var/random_y = rand(0, 72) + AT.pixel_y += random_y + return ..() + /obj/item/projectile/colossus name ="death bolt" icon_state= "chronobolt" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index ccd00514daa..8b6d6fed947 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -599,4 +599,74 @@ obj/effect/temp_visual/fireball player_cooldown = world.time + 200 // needs seperate cooldown or cant use fire attacks /mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype) + return + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon + name = "space dragon" + maxHealth = 250 + health = 250 + faction = list("neutral") + desc = "A space carp turned dragon by vile magic. Has the same ferocity of a space carp, but also a much more enabling body." + icon = 'icons/mob/spacedragon.dmi' + icon_state = "spacedragon" + icon_living = "spacedragon" + icon_dead = "spacedragon_dead" + obj_damage = 80 + melee_damage_upper = 35 + melee_damage_lower = 35 + speed = 0 + mouse_opacity = MOUSE_OPACITY_ICON + loot = list() + crusher_loot = list() + butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/bone = 30) + move_force = MOVE_FORCE_NORMAL + move_resist = MOVE_FORCE_NORMAL + pull_force = MOVE_FORCE_NORMAL + deathmessage = "screeches as its wings turn to dust and it collapses on the floor, life estinguished." + attack_action_types = list() + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/grant_achievement(medaltype, scoretype) + return + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/Initialize(mapload) + var/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon/repulse_action = new /obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon(src) + repulse_action.action.Grant(src) + mob_spell_list += repulse_action + . = ..() + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/proc/fire_stream(var/atom/at = target) + playsound(get_turf(src),'sound/magic/fireball.ogg', 200, TRUE) + SLEEP_CHECK_DEATH(0) + var/range = 20 + var/list/turfs = list() + turfs = line_target(0, range, at) + INVOKE_ASYNC(src, .proc/fire_line, turfs) + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/OpenFire() + if(swooping) + return + ranged_cooldown = world.time + ranged_cooldown_time + fire_stream() + +/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon + name = "Tail Sweep" + desc = "Throw back attackers with a sweep of your tail." + sound = 'sound/magic/tail_swing.ogg' + charge_max = 150 + clothes_req = FALSE + range = 1 + cooldown_min = 150 + invocation_type = "none" + sparkle_path = /obj/effect/temp_visual/dir_setting/tailsweep + action_icon_state = "tailsweep" + action_background_icon_state = "bg_alien" + +/obj/effect/proc_holder/spell/aoe_turf/repulse/spacedragon/cast(list/targets, mob/user = usr) + if(iscarbon(user)) + var/mob/living/carbon/C = user + playsound(C.loc, 'sound/effects/hit_punch.ogg', 80, TRUE, TRUE) + C.spin(6, 1) + ..(targets, user, 3) + +/mob/living/simple_animal/hostile/megafauna/dragon/space_dragon/AltClickOn(atom/movable/A) return \ No newline at end of file diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index bea6f281f7a60eda74b14a71a9895cec67741782..89f57b2517dafd8c579ba96eb10aa8c70fec12fc 100644 GIT binary patch delta 23733 zcmZU31ymJX`|qK<4?N^_A6NEJhwHDKl19)LfNOa145yd44Ah29APy{ZQ_DD~)AO^#wRg z_RMaJX72F+#gN@*Fo|7~*QHrx6g~Fx)2YUW5xPPBh>BZROJ(46`rmavYGy%kBJ0`b zK`W(v@1&AHG#j7Ubr=8N9=+B(8^8Y#la=!azBeG%Q#FK6c4p8?AziEo6RI$hJNlcj!O3al0U zv`5JnMxrH{EygVtiFfLcw{S#D+#>c-9$#)~@nDb{izhNm9?XcF0C0&_DHki#HPC^` z%6~eKLR3i{MS~WR#I`nMY)L^y5A(u?6s0k<)Jg#3Ju{ zrKaB=#s^B6qTY0~_U9s-%{k;0{n52;7(PcXV$P9ixksRe)$l4HQ%A>P86J63qxNT zCV zK-5ocC^?S^_@4Cx+WNl2zN3GsMXa4=+rly7uv?Ata}vjgUA~0B$PQ%{?LB~(dI6e^ z0Rw4mEP6$7L&*#H;#Zt$pY-!2)l9|GL^;_}(#Y&KR5Ia`1{QCUQNkD1{L~ zOHPWlplg`-sdyE+(#(>UBykB;!6T`hrjzi(h>Ryr6A?S4&!`hU%e>kEz(_?dKo@L~^%hdW81umx*UUc4-~&q3a*_b6=j zg+61b#^lMyx6@~e!y=3545a-P9!ccIbn)2OM*W{9+auqEc;Pi5AJfnR&9L9MWL}s2 zN0g2${>?%BQSVH#kJ!G*BR9{|oByPQV;$Rn{+lz4gpCnJg|+b``TNN+D*MkL!&865 z2;_a&ynZ_wAS+$46P5_LL^lqm=e#ASP#|AQ5m-nPP*TJ%7E~_VFk|QMKvkQVMNcuF~M{XG*GDPxCEu6k9j3f@e2>*yNr|`Z13Q~o?=P)yVW#88|iuVqt z8@gkUX}WnYV+k5=KLdM~0tGoXBwYs_u|V||;j|X@a~97GEN$~|Gb*>+C_!o}ef)TKz(UWgIP|**tH4zJtI>=yTzba4pCM@^i=jj=Y%SzEZkvP zI4=ytN1Z@JgpnhJk>S7-9y}4i6A?U-z6c{DAJG8Thu=arnh%7>-~HCN_B;ZKBOg7f0LTo zb$J4G_?@3*cP$^Tc6>25+xp6T zso2c`9x2!ig<`^9T0_6R^Qq{!9WsY+;cu$W0@PO@#HVSCGYisk0B zFBN0Xu80C0+wctmq9iVO^v897rS@|6Sv0iE`^&MG2>GFXeXpQ^Pi!bMXBm|br>7Ga z#`8@3%Ea^)B%_&HNezl+PQWjjtZm_Hu3#-6!c~b05g!{btYEuL+~S9!;h!l}0-Kwo zPWCDEu|%O03^+abvdl*xoIeh+5L5+|D+kljq_B54DJvwy%TAgsGT1h1cVDVAa~A5n zF*Q9!XmTN$^8O&$To4FfihC;;a}{RE8@9*SO1KJ4?u9%W`}(IQvi;L;T$H zBF?Vqu|Gb$Z(}`8KZLCkq6dGboV!(QV7)q}U&Zk)0!W`D`e?K7Cp%E#hD(|GJq{kC zlm6$E(+(Ta)_8#ttGVfeJ@2xR-|{%0*Esg4?vTd~BCFLbpav~~}w!{mbcvr8;?Oa(^Ul; zMwp_p_KPxwt8ijmVlCM~lu$Bep;6D;ouGgYMQg5XbrZV2PSP-u$;?QZwodOa6`jNe zMJRn_GNSD4%8Lx*6dSF?VXmIuD&5}x)i^nXTsvuXH?Nu)`_91dLrGQ3k2cI3@{H6< z_!hDuR5L%zbWO6@h?8(aDK+-75{Kj9q)yJ4%kFiFIn69rX^1$0oSpLf%u@VT+sC_Y ztvUnaL{=6iWe)LpH!Eo7{#!3L4mP;%UJ-(n6Iy~JQjXKJ5yJc(8w(et4Ghhpgjdul z>?S_rIV!!-%h;^0BkaHnw3^ql2?8l5=}Pp}|3vW@|NMptTGU?mH-MSz*!VajVSqCP za=G5{RojfLE;UcNoG&rmnfQK>~J zVVaG^>{PSY!?%fsNHlgSl6vjRs&2l$p^ZUUG`Amb#*lg~d;vsJLq8+SK{5@x-@N0Y zK-2btdk0SfT37G(Tu&vA{zL~#5e!i%80%f}>;A+J5rf%HXtHHC)3K^)iH=G3i(4D1 zxFkjZ3g&_zAYM%m8CX%0A72Wg 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 delta 19710 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

ZdB0{>;Z%(E8;eboxW5Ma! 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 literal 0 HcmV?d00001 From 60c04285cf892117bb9f23687477503ed3eeb637 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Wed, 11 Sep 2019 23:06:34 -0400 Subject: [PATCH 3/3] Bubblegum rework --- code/modules/flufftext/Hallucination.dm | 74 ++- .../mob/living/carbon/human/human_damage.dm | 2 +- .../hostile/megafauna/bubblegum.dm | 612 +++++++++++------- code/modules/surgery/organs/helpers.dm | 3 + 4 files changed, 429 insertions(+), 262 deletions(-) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index af366683570..b177d7a7aaf 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -269,51 +269,59 @@ Gunshots/explosions/opening doors/less rare audio (done) px = -32 /obj/effect/hallucination/oh_yeah - var/turf/simulated/wall/wall - var/obj/effect/hallucination/simple/bubblegum/bubblegum = null + var/obj/effect/hallucination/simple/bubblegum/bubblegum var/image/fakebroken var/image/fakerune -/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/T) +/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/C) + set waitfor = FALSE ..() - target = T - for(var/turf/simulated/wall/W in range(7,target)) + target = C + var/turf/simulated/wall/wall + for(var/turf/simulated/wall/W in range(7, target)) wall = W break - if(wall) - fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER) - var/turf/landing = get_turf(target) - var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3 - fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER) - fakebroken.override = TRUE - if(target.client) - target.client.images |= fakebroken - target.client.images |= fakerune - target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1) - bubblegum = new(wall, target) - sleep(10) //ominous wait - var/charged = FALSE //only get hit once - while(get_turf(bubblegum) != landing && target) - bubblegum.forceMove(get_step_towards(bubblegum, landing)) - bubblegum.setDir(get_dir(bubblegum, landing)) - target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1) - shake_camera(target, 2, 1) - if(bubblegum.Adjacent(target) && !charged) - charged = TRUE - target.Weaken(4) - target.adjustStaminaLoss(40) - step_away(target, bubblegum) - shake_camera(target, 4, 3) - target.visible_message("[target] jumps backwards, falling on the ground!","[bubblegum] slams into you!") - sleep(2) - sleep(30) - qdel(bubblegum) + if(!wall) + qdel(src) + return + + fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER) + var/turf/landing = get_turf(target) + var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3 + fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER) + fakebroken.override = TRUE + if(target.client) + target.client.images |= fakebroken + target.client.images |= fakerune + target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1) + bubblegum = new(wall, target) + addtimer(CALLBACK(src, .proc/bubble_attack, landing), 10) + +/obj/effect/hallucination/oh_yeah/proc/bubble_attack(turf/landing) + var/charged = FALSE //only get hit once + while(get_turf(bubblegum) != landing && target && target.stat != DEAD) + bubblegum.forceMove(get_step_towards(bubblegum, landing)) + bubblegum.setDir(get_dir(bubblegum, landing)) + target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1) + shake_camera(target, 2, 1) + if(bubblegum.Adjacent(target) && !charged) + charged = TRUE + target.Weaken(4) + target.adjustStaminaLoss(40) + step_away(target, bubblegum) + shake_camera(target, 4, 3) + target.visible_message("[target] jumps backwards, falling on the ground!", "[bubblegum] slams into you!") + sleep(2) + sleep(30) qdel(src) /obj/effect/hallucination/oh_yeah/Destroy() if(target.client) target.client.images.Remove(fakebroken) target.client.images.Remove(fakerune) + QDEL_NULL(fakebroken) + QDEL_NULL(fakerune) + QDEL_NULL(bubblegum) return ..() /obj/effect/hallucination/singularity_scare diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 762df8d3b8b..71a3ae3e87c 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -328,7 +328,7 @@ This function restores all organs. return 0 -/mob/living/carbon/human/proc/get_organ(zone) +/mob/living/carbon/human/get_organ(zone) if(!zone) zone = "chest" if(zone in list("eyes", "mouth")) 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 43274952362..66799ffc6c6 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,8 @@ +#define BUBBLEGUM_SMASH (health <= maxHealth * 0.5) // angery +#define BUBBLEGUM_CAN_ENRAGE (enrage_till + (enrage_time * 2) <= world.time) +#define BUBBLEGUM_IS_ENRAGED (enrage_till > world.time) + + /* BUBBLEGUM @@ -5,14 +10,16 @@ BUBBLEGUM Bubblegum spawns randomly wherever a lavaland creature is able to spawn. It is the most powerful slaughter demon in existence. 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 acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power -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 leaves blood trails behind wherever it goes, its clones do as well. +It tries to strike at its target through any bloodpools under them; if it fails to do that. +If it does warp it will enter an enraged state, becoming immune to all projectiles, becoming much faster, and dealing damage and knockback to anything that gets in the cloud around it. +It may summon clones charging from all sides, one of these charges being bubblegum himself. +It can charge at its target, and also heavily damaging anything directly hit in the charge. +If at half health it will start to charge from all sides with clones. -When Bubblegum dies, it leaves behind a chest that can contain three things: +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 @@ -37,19 +44,31 @@ Difficulty: Hard armour_penetration = 40 melee_damage_lower = 40 melee_damage_upper = 40 - speed = 1 - move_to_delay = 10 - ranged = 1 + speed = 5 + move_to_delay = 5 + retreat_distance = 5 + minimum_distance = 5 + rapid_melee = 8 // every 1/4 second + melee_queue_distance = 20 // as far as possible really, need this because of blood warp + ranged = TRUE pixel_x = -32 - del_on_death = 1 + del_on_death = TRUE crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher) loot = list(/obj/structure/closet/crate/necropolis/bubblegum) - var/charging = 0 + blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME + var/charging = FALSE + var/enrage_till = 0 + var/enrage_time = 70 + var/revving_charge = FALSE internal_type = /obj/item/gps/internal/bubblegum medal_type = BOSS_MEDAL_BUBBLEGUM score_type = BUBBLEGUM_SCORE deathmessage = "sinks into a pool of blood, fleeing the battle. You've won, for now... " death_sound = 'sound/misc/enter_blood.ogg' + attack_action_types = list(/datum/action/innate/megafauna_attack/triple_charge, + /datum/action/innate/megafauna_attack/hallucination_charge, + /datum/action/innate/megafauna_attack/hallucination_surround, + /datum/action/innate/megafauna_attack/blood_warp) /obj/item/gps/internal/bubblegum icon_state = null @@ -57,54 +76,6 @@ 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(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(cardinal)) - else - B.dir = pick(cardinal) - . = ..() - -/obj/effect/decal/cleanable/blood/gibs/bubblegum - name = "thick blood" - desc = "Thick, splattered blood." - random_icon_states = list("gib3", "gib5", "gib6") - amount = 20 - -/obj/effect/decal/cleanable/blood/gibs/bubblegum/can_bloodcrawl_in() - return TRUE - -/mob/living/simple_animal/hostile/megafauna/bubblegum/Life(seconds, times_fired) - ..() - move_to_delay = Clamp((health/maxHealth) * 10, 5, 10) - -/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() - anger_modifier = Clamp(((maxHealth - health)/60),0,20) - if(charging) - return - ranged_cooldown = world.time + ranged_cooldown_time - - var/warped = FALSE - if(!try_bloodattack()) - spawn(0) - blood_spray() - warped = blood_warp() - if(warped && prob(100 - anger_modifier)) - return - - if(prob(90 - anger_modifier) || slaughterlings()) - if(health > maxHealth * 0.5) - spawn(0) - charge() - else - if(prob(70) || warped) - spawn(0) - triple_charge() - else - spawn(0) - warp_charge() - /mob/living/simple_animal/hostile/megafauna/bubblegum/Initialize(mapload) . = ..() if(true_spawn) @@ -112,88 +83,118 @@ Difficulty: Hard if(B != src) qdel(src) //There can be only one return - var/obj/effect/proc_holder/spell/bloodcrawl/bloodspell = new - AddSpell(bloodspell) - if(istype(loc, /obj/effect/dummy/slaughter)) - bloodspell.phased = 1 -/mob/living/simple_animal/hostile/megafauna/bubblegum/do_attack_animation(atom/A, visual_effect_icon, used_item, no_effect, end_pixel_y) - if(!charging) - ..() +/datum/action/innate/megafauna_attack/triple_charge + name = "Triple Charge" + icon_icon = 'icons/mob/actions/actions.dmi' + button_icon_state = "sniper_zoom" + chosen_message = "You are now triple charging at the target you click on." + chosen_attack_num = 1 -/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget() - if(!charging) - return ..() +/datum/action/innate/megafauna_attack/hallucination_charge + name = "Hallucination Charge" + icon_icon = 'icons/effects/bubblegum.dmi' + button_icon_state = "smack ya one" + chosen_message = "You are now charging with hallucinations at the target you click on." + chosen_attack_num = 2 -/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) - if(!charging) - ..() +/datum/action/innate/megafauna_attack/hallucination_surround + name = "Surround Target" + icon_icon = 'icons/turf/walls/wall.dmi' + button_icon_state = "wall" + chosen_message = "You are now surrounding the target you click on with hallucinations." + chosen_attack_num = 3 -/mob/living/simple_animal/hostile/megafauna/bubblegum/MoveToTarget(list/possible_targets) - if(!charging) - ..() +/datum/action/innate/megafauna_attack/blood_warp + name = "Blood Warp" + icon_icon = 'icons/effects/blood.dmi' + button_icon_state = "floor1" + chosen_message = "You are now warping to blood around your clicked position." + chosen_attack_num = 4 -/mob/living/simple_animal/hostile/megafauna/bubblegum/Move() +/mob/living/simple_animal/hostile/megafauna/bubblegum/OpenFire() if(charging) - 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() + return -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge() - blood_warp() - charge() + anger_modifier = Clamp(((maxHealth - health)/60),0,20) + enrage_time = initial(enrage_time) * Clamp(anger_modifier / 20, 0.5, 1) + ranged_cooldown = world.time + 50 + + if(client) + switch(chosen_attack) + if(1) + triple_charge() + if(2) + hallucination_charge() + if(3) + surround_with_hallucinations() + if(4) + blood_warp() + return + + if(!try_bloodattack() || prob(25 + anger_modifier)) + blood_warp() + + if(!BUBBLEGUM_SMASH) + triple_charge() + else + if(prob(50 + anger_modifier)) + hallucination_charge() + else + surround_with_hallucinations() /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge() - charge() - charge() - charge() + charge(delay = 6) + charge(delay = 4) + charge(delay = 2) + SetRecoveryTime(15) -/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge() - var/turf/T = get_turf(target) - if(!T || T == loc) +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/hallucination_charge() + if(!BUBBLEGUM_SMASH || prob(33)) + hallucination_charge_around(times = 6, delay = 8) + SetRecoveryTime(10) + else + hallucination_charge_around(times = 4, delay = 9) + hallucination_charge_around(times = 4, delay = 8) + hallucination_charge_around(times = 4, delay = 7) + triple_charge() + SetRecoveryTime(20) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/surround_with_hallucinations() + for(var/i = 1 to 5) + INVOKE_ASYNC(src, .proc/hallucination_charge_around, 2, 8, 2, 0, 4) + if(ismob(target)) + charge(delay = 6) + else + SLEEP_CHECK_DEATH(6) + SetRecoveryTime(20) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge(atom/chargeat = target, delay = 3, chargepast = 2) + if(!chargeat) return - new /obj/effect/temp_visual/dragon_swoop(T) - charging = 1 + var/chargeturf = get_turf(chargeat) + if(!chargeturf) + return + var/dir = get_dir(src, chargeturf) + var/turf/T = get_ranged_target_turf(chargeturf, dir, chargepast) + if(!T) + return + new /obj/effect/temp_visual/dragon_swoop/bubblegum(T) + charging = TRUE + revving_charge = TRUE DestroySurroundings() walk(src, 0) - dir = 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 = 5) - sleep(5) - throw_at(T, get_dist(src, T), 1, src, 0) - charging = 0 + setDir(dir) + 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_CHECK_DEATH(delay) + revving_charge = FALSE + var/movespeed = 0.7 + walk_towards(src, T, movespeed) + SLEEP_CHECK_DEATH(get_dist(src, T) * movespeed) + walk(src, 0) // cancel the movement try_bloodattack() - if(target) - Goto(target, move_to_delay, minimum_distance) - - -/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A) - if(charging) - if(isturf(A) || isobj(A) && A.density) - A.ex_act(2) - DestroySurroundings() - ..() - -/mob/living/simple_animal/hostile/megafauna/bubblegum/throw_impact(atom/A) - if(!charging) - return ..() - - else if(isliving(A)) - var/mob/living/L = A - L.visible_message("[src] slams into [L]!", "[src] slams into you!") - L.apply_damage(40, BRUTE) - playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1) - shake_camera(L, 4, 3) - shake_camera(src, 2, 3) - var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src))) - L.throw_at(throwtarget, 3) - - charging = 0 - + charging = FALSE /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood() var/list/targets = ListTargets() @@ -206,9 +207,7 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack() var/list/targets = get_mobs_on_blood() if(targets.len) - spawn(0) - bloodattack(targets, prob(50)) - + INVOKE_ASYNC(src, .proc/bloodattack, targets, prob(50)) return TRUE return FALSE @@ -249,14 +248,14 @@ Difficulty: Hard new /obj/effect/temp_visual/bubblegum_hands/rightsmack(T) else new /obj/effect/temp_visual/bubblegum_hands/leftsmack(T) - sleep(2.5) + SLEEP_CHECK_DEATH(4) 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 = 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) + playsound(T, attack_sound, 100, TRUE, -1) + var/limb_to_hit = L.get_organ(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(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration)) + SLEEP_CHECK_DEATH(3) /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness) if(handedness) @@ -265,18 +264,221 @@ Difficulty: Hard else new /obj/effect/temp_visual/bubblegum_hands/leftpaw(T) new /obj/effect/temp_visual/bubblegum_hands/leftthumb(T) - sleep(6) + SLEEP_CHECK_DEATH(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/misc/enter_blood.ogg', 100, 1, -1) - var/turf/targetturf = get_step(src, dir) - L.forceMove(targetturf) - playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, 1, -1) if(L.stat != CONSCIOUS) - spawn(2) - devour(L) - sleep(1) + to_chat(L, "[src] drags you through the blood!") + playsound(T, 'sound/misc/enter_blood.ogg', 100, TRUE, -1) + var/turf/targetturf = get_step(src, dir) + L.forceMove(targetturf) + playsound(targetturf, 'sound/misc/exit_blood.ogg', 100, TRUE, -1) + addtimer(CALLBACK(src, .proc/devour, L), 2) + SLEEP_CHECK_DEATH(1) + +/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), 5) + var/list/pools_to_remove = get_pools(get_turf(target), 4) + 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_CHECK_DEATH(3) + qdel(DA) + + var/obj/effect/decal/cleanable/blood/found_bloodpool + pools = get_pools(get_turf(target), 5) + pools_to_remove = get_pools(get_turf(target), 4) + pools -= pools_to_remove + if(pools.len) + shuffle_inplace(pools) + found_bloodpool = pick(pools) + if(found_bloodpool) + visible_message("[src] sinks into the blood...") + playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, TRUE, -1) + forceMove(get_turf(found_bloodpool)) + playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, TRUE, -1) + visible_message("And springs back out!") + blood_enrage() + return TRUE + return FALSE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/be_aggressive() + if(BUBBLEGUM_IS_ENRAGED) + return TRUE + if(isliving(target)) + var/mob/living/livingtarget = target + return (livingtarget.stat != CONSCIOUS || livingtarget.lying) + return FALSE + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_retreat_distance() + return (be_aggressive() ? null : initial(retreat_distance)) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_minimum_distance() + return (be_aggressive() ? 1 : initial(minimum_distance)) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/update_approach() + retreat_distance = get_retreat_distance() + minimum_distance = get_minimum_distance() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage() + if(!BUBBLEGUM_CAN_ENRAGE) + return FALSE + enrage_till = world.time + enrage_time + update_approach() + change_move_delay(3.75) + var/newcolor = rgb(149, 10, 10) + add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY) + var/datum/callback/cb = CALLBACK(src, .proc/blood_enrage_end) + addtimer(cb, enrage_time) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_enrage_end(newcolor = rgb(149, 10, 10)) + update_approach() + change_move_delay() + remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/change_move_delay(newmove = initial(move_to_delay)) + move_to_delay = newmove + speed = move_to_delay + handle_automated_action() // need to recheck movement otherwise move_to_delay won't update until the next checking aka will be wrong speed for a bit + +/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 + +/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/hallucination_charge_around(times = 4, delay = 6, chargepast = 0, useoriginal = 1, radius) + var/startingangle = rand(1, 360) + if(!target) + return + var/turf/chargeat = get_turf(target) + var/srcplaced = FALSE + if(!radius) + radius = times + for(var/i = 1 to times) + var/ang = (startingangle + 360/times * i) + if(!chargeat) + return + var/turf/place = locate(chargeat.x + cos(ang) * radius, chargeat.y + sin(ang) * radius, chargeat.z) + if(!place) + continue + if(!nest || nest && nest.parent && get_dist(nest.parent, place) <= nest_range) + if(!srcplaced && useoriginal) + forceMove(place) + srcplaced = TRUE + continue + var/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/B = new /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination(loc) + B.forceMove(place) + INVOKE_ASYNC(B, .proc/charge, chargeat, delay, chargepast) + if(useoriginal) + charge(chargeat, delay, chargepast) + +/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount, updating_health = TRUE) + . = ..() + 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(cardinal)) + else + B.setDir(pick(cardinal)) + +/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/do_attack_animation(atom/A, visual_effect_icon) + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/AttackingTarget() + if(!charging) + . = ..() + if(.) + recovery_time = world.time + 20 // can only attack melee once every 2 seconds but rapid_melee gives higher priority + +/mob/living/simple_animal/hostile/megafauna/bubblegum/bullet_act(obj/item/projectile/P) + if(BUBBLEGUM_IS_ENRAGED) + visible_message("[src] deflects the projectile; [p_they()] can't be hit with ranged weapons while enraged!", "You deflect the projectile!") + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 300, TRUE) + return + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/ex_act(severity, target) + if(severity >= EXPLODE_LIGHT) + return + severity = EXPLODE_LIGHT // puny mortals + return ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/CanPass(atom/movable/mover, turf/target) + if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination)) + return TRUE + return ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Goto(target, delay, minimum_distance) + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/MoveToTarget(list/possible_targets) + if(!charging) + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Move() + update_approach() + if(revving_charge) + return FALSE + if(charging) + new /obj/effect/temp_visual/decoy/fading(loc,src) + DestroySurroundings() + ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Moved(atom/OldLoc, Dir, Forced = FALSE) + if(Dir) + new /obj/effect/decal/cleanable/blood/bubblegum(loc) + if(charging) + DestroySurroundings() + playsound(src, 'sound/effects/meteorimpact.ogg', 200, TRUE, 2, TRUE) + return ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A) + if(charging) + if(isturf(A) || isobj(A) && A.density) + A.ex_act(EXPLODE_HEAVY) + DestroySurroundings() + if(isliving(A)) + var/mob/living/L = A + L.visible_message("[src] slams into [L]!", "[src] tramples you into the ground!") + forceMove(get_turf(L)) + L.apply_damage(istype(src, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination) ? 15 : 30, BRUTE) + playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, TRUE) + shake_camera(L, 4, 3) + shake_camera(src, 2, 3) + ..() + +/obj/effect/temp_visual/dragon_swoop/bubblegum + duration = 10 /obj/effect/temp_visual/bubblegum_hands icon = 'icons/effects/bubblegum.dmi' @@ -290,11 +492,11 @@ Difficulty: Hard /obj/effect/temp_visual/bubblegum_hands/rightpaw icon_state = "rightpawgrab" - layer = MOB_LAYER - 0.1 + layer = BELOW_MOB_LAYER /obj/effect/temp_visual/bubblegum_hands/leftpaw icon_state = "leftpawgrab" - layer = MOB_LAYER - 0.1 + layer = BELOW_MOB_LAYER /obj/effect/temp_visual/bubblegum_hands/rightsmack icon_state = "rightsmack" @@ -302,94 +504,48 @@ Difficulty: Hard /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 +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination + name = "bubblegum's hallucination" + desc = "Is that really just a hallucination?" + health = 1 + maxHealth = 1 + alpha = 127.5 + crusher_loot = null + loot = null + medal_type = null + score_type = null + deathmessage = "Explodes into a pool of blood!" + death_sound = 'sound/effects/splat.ogg' + true_spawn = 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 +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Initialize(mapload) + . = ..() + toggle_ai(AI_OFF) - 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 = 5) - sleep(5) - qdel(DA) +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/charge(atom/chargeat = target, delay = 3, chargepast = 2) + ..() + qdel(src) - 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 - if(pools.len) - shuffle(pools) - found_bloodpool = pick(pools) - if(found_bloodpool) - visible_message("[src] sinks into the blood...") - playsound(get_turf(src), 'sound/misc/enter_blood.ogg', 100, 1, -1) - forceMove(get_turf(found_bloodpool)) - playsound(get_turf(src), 'sound/misc/exit_blood.ogg', 100, 1, -1) - visible_message("And springs back out!") +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/Destroy() + new /obj/effect/decal/cleanable/blood(get_turf(src)) + . = ..() + +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/CanPass(atom/movable/mover, turf/target) + if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum)) // hallucinations should not be stopping bubblegum or eachother return TRUE - return FALSE + return ..() -/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/hallucination/Life() + return -/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/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.CanAtmosPass(J)) - break - new /obj/effect/decal/cleanable/blood/bubblegum(J) - previousturf = J - sleep(1) +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/adjustBruteLoss(amount, updating_health = TRUE) + return -/obj/effect/decal/cleanable/blood/bubblegum - amount = 0 +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/OpenFire() + return -/obj/effect/decal/cleanable/blood/bubblegum/can_bloodcrawl_in() - return TRUE +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/AttackingTarget() + return -/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/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." - 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 +/mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination/try_bloodattack() + return \ No newline at end of file diff --git a/code/modules/surgery/organs/helpers.dm b/code/modules/surgery/organs/helpers.dm index fb1167edb01..91bba8d4a1b 100644 --- a/code/modules/surgery/organs/helpers.dm +++ b/code/modules/surgery/organs/helpers.dm @@ -10,6 +10,9 @@ /mob/proc/get_int_organ_tag(tag) //is it a brain, is it a brain_tumor? return +/mob/living/proc/get_organ(zone) + return + /mob/living/carbon/get_int_organ(typepath) return (locate(typepath) in internal_organs)