Modifié par pelhikano, 08 mai 2011 - 12:44 .
ActionMoveToObject in custom combat AI
#1
Posté 08 mai 2011 - 12:41
#2
Posté 08 mai 2011 - 12:55
#3
Posté 08 mai 2011 - 01:47
#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
Posté 08 mai 2011 - 10:08
A couple of small things to try: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.
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
Posté 09 mai 2011 - 10:48
#6
Posté 09 mai 2011 - 04:02
#7
Posté 09 mai 2011 - 07:47
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
Posté 09 mai 2011 - 08:22
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
Posté 09 mai 2011 - 08:43
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
Posté 09 mai 2011 - 08:58
#11
Posté 10 mai 2011 - 06:54
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
Posté 10 mai 2011 - 09:54





Retour en haut






