PDA

View Full Version : Use OnTickTime to re-evaluate AI air group waypoints


hc_wolf
11-01-2011, 02:38 AM
Hi,

I have good coding where AI planes on spawn will locate an enemy location and fly to it and attack. The problem is. If the enemy is a plane. By the time the AI reach their waypoint where they are to attack. the enemey planes have of course flowen away.

What is the best code to insert that will have the AI check their current waypoint to reset if the target has moved to new location or if there is a closer enemy they decide to attack?






public override void OnTickGame()
{
base.OnTickGame();
if (koefDiskr == 0) koefDiskr = 640;
if (Time.tickCounter() % koefDiskr == 0)
AiActor result = null;
AiAirGroup[] enemyAG = GamePlay.gpAirGroups((myGroup.Army() == 1) ? 2 : 1);
Point3d attackerPos = myGroup.Pos();
if (enemyAG != null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (CurTankGroups.Count != 0)
{
int i = (int)(Time.tickCounter() / koefDiskr) % CurTankGroups.Count;
{
if ((CurTankGroups[i].TankGroup != null) && (CurTankGroups[i].cur_rp != null))
if ((CurTankGroups[i].cur_rp.State == RecalcPathState.SUCCESS) )
{
CurTankGroups[i].TankGroup.SetWay((CurTankGroups[i].cur_rp.Path));
CurTankGroups[i].cur_rp = null;
}
}
}
if (eGroup.isAircraftType(AircraftType.Bomber) || eGroup.isAircraftType(AircraftType.DiveBomber))
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
if (result == null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
}
return result;
}




Below are the two Waypoints I want the AI to check every minute.



public override void OnMissionLoaded(int missionNumber)
{
base.OnMissionLoaded(missionNumber);
MissionsCount++;
}

internal AiActor FindGroundTarget(int army, Point3d attackerPos)
{
AiActor result = null;
AiGroundGroup[] enemyGG = GamePlay.gpGroundGroups((army == 1) ? 2 : 1);
if (enemyGG != null)
{
result = enemyGG[0];
for (int i = 1; i < enemyGG.Length; i++)
{
if (enemyGG[i] != null)
if (result.Pos().distance(ref attackerPos) > enemyGG[i].Pos().distance(ref attackerPos))
{ result = enemyGG[i]; }
}
}
return result;
}

internal AiActor FindAirTarget(AiAirGroup myGroup)
{
AiActor result = null;
AiAirGroup[] enemyAG = GamePlay.gpAirGroups((myGroup.Army() == 1) ? 2 : 1);
Point3d attackerPos = myGroup.Pos();
if (enemyAG != null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (eGroup.isAircraftType(AircraftType.Bomber) || eGroup.isAircraftType(AircraftType.DiveBomber))
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
if (result == null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
}
return result;
}

SNAFU
11-02-2011, 07:45 AM
I am very interested in this subject, due to the fact that I use a similar "AI find your target yourself" script on our server. It works so far quite well, but a routine, which would set the intervall the AI searches for new targets and sets their new tasks accordingly would be really good.

I have at the moment other irons to hammer, but if you find a solution, please drop a line. ;)

PS: I used Naryvs approach, had no time to compare it with yours, but you find the code below:

using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using maddox.GP;


public class Mission : AMission
{
int AirStrikeMissNum = -1;

internal AiActor FindGroundTarget(int army, Point3d attackerPos)
{
AiActor result = null;
AiGroundGroup[] enemyGG = GamePlay.gpGroundGroups((army == 1) ? 2 : 1);
if (enemyGG != null)
{
result = enemyGG[0];
for (int i = 1; i < enemyGG.Length; i++)
{
if (enemyGG[i] != null)
if (result.Pos().distance(ref attackerPos) > enemyGG[i].Pos().distance(ref attackerPos))
{ result = enemyGG[i]; }
}
}
return result;
}

internal AiActor FindAirTarget(AiAirGroup myGroup)
{
AiActor result = null;
AiAirGroup[] enemyAG = GamePlay.gpAirGroups((myGroup.Army() == 1) ? 2 : 1);
Point3d attackerPos = myGroup.Pos();
if (enemyAG != null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (eGroup.isAircraftType(AircraftType.Bomber) || eGroup.isAircraftType(AircraftType.DiveBomber))
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
if (result == null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
}
return result;
}


internal AiAirport FindOurAirfield(int army, AiActor actor)
{
AiAirport result = null;
Point3d attackerPos = actor.Pos();
AiAirport[] airports = GamePlay.gpAirports();

if (airports != null)
{
foreach (AiAirport airport in airports)
{
if (GamePlay.gpFrontArmy(airport.Pos().x, airport.Pos().y) == army)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > airport.Pos().distance(ref attackerPos))
result = airport;
}
else result = airport;
}
}
}
return result;
}


