Jump to content

[LE] AI aggression problem


Recommended Posts

I'm poking at trying to make a version of the Command Animal power that is usable (and used) by NPCs. Unfortunately several chunks of the standard one are implemented in player-specific fashion that doesn't have a generic equivalent.

 

Right now, the power will pacify (all, not just one, but I think I can solve that) animals within the spell's AoE. So far so good, but I'd like them to help out the caster, as they would the player.

 

This is where I get stuck. I can't seem to find a combination of faction relations and AI settings that will:

 

1. By default make the animal nonaggressive against everyone

2. Make them attack actors if, and only if, they're in combat with the casting actor

 

Right now I'm looking at adding a cloak spell to the casting actor to find everybody who is hostile to them, and stuffing them into a faction set as an enemy to the pacified faction, but that's a very kludgey thing to try. Anyone have some experience in the area and/or pointers?

Link to comment
Share on other sites

Probably you'll find that too. Something can be tweaked in next sample script, take it as a base!

I believe if an actor has been attacked, and another actor with the same faction (with good faction rank) is nearby this actor is going to combat too.

 

foamAnimalScript

 

Scriptname foamAnimalScript extends ActiveMagicEffect
{make the animal nonaggressive against everyone and attack actors, if they are in combat with the caster}
; https://forums.nexusmods.com/index.php?/topic/7535376-ai-aggression-problem/

; 0 - Unaggressive    - will not initiate combat
; 1 - Aggressive      - will attack enemies on sight
; 2 - Very Aggressive - will attack enemies and neutrals on sight
; 3 - Frenzied        - will attack anyone else

  Keyword PROPERTY ActorTypeAnimal  auto    ; use autofill
  Faction PROPERTY mySpecialFaction auto    ; new created faction


; -- EVENTs --

EVENT OnEffectStart(Actor akTarget, Actor akCaster)
IF akTarget.HasKeyword(ActorTypeAnimal)
ELSE
    self.Dispel()
    RETURN    ; - STOP -    this is not an animal, remove effect
ENDIF
;---------------------
; pacify animal to everyone
    akTarget.RemoveFromAllFactions()
    akTarget.SetActorValue("Aggression", 0)
    akTarget.StopCombatAlarm()
    akTarget.StopCombat()

; caster and target should be in unique faction (to support each other)
    akCaster.AddToFaction(mySpecialFaction)
    akTarget.AddToFaction(mySpecialFaction)
;;;    akTarget.SetFactionRank(mySpecialFaction, 0)    ; valid range is -128 to 127

    gotoState("Waiting")            ; ### STATE ###
ENDEVENT


EVENT OnEffectFinish(Actor akTarget, Actor akCaster)
    gotoState("")                    ; ### STATE ###
    Debug.Trace("foamAnimal: OnEffectFinish() - for " +akTarget+", " +self)
ENDEVENT


;==========================
state Waiting
;============
;/ ***
EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, Bool abPowerAttack, Bool abSneakAttack, Bool abBashAttack, Bool abHitBlocked)
IF (akAggressor as Actor)
ELSE
    RETURN    ; - STOP - no actor
ENDIF
;---------------------
IF ((akAggressor as Actor) == self.GetCasterActor())
    ; handle casters friendly hits
ELSE
    ; other hits
ENDIF
ENDEVENT
*** /;

EVENT OnDeath(Actor akKiller)
    gotoState("")                    ; ### STATE ###
    Debug.Notification("Animal is dead!")
    Debug.Trace("foamAnimal: OnDeath() - for " +self.GetTargetActor()+", " +self)
ENDEVENT

EVENT OnEndState()
    myF_Revert()
ENDEVENT
;=======
endState


; -- FUNCTION --

;--------------------
FUNCTION myF_Revert()
;--------------------
    self.GetTargetActor().RemoveFromFaction(mySpecialFaction)
    self.GetCasterActor().RemoveFromFaction(mySpecialFaction)
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

There's a couple of problems with that approach: The first, as I have discovered through other attempts at this, is that the Aggro Radius behaviour will override Aggression 0 or 1 and animals with it set will attack Neutrals regardless of that setting. The second is that it irrevocably wipes any prior factions the animal has, which isn't a huge thing since 99% of animals are non-unique, respawning references, but is something I'd prefer to avoid.

 

(I also would have to set the Assistance AV to 'helps allies', just to be sure, and include both Aggression and Assistance revert-to-saved bits, but that's all trivial)

Link to comment
Share on other sites

This is getting kinda frustrating. No matter what I try I can't seem to find a way to make the damn things aggro against stuff in the Friend faction other than setting aggression to 3+, which has the undesired behaviour of making them hostile to *everything*, including the person using the pacification spell.

 

StartCombat() does nothing. Setting an individual relationship rank or adding an enemy faction does not create hostility or combat. They don't come to the assistance of allies against friends. I thought I could trigger a cast of a hostile spell against the commanded animal, but a. a Cast() call on people in combat doesn't use the supplied target parameter and b. even when the spell does process it doesn't make them hostile!

Link to comment
Share on other sites

What is about this?

Player can summon some kind of attronach.

 

You could use such spell like frost attronach, but instead of attronach you summon an animal (selected by formlist) and disable the real animal that you want to pacify.

After the spell has been finished by time out or the summoned animal is dead, enable the real animal again.

Or cast to the real animal a second spell that will auto enable them after 24 hours ingame.

Edited by ReDragon2013
Link to comment
Share on other sites

What is about this?

Player can summon some kind of attronach.

 

You could use such spell like frost attronach, but instead of attronach you summon an animal (selected by formlist) and disable the real animal that you want to pacify.

After the spell has been finished by time out or the summoned animal is dead, enable the real animal again.

Or cast to the real animal a second spell that will auto enable them after 24 hours ingame.

 

Hm. That might be possible, with maybe some work to make sure things like actor values and factions get copied, but there's a lot of animals I'd need to make summonable versions of.

Link to comment
Share on other sites

I think I found a solution!

It appears that aggro radius (which isn't overridden by relationships but is by factions) appears to apply solely to the player. I had thought it applied to everyone.

 

This let me do some individual relationship management. If they're hostile towards the caster of the spell, they have the relationship to the commanded animal set to enemy, and if they are not, it is set to friendly. For non-player actors this is done through SetRelationshipRank; for the player, it is by adding and removing the animal from a PlayerFriendFaction I created, which is friendly to a PlayerFaction, but neutral to other factions including itself. The animal's own AI data and factions are saved (factions required SKSE, but oh well), then the factions are cleared (so that the only thing impacting aggro is the spell itself) and the AI data set to Helps Allies / Foolhardy / Attacks Enemies. When the spell expires the saved data is restored.

 

Unfortunately it relies on the caster also being given a cloak ability to monitor for nearby actors, so there could be some pretty substantial load on the engine, but so far I haven't found a way around that.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...