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:
Code:
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_VelocityTAS, -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_VelocityTAS, -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_VelocityTAS, -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_VelocityTAS, -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
}