internal AiWayPoint[] LandingWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[1];

if (airGroup.GetWay().Length != 1)
{
Point3d curPos = airGroup.Pos();
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);

AiAirport findOurAirfield = FindOurAirfield(airGroup.Army(), airGroup);
if (findOurAirfield != null)
{
curPos = findOurAirfield.Pos();
AiAirWayPoint aaWP = new AiAirWayPoint(ref curPos, speed);
aaWP.Action = AiAirWayPointType.LANDING;
aaWP.Target = findOurAirfield;
result[0] = aaWP;
}
else
{
result = WaitingTargetWay(airGroup);
}
}
else result = airGroup.GetWay();

return result;
}

internal AiWayPoint[] WaitingTargetWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[3];
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = airGroup.Pos();
addPoint.add(2000, 2000, 0);
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{ aaWP.Action = AiAirWayPointType.HUNTING; }
else aaWP.Action = AiAirWayPointType.NORMFLY;
result[0] = aaWP;
addPoint.add(-1500, -1500, 0);
aaWP.P = addPoint;
result[1] = aaWP;
addPoint.add(1000, 1000, 0);
aaWP.P = addPoint;
aaWP.Action = AiAirWayPointType.LANDING;
result[2] = aaWP;
return result;
}

internal void SetNewTask(AiAirGroup airGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];
if ((chkWP.Length == 1) && ((chkWP[0] as AiAirWayPoint).Action == AiAirWayPointType.LANDING))
{
return;
/*if (((chkWP[0] as AiAirWayPoint).Target as AiAirport) != null)
if (GamePlay.gpFrontArmy(((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().x, ((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().y) == airGroup.Army())
{ return; }
else
{
airGroupWay = WaitingTargetWay(airGroup);
airGroup.SetWay(airGroupWay);
return;
} */
}
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Bomber) || airGroup.isAircraftType(AircraftType.DiveBomber))
{
AiActor nearestGT = FindGroundTarget(airGroup.Army(), airGroup.Pos());
if (airGroup.hasBombs())
{
if (nearestGT != null)
{
aaWP.P = nearestGT.Pos();
aaWP.P.z = curPos.z;
aaWP.Target = nearestGT;
aaWP.GAttackType = AiAirWayPointGAttackType.LEVEL;
aaWP.Action = AiAirWayPointType.GATTACK_TARG;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = WaitingTargetWay(airGroup);
}
}
else airGroupWay = LandingWay(airGroup);
}

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
AiAirGroup enemyGroup = FindAirTarget(airGroup) as AiAirGroup;

if (enemyGroup == null)
return;

if (airGroup.hasCourseWeapon())
{
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = LandingWay(airGroup);
}
}
if (airGroupWay != null)
{
foreach (AiWayPoint aWP in airGroupWay)
{
if (aWP == null)
return;
}
airGroup.SetWay(airGroupWay);
}
}

internal void SetNewFighterTask(AiAirGroup airGroup, AiAirGroup enemyGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];

double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
if (enemyGroup == null)
return;
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
if (airGroupWay != null) airGroup.SetWay(airGroupWay);
}

public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
{
base.OnActorTaskCompleted(missionNumber, shortName, actor);
AiAirGroup airGroup = actor as AiAirGroup;
if ((airGroup != null) && (missionNumber != AirStrikeMissNum))
{
SetNewTask(airGroup);
}
}

