From 15c3cd2c97c8ce2b4dafa58d47b7f0273a9a2135 Mon Sep 17 00:00:00 2001 From: SMOSMOSMOSMOSMO <95004236+SmoSmoSmoSmok@users.noreply.github.com> Date: Mon, 14 Aug 2023 21:39:30 +0300 Subject: [PATCH] basic ice whelps (#77493) ## About The Pull Request i have refactored ice whelps into basic mobs. They are now the artistic sort as theyll mark their territory by seeking out icy rocks and carve out statues of theirselves using their claws to serve as a warning to players/animals that this is dragon turf and theyll also go out of their way to burn any trees in vicinity just for the hell of it. they are now gruesome cannibals if they find a corpse of one of their kin near them theyll go eat it for nurishment. AS for combat, they have a new ability which allows them to release fire in all directions however theyll only use this ability once their enraged meter is full. to make it fair ive given them a new component which allows them to telegraph abilities and only do them after a delay so players can react in time for it. ## Why It's Good For The Game basic mob refactor ## Changelog :cl: refactor: ice whelps have been refactored to basic mobs add: ice whelps have a new dangerous ability which theyll use once their enraged meter is full /:cl: --- code/__DEFINES/ai/monsters.dm | 14 ++ code/datums/actions/cooldown_action.dm | 2 +- .../targeted_mob_ability.dm | 5 +- code/datums/components/telegraph_ability.dm | 50 +++++ code/datums/mapgen/Cavegens/IcemoonCaves.dm | 6 +- .../structures/icemoon/cave_entrance.dm | 2 +- .../basic/icemoon/ice_whelp/ice_whelp.dm | 88 +++++++++ .../icemoon/ice_whelp/ice_whelp_abilities.dm | 36 ++++ .../basic/icemoon/ice_whelp/ice_whelp_ai.dm | 182 ++++++++++++++++++ .../hostile/mining_mobs/ice_whelp.dm | 53 ----- .../unit_tests/simple_animal_freeze.dm | 1 - tgstation.dme | 5 +- .../UpdatePaths/Scripts/77489_ice_whelps.txt | 1 + 13 files changed, 384 insertions(+), 61 deletions(-) create mode 100644 code/datums/components/telegraph_ability.dm create mode 100644 code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm create mode 100644 code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_abilities.dm create mode 100644 code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm delete mode 100644 code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm create mode 100644 tools/UpdatePaths/Scripts/77489_ice_whelps.txt diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 76de4ac8079..4ad06155f6c 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -71,3 +71,17 @@ #define BB_MACHINE_TARGET "BB_machine_target" ///the hivebot partner we will go communicate with #define BB_HIVE_PARTNER "BB_hive_partner" + +// Ice Whelps +///whelp's straight line fire ability +#define BB_WHELP_STRAIGHTLINE_FIRE "BB_whelp_straightline_fire" +///whelp's secondary enraged ability +#define BB_WHELP_WIDESPREAD_FIRE "BB_whelp_widespread_fire" +///how enraged the whelp is +#define BB_WHELP_ENRAGED "BB_whelp_enraged" +///the target rock we will attempt to create a sculpture out of +#define BB_TARGET_ROCK "BB_target_rock" +///the cannibal target we shall consume +#define BB_TARGET_CANNIBAL "BB_target_cannibal" +///the tree we will burn down +#define BB_TARGET_TREE "BB_target_tree" diff --git a/code/datums/actions/cooldown_action.dm b/code/datums/actions/cooldown_action.dm index 29bf2ff48ca..35539b7424f 100644 --- a/code/datums/actions/cooldown_action.dm +++ b/code/datums/actions/cooldown_action.dm @@ -238,7 +238,7 @@ /// For signal calling /datum/action/cooldown/proc/PreActivate(atom/target) - if(SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_STARTED, src) & COMPONENT_BLOCK_ABILITY_START) + if(SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_STARTED, src, target) & COMPONENT_BLOCK_ABILITY_START) return // Note, that PreActivate handles no cooldowns at all by default. // Be sure to call StartCooldown() in Activate() where necessary. diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm index f3f18f94355..c0bd9d1323b 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm @@ -5,7 +5,7 @@ /datum/ai_behavior/targeted_mob_ability /datum/ai_behavior/targeted_mob_ability/perform(seconds_per_tick, datum/ai_controller/controller, ability_key, target_key) - var/datum/action/cooldown/ability = controller.blackboard[ability_key] + var/datum/action/cooldown/ability = get_ability_to_use(controller, ability_key) var/mob/living/target = controller.blackboard[target_key] if(QDELETED(ability) || QDELETED(target)) finish_action(controller, FALSE, ability_key, target_key) @@ -26,6 +26,9 @@ if(living_target.stat >= UNCONSCIOUS) controller.clear_blackboard_key(target_key) +/datum/ai_behavior/targeted_mob_ability/proc/get_ability_to_use(datum/ai_controller/controller, ability_key) + return controller.blackboard[ability_key] + /** * # Try Mob Ability and plan execute * Attempts to use a mob's cooldown ability on a target and then move the target into a special target blackboard datum diff --git a/code/datums/components/telegraph_ability.dm b/code/datums/components/telegraph_ability.dm new file mode 100644 index 00000000000..bff2ea7ea8f --- /dev/null +++ b/code/datums/components/telegraph_ability.dm @@ -0,0 +1,50 @@ +/** + * Component given to creatures to telegraph their abilities! + */ +/datum/component/basic_mob_ability_telegraph + /// how long before we use our attack + var/telegraph_time + /// sound to play, if any + var/sound_path + /// are we currently telegraphing + var/currently_telegraphing = FALSE + +/datum/component/basic_mob_ability_telegraph/Initialize(telegraph_time = 1 SECONDS, sound_path) + + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + src.telegraph_time = telegraph_time + src.sound_path = sound_path + +/datum/component/basic_mob_ability_telegraph/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_ABILITY_STARTED, PROC_REF(on_ability_activate)) + +/datum/component/basic_mob_ability_telegraph/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOB_ABILITY_STARTED) + +///delay the ability +/datum/component/basic_mob_ability_telegraph/proc/on_ability_activate(mob/living/source, datum/action/cooldown/activated, atom/target) + SIGNAL_HANDLER + + if(currently_telegraphing) + return COMPONENT_BLOCK_ABILITY_START + + if(!activated.IsAvailable()) + return + + currently_telegraphing = TRUE + generate_tell_signs(source) + addtimer(CALLBACK(src, PROC_REF(use_ability), source, activated, target), telegraph_time) + return COMPONENT_BLOCK_ABILITY_START + +///generates the telegraph signs to inform the player we're about to launch an attack +/datum/component/basic_mob_ability_telegraph/proc/generate_tell_signs(mob/living/source) + if(sound_path) + playsound(source, sound_path, 50, FALSE) + source.Shake(duration = telegraph_time) + +///use the ability +/datum/component/basic_mob_ability_telegraph/proc/use_ability(mob/living/source, datum/action/cooldown/activated, atom/target) + if(!QDELETED(target) && source.stat != DEAD) //target is gone or we died + activated.Activate(target) + currently_telegraphing = FALSE diff --git a/code/datums/mapgen/Cavegens/IcemoonCaves.dm b/code/datums/mapgen/Cavegens/IcemoonCaves.dm index 8e94c9563bd..fcb4e1d712e 100644 --- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm +++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm @@ -62,12 +62,12 @@ weighted_closed_turf_types = list(/turf/closed/mineral/random/snow/underground = 1) weighted_mob_spawn_list = list( SPAWN_MEGAFAUNA = 1, - /mob/living/simple_animal/hostile/asteroid/ice_demon = 100, - /mob/living/simple_animal/hostile/asteroid/ice_whelp = 60, + /mob/living/basic/mining/ice_whelp = 60, /mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 100, + /mob/living/simple_animal/hostile/asteroid/ice_demon = 100, /obj/structure/spawner/ice_moon/demonic_portal = 6, - /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 6, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 6, + /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 6, ) weighted_megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/colossus = 1) weighted_flora_spawn_list = list( diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm index f5d6115f86c..ded6851914b 100644 --- a/code/game/objects/structures/icemoon/cave_entrance.dm +++ b/code/game/objects/structures/icemoon/cave_entrance.dm @@ -99,7 +99,7 @@ GLOBAL_LIST_INIT(ore_probability, list( return /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp - mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_whelp) + mob_types = list(/mob/living/basic/mining/ice_whelp) /obj/structure/spawner/ice_moon/demonic_portal/snowlegion mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow/portal) diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm new file mode 100644 index 00000000000..465d724944b --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm @@ -0,0 +1,88 @@ +/mob/living/basic/mining/ice_whelp + name = "ice whelp" + desc = "The offspring of an ice drake, weak in comparison but still terrifying." + icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + icon_state = "ice_whelp" + icon_living = "ice_whelp" + icon_dead = "ice_whelp_dead" + mob_biotypes = MOB_ORGANIC|MOB_BEAST + mouse_opacity = MOUSE_OPACITY_ICON + butcher_results = list( + /obj/item/stack/ore/diamond = 3, + /obj/item/stack/sheet/animalhide/ashdrake = 1, + /obj/item/stack/sheet/bone = 10, + /obj/item/stack/sheet/sinew = 2, + ) + crusher_loot = /obj/item/crusher_trophy/tail_spike + speed = 12 + + maxHealth = 300 + health = 300 + obj_damage = 40 + armour_penetration = 20 + melee_damage_lower = 20 + melee_damage_upper = 20 + + attack_verb_continuous = "chomps" + attack_verb_simple = "chomp" + death_message = "collapses on its side." + death_sound = 'sound/magic/demon_dies.ogg' + + attack_sound = 'sound/magic/demon_attack1.ogg' + move_force = MOVE_FORCE_VERY_STRONG + move_resist = MOVE_FORCE_VERY_STRONG + pull_force = MOVE_FORCE_VERY_STRONG + + ai_controller = /datum/ai_controller/basic_controller/ice_whelp + ///how much we will heal when cannibalizing a target + var/heal_on_cannibalize = 5 + +/mob/living/basic/mining/ice_whelp/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_NO_GLIDE, INNATE_TRAIT) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_HEAVY) + AddComponent(/datum/component/basic_mob_ability_telegraph) + AddComponent(/datum/component/basic_mob_attack_telegraph, telegraph_duration = 0.6 SECONDS) + var/datum/action/cooldown/mob_cooldown/ice_breath/flamethrower = new(src) + var/datum/action/cooldown/mob_cooldown/ice_breathe_all_directions/wide_flames = new(src) + flamethrower.Grant(src) + wide_flames.Grant(src) + ai_controller.set_blackboard_key(BB_WHELP_WIDESPREAD_FIRE, wide_flames) + ai_controller.set_blackboard_key(BB_WHELP_STRAIGHTLINE_FIRE, flamethrower) + RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack)) + + +/mob/living/basic/mining/ice_whelp/proc/pre_attack(mob/living/sculptor, atom/target) + SIGNAL_HANDLER + + if(istype(target, /obj/structure/flora/rock/icy)) + INVOKE_ASYNC(src, PROC_REF(create_sculpture), target) + return COMPONENT_HOSTILE_NO_ATTACK + + if(!istype(target, src.type)) + return + + var/mob/living/victim = target + if(victim.stat != DEAD) + return + + INVOKE_ASYNC(src, PROC_REF(cannibalize_victim), victim) + return COMPONENT_HOSTILE_NO_ATTACK + +/mob/living/basic/mining/ice_whelp/proc/create_sculpture(atom/target) + balloon_alert(src, "sculpting...") + if(!do_after(src, 5 SECONDS, target = target)) + return + var/obj/structure/statue/custom/dragon_statue = new(get_turf(target)) + dragon_statue.set_visuals(src) + dragon_statue.name = "statue of [src]" + dragon_statue.desc = "Let this serve as a warning." + dragon_statue.set_anchored(TRUE) + qdel(target) + +/mob/living/basic/mining/ice_whelp/proc/cannibalize_victim(mob/living/target) + balloon_alert(src, "devouring...") + if(!do_after(src, 5 SECONDS, target)) + return + target.gib() + adjustBruteLoss(-1 * heal_on_cannibalize) diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_abilities.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_abilities.dm new file mode 100644 index 00000000000..fa42958f9a0 --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_abilities.dm @@ -0,0 +1,36 @@ +/datum/action/cooldown/mob_cooldown/ice_breath + name = "Ice Breath" + desc = "Fire a cold line of fire towards the enemy!" + button_icon = 'icons/effects/magic.dmi' + button_icon_state = "fireball" + cooldown_time = 3 SECONDS + melee_cooldown_time = 0 SECONDS + click_to_activate = TRUE + ///the range of fire + var/fire_range = 4 + +/datum/action/cooldown/mob_cooldown/ice_breath/Activate(atom/target_atom) + var/turf/target_fire_turf = get_ranged_target_turf_direct(owner, target_atom, fire_range) + var/list/burn_turfs = get_line(owner, target_fire_turf) - get_turf(owner) + dragon_fire_line(owner, burn_turfs, frozen = TRUE) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/ice_breathe_all_directions + name = "Fire all directions" + desc = "Unleash lines of cold fire in all directions" + button_icon = 'icons/effects/fire.dmi' + button_icon_state = "1" + cooldown_time = 4 SECONDS + melee_cooldown_time = 0 SECONDS + click_to_activate = FALSE + ///the range of fire + var/fire_range = 6 + +/datum/action/cooldown/mob_cooldown/ice_breathe_all_directions/Activate(atom/target_atom) + for(var/direction in GLOB.cardinals) + var/turf/target_fire_turf = get_ranged_target_turf(owner, direction, fire_range) + var/list/burn_turfs = get_line(owner, target_fire_turf) - get_turf(owner) + INVOKE_ASYNC(GLOBAL_PROC, GLOBAL_PROC_REF(dragon_fire_line), owner, burn_turfs, frozen = TRUE) + StartCooldown() + return TRUE diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm new file mode 100644 index 00000000000..08c5fda3fd8 --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm @@ -0,0 +1,182 @@ +#define ENRAGE_ADDITION 25 +/datum/ai_controller/basic_controller/ice_whelp + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items/goliath, + BB_WHELP_ENRAGED = 0, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability/ice_whelp, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/sculpt_statues, + /datum/ai_planning_subtree/find_and_hunt_target/cannibalize, + /datum/ai_planning_subtree/burn_trees, + ) + + +/datum/ai_planning_subtree/find_and_hunt_target/cannibalize + target_key = BB_TARGET_CANNIBAL + hunting_behavior = /datum/ai_behavior/cannibalize + finding_behavior = /datum/ai_behavior/find_hunt_target/dragon_corpse + hunt_targets = list(/mob/living/basic/mining/ice_whelp) + hunt_range = 10 + +/datum/ai_behavior/find_hunt_target/dragon_corpse + +/datum/ai_behavior/find_hunt_target/dragon_corpse/valid_dinner(mob/living/source, mob/living/dinner, radius) + if(dinner.stat != DEAD) + return FALSE + if(dinner.pulledby) //someone already got him before us + return FALSE + + return can_see(source, dinner, radius) + +/datum/ai_behavior/cannibalize + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + +/datum/ai_behavior/cannibalize/setup(datum/ai_controller/controller, target_key) + . = ..() + var/atom/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +/datum/ai_behavior/cannibalize/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) + . = ..() + var/mob/living/basic/living_pawn = controller.pawn + var/mob/living/target = controller.blackboard[target_key] + + if(QDELETED(target)) + finish_action(controller, FALSE) + return + + if(target.stat != DEAD || target.pulledby) //we were too slow + finish_action(controller, FALSE) + return + + living_pawn.start_pulling(target) + living_pawn.melee_attack(target) + finish_action(controller, TRUE) + +/datum/ai_behavior/cannibalize/finish_action(datum/ai_controller/controller, succeeded, target_key) + . = ..() + controller.clear_blackboard_key(target_key) + +///subtree to find icy rocks and create sculptures out of them +/datum/ai_planning_subtree/sculpt_statues + +/datum/ai_planning_subtree/sculpt_statues/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/obj/target = controller.blackboard[BB_TARGET_ROCK] + + if(QDELETED(target)) + controller.queue_behavior(/datum/ai_behavior/find_and_set, BB_TARGET_ROCK, /obj/structure/flora/rock/icy) + return + + controller.queue_behavior(/datum/ai_behavior/sculpt_statue, BB_TARGET_ROCK) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/ai_behavior/sculpt_statue + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + action_cooldown = 5 MINUTES + +/datum/ai_behavior/sculpt_statue/setup(datum/ai_controller/controller, target_key) + . = ..() + var/obj/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +/datum/ai_behavior/sculpt_statue/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + . = ..() + + var/atom/target = controller.blackboard[target_key] + var/mob/living/basic/living_pawn = controller.pawn + + if(QDELETED(target)) + finish_action(controller, FALSE, target_key) + return + + living_pawn.melee_attack(target) + finish_action(controller, TRUE, target_key) + +/datum/ai_behavior/sculpt_statue/finish_action(datum/ai_controller/controller, succeeded, target_key) + . = ..() + controller.clear_blackboard_key(target_key) + + +//subtree to use our attacks on the victim +/datum/ai_planning_subtree/targeted_mob_ability/ice_whelp + ability_key = BB_WHELP_STRAIGHTLINE_FIRE + use_ability_behaviour = /datum/ai_behavior/targeted_mob_ability/ice_whelp + finish_planning = FALSE + + +/datum/ai_behavior/targeted_mob_ability/ice_whelp + ///key that stores how enraged we are + var/enraged_key = BB_WHELP_ENRAGED + ///key that stores the ability we will use instead if we are fully enraged + var/secondary_ability_key = BB_WHELP_WIDESPREAD_FIRE + +/datum/ai_behavior/targeted_mob_ability/ice_whelp/get_ability_to_use(datum/ai_controller/controller, ability_key) + var/enraged_value = controller.blackboard[enraged_key] + + if(prob(enraged_value)) + controller.set_blackboard_key(enraged_key, 0) + return controller.blackboard[secondary_ability_key] + + controller.set_blackboard_key(enraged_key, enraged_value + ENRAGE_ADDITION) + return controller.blackboard[ability_key] + +///subtree to look for trees and burn them with our flamethrower +/datum/ai_planning_subtree/burn_trees + +/datum/ai_planning_subtree/burn_trees/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/datum/action/cooldown/using_action = controller.blackboard[BB_WHELP_STRAIGHTLINE_FIRE] + if (!using_action.IsAvailable()) + return + + var/obj/structure/target = controller.blackboard[BB_TARGET_TREE] + if(QDELETED(target)) + controller.queue_behavior(/datum/ai_behavior/set_target_tree, BB_TARGET_TREE) + return + + controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees, BB_WHELP_STRAIGHTLINE_FIRE, BB_TARGET_TREE) + return SUBTREE_RETURN_FINISH_PLANNING + +/datum/ai_behavior/set_target_tree + +/datum/ai_behavior/set_target_tree/perform(seconds_per_tick, datum/ai_controller/controller, tree_key) + . = ..() + + var/mob/living_pawn = controller.pawn + var/list/possible_trees = list() + + for(var/obj/structure/flora/tree/possible_tree in oview(9, living_pawn)) + if(istype(possible_tree, /obj/structure/flora/tree/stump)) //no leaves to burn + continue + possible_trees += possible_tree + + if(!length(possible_trees)) + finish_action(controller, FALSE) + return + + controller.set_blackboard_key(tree_key, pick(possible_trees)) + finish_action(controller, TRUE) + +/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + required_distance = 2 + action_cooldown = 2 MINUTES + +/datum/ai_behavior/targeted_mob_ability/and_clear_target/burn_trees/setup(datum/ai_controller/controller, ability_key, target_key) + . = ..() + var/obj/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +#undef ENRAGE_ADDITION diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm deleted file mode 100644 index 123f26f69e4..00000000000 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_whelp.dm +++ /dev/null @@ -1,53 +0,0 @@ -/mob/living/simple_animal/hostile/asteroid/ice_whelp - name = "ice whelp" - desc = "The offspring of an ice drake, weak in comparison but still terrifying." - icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' - icon_state = "ice_whelp" - icon_living = "ice_whelp" - icon_dead = "ice_whelp_dead" - mob_biotypes = MOB_ORGANIC|MOB_BEAST - mouse_opacity = MOUSE_OPACITY_ICON - friendly_verb_continuous = "stares down" - friendly_verb_simple = "stare down" - speak_emote = list("roars") - speed = 12 - move_to_delay = 12 - ranged = TRUE - ranged_cooldown_time = 5 SECONDS - maxHealth = 300 - health = 300 - obj_damage = 40 - armour_penetration = 20 - melee_damage_lower = 20 - melee_damage_upper = 20 - attack_verb_continuous = "chomps" - attack_verb_simple = "chomp" - attack_sound = 'sound/magic/demon_attack1.ogg' - attack_vis_effect = ATTACK_EFFECT_BITE - ranged_message = "breathes fire at" - vision_range = 9 - aggro_vision_range = 9 - move_force = MOVE_FORCE_VERY_STRONG - move_resist = MOVE_FORCE_VERY_STRONG - pull_force = MOVE_FORCE_VERY_STRONG - butcher_results = list(/obj/item/stack/ore/diamond = 3, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 10, /obj/item/stack/sheet/animalhide/ashdrake = 1) - loot = list() - crusher_loot = /obj/item/crusher_trophy/tail_spike - death_message = "collapses on its side." - death_sound = 'sound/magic/demon_dies.ogg' - stat_attack = HARD_CRIT - robust_searching = TRUE - footstep_type = FOOTSTEP_MOB_CLAW - /// How far the whelps fire can go - var/fire_range = 4 - -/mob/living/simple_animal/hostile/asteroid/ice_whelp/Shoot() - var/turf/target_fire_turf = get_ranged_target_turf_direct(src, target, fire_range) - var/list/burn_turfs = get_line(src, target_fire_turf) - get_turf(src) - dragon_fire_line(src, burn_turfs, frozen = TRUE) - -/mob/living/simple_animal/hostile/asteroid/ice_whelp/death(gibbed) - move_force = MOVE_FORCE_DEFAULT - move_resist = MOVE_RESIST_DEFAULT - pull_force = PULL_FORCE_DEFAULT - return ..() diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index e0d36c22c96..1c5a574c8f5 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -84,7 +84,6 @@ /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/advanced, /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion/snow, /mob/living/simple_animal/hostile/asteroid/ice_demon, - /mob/living/simple_animal/hostile/asteroid/ice_whelp, /mob/living/simple_animal/hostile/asteroid/polarbear, /mob/living/simple_animal/hostile/asteroid/polarbear/lesser, /mob/living/simple_animal/hostile/asteroid/wolf, diff --git a/tgstation.dme b/tgstation.dme index 5b55d2788a3..0561fb1eac1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1074,6 +1074,7 @@ #include "code\datums\components\tattoo.dm" #include "code\datums\components\technointrovert.dm" #include "code\datums\components\technoshy.dm" +#include "code\datums\components\telegraph_ability.dm" #include "code\datums\components\temporary_body.dm" #include "code\datums\components\tether.dm" #include "code\datums\components\thermite.dm" @@ -4136,6 +4137,9 @@ #include "code\modules\mob\living\basic\farm_animals\cow\cow_wisdom.dm" #include "code\modules\mob\living\basic\heretic\fire_shark.dm" #include "code\modules\mob\living\basic\heretic\star_gazer.dm" +#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp.dm" +#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_abilities.dm" +#include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_ai.dm" #include "code\modules\mob\living\basic\lavaland\mining.dm" #include "code\modules\mob\living\basic\lavaland\bileworm\_bileworm.dm" #include "code\modules\mob\living\basic\lavaland\bileworm\bileworm_actions.dm" @@ -4473,7 +4477,6 @@ #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\hivelord.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm" -#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_whelp.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\wolf.dm" diff --git a/tools/UpdatePaths/Scripts/77489_ice_whelps.txt b/tools/UpdatePaths/Scripts/77489_ice_whelps.txt new file mode 100644 index 00000000000..a454c9785ca --- /dev/null +++ b/tools/UpdatePaths/Scripts/77489_ice_whelps.txt @@ -0,0 +1 @@ +/mob/living/simple_animal/hostile/asteroid/ice_whelp : /mob/living/basic/mining/ice_whelp{@OLD} \ No newline at end of file