help needed for a script to improve the npc combat AI
#1
Posté 09 avril 2011 - 12:47
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);
}
#2
Posté 09 avril 2011 - 01:35
Do you got both expansions?
#3
Posté 09 avril 2011 - 02:14
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: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?
http://nwvault.ign.c....Detail&id=3779
but it is good only for humanoids enemies.
Modifié par Uther78, 09 avril 2011 - 02:17 .
#4
Posté 09 avril 2011 - 02:39
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.
#5
Posté 09 avril 2011 - 03:53
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 .
#6
Posté 09 avril 2011 - 04:14
http://social.biowar...6299151#6302462
Modifié par Lightfoot8, 09 avril 2011 - 04:16 .
#7
Posté 09 avril 2011 - 08:34
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?
#8
Posté 17 avril 2011 - 09:47
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 .
#9
Posté 18 avril 2011 - 06:18
Modifié par Uther78, 18 avril 2011 - 06:31 .
#10
Posté 20 avril 2011 - 11:15
#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 .





Retour en haut






