Author Topic: help needed for a script to improve the npc combat AI  (Read 496 times)

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« on: April 09, 2011, 01:47:08 pm »


                Hi, i have tried many solutions to fix this AI bug.

http://nwn.bioware.c...5&forum=45&sp=0

That bug make easy to escape from a melee enemy. 
Finally I have  had an idea:
The npc should calculate the future position of the PC by considering the 2 positions of the PC in an interval of 1.5 seconds: the future (third) position will be in an imaginary line that passes through  the 2 points, in a distance from the second position equivalent to distance between position 1 and 2.

I have done this script, that will be launched from an heartbeat, but it dont work: someone can tell me why?

void main()



{

object oPC = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);

location loc1 = (GetLocation(oPC));


DelayCommand(1.5f, ClearAllActions(TRUE));
DelayCommand(1.5f , SetLocalLocation (OBJECT_SELF, "loc2" , GetLocation(oPC)));
ActionAttack (oPC);
float angololoc = GetAngleBetweenLocations(loc1, GetLocalLocation(OBJECT_SELF, "loc2"));

float distanzaloc = GetDistanceBetweenLocations(loc1, GetLocalLocation(OBJECT_SELF, "loc2"));
location loc3= (GenerateNewLocationFromLocation(GetLocalLocation(OBJECT_SELF, "loc2"), distanzaloc, angololoc, angololoc));
ActionForceMoveToLocation(loc3, TRUE, 3.0);
ActionAttack (oPC);

}
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #1 on: April 09, 2011, 02:35:27 pm »


               I would try to adjust creaturespeed.2da rather. But really is that an issue?, I can't see the problem in current monster speed.

Do you got both expansions?
               
               

               
            

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #2 on: April 09, 2011, 03:14:59 pm »


               

ShaDoOoW wrote...

I would try to adjust creaturespeed.2da rather. But really is that an issue?, I can't see the problem in current monster speed.

Do you got both expansions?

I have 1.69 and expansions. The bug is noticeable when you escape from a enemy melee npc following a straight line: the npc, even if he has dm speed, follow you and mantain a distance (4-5 meters, or more if is a giant monster) without attacking. A way to fix it is this:

http://nwvault.ign.c....Detail&id=3779

but it is good only for humanoids enemies.
               
               

               


                     Modifié par Uther78, 09 avril 2011 - 02:17 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #3 on: April 09, 2011, 03:39:23 pm »


               I see, thats a "waggon" issue, I have the same problem at Bastions of War, i can be faster than my enemy, but if I just attack him im making a "waggon", following him but can't reach him and attack although I have greatsword. In pvp, I can outrun my target but when he see this he just change a direction, very annoying when you chasing run-shooting archers...

Well really try to adjust creaturespeed to in way that WALK speed will be the same as RUN speed, I think that this issues is because when chasing an enemy character stop running and starts to walk...

Well try it, but if it wont help then I dont really know how to fix it and I dont think your script would be any help even if it would worked.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #4 on: April 09, 2011, 04:53:30 pm »


               

Uther78 wrote...

I have done this script, that will be launched from an heartbeat, but it dont work: someone can tell me why?

void main()



{

object oPC = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,PERCEPTION_SEEN);

location loc1 = (GetLocation(oPC));


DelayCommand(1.5f, ClearAllActions(TRUE));
DelayCommand(1.5f , SetLocalLocation (OBJECT_SELF, "loc2" , GetLocation(oPC)));
ActionAttack (oPC);
float angololoc = GetAngleBetweenLocations(loc1, GetLocalLocation(OBJECT_SELF, "loc2"));

float distanzaloc = GetDistanceBetweenLocations(loc1, GetLocalLocation(OBJECT_SELF, "loc2"));
location loc3= (GenerateNewLocationFromLocation(GetLocalLocation(OBJECT_SELF, "loc2"), distanzaloc, angololoc, angololoc));
ActionForceMoveToLocation(loc3, TRUE, 3.0);
ActionAttack (oPC);

}


It is hard to say why some of it dose not work since I have no clear Idea where you are getting the finctions  
GetAngleBetweenLocations and GenerateNewLocationFromLocation. I assume that they are the ones out of the boiware includes.  I will go with that assumption. That brings  to light one of the problems, The Function GetAngleBetweenLocations in my opion is bugged, they may have had uses for how it is written  that I do not know, but I find the angles it returns compleatly useless.

Ok on the the logic error in the script.  You start off with two commands delayed by 1.5 seconds ClearAllActions and SetLocaltion 2. Nither of thies will happen while this script is running but 1.5 seconds after it has finished running.   The next line of the script tells the PC to attack oPC.  Since the PC is now attacking oPC he will not do any other actions loaded to his que untill he has finished attacking.  That is untill 1.5 seconds later when your ClearAllActions kicks in and he just stands there waiting for more actions to be loaded into his que.

