Code:
using System.Text;
using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using part;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Reflection;
using maddox.GP;
using System.Text.RegularExpressions;
public class Mission : AMission
{
Random random = new Random();
// random AA on battle startup (generate random AA at airfields on battle start)
bool GenerateRandomAA = true; // turn random AA at airfields on/off
bool SpawnBasesAAOnly = false; // random AA generated at spawn airfields only
int ChanceSpawnbaseHasAA = 100; // percent chance a spawn base has AA defences
int ChanceNonSpawnbaseHasAA = 0; // percent chance a non-spawn base has AA defences
int RedMinAirfieldAA = 10; // minimum number of AA units at red airfields
int RedMaxAirfieldAA = 12; // maximum number of AA units at red airfields
int BlueMinAirfieldAA = 10; // minimum number of AA units at blue airfields
int BlueMaxAirfieldAA = 12; // maximum number of AA units at blue airfields
public override void OnBattleStarted()
{
base.OnBattleStarted();
if (GenerateRandomAA ) GenerateRandomAAatAirfields();
}
public void GenerateRandomAAatAirfields()
{ // spawn random AA at airfields
List<string> AlliedAA = new List<string>
{
"Artillery.3_inch_20_CWT_QF_Mk_I gb",
"Artillery.3_7_inch_QF_Mk_I gb",
"Artillery.Bofors gb",
"Artillery.20_mm_Flak_38 gb"
};
List<string> AxisAA = new List<string>
{
"Artillery.Flak30_Shield de",
"Artillery.Flak37 de",
"Artillery.20_mm_Flak_38 de",
"Artillery.Zwillingssockel36_GER1 de",
"Artillery.4_cm_Flak_28 de"
};
// do some parameter intergity checks
if (ChanceSpawnbaseHasAA > 100) ChanceSpawnbaseHasAA = 100;
if (ChanceSpawnbaseHasAA < 0) ChanceSpawnbaseHasAA = 0;
if (ChanceNonSpawnbaseHasAA > 100) ChanceNonSpawnbaseHasAA = 100;
if (ChanceNonSpawnbaseHasAA < 0) ChanceNonSpawnbaseHasAA = 0;
if (RedMinAirfieldAA < 0) RedMinAirfieldAA = 0;
if (BlueMinAirfieldAA < 0) BlueMinAirfieldAA = 0;
if (RedMaxAirfieldAA < RedMinAirfieldAA) RedMaxAirfieldAA = RedMinAirfieldAA;
if (BlueMaxAirfieldAA < BlueMinAirfieldAA) BlueMaxAirfieldAA = BlueMinAirfieldAA;
int staticno = 0;
ISectionFile f = GamePlay.gpCreateSectionFile();
foreach (AiAirport TargetAirport in GamePlay.gpAirports()) // loop through all map airfields
{
Point2d port = new Point2d(); // remember the airfield position
port.x = TargetAirport.Pos().x;
port.y = TargetAirport.Pos().y;
if (IsInBattleZone(port)) // is airfield inside the battle zone grid?
{
Point2d AApos = new Point2d(); // create a point for the AA position
int AirportArmy = GetArmyAtPoint(port.x, port.y); // remember the airport army
if (AirportArmy == 0) AirportArmy = TargetAirport.Army(); // remember the airport army
// ------------------------------------------------------------------------------------------------
// ALLIED ARMY SPAWN BASES
// ------------------------------------------------------------------------------------------------
if (AirportArmy == 1 && IsBirthplace(TargetAirport)) // airfield is allied army & a spawn point
{
if (random.Next(100) < ChanceSpawnbaseHasAA) // chance a spawn airfield has AA defences
{
int i = random.Next(RedMinAirfieldAA, RedMaxAirfieldAA + 1); // decide how many AA units to spawn at the airfield
for (int j = 0; j < i; j++)
{
// find a suitable AA position close to, but just outside, the airfield perimeter
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
while (port.distance(ref AApos) < (TargetAirport.FieldR() * 0.95) || IsInvalidAAposition(AApos, 100))
{
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
};
// make a new unique static object number for mission file
staticno++;
if (j == 0)
{ // at least one black flak unit
f.add("Stationary", "Static" + staticno.ToString("0000"), AlliedAA[0] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0/skill 1");
}
else
{
int rnd = random.Next(AlliedAA.Count);
f.add("Stationary", "Static" + staticno.ToString("0000"), AlliedAA[rnd] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0/skill 1");
}
}
}
}
// ------------------------------------------------------------------------------------------------
// AXIS ARMY SPAWN BASES
// ------------------------------------------------------------------------------------------------
if (AirportArmy == 2 && IsBirthplace(TargetAirport)) // airfield is axis army & a spawn point
{
if (random.Next(100) < ChanceSpawnbaseHasAA) // chance a spawn airfield has AA defences
{
int i = random.Next(BlueMinAirfieldAA, BlueMaxAirfieldAA + 1); // decide how many AA units to spawn at the airfield
for (int j = 0; j < i; j++)
{
// find a suitable AA position close to, but just outside, the airfield perimeter
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
while (port.distance(ref AApos) < (TargetAirport.FieldR() * 0.95) || IsInvalidAAposition(AApos, 100))
{
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
};
// make a new unique static object number for mission file
staticno++;
if (j == 0)
{ // at least one black flak unit
f.add("Stationary", "Static" + staticno.ToString("0000"), "Artillery.20_mm_Flak_38 de " + AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0");
}
else
{
int rnd = random.Next(AxisAA.Count);
f.add("Stationary", "Static" + staticno.ToString("0000"), AxisAA[rnd] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0");
}
}
}
if (!SpawnBasesAAOnly) // do we also want AA units at non-spawn bases?
{
// ------------------------------------------------------------------------------------------------
// ALLIED ARMY NON-SPAWN BASES
// ------------------------------------------------------------------------------------------------
if (AirportArmy == 1 && !IsBirthplace(TargetAirport)) // airfield is allied army & NOT a spawn point
{
if (random.Next(100) < ChanceNonSpawnbaseHasAA) // chance a non-spawn airfield has AA defences
{
int i = random.Next(RedMinAirfieldAA, RedMaxAirfieldAA + 1); // decide how many AA units to spawn at the airfield
for (int j = 0; j < i; j++)
{
// find a suitable AA position close to, but just outside, the airfield perimeter
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
while (port.distance(ref AApos) < (TargetAirport.FieldR() * 0.95) || IsInvalidAAposition(AApos, 100))
{
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
};
// make a new unique static object number for mission file
staticno++;
if (j == 0)
{ // at least one black flak unit
f.add("Stationary", "Static" + staticno.ToString("0000"), AlliedAA[0] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0/skill 1");
Point3d p;
p.x = AApos.x;
p.y = AApos.y;
p.z = 0;
}
else
{
int rnd = random.Next(AlliedAA.Count);
f.add("Stationary", "Static" + staticno.ToString("0000"), AlliedAA[rnd] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0/skill 1");
}
}
}
}
if (AirportArmy == 2 && !IsBirthplace(TargetAirport)) // airfield is axis army & NOT a spawn point
{
// ------------------------------------------------------------------------------------------------
// AXIS ARMY NON-SPAWN BASES
// ------------------------------------------------------------------------------------------------
if (random.Next(100) < ChanceNonSpawnbaseHasAA) // chance a non-spawn airfield has AA defences
{
int i = random.Next(BlueMinAirfieldAA, BlueMaxAirfieldAA + 1); // decide how many AA units to spawn at the airfield
for (int j = 0; j < i; j++)
{
// find a suitable AA position close to, but just outside, the airfield perimeter
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
while (port.distance(ref AApos) < (TargetAirport.FieldR() * 0.95) || IsInvalidAAposition(AApos, 100))
{
AApos = GetRandomPointInsideCircle(TargetAirport.Pos().x, TargetAirport.Pos().y, TargetAirport.FieldR() * 0.70 * 1.25);
};
// make a new unique static object number for mission file
staticno++;
if (j == 0)
{ // at least one black flak unit
f.add("Stationary", "Static" + staticno.ToString("0000"), "Artillery.20_mm_Flak_38 de " + AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0");
}
else
{
int rnd = random.Next(AxisAA.Count);
f.add("Stationary", "Static" + staticno.ToString("0000"), AxisAA[rnd] + " " +
AApos.x.ToString() + " " + AApos.y.ToString() + " " + random.Next(1, 178 + 1).ToString() + " /timeout 0/radius_hide 0");
}
}
}
}
}
}
else
{ // write an error message to the concole
//Console.WriteLine("CAUTION: Could not spawn AA at " + TargetAirport.Name() + "(army=" + AirportArmy.ToString() + ") [GenerateRandomAAatAirfields]");
}
}
}
GamePlay.gpPostMissionLoad(f); // load the mission with the AA units
}
public bool IsBirthplace(AiAirport airfield)
{
bool result = false;
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
Point3d p = bp.Pos();
if (airfield.Pos().distance(ref p) <= airfield.CoverageR() || airfield.Pos().distance(ref p) <= airfield.FieldR())
{
result = true;
}
}
return result;
}
public bool IsInBattleZone(Point2d p)
{ // returns true if specified point is inside the battle zone grid
bool result = false;
string sector = GamePlay.gpSectorName(p.x, p.y); // get the sector at the specified point
string[] words = sector.Split(','); // break up the sector name
string axis1 = words[0]; // first part is X axis
string axis2 = words[1]; // second part is Y axis
// is it inside the battle grid?
if (Regex.IsMatch(axis1, @"^[a-zA-Z0-9]+$") && Regex.IsMatch(axis2, @"^[a-zA-Z0-9]+$")) result = true;
return result;
}
public bool IsInvalidAAposition(Point2d point, double radius)
{
bool result = false;
Point3d p = new Point3d();
p.x = point.x;
p.y = point.y;
p.z = 0;
// too close to other ground units
try
{
foreach (GroundStationary gs in GamePlay.gpGroundStationarys())
{
if (gs.pos.distance(ref p) <= radius) result = true;
}
}
catch { }
// wrong terrain
if (GamePlay.gpLandType(point.x, point.y) == LandTypes.RAIL || GamePlay.gpLandType(point.x, point.y) == LandTypes.ROAD ||
GamePlay.gpLandType(point.x, point.y) == LandTypes.WATER || GamePlay.gpLandType(point.x, point.y) == LandTypes.OBJECTS_MASK ||
GamePlay.gpLandType(point.x, point.y) == LandTypes.ROAD_MASK || GamePlay.gpLandType(point.x, point.y) == LandTypes.HIGHWAY ||
GamePlay.gpLandType(point.x, point.y) == LandTypes.CITY) result = true;
// outside the battle zone?
if (!IsInBattleZone(point)) result = true;
return result;
}
catch { return true; }
}
public int GetArmyAtPoint(double x, double y)
{
int result = 0;
result = GamePlay.gpFrontArmy(x, y);
return result;
}
public Point2d GetRandomPointInsideCircle(double x, double y, double r)
{ // return a random 2d point inside circle with center x, y and radius r (meters)
Point2d p = new Point2d();
p.x = x + r * Math.Cos(random.Next());
p.y = y + r * Math.Sin(random.Next());
return p;
}
}
Bookmarks