Skip to content

Commit

Permalink
basic ice whelps (tgstation#77493)
Browse files Browse the repository at this point in the history
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.

basic mob refactor

: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:
  • Loading branch information
SMOSMOSMOSMOSMO authored and dwasint committed Aug 22, 2023
1 parent 90f1dd1 commit 6c5c8c9
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 60 deletions.
14 changes: 14 additions & 0 deletions code/__DEFINES/ai/monsters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion code/datums/actions/cooldown_action.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
50 changes: 50 additions & 0 deletions code/datums/components/telegraph_ability.dm
Original file line number Diff line number Diff line change
@@ -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
6 changes: 3 additions & 3 deletions code/datums/mapgen/Cavegens/IcemoonCaves.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion code/game/objects/structures/icemoon/cave_entrance.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
88 changes: 88 additions & 0 deletions code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 6c5c8c9

Please sign in to comment.