public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
if (missionNumber != AirStrikeMissNum)
{
AiAirGroup airGroup = actor as AiAirGroup;
if (airGroup != null)
{
SetNewTask(airGroup);
AiAirGroup[] eGroups = GamePlay.gpAirGroups((airGroup.Army() == 1) ? 2 : 1);
if (eGroups != null)
foreach (AiAirGroup eGroup in eGroups)
{
if (eGroup != null)
{
if ((eGroup.hasCourseWeapon()) && ((airGroup.isAircraftType(AircraftType.Fighter)) || (airGroup.isAircraftType(AircraftType.HeavyFighter ))))
{
AiWayPoint[] chkWP = eGroup.GetWay();
bool res = true;
foreach (AiWayPoint eWP in chkWP)
{
AiAirWayPoint aAWP = (eWP as AiAirWayPoint);
if ((aAWP.Action != AiAirWayPointType.HUNTING) || (aAWP.Action != AiAirWayPointType.NORMFLY) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())))
{
res = false;
break;
}
}
if (res)
{
SetNewFighterTask(eGroup, airGroup);
}
}
}
}
}
}
}
///////////////ENDE
}

adonys
11-02-2011, 08:05 AM
I was planning to work on something like this myself too, using narvy's example, for the WIP Mission Tools.

Is a ugly way to overwrite, and thus make a dirty fix, with the current broken AI behavior (I've seen countless times AI flights passing by each other with less than 500 m between them, and giving no sign they've seen each other), until we'll get some AI from MG..

hc_wolf
11-02-2011, 08:28 AM
Yes we are using the same code in a way. But in my actual scripting (not above here) I meshed in AI ground vehicles also. Now the AI ground are fine and do an update and check on their targets and pathway every 5 mins and that is great.

But yes there was a small bit of code that set off the AI Air find targets etc.. then ai air groups would (just like real pilots) look around them and alter their targets based on current situation.

As for AI not attacking. I read something and did some testing. Looks like AI will not attack (at the moment) if their group is smaller then the Air target or if their awareness is lower than ace. So if you are on your own and two or more 109's are near they will attack. But if you are equal 1:1 or you have more fighters in group they just ignore you.

Will all be fixed I am sure in later patches

41Sqn_Banks
11-02-2011, 09:03 AM
I did some experiments on that subject some month ago. The main problem is that you cannot change the existing waypoint objects, this means you have to create and assign new waypoint objects (that include the updated target position). Now the problem is that you cannot simply clone all waypoints of the air group, update the position of the "attack" waypoints with the current target position and then assign them again, because the air group would turn around and fly back to their first (takeoff) waypoint and start all over.

41Sqn_Banks
11-02-2011, 11:02 AM
I have 2 solutions in my mind:

a) I followed this approach during my experiment. I only assign the next waypoint to the air group. I react on the OnActorTaskComplete event to assign a new waypoint for the air group. After the takeoff waypoint I assign an attack waypoint on the target position. I adjust the position of the attack waypoint periodically. After the attack waypoint was completed a landing waypoint is assigned. Did work pretty good to lead the air group to the target, however updating the waypoints interrupted the current task of the air group (they stopped attacking or crashed during takeoff).

b) I need to find out which waypoints were already passed by the air group. When I assign the updated waypoints I only assign waypoints that were not passed so far. I have so far no solution to find out which waypoints were passed. Triggers could be a solution or a smart algorithm that looks at the position and heading of the air group.

I will look at the issue in a couple of week as I'm currently busy with implementing the online support and moving frontline/ground war for IL2DCE.

hc_wolf
11-03-2011, 12:10 AM
Banks I agree with Part a) as sounds good. I will let you go as you work on DCE.

If you are able to. Could you email me the one or both test mission scripts so I could take a look while you are working on DCE for a couple of weeks.

Or post the two test missions up on here.

if not that's ok.

HC_Wolf@optusnet.com.au

salmo
11-03-2011, 03:13 AM
I have 2 solutions in my mind:

a) I followed this approach during my experiment. I only assign the next waypoint to the air group. I react on the OnActorTaskComplete event to assign a new waypoint for the air group. After the takeoff waypoint I assign an attack waypoint on the target position. I adjust the position of the attack waypoint periodically. After the attack waypoint was completed a landing waypoint is assigned. Did work pretty good to lead the air group to the target, however updating the waypoints interrupted the current task of the air group (they stopped attacking or crashed during takeoff).

