mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 07:08:00 +01:00
Basic Faithless Mob (#72479)
## About The Pull Request Turns the faithless mob into a basic mob with unique behaviors, it will now break lights and drag around victims bodies. Can also punch open airlocks if they can be opened. ## Why It's Good For The Game Now the faithless mob has its own unique behavior and it is cool to see more AI variety. ## Changelog 🆑 add: Faithless will now also break lights and drag victims around refactor: Faithless into basic mob /🆑
This commit is contained in:
@@ -68,7 +68,7 @@ GLOBAL_LIST_INIT(phobia_mobs, list(
|
||||
/mob/living/simple_animal/bot/mulebot/paranormal,
|
||||
/mob/living/simple_animal/hostile/construct,
|
||||
/mob/living/simple_animal/hostile/dark_wizard,
|
||||
/mob/living/simple_animal/hostile/faithless,
|
||||
/mob/living/basic/faithless,
|
||||
/mob/living/simple_animal/hostile/heretic_summon,
|
||||
/mob/living/simple_animal/hostile/imp,
|
||||
/mob/living/simple_animal/hostile/retaliate/bat,
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
action_cooldown = 1 SECONDS
|
||||
/// If we should attack walls, be prepared for complaints about breaches
|
||||
var/can_attack_turfs = FALSE
|
||||
/// Tries to bump open airlocks with an attack
|
||||
var/bump_open_airlock = FALSE
|
||||
|
||||
/datum/ai_behavior/attack_obstructions/perform(delta_time, datum/ai_controller/controller, target_key)
|
||||
. = ..()
|
||||
@@ -76,3 +78,6 @@
|
||||
if (basic_mob.see_invisible < object.invisibility)
|
||||
return FALSE
|
||||
return TRUE // It's in our way, let's get it out of our way
|
||||
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path/low_priority_target
|
||||
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
|
||||
|
||||
@@ -106,3 +106,7 @@
|
||||
dog_pawn.update_dog_speech(src)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/ai_planning_subtree/random_speech/faithless
|
||||
speech_chance = 1
|
||||
emote_see = list("wails.")
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT
|
||||
/// How long do we have to wait after a successful hunt?
|
||||
var/hunt_cooldown = 5 SECONDS
|
||||
/// Do we reset the target after attacking something, so we can check for status changes.
|
||||
var/always_reset_target = FALSE
|
||||
|
||||
/datum/ai_behavior/hunt_target/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key)
|
||||
. = ..()
|
||||
@@ -118,6 +120,8 @@
|
||||
controller.blackboard[hunting_cooldown_key] = world.time + hunt_cooldown
|
||||
else if(hunting_target_key)
|
||||
controller.blackboard[hunting_target_key] = null
|
||||
if(always_reset_target && hunting_target_key)
|
||||
controller.blackboard[hunting_target_key] = null
|
||||
|
||||
/datum/ai_behavior/hunt_target/unarmed_attack_target
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures
|
||||
target_key = BB_LOW_PRIORITY_HUNTING_TARGET
|
||||
finding_behavior = /datum/ai_behavior/find_hunt_target/light_fixtures
|
||||
hunting_behavior = /datum/ai_behavior/hunt_target/light_fixtures
|
||||
hunt_targets = list(/obj/machinery/light)
|
||||
hunt_range = 7
|
||||
|
||||
/datum/ai_behavior/hunt_target/light_fixtures
|
||||
hunt_cooldown = 10 SECONDS
|
||||
always_reset_target = TRUE
|
||||
|
||||
/datum/ai_behavior/hunt_target/light_fixtures/target_caught(mob/living/hunter, obj/machinery/light/hunted)
|
||||
hunter.UnarmedAttack(hunted, TRUE)
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/light_fixtures
|
||||
|
||||
/datum/ai_behavior/find_hunt_target/light_fixtures/valid_dinner(mob/living/source, obj/machinery/light/dinner, radius)
|
||||
if(istype(dinner, /obj/machinery/light))
|
||||
var/obj/machinery/light/light_target = dinner
|
||||
if(light_target.status == LIGHT_BROKEN) //light is already broken
|
||||
return FALSE
|
||||
|
||||
return can_see(source, dinner, radius)
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Attached to a basic mob.
|
||||
* Causes attacks on doors to attempt to open them.
|
||||
*/
|
||||
/datum/component/pry_open_door
|
||||
/// Odds the attack opens the door
|
||||
var/open_chance
|
||||
/// Time it takes to open a door with force
|
||||
var/force_wait
|
||||
|
||||
/datum/component/pry_open_door/Initialize(open_chance = 100, force_wait = 10 SECONDS)
|
||||
. = ..()
|
||||
|
||||
if(!isbasicmob(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
src.open_chance = open_chance
|
||||
src.force_wait = force_wait
|
||||
|
||||
/datum/component/pry_open_door/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(hostile_attackingtarget))
|
||||
|
||||
/datum/component/pry_open_door/UnregisterFromParent()
|
||||
UnregisterSignal(parent, COMSIG_HOSTILE_POST_ATTACKINGTARGET)
|
||||
|
||||
/datum/component/pry_open_door/proc/hostile_attackingtarget(mob/living/basic/attacker, atom/target, success)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(!success)
|
||||
return
|
||||
if(istype(target, /obj/machinery/door/airlock) && prob(open_chance))
|
||||
var/obj/machinery/door/airlock/airlock_target = target
|
||||
INVOKE_ASYNC(src, PROC_REF(open_door), attacker, airlock_target)
|
||||
|
||||
/datum/component/pry_open_door/proc/open_door(mob/living/basic/attacker, obj/machinery/door/airlock/airlock_target)
|
||||
if(airlock_target.locked)
|
||||
to_chat(attacker, span_warning("The airlock's bolts prevent it from being forced!"))
|
||||
return
|
||||
else if(!airlock_target.allowed(attacker) && airlock_target.hasPower())
|
||||
attacker.visible_message(span_warning("We start forcing the [airlock_target] open."), \
|
||||
span_hear("You hear a metal screeching sound."))
|
||||
playsound(airlock_target, 'sound/machines/airlock_alien_prying.ogg', 100, TRUE)
|
||||
if(!do_after(attacker, force_wait, airlock_target))
|
||||
return
|
||||
if(airlock_target.locked)
|
||||
return
|
||||
attacker.visible_message(span_warning("We force the [airlock_target] to open."))
|
||||
airlock_target.open(2)
|
||||
else if(!airlock_target.hasPower())
|
||||
attacker.visible_message(span_warning("We force the [airlock_target] to open."))
|
||||
airlock_target.open(1)
|
||||
else
|
||||
airlock_target.open(0)
|
||||
@@ -0,0 +1,84 @@
|
||||
/mob/living/basic/faithless
|
||||
name = "The Faithless"
|
||||
desc = "The Wish Granter's faith in humanity, incarnate."
|
||||
icon_state = "faithless"
|
||||
icon_living = "faithless"
|
||||
icon_dead = "faithless_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
gender = MALE
|
||||
response_help_continuous = "passes through"
|
||||
response_help_simple = "pass through"
|
||||
speed = 0.5
|
||||
maxHealth = 80
|
||||
health = 80
|
||||
|
||||
obj_damage = 50
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attack_verb_continuous = "grips"
|
||||
attack_verb_simple = "grip"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
speak_emote = list("growls")
|
||||
|
||||
unsuitable_atmos_damage = 0
|
||||
unsuitable_cold_damage = 0
|
||||
unsuitable_heat_damage = 0
|
||||
|
||||
faction = list("faithless")
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
ai_controller = /datum/ai_controller/basic_controller/faithless
|
||||
|
||||
/mob/living/basic/faithless/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
|
||||
AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE)
|
||||
AddComponent(/datum/component/pry_open_door)
|
||||
|
||||
/datum/ai_controller/basic_controller/faithless
|
||||
blackboard = list(
|
||||
BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/faithless(),
|
||||
BB_LOW_PRIORITY_HUNTING_TARGET = null, // lights
|
||||
)
|
||||
|
||||
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/attack_obstacle_in_path,
|
||||
/datum/ai_planning_subtree/attack_obstacle_in_path/low_priority_target,
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree/faithless,
|
||||
/datum/ai_planning_subtree/find_and_hunt_target/look_for_light_fixtures,
|
||||
/datum/ai_planning_subtree/random_speech/faithless,
|
||||
)
|
||||
|
||||
/datum/targetting_datum/basic/faithless
|
||||
stat_attack = UNCONSCIOUS
|
||||
|
||||
/datum/ai_planning_subtree/basic_melee_attack_subtree/faithless
|
||||
melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/faithless
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/faithless
|
||||
action_cooldown = 1 SECONDS
|
||||
/// What are the odds we paralyze a target
|
||||
var/paralyze_chance = 12
|
||||
/// How long do we paralyze a target for if we attack them
|
||||
var/paralyze_duration = 2 SECONDS
|
||||
|
||||
/datum/ai_behavior/basic_melee_attack/faithless/perform(delta_time, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key)
|
||||
. = ..()
|
||||
var/datum/weakref/weak_target = controller.blackboard[target_key]
|
||||
var/atom/target = weak_target?.resolve()
|
||||
var/mob/living/living_pawn = controller.pawn
|
||||
|
||||
if(!isliving(target))
|
||||
return
|
||||
var/mob/living/living_target = target
|
||||
if(living_target.pulledby != living_pawn && !HAS_AI_CONTROLLER_TYPE(living_target.pulledby, /datum/ai_controller/basic_controller/faithless)) //Dont steal from my fellow faithless.
|
||||
if(living_pawn.Adjacent(living_target) && isturf(living_target.loc) && living_target.stat == SOFT_CRIT)
|
||||
living_target.grabbedby(living_pawn) //Drag their bodies around as a menace.
|
||||
if(prob(paralyze_chance) && iscarbon(target))
|
||||
var/mob/living/carbon/carbon_target = target
|
||||
carbon_target.Paralyze(paralyze_duration)
|
||||
carbon_target.visible_message(span_danger("\The [living_pawn] knocks down \the [carbon_target]!"), \
|
||||
span_userdanger("\The [living_pawn] knocks you down!"))
|
||||
@@ -1,48 +0,0 @@
|
||||
/mob/living/simple_animal/hostile/faithless
|
||||
name = "The Faithless"
|
||||
desc = "The Wish Granter's faith in humanity, incarnate."
|
||||
icon_state = "faithless"
|
||||
icon_living = "faithless"
|
||||
icon_dead = "faithless_dead"
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
gender = MALE
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
response_help_continuous = "passes through"
|
||||
response_help_simple = "pass through"
|
||||
emote_taunt = list("wails")
|
||||
taunt_chance = 25
|
||||
speed = 0
|
||||
maxHealth = 80
|
||||
health = 80
|
||||
stat_attack = HARD_CRIT
|
||||
robust_searching = 1
|
||||
|
||||
harm_intent_damage = 10
|
||||
obj_damage = 50
|
||||
melee_damage_lower = 15
|
||||
melee_damage_upper = 15
|
||||
attack_verb_continuous = "grips"
|
||||
attack_verb_simple = "grip"
|
||||
attack_sound = 'sound/hallucinations/growl1.ogg'
|
||||
speak_emote = list("growls")
|
||||
|
||||
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
|
||||
minbodytemp = 0
|
||||
|
||||
faction = list("faithless")
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
|
||||
footstep_type = FOOTSTEP_MOB_SHOE
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT)
|
||||
|
||||
/mob/living/simple_animal/hostile/faithless/AttackingTarget()
|
||||
. = ..()
|
||||
if(. && prob(12) && iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.Paralyze(60)
|
||||
C.visible_message(span_danger("\The [src] knocks down \the [C]!"), \
|
||||
span_userdanger("\The [src] knocks you down!"))
|
||||
@@ -149,7 +149,6 @@
|
||||
/mob/living/simple_animal/hostile/construct/wraith/noncult,
|
||||
/mob/living/simple_animal/hostile/dark_wizard,
|
||||
/mob/living/simple_animal/hostile/eyeball,
|
||||
/mob/living/simple_animal/hostile/faithless,
|
||||
/mob/living/simple_animal/hostile/giant_spider,
|
||||
/mob/living/simple_animal/hostile/giant_spider/hunter,
|
||||
/mob/living/simple_animal/hostile/giant_spider/hunter/flesh,
|
||||
|
||||
+3
-1
@@ -765,6 +765,7 @@
|
||||
#include "code\datums\ai\hauntium\hauntium_subtrees.dm"
|
||||
#include "code\datums\ai\hunting_behavior\hunting_behaviors.dm"
|
||||
#include "code\datums\ai\hunting_behavior\hunting_cockroach.dm"
|
||||
#include "code\datums\ai\hunting_behavior\hunting_lights.dm"
|
||||
#include "code\datums\ai\hunting_behavior\hunting_mouse.dm"
|
||||
#include "code\datums\ai\idle_behaviors\_idle_behavior.dm"
|
||||
#include "code\datums\ai\idle_behaviors\idle_dog.dm"
|
||||
@@ -911,6 +912,7 @@
|
||||
#include "code\datums\components\pellet_cloud.dm"
|
||||
#include "code\datums\components\phylactery.dm"
|
||||
#include "code\datums\components\pricetag.dm"
|
||||
#include "code\datums\components\pry_open_door.dm"
|
||||
#include "code\datums\components\punchcooldown.dm"
|
||||
#include "code\datums\components\puzzgrid.dm"
|
||||
#include "code\datums\components\radiation_countdown.dm"
|
||||
@@ -3688,6 +3690,7 @@
|
||||
#include "code\modules\mob\living\basic\space_fauna\carp\carp_controllers.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\carp\magicarp.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\carp\megacarp.dm"
|
||||
#include "code\modules\mob\living\basic\space_fauna\faithless\faithless.dm"
|
||||
#include "code\modules\mob\living\basic\syndicate\syndicate.dm"
|
||||
#include "code\modules\mob\living\basic\syndicate\syndicate_ai.dm"
|
||||
#include "code\modules\mob\living\basic\vermin\axolotl.dm"
|
||||
@@ -3900,7 +3903,6 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\cat_butcher.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\goose.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/mob/living/simple_animal/hostile/faithless : /mob/living/basic/faithless{@OLD}
|
||||
Reference in New Issue
Block a user