diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index 76de4ac8079fe8..4ad06155f6c9a1 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 9d31f2b5d37a7d..1efaa5921a31eb 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 f3f18f9435533b..c0bd9d1323bae5 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 00000000000000..bff2ea7ea8f635 --- /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 902b522cafcca3..1e4d10a7dd56e3 100644 --- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm +++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm @@ -42,12 +42,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(/obj/structure/flora/rock/icy/style_random = 6, /obj/structure/flora/rock/pile/icy/style_random = 6, /obj/structure/flora/ash/chilly = 1) diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm index a6ce5142c85735..c95eeedf12605b 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) 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 00000000000000..465d724944b2f9 --- /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 00000000000000..fa42958f9a00e8 --- /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 00000000000000..08c5fda3fd89e0 --- /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 123f26f69e4ff6..00000000000000 --- 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/tgstation.dme b/tgstation.dme index 3440afc117e6eb..d5a09d4f3c897b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1080,6 +1080,8 @@ #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" #include "code\datums\components\tippable.dm" @@ -3983,6 +3985,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" @@ -4314,7 +4319,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 00000000000000..a454c9785ca2cb --- /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