b) I need to find out which waypoints were already passed by the air group. When I assign the updated waypoints I only assign waypoints that were not passed so far. I have so far no solution to find out which waypoints were passed. Triggers could be a solution or a smart algorithm that looks at the position and heading of the air group.

I will look at the issue in a couple of week as I'm currently busy with implementing the online support and moving frontline/ground war for IL2DCE.

In a similar vien, I was looking at how to get a badly damaged AI plane to abort it's waypoints & head straight for the nearest friendly airfield. I'm sick of the damaged AI's doing circuits waiting to land at their home base, and then flying off to never-land to crash on some hill somewhere. :evil:

hc_wolf
11-25-2011, 10:04 PM
Hi, I came across this script for Radar and Tracking. Anyone care to take a stab at this and converti it so it is AI updating thier waypoints to re-evaluate their targets position and thus re-assign to the targets new location?


http://translate.googleusercontent.com/translate_c?hl=en&rurl=translate.google.com&sl=ru&tl=en&u=http://www.sukhoi.ru/forum/showthread.php%3Ft%3D68765&usg=ALkJrhi-Iqnx2bT2CGj6ce_VHHDnwatyyw

David198502
04-24-2012, 09:48 PM
I am very interested in this subject, due to the fact that I use a similar "AI find your target yourself" script on our server. It works so far quite well, but a routine, which would set the intervall the AI searches for new targets and sets their new tasks accordingly would be really good.

I have at the moment other irons to hammer, but if you find a solution, please drop a line. ;)

PS: I used Naryvs approach, had no time to compare it with yours, but you find the code below:

using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using maddox.GP;


public class Mission : AMission
{
int AirStrikeMissNum = -1;

internal AiActor FindGroundTarget(int army, Point3d attackerPos)
{
AiActor result = null;
AiGroundGroup[] enemyGG = GamePlay.gpGroundGroups((army == 1) ? 2 : 1);
if (enemyGG != null)
{
result = enemyGG[0];
for (int i = 1; i < enemyGG.Length; i++)
{
if (enemyGG[i] != null)
if (result.Pos().distance(ref attackerPos) > enemyGG[i].Pos().distance(ref attackerPos))
{ result = enemyGG[i]; }
}
}
return result;
}

internal AiActor FindAirTarget(AiAirGroup myGroup)
{
AiActor result = null;
AiAirGroup[] enemyAG = GamePlay.gpAirGroups((myGroup.Army() == 1) ? 2 : 1);
Point3d attackerPos = myGroup.Pos();
if (enemyAG != null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (eGroup.isAircraftType(AircraftType.Bomber) || eGroup.isAircraftType(AircraftType.DiveBomber))
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
if (result == null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
}
return result;
}


internal AiAirport FindOurAirfield(int army, AiActor actor)
{
AiAirport result = null;
Point3d attackerPos = actor.Pos();
AiAirport[] airports = GamePlay.gpAirports();

if (airports != null)
{
foreach (AiAirport airport in airports)
{
if (GamePlay.gpFrontArmy(airport.Pos().x, airport.Pos().y) == army)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > airport.Pos().distance(ref attackerPos))
result = airport;
}
else result = airport;
}
}
}
return result;
}


internal AiWayPoint[] LandingWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[1];

if (airGroup.GetWay().Length != 1)
{
Point3d curPos = airGroup.Pos();
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);

AiAirport findOurAirfield = FindOurAirfield(airGroup.Army(), airGroup);
if (findOurAirfield != null)
{
curPos = findOurAirfield.Pos();
AiAirWayPoint aaWP = new AiAirWayPoint(ref curPos, speed);
aaWP.Action = AiAirWayPointType.LANDING;
aaWP.Target = findOurAirfield;
result[0] = aaWP;
}
else
{
result = WaitingTargetWay(airGroup);
}
}
else result = airGroup.GetWay();

return result;
}

internal AiWayPoint[] WaitingTargetWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[3];
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = airGroup.Pos();
addPoint.add(2000, 2000, 0);
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{ aaWP.Action = AiAirWayPointType.HUNTING; }
else aaWP.Action = AiAirWayPointType.NORMFLY;
result[0] = aaWP;
addPoint.add(-1500, -1500, 0);
aaWP.P = addPoint;
result[1] = aaWP;
addPoint.add(1000, 1000, 0);
aaWP.P = addPoint;
aaWP.Action = AiAirWayPointType.LANDING;
result[2] = aaWP;
return result;
}