the next line Gets the angle between location 1 and 2.  Here again we have a problem.  IT is inpossiable to say just what location 2 is set to at this point.   It has not yet been set during this execution of the script, If it has been set it was 4.5 seconds ago from when the script ran on the previous  round.   This causes a problem We can not even say if  oPC was in the same area the round before. Let alone the same tagret.  Is it the location of a target that is still alive even? Who knows. There may not even have been a valid enemy that round making it an invalid location all together.  

The next two lines have the same problem.  Loc2 is an unknow location. 

Next line. 
ActionForceMoveToLocation(loc3, TRUE, 3.0);

Well this line never really fires. It gets loaded to the action Que. But the NPC is attacking so will not do it untill he is finished.  It most likely gets cleared in then ClearAllActions that will happen in 1.5 seconds.  Even if it did Fire, I see problems.   The Force move will jump the creature to the location after 3 seconds.  This would cause even a zombie to be able to keep up with a jack rabbit.  Even Jump said zombie into the death plane to follow said jack rabbit. 

next line.  Attack(oPC)   again never fires for the reasons above.


I will try  find a function for you to use in your rewrite.  Bset of luck on this.


EDIT:  I also agree with shadow.  Even if you get the script working the way you want.  It just may flat out not work.
               
               

               


                     Modifié par Lightfoot8, 09 avril 2011 - 03:54 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #5 on: April 09, 2011, 05:14:51 pm »


               If you try a rewrite of your script, You may want to try useing the finction GetLocTowrdsLoc in the link below.

http://social.biowar...6299151#6302462
               
               

               


                     Modifié par Lightfoot8, 09 avril 2011 - 04:16 .
                     
                  


            

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #6 on: April 09, 2011, 09:34:24 pm »


               It seems too difficult to apply my idea, but I already had found a solution:

http://nwvault.ign.c....Detail&id=3779

(if the PC escapes, the npc every heartbeat equip ranged weapon, attacks for 1 sec,  equip melee and restart the chase)

That solution works and is easy for implementing, but is good only for humanoids.
(Magical creatures can cast spells rather than use ranged).
What to do with animals?
               
               

               
            

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #7 on: April 17, 2011, 10:47:59 pm »


               I thing I have done it!
The script is this:
_________________________________________________________________________________

#include "nw_i0_generic"



void main()



{

object oPC = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,

PERCEPTION_SEEN);

ClearAllActions(TRUE);


float distance = GetDistanceBetween(OBJECT_SELF, oPC);

location loc1 = GenerateNewLocationFromLocation(GetLocation(OBJECT_SELF),distance*1.5, GetFacing(OBJECT_SELF), GetFacing(OBJECT_SELF));


ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectMovementSpeedIncrease(99),OBJECT_SELF,2.0f);
TurnToFaceObject(oPC,OBJECT_SELF);
ActionForceMoveToLocation(loc1, TRUE,0.3f);


ActionAttack (oPC);







}

__________________________________________________________________________________
The script, called "distanceattack" must be launched putting in heartbeat those lines:

object oPC = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,

PERCEPTION_SEEN);

if (oPC != OBJECT_INVALID && GetIsEnemy(oPC))

if ((GetDistanceToObject(oPC) >= 3.5f) && (GetDistanceToObject(oPC) <= 6.5f))

{


ExecuteScript("distanceattack", OBJECT_SELF);

}

_______________________________________________________________________________

It works almost perfectly: every 6 seconds the enemy runs to PC and attack him.

Problems:
1- Sometime the forcemove command causes a enemy teleport.
2- Because of a interference with the other default ai scripts, sometimes between a charge and another 12 seconds passe. That dont happen if you deselect all the other ai script for the enemy npc.
3- Sometime (rarely) the enemy run in the wrong direction.
Suggestions are welcome!
               
               

               


                     Modifié par Uther78, 17 avril 2011 - 09:52 .
                     
                  


            

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #8 on: April 18, 2011, 07:18:56 pm »


               Lol the npc attack fails when PC run in north-east direction.... stupid bugged piece of ****
               
               

               


                     Modifié par Uther78, 18 avril 2011 - 06:31 .
                     
                  


            

Legacy_Uther78

  • Newbie
  • *
  • Posts: 36
  • Karma: +0/-0
help needed for a script to improve the npc combat AI
« Reply #9 on: April 20, 2011, 12:15:50 pm »


               Mmmm that script sems to work:


#include "nw_i0_generic"
#include "x0_i0_position"


void main()



{



object oPC = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION,

PERCEPTION_SEEN);

if (GetAngleBetweenLocations(GetLocation(oPC), GetLocation(OBJECT_SELF)) >15.0)

{

ClearAllActions(TRUE);




location loc1 = GetAheadLocation(oPC);

ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectMovementSpeedIncrease(99),OBJECT_SELF,2.0f);
TurnToFaceObject(oPC,OBJECT_SELF);
ActionForceMoveToLocation(loc1, TRUE,0.3f);


ActionAttack (oPC);

}





}
               
               

               


                     Modifié par Uther78, 20 avril 2011 - 11:25 .