Aller au contenu

Photo

ActionMoveToObject in custom combat AI


  • Veuillez vous connecter pour répondre
11 réponses à ce sujet

#1
pelhikano

pelhikano
  • Members
  • 171 messages
I  am working on a custom combat AI (using the X2_SPECIAL_COMBAT_AI_SCRIPT variable) where creatures will sometimes break off fighting and run back to a "boss" in the same area. For some reason, the ActionMoveToObject() function doesn't seem to work right sometimes and the creature will be "undecided" and sort of run back and forth between a player just standing there and the boss. Does anyone know how to stop it doing that?

Modifié par pelhikano, 08 mai 2011 - 12:44 .


#2
_Knightmare_

_Knightmare_
  • Members
  • 643 messages
Can you post your script for us to take a look at?

#3
pelhikano

pelhikano
  • Members
  • 171 messages
This is the simplest version of that script:

#include "nw_i0_generic"
#include "x2_inc_switches"
void main()
{
    // The following two lines should not be touched
    object oIntruder = GetCreatureOverrideAIScriptTarget();
    ClearCreatureOverrideAIScriptTarget();

    // ********************* Start of custom AI script
    object oEnemy = GetNearestSeenOrHeardEnemy();
    if(GetIsObjectValid(oEnemy))
     {
        string strBossTag = GetLocalString(OBJECT_SELF, "bosstag");
        object oTheBoss = GetObjectByTag(strBossTag);
        
        float fGuardrange = 20.0;

        // compute distances
        float fEnemyToBossRange = GetDistanceBetween(oTheBoss, oEnemy);

        if (oTheBoss != OBJECT_INVALID)
        {
                if (fEnemyToBossRange <= fGuardrange)
                {
                    // enemy too close to boss: attack
                    ClearAllActions();
                    WrapperActionAttack(oEnemy);
                }
                else
                {
                    ClearAllActions(TRUE);
                    ActionMoveToObject(oTheBoss, TRUE);
                }
        }
        else
        {
            // boss dead
            WrapperActionAttack(oEnemy);
        }
    }

    // ********************* End of custom AI script
    SetCreatureOverrideAIScriptFinished();
}

This works more or less, but the creature will do some sort of confused back-and-forth running sometimes even if the enemy (PC) isn't in the "attack range". I'd like to know what causes that so I can turn it off.

Modifié par pelhikano, 08 mai 2011 - 01:49 .


#4
Orion7486

Orion7486
  • Members
  • 161 messages

pelhikano wrote...

This is the simplest version of that script:

#include "nw_i0_generic"
#include "x2_inc_switches"
void main()
{
    // The following two lines should not be touched
    object oIntruder = GetCreatureOverrideAIScriptTarget();
    ClearCreatureOverrideAIScriptTarget();

    // ********************* Start of custom AI script
    object oEnemy = GetNearestSeenOrHeardEnemy();
    if(GetIsObjectValid(oEnemy))
     {
        string strBossTag = GetLocalString(OBJECT_SELF, "bosstag");
        object oTheBoss = GetObjectByTag(strBossTag);
        
        float fGuardrange = 20.0;

        // compute distances
        float fEnemyToBossRange = GetDistanceBetween(oTheBoss, oEnemy);

        if (oTheBoss != OBJECT_INVALID)
        {
                if (fEnemyToBossRange <= fGuardrange)
                {
                    // enemy too close to boss: attack
                    ClearAllActions();
                    WrapperActionAttack(oEnemy);
                }
                else
                {
                    ClearAllActions(TRUE);
                    ActionMoveToObject(oTheBoss, TRUE);
                }
        }
        else
        {
            // boss dead
            WrapperActionAttack(oEnemy);
        }
    }

    // ********************* End of custom AI script
    SetCreatureOverrideAIScriptFinished();
}

This works more or less, but the creature will do some sort of confused back-and-forth running sometimes even if the enemy (PC) isn't in the "attack range". I'd like to know what causes that so I can turn it off.