internal void SetNewTask(AiAirGroup airGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];
if ((chkWP.Length == 1) && ((chkWP[0] as AiAirWayPoint).Action == AiAirWayPointType.LANDING))
{
return;
/*if (((chkWP[0] as AiAirWayPoint).Target as AiAirport) != null)
if (GamePlay.gpFrontArmy(((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().x, ((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().y) == airGroup.Army())
{ return; }
else
{
airGroupWay = WaitingTargetWay(airGroup);
airGroup.SetWay(airGroupWay);
return;
} */
}
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Bomber) || airGroup.isAircraftType(AircraftType.DiveBomber))
{
AiActor nearestGT = FindGroundTarget(airGroup.Army(), airGroup.Pos());
if (airGroup.hasBombs())
{
if (nearestGT != null)
{
aaWP.P = nearestGT.Pos();
aaWP.P.z = curPos.z;
aaWP.Target = nearestGT;
aaWP.GAttackType = AiAirWayPointGAttackType.LEVEL;
aaWP.Action = AiAirWayPointType.GATTACK_TARG;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = WaitingTargetWay(airGroup);
}
}
else airGroupWay = LandingWay(airGroup);
}

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
AiAirGroup enemyGroup = FindAirTarget(airGroup) as AiAirGroup;

if (enemyGroup == null)
return;

if (airGroup.hasCourseWeapon())
{
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = LandingWay(airGroup);
}
}
if (airGroupWay != null)
{
foreach (AiWayPoint aWP in airGroupWay)
{
if (aWP == null)
return;
}
airGroup.SetWay(airGroupWay);
}
}

internal void SetNewFighterTask(AiAirGroup airGroup, AiAirGroup enemyGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];

double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
if (enemyGroup == null)
return;
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
if (airGroupWay != null) airGroup.SetWay(airGroupWay);
}

public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
{
base.OnActorTaskCompleted(missionNumber, shortName, actor);
AiAirGroup airGroup = actor as AiAirGroup;
if ((airGroup != null) && (missionNumber != AirStrikeMissNum))
{
SetNewTask(airGroup);
}
}

public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
if (missionNumber != AirStrikeMissNum)
{
AiAirGroup airGroup = actor as AiAirGroup;
if (airGroup != null)
{
SetNewTask(airGroup);
AiAirGroup[] eGroups = GamePlay.gpAirGroups((airGroup.Army() == 1) ? 2 : 1);
if (eGroups != null)
foreach (AiAirGroup eGroup in eGroups)
{
if (eGroup != null)
{
if ((eGroup.hasCourseWeapon()) && ((airGroup.isAircraftType(AircraftType.Fighter)) || (airGroup.isAircraftType(AircraftType.HeavyFighter ))))
{
AiWayPoint[] chkWP = eGroup.GetWay();
bool res = true;
foreach (AiWayPoint eWP in chkWP)
{
AiAirWayPoint aAWP = (eWP as AiAirWayPoint);
if ((aAWP.Action != AiAirWayPointType.HUNTING) || (aAWP.Action != AiAirWayPointType.NORMFLY) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())))
{
res = false;
break;
}
}
if (res)
{
SetNewFighterTask(eGroup, airGroup);
}
}
}
}
}
}
}
///////////////ENDE
}





how exactly does the AI behave differently with than without the script???
how can i imagine that?
if i set waypoints for a AI group, will they act spontaniously when they get in the surrounding of enemies, and ignore there waypoints?
or will they know automatically where all enemies are on the map, when they get spawned, and fly to that point?

hc_wolf
04-24-2012, 11:41 PM
They should fly to nearest enemy. If you have their AI level set to ace and maybe dull doen their gunnery and some otheres ... if attacked they will split up. If attack stops or one gunned down the others will form up and continue onto target

David198502
04-25-2012, 06:04 AM
ok, but how do they "know" the position of the enemy?will it be updated with every waypoint?or do they have this information only once at their spawnpoint?

