mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
Component Model + PoC Mob (#13866)
* Initial work on component mobs. * Revert simple_animal.dm * Fix movement. * Component signals are now #defines. * Fix magic number in atmos.dm * Added basic melee attacks. * Get rid of test spam
This commit is contained in:
51
code/modules/components/ai/hostile/escape_confinement.dm
Normal file
51
code/modules/components/ai/hostile/escape_confinement.dm
Normal file
@@ -0,0 +1,51 @@
|
||||
/datum/component/ai/escape_confinement
|
||||
var/life_tick=0
|
||||
|
||||
/datum/component/ai/escape_confinement/RecieveSignal(var/message_type, var/list/args)
|
||||
switch(message_type)
|
||||
if(COMSIG_LIFE)
|
||||
OnLife()
|
||||
|
||||
/datum/component/ai/escape_confinement/proc/OnLife()
|
||||
life_tick++
|
||||
var/mob/M = container.holder
|
||||
if(!controller)
|
||||
controller = GetComponent(/datum/component/controller)
|
||||
if(controller.getBusy())
|
||||
return
|
||||
switch(controller.getState())
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
EscapeConfinement()
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
if(!(M.flags & INVULNERABLE))
|
||||
DestroySurroundings()
|
||||
if(HOSTILE_STANCE_ATTACKING)
|
||||
if(!(M.flags & INVULNERABLE))
|
||||
DestroySurroundings()
|
||||
|
||||
/datum/component/ai/escape_confinement/proc/EscapeConfinement()
|
||||
var/atom/A = container.holder
|
||||
if(istype(A, /mob))
|
||||
var/mob/M = A
|
||||
if(M.locked_to)
|
||||
M.locked_to.attack_animal(A)
|
||||
if(!isturf(A.loc) && A.loc != null)//Did someone put us in something?
|
||||
var/atom/locA = A.loc
|
||||
locA.attack_animal(A)//Bang on it till we get out
|
||||
|
||||
/datum/component/ai/escape_confinement/proc/DestroySurroundings()
|
||||
EscapeConfinement()
|
||||
var/list/smash_dirs = list(0)
|
||||
var/atom/target = controller.getTarget()
|
||||
if(!target || !controller.canAttack(target))
|
||||
smash_dirs |= alldirs //if no target, attack everywhere
|
||||
else
|
||||
var/targdir = get_dir(src, target)
|
||||
smash_dirs |= widen_dir(targdir) //otherwise smash towards the target
|
||||
for(var/dir in smash_dirs)
|
||||
var/turf/T = get_step(src, dir)
|
||||
if(istype(T, /turf/simulated/wall) && container.holder.Adjacent(T))
|
||||
T.attack_animal(src)
|
||||
for(var/atom/A in T)
|
||||
if((istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille) || istype(A, /obj/structure/rack)) && container.holder.Adjacent(A))
|
||||
A.attack_animal(src)
|
||||
53
code/modules/components/ai/hostile/hunt.dm
Normal file
53
code/modules/components/ai/hostile/hunt.dm
Normal file
@@ -0,0 +1,53 @@
|
||||
// Hunting controller from spiders
|
||||
/datum/component/ai/hunt
|
||||
var/last_dir=0 // cardinal direction
|
||||
var/last_was_bumped=0 // Boolean, indicates whether the last movement resulted in a Bump().
|
||||
var/life_tick=0
|
||||
|
||||
var/movement_range=20 // Maximum range of points we move to (20 in spiders)
|
||||
|
||||
var/targetfind_delay=10
|
||||
var/datum/component/ai/target_holder/target_holder = null
|
||||
|
||||
/datum/component/ai/hunt/RecieveSignal(var/message_type, var/list/args)
|
||||
switch(message_type)
|
||||
if(COMSIG_LIFE) // no arguments
|
||||
OnLife()
|
||||
|
||||
if(COMSIG_BUMPED) // list("movable"=AM)
|
||||
OnBumped(args["movable"])
|
||||
|
||||
/datum/component/ai/hunt/proc/OnLife()
|
||||
life_tick++
|
||||
//testing("HUNT LIFE, controller=[!isnull(controller)], busy=[controller && controller.getBusy()], state=[controller && controller.getState()]")
|
||||
if(!target_holder)
|
||||
target_holder = GetComponent(/datum/component/ai/target_holder)
|
||||
if(!controller)
|
||||
controller = GetComponent(/datum/component/controller)
|
||||
if(controller.getBusy())
|
||||
return
|
||||
switch(controller.getState())
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
var/atom/target = target_holder.GetBestTarget(src, "target_evaluator")
|
||||
//testing(" IDLE STANCE, target=\ref[target]")
|
||||
if(!isnull(target))
|
||||
SendSignal(COMSIG_TARGET, list("target"=target))
|
||||
SendSignal(COMSIG_STATE, list("state"=HOSTILE_STANCE_ATTACK))
|
||||
else
|
||||
SendSignal(COMSIG_MOVE, list("loc" = pick(orange(movement_range, src))))
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
var/atom/target = target_holder.GetBestTarget(src, "target_evaluator")
|
||||
//testing(" ATTACK STANCE, target=\ref[target]")
|
||||
if(!isnull(target))
|
||||
var/turf/T = get_turf(target)
|
||||
container.SendSignalToFirst(/datum/component/ai, COMSIG_ATTACKING, list("target"=target)) // We're telling the attack modules that we have attack intention. They then individually decide whether to fire.
|
||||
if(T)
|
||||
SendSignal(COMSIG_MOVE, list("loc" = T))
|
||||
return
|
||||
SendSignal(COMSIG_STATE, list("state"=HOSTILE_STANCE_IDLE)) // Lost target
|
||||
|
||||
/datum/component/ai/hunt/proc/OnBumped(var/atom/movable/AM)
|
||||
// TODO
|
||||
|
||||
/datum/component/ai/hunt/proc/target_evaluator(var/atom/target)
|
||||
return TRUE
|
||||
@@ -0,0 +1,7 @@
|
||||
// This just calls animal_attack() on stuff.
|
||||
/datum/component/ai/melee/attack_animal/OnAttackingTarget(var/atom/target)
|
||||
if(..(target))
|
||||
var/mob/living/L = target
|
||||
L.attack_animal(container.holder)
|
||||
return 1 // Accepted
|
||||
return 0 // Unaccepted
|
||||
19
code/modules/components/ai/hostile/melee/inject_reagent.dm
Normal file
19
code/modules/components/ai/hostile/melee/inject_reagent.dm
Normal file
@@ -0,0 +1,19 @@
|
||||
/datum/component/ai/melee/inject_reagent
|
||||
var/poison_type = "" // STOXIN, etc
|
||||
var/poison_per_bite = 0 // Mols to inject
|
||||
var/inject_prob = 0 // Chance to inject, -1 = ALWAYS
|
||||
var/max_poison = 0 // Maximum mols in target's blood. 0 = INF
|
||||
|
||||
/datum/component/ai/melee/inject_reagent/OnAttackingTarget(var/atom/target)
|
||||
if(..(target))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
if(inject_prob == -1 || prob(inject_prob))
|
||||
var/curamt = L.reagents.get_reagent_amount(poison_type)
|
||||
var/newamt = max_poison - curamt
|
||||
if(newamt >= 1)
|
||||
// TEXT-FORMATTING FUNCTIONS WHEN BYOND?
|
||||
container.holder.visible_message("<span class='warning'>\The [src] injects something into \the [target]!</span>")
|
||||
L.reagents.add_reagent(poison_type, poison_per_bite)
|
||||
return 1 // Accepted signal
|
||||
return 0 // Did not accept signal
|
||||
14
code/modules/components/ai/hostile/melee/melee.dm
Normal file
14
code/modules/components/ai/hostile/melee/melee.dm
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
/datum/component/ai/melee/RecieveSignal(var/message_type, var/list/args)
|
||||
switch(message_type)
|
||||
if(COMSIG_ATTACKING) // list("target"=A)
|
||||
return OnAttackingTarget(args["target"])
|
||||
else
|
||||
return ..(message_type, args)
|
||||
|
||||
/datum/component/ai/melee/proc/OnAttackingTarget(var/atom/target)
|
||||
if(!isliving(target))
|
||||
return 0
|
||||
var/mob/living/L = target
|
||||
return L.Adjacent(container.holder)
|
||||
Reference in New Issue
Block a user