mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
244 lines
9.5 KiB
Plaintext
244 lines
9.5 KiB
Plaintext
/// Slow moving mob which attempts to immobilise its target
|
|
/mob/living/basic/mining/goliath
|
|
name = "goliath"
|
|
desc = "A hulking, armor-plated beast with long tendrils arching from its back."
|
|
icon = 'icons/mob/simple/lavaland/lavaland_monsters_wide.dmi'
|
|
icon_state = "goliath"
|
|
icon_living = "goliath"
|
|
icon_dead = "goliath_dead"
|
|
pixel_x = -12
|
|
base_pixel_x = -12
|
|
gender = MALE // Female ones are the bipedal elites
|
|
speed = 30
|
|
basic_mob_flags = IMMUNE_TO_FISTS
|
|
maxHealth = 300
|
|
health = 300
|
|
friendly_verb_continuous = "wails at"
|
|
friendly_verb_simple = "wail at"
|
|
speak_emote = list("bellows")
|
|
obj_damage = 100
|
|
melee_damage_lower = 25
|
|
melee_damage_upper = 25
|
|
attack_sound = 'sound/items/weapons/punch1.ogg'
|
|
attack_verb_continuous = "pulverizes"
|
|
attack_verb_simple = "pulverize"
|
|
throw_blocked_message = "does nothing to the tough hide of"
|
|
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/goliath
|
|
|
|
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
|
|
butcher_results = list(/obj/item/food/meat/slab/goliath = 2, /obj/item/stack/sheet/bone = 2)
|
|
guaranteed_butcher_results = list(/obj/item/stack/sheet/animalhide/goliath_hide = 1)
|
|
/// Icon state to use when tentacles are available
|
|
var/tentacle_warning_state = "goliath_preattack"
|
|
/// Can this kind of goliath be tamed?
|
|
var/tameable = TRUE
|
|
/// Has this particular goliath been tamed?
|
|
var/tamed = FALSE
|
|
/// Can someone ride us around like a horse?
|
|
var/saddled = FALSE
|
|
/// Slight cooldown to prevent double-dipping if we use both abilities at once
|
|
COOLDOWN_DECLARE(ability_animation_cooldown)
|
|
/// Our base tentacles ability
|
|
var/datum/action/cooldown/mob_cooldown/goliath_tentacles/tentacles
|
|
/// Our melee tentacles ability
|
|
var/datum/action/cooldown/mob_cooldown/tentacle_burst/melee_tentacles
|
|
/// Our long-ranged tentacles ability
|
|
var/datum/action/cooldown/mob_cooldown/tentacle_grasp/tentacle_line
|
|
/// Things we want to eat off the floor (or a plate, we're not picky)
|
|
var/static/list/goliath_foods = list(/obj/item/food/grown/ash_flora, /obj/item/food/bait/worm)
|
|
|
|
/mob/living/basic/mining/goliath/Initialize(mapload)
|
|
. = ..()
|
|
ADD_TRAIT(src, TRAIT_TENTACLE_IMMUNE, INNATE_TRAIT)
|
|
AddElement(/datum/element/ai_retaliate)
|
|
AddElement(/datum/element/footstep, FOOTSTEP_MOB_HEAVY)
|
|
AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = goliath_foods)
|
|
AddElement(\
|
|
/datum/element/change_force_on_death,\
|
|
move_force = MOVE_FORCE_DEFAULT,\
|
|
move_resist = MOVE_RESIST_DEFAULT,\
|
|
pull_force = PULL_FORCE_DEFAULT,\
|
|
)
|
|
|
|
AddComponent(/datum/component/ai_target_timer)
|
|
AddComponentFrom(INNATE_TRAIT, /datum/component/shovel_hands)
|
|
if (tameable)
|
|
AddComponent(/datum/component/tameable, tame_chance = 10, bonus_tame_chance = 5)
|
|
|
|
tentacles = new (src)
|
|
tentacles.Grant(src)
|
|
melee_tentacles = new(src)
|
|
melee_tentacles.Grant(src)
|
|
AddComponent(/datum/component/revenge_ability, melee_tentacles, targeting = GET_TARGETING_STRATEGY(ai_controller.blackboard[BB_TARGETING_STRATEGY]), max_range = 1, target_self = TRUE)
|
|
tentacle_line = new (src)
|
|
tentacle_line.Grant(src)
|
|
AddComponent(/datum/component/revenge_ability, tentacle_line, targeting = GET_TARGETING_STRATEGY(ai_controller.blackboard[BB_TARGETING_STRATEGY]), min_range = 2, max_range = 9)
|
|
|
|
tentacles_ready()
|
|
RegisterSignal(src, COMSIG_MOB_ABILITY_FINISHED, PROC_REF(used_ability))
|
|
ai_controller.set_blackboard_key(BB_BASIC_FOODS, typecacheof(goliath_foods))
|
|
ai_controller.set_blackboard_key(BB_GOLIATH_TENTACLES, tentacles)
|
|
update_appearance(UPDATE_OVERLAYS)
|
|
|
|
/mob/living/basic/mining/goliath/Destroy()
|
|
QDEL_NULL(tentacles)
|
|
QDEL_NULL(melee_tentacles)
|
|
QDEL_NULL(tentacle_line)
|
|
return ..()
|
|
|
|
/mob/living/basic/mining/goliath/examine(mob/user)
|
|
. = ..()
|
|
if (saddled)
|
|
. += span_info("Someone appears to have attached a saddle to this one.")
|
|
|
|
// Goliaths can summon tentacles more frequently as they take damage, scary.
|
|
/mob/living/basic/mining/goliath/apply_damage(damage, damagetype, def_zone, blocked, forced, spread_damage, wound_bonus, exposed_wound_bonus, sharpness, attack_direction, attacking_item)
|
|
. = ..()
|
|
if (. <= 0)
|
|
return
|
|
if (tentacles.cooldown_time > 1 SECONDS)
|
|
tentacles.cooldown_time -= 1 SECONDS
|
|
|
|
/mob/living/basic/mining/goliath/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
|
|
if (!istype(attacking_item, /obj/item/goliath_saddle))
|
|
return ..()
|
|
if (!tameable)
|
|
balloon_alert(user, "doesn't fit!")
|
|
return
|
|
if (saddled)
|
|
balloon_alert(user, "already saddled!")
|
|
return
|
|
if (!tamed)
|
|
balloon_alert(user, "too rowdy!")
|
|
return
|
|
balloon_alert(user, "affixing saddle...")
|
|
if (!do_after(user, delay = 5.5 SECONDS, target = src))
|
|
return
|
|
balloon_alert(user, "ready to ride")
|
|
qdel(attacking_item)
|
|
make_rideable()
|
|
|
|
/mob/living/basic/mining/goliath/proc/make_rideable()
|
|
saddled = TRUE
|
|
add_overlay("goliath_saddled")
|
|
AddElement(/datum/element/ridable, /datum/component/riding/creature/goliath)
|
|
|
|
/// When we use an ability, activate some kind of visual tell
|
|
/mob/living/basic/mining/goliath/proc/used_ability(mob/living/source, datum/action/cooldown/ability)
|
|
SIGNAL_HANDLER
|
|
if (stat == DEAD || ability.IsAvailable())
|
|
return // We died or the action failed for some reason like being out of range
|
|
if (istype(ability, /datum/action/cooldown/mob_cooldown/goliath_tentacles))
|
|
if (ability.cooldown_time <= 2 SECONDS)
|
|
return
|
|
icon_state = icon_living
|
|
addtimer(CALLBACK(src, PROC_REF(tentacles_ready)), ability.cooldown_time - 2 SECONDS, TIMER_DELETE_ME)
|
|
return
|
|
if (!COOLDOWN_FINISHED(src, ability_animation_cooldown))
|
|
return
|
|
COOLDOWN_START(src, ability_animation_cooldown, 2 SECONDS)
|
|
playsound(src, 'sound/effects/magic/demon_attack1.ogg', vol = 50, vary = TRUE)
|
|
Shake(1, 0, 1.5 SECONDS)
|
|
|
|
/// Called slightly before tentacles ability comes off cooldown, as a warning
|
|
/mob/living/basic/mining/goliath/proc/tentacles_ready()
|
|
if (stat == DEAD)
|
|
return
|
|
icon_state = tentacle_warning_state
|
|
|
|
/// Get ready for mounting
|
|
/mob/living/basic/mining/goliath/tamed(mob/living/tamer, atom/food)
|
|
tamed = TRUE
|
|
|
|
// Copy entire faction rather than just placing user into faction, to avoid tentacle peril on station
|
|
/mob/living/basic/mining/goliath/befriend(mob/living/new_friend)
|
|
. = ..()
|
|
if(isnull(.))
|
|
return
|
|
faction = new_friend.faction.Copy()
|
|
|
|
/mob/living/basic/mining/goliath/RangedAttack(atom/atom_target, modifiers)
|
|
tentacles?.Trigger(target = atom_target)
|
|
|
|
/mob/living/basic/mining/goliath/ranged_secondary_attack(atom/atom_target, modifiers)
|
|
tentacle_line?.Trigger(target = atom_target)
|
|
|
|
/mob/living/basic/mining/goliath/update_overlays()
|
|
. = ..()
|
|
if (stat != DEAD)
|
|
. += emissive_appearance(icon, "[icon_living]_e", src, effect_type = EMISSIVE_NO_BLOOM)
|
|
|
|
/// Version of the goliath that already starts saddled and doesn't require a lasso to be ridden.
|
|
/mob/living/basic/mining/goliath/deathmatch
|
|
saddled = TRUE
|
|
buckle_lying = 0
|
|
|
|
/mob/living/basic/mining/goliath/deathmatch/Initialize(mapload)
|
|
. = ..()
|
|
make_rideable()
|
|
|
|
/mob/living/basic/mining/goliath/deathmatch/make_rideable()
|
|
add_overlay("goliath_saddled")
|
|
AddElement(/datum/element/ridable, /datum/component/riding/creature/goliath/deathmatch)
|
|
|
|
/// Legacy Goliath mob with different sprites, largely the same behaviour
|
|
/mob/living/basic/mining/goliath/ancient
|
|
name = "ancient goliath"
|
|
desc = "A massive beast that uses long tentacles to ensnare its prey, threatening them is not advised under any conditions."
|
|
icon = 'icons/mob/simple/lavaland/lavaland_monsters_wide.dmi'
|
|
icon_state = "ancient_goliath"
|
|
icon_living = "ancient_goliath"
|
|
icon_dead = "ancient_goliath_dead"
|
|
tentacle_warning_state = "ancient_goliath_preattack"
|
|
tameable = FALSE
|
|
|
|
/// Rare Goliath variant which occasionally replaces the normal mining mob, releases shitloads of tentacles
|
|
/mob/living/basic/mining/goliath/ancient/immortal
|
|
name = "immortal goliath"
|
|
desc = "Goliaths are biologically immortal, and rare specimens have survived for centuries. \
|
|
This one is clearly ancient, and its tentacles constantly churn the earth around it."
|
|
maxHealth = 400
|
|
health = 400
|
|
crusher_drop_chance = 30 // Wow a whole 5% more likely, how generous
|
|
/// Don't re-check nearby turfs for this long
|
|
COOLDOWN_DECLARE(retarget_turfs_cooldown)
|
|
/// List of places we might spawn a tentacle, if we're alive
|
|
var/list/tentacle_target_turfs
|
|
|
|
/mob/living/basic/mining/goliath/ancient/immortal/Life(seconds_per_tick, times_fired)
|
|
. = ..()
|
|
if (!. || !isturf(loc))
|
|
return
|
|
if (!LAZYLEN(tentacle_target_turfs) || COOLDOWN_FINISHED(src, retarget_turfs_cooldown))
|
|
cache_nearby_turfs()
|
|
for (var/turf/target_turf in tentacle_target_turfs)
|
|
if (target_turf.is_blocked_turf(exclude_mobs = TRUE))
|
|
tentacle_target_turfs -= target_turf
|
|
continue
|
|
if (prob(10))
|
|
new /obj/effect/goliath_tentacle(target_turf)
|
|
|
|
/mob/living/basic/mining/goliath/ancient/immortal/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
|
|
. = ..()
|
|
if (loc == old_loc || stat == DEAD || !isturf(loc))
|
|
return
|
|
cache_nearby_turfs()
|
|
|
|
/// Store nearby turfs in our list so we can pop them out later
|
|
/mob/living/basic/mining/goliath/ancient/immortal/proc/cache_nearby_turfs()
|
|
COOLDOWN_START(src, retarget_turfs_cooldown, 10 SECONDS)
|
|
LAZYCLEARLIST(tentacle_target_turfs)
|
|
for(var/turf/open/floor in orange(4, loc))
|
|
LAZYADD(tentacle_target_turfs, floor)
|
|
|
|
/// Use this to ride a goliath
|
|
/obj/item/goliath_saddle
|
|
name = "goliath saddle"
|
|
desc = "This rough saddle will give you a serviceable seat upon a goliath! Provided you can get one to stand still."
|
|
icon = 'icons/obj/mining.dmi'
|
|
icon_state = "goliath_saddle"
|