well, i copied the script, and used it for a mission, where i spawn one group of 109s on an airfield in france, and spits at manston.....the strange thing is, that the spitfires never take off.
the 109s will fly directly to manston and attack the spits which are still on the ground.
as soon as i delete the script, the spitfires will take off normally.

David198502
06-14-2012, 01:00 PM
using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using maddox.GP;


public class Mission : AMission
{
int AirStrikeMissNum = -1;

internal AiActor FindGroundTarget(int army, Point3d attackerPos)
{
AiActor result = null;
AiGroundGroup[] enemyGG = GamePlay.gpGroundGroups((army == 1) ? 2 : 1);
if (enemyGG != null)
{
result = enemyGG[0];
for (int i = 1; i < enemyGG.Length; i++)
{
if (enemyGG[i] != null)
if (result.Pos().distance(ref attackerPos) > enemyGG[i].Pos().distance(ref attackerPos))
{ result = enemyGG[i]; }
}
}
return result;
}

internal AiActor FindAirTarget(AiAirGroup myGroup)
{
AiActor result = null;
AiAirGroup[] enemyAG = GamePlay.gpAirGroups((myGroup.Army() == 1) ? 2 : 1);
Point3d attackerPos = myGroup.Pos();
if (enemyAG != null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (eGroup.isAircraftType(AircraftType.Bomber) || eGroup.isAircraftType(AircraftType.DiveBomber))
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
if (result == null)
{
foreach (AiAirGroup eGroup in enemyAG)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > eGroup.Pos().distance(ref attackerPos))
result = eGroup;
}
else result = eGroup;
}
}
}
return result;
}


internal AiAirport FindOurAirfield(int army, AiActor actor)
{
AiAirport result = null;
Point3d attackerPos = actor.Pos();
AiAirport[] airports = GamePlay.gpAirports();

if (airports != null)
{
foreach (AiAirport airport in airports)
{
if (GamePlay.gpFrontArmy(airport.Pos().x, airport.Pos().y) == army)
{
if (result != null)
{
if (result.Pos().distance(ref attackerPos) > airport.Pos().distance(ref attackerPos))
result = airport;
}
else result = airport;
}
}
}
return result;
}


internal AiWayPoint[] LandingWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[1];

if (airGroup.GetWay().Length != 1)
{
Point3d curPos = airGroup.Pos();
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);

AiAirport findOurAirfield = FindOurAirfield(airGroup.Army(), airGroup);
if (findOurAirfield != null)
{
curPos = findOurAirfield.Pos();
AiAirWayPoint aaWP = new AiAirWayPoint(ref curPos, speed);
aaWP.Action = AiAirWayPointType.LANDING;
aaWP.Target = findOurAirfield;
result[0] = aaWP;
}
else
{
result = WaitingTargetWay(airGroup);
}
}
else result = airGroup.GetWay();

return result;
}

internal AiWayPoint[] WaitingTargetWay(AiAirGroup airGroup)
{
AiWayPoint[] result = new AiWayPoint[3];
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = airGroup.Pos();
addPoint.add(2000, 2000, 0);
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{ aaWP.Action = AiAirWayPointType.HUNTING; }
else aaWP.Action = AiAirWayPointType.NORMFLY;
result[0] = aaWP;
addPoint.add(-1500, -1500, 0);
aaWP.P = addPoint;
result[1] = aaWP;
addPoint.add(1000, 1000, 0);
aaWP.P = addPoint;
aaWP.Action = AiAirWayPointType.LANDING;
result[2] = aaWP;
return result;
}

internal void SetNewTask(AiAirGroup airGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];
if ((chkWP.Length == 1) && ((chkWP[0] as AiAirWayPoint).Action == AiAirWayPointType.LANDING))
{
return;
/*if (((chkWP[0] as AiAirWayPoint).Target as AiAirport) != null)
if (GamePlay.gpFrontArmy(((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().x, ((chkWP[0] as AiAirWayPoint).Target as AiAirport).Pos().y) == airGroup.Army())
{ return; }
else
{
airGroupWay = WaitingTargetWay(airGroup);
airGroup.SetWay(airGroupWay);
return;
} */
}
double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Bomber) || airGroup.isAircraftType(AircraftType.DiveBomber))
{
AiActor nearestGT = FindGroundTarget(airGroup.Army(), airGroup.Pos());
if (airGroup.hasBombs())
{
if (nearestGT != null)
{
aaWP.P = nearestGT.Pos();
aaWP.P.z = curPos.z;
aaWP.Target = nearestGT;
aaWP.GAttackType = AiAirWayPointGAttackType.LEVEL;
aaWP.Action = AiAirWayPointType.GATTACK_TARG;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = WaitingTargetWay(airGroup);
}
}
else airGroupWay = LandingWay(airGroup);
}

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
AiAirGroup enemyGroup = FindAirTarget(airGroup) as AiAirGroup;