A couple of small things to try:
ClearAllActions(TRUE).  This clears the combat state.
Try ActionForceMoveToObject.
Also, I read this as if the PC is closer than 20 to the boss, then have this npc attack.  If not, then have this npc move towards boss.
If I read it right, then a couple of other things might be causing the problem.
There are several things that might be calling DetermineCombatRound.  Do all these occurences fire this AI script.  If not, then the npc's default AI might be taking over sometimes.
Also, GetNearestHeardorSeen is a perception call.  I don't think that this function renews each time this script fires.  So, if there is more than just the player's PC in the player's party, this script might be getting confused on which player member should be checked on who's close or not.  Maybe doing this with a GetFirstFactionMember,  GetNextFactionMember loop for the PC's party might work.

#5
pelhikano

pelhikano
  • Members
  • 171 messages
I had tried ActionForceMoveToObject before, didn't make a difference. I tried also taking out the calls to ClearAllActions, but that didn't do it either. I suppose there's some other scripts that intrude on the custom script. I'd prefer it if I can leave it all in one place.

#6
Orion7486

Orion7486
  • Members
  • 161 messages
Try to define oEnemy with a faction loop like I mentioned above.

#7
MasterChanger

MasterChanger
  • Members
  • 686 messages

pelhikano wrote...
This works more or less, but the creature will do some sort of confused back-and-forth running sometimes even if the enemy (PC) isn't in the "attack range". I'd like to know what causes that so I can turn it off.


I did not see a minimum "attack range" in the code you showed (other than perception range, implicitly). I see the maximum guard range beyond which the enemy should return to their boss.

You might need to put in some SpeakStrings/SendMessageToPC in order to understand what is actually happening with the back and forth movement. I could see it happening, for example, that the enemy keeps going in and out of range: If they're 25 meters away, for example, they'll want to move towards their boss the next round. But the round after, they will have moved more than the 5 meters (say their move range is 20), so they will turn around and charge back out of range, and rinse and repeat endlessly. Your creatures only being able to take a single action per round may be what's causing behavior that isn't smooth.

So, if you test this with a relatively small group of enemies, it might be instructive to hear each enemy report in: "I'm ___ meters from my boss. I will attack/move back towards home base."

#8
pelhikano

pelhikano
  • Members
  • 171 messages
I did do the debug message thing. What happens is that after a message that the minion is returning it will turn around without apparently calling the custom script.

I also assumed that if any valid enemy is detected, this will be immediately be processed in the script, but it seems that might not be the case.

#9
MasterChanger

MasterChanger
  • Members
  • 686 messages

pelhikano wrote...

I did do the debug message thing. What happens is that after a message that the minion is returning it will turn around without apparently calling the custom script.

I also assumed that if any valid enemy is detected, this will be immediately be processed in the script, but it seems that might not be the case.


The custom AI script is called at the beginning of DetermineCombatRound, so it would be called whenever the creature is in combat. This also means that it does go through its normal AI after yours. This is advantageous when you're just adding in a bit of behavior. I did this when I made some wolves flank an enemy, and then I let them actually attack using the default AI. If you want to control the AI entirely, it might be best to write an entirely new HB script for them.

Of course, just because they're possibly getting multiple instructions per round does not mean that they're acting upon them.  Hopefully your ClearAllActions would mean that your actions are the only ones they carry out, but stranger things have happened with the AI code being as tangled as it is.

I'd say try your script as a custom HB and see what happens. You can use ExecuteScript from the default1 or from your script to link the two together, or you can just try yours as a standalone to isolate the problem.

Modifié par MasterChanger, 09 mai 2011 - 08:48 .


#10
pelhikano

pelhikano
  • Members
  • 171 messages
Would someone have a link to a custom AI tutorial? I'm pretty much flying blind at the moment.

#11
Shallina

Shallina
  • Members
  • 1 012 messages
I am working on a custom combat AI (using the X2_SPECIAL_COMBAT_AI_SCRIPT variable) where creatures will sometimes break off fighting and run back to a "boss"

Ok what I have found : If the creature is in combat, you can't force them to do any action. The AI script/event script will clear every "forced" action and will make them fight.

You have 2 solution, make specific AI combat script for them (difficult).

Or when they reach a % of health (on damaged script for exemple), you put them out of combat, change their faction (no hostile faction) so they won't enter combat again, and move them where you want.

When they are where you want, if you want them to resume fighting, turn them hostile again.

#12
pelhikano

pelhikano
  • Members
  • 171 messages
Alright, thank you for that tip. I will try something different for that enemy type, maybe I can try this behavior at a later point.