if (enemyGroup == null)
return;

if (airGroup.hasCourseWeapon())
{
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
else
{
airGroupWay = LandingWay(airGroup);
}
}
if (airGroupWay != null)
{
foreach (AiWayPoint aWP in airGroupWay)
{
if (aWP == null)
return;
}
airGroup.SetWay(airGroupWay);
}
}

internal void SetNewFighterTask(AiAirGroup airGroup, AiAirGroup enemyGroup)
{
AiWayPoint[] chkWP = airGroup.GetWay();

Point3d curPos = airGroup.Pos();
AiWayPoint[] airGroupWay = new AiWayPoint[2];

double speed = (airGroup.GetItems()[0] as AiAircraft).getParameter(part.ParameterTypes.Z_Vel ocityTAS, -1);
Point3d addPoint = curPos;
AiAirWayPoint aaWP = new AiAirWayPoint(ref addPoint, speed);
aaWP.Action = AiAirWayPointType.NORMFLY;
airGroupWay[0] = aaWP;

if (airGroup.isAircraftType(AircraftType.Fighter) || airGroup.isAircraftType(AircraftType.HeavyFighter) )
{
if (enemyGroup == null)
return;
aaWP.P = enemyGroup.Pos();
aaWP.Target = enemyGroup;
if (enemyGroup.isAircraftType(AircraftType.Bomber) || enemyGroup.isAircraftType(AircraftType.DiveBomber) )
aaWP.Action = AiAirWayPointType.AATTACK_BOMBERS;
else aaWP.Action = AiAirWayPointType.AATTACK_FIGHTERS;
airGroupWay[1] = aaWP;
}
if (airGroupWay != null) airGroup.SetWay(airGroupWay);
}

public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
{
base.OnActorTaskCompleted(missionNumber, shortName, actor);
AiAirGroup airGroup = actor as AiAirGroup;
if ((airGroup != null) && (missionNumber != AirStrikeMissNum))
{
SetNewTask(airGroup);
}
}

public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
base.OnActorCreated(missionNumber, shortName, actor);
if (missionNumber != AirStrikeMissNum)
{
AiAirGroup airGroup = actor as AiAirGroup;
if (airGroup != null)
{
SetNewTask(airGroup);
AiAirGroup[] eGroups = GamePlay.gpAirGroups((airGroup.Army() == 1) ? 2 : 1);
if (eGroups != null)
foreach (AiAirGroup eGroup in eGroups)
{
if (eGroup != null)
{
if ((eGroup.hasCourseWeapon()) && ((airGroup.isAircraftType(AircraftType.Fighter)) || (airGroup.isAircraftType(AircraftType.HeavyFighter ))))
{
AiWayPoint[] chkWP = eGroup.GetWay();
bool res = true;
foreach (AiWayPoint eWP in chkWP)
{
AiAirWayPoint aAWP = (eWP as AiAirWayPoint);
if ((aAWP.Action != AiAirWayPointType.HUNTING) || (aAWP.Action != AiAirWayPointType.NORMFLY) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())) || ((aAWP.Action == AiAirWayPointType.AATTACK_BOMBERS) && (aAWP.Target != null) && (aAWP.Target.IsValid())))
{
res = false;
break;
}
}
if (res)
{
SetNewFighterTask(eGroup, airGroup);
}
}
}
}
}
}
}
///////////////ENDE
}

is this really working for you guys?
as soon as i insert the script, all my RAF planes will not take off anymore for some dubious reason...
the 109s though, will take off, fly all over the channel,ignoring their waypoints, and strave the spits on the airfield, who still sit on the ground.
it seems to work fine with 109s, but raf planes, at least spits and hurris, just wont take off....