This dictionary provides **clear explanations** and **examples** for each function in **TWC.cs**.
Comments by Flug & Fatal are highlighted in green for easy reference,hope this helps all you new coders out there.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
public aPlayer()
{
player = null;
name = "";
army = 0;
}
public aPlayer (aPlayer p )
{
player = p;
name = player.Name();
army = player.Army();
}
public aPlayer(Player p)
{
player = p;
name = player.Name();
army = player.Army();
}
public aPlayer(string n, int a)
{
name = n;
army = a;
}
/*
public override bool Equals(Object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
else return this == (aPlayer)obj;
}
public override int GetHashCode()
{
return Tuple.Create(name, army).GetHashCode();
}
public static bool operator ==(aPlayer x, aPlayer y)
{
return x.name == y.name && x.army == y.army;
}
public static bool operator !=(aPlayer x, aPlayer y)
{
return !(x == y);
}
public override String ToString()
{
return String.Format("({0}, {1})", name, army);
}
*/
}
[DataContract]
public class aAiAirport : AiAirport
{
[DataMember] public string name;
[DataMember] public int army;
[DataMember] public Point3d pos;
[DataMember] public object Tag { get; set; }
private AiAirport ap;
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
public maddox.game.world.AiActor[] QueueLanding() { return null; }
public maddox.game.world.AiActor[] QueueTakeoff() { return null; }
public maddox.game.world.AiGroup Group() { return null; }
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
No description available.
// No example provided.
public class Mission : AMission, IMainMission public class Mission : BaseMission, IMainMission //Constants constants; public int PERCENT_SUBMISSIONS_TO_LOAD = 100; //percentage of the aircraft sub-missions to load. 50 will load just half of the sub-missions etc...
Random ran = new Random();
public aAiAirport()
{
ap = null;
name = "aAirfield_" + ran.Next(999).ToString();
army = 0;
pos = new Point3d(0, 0, 0);
}
public aAiAirport(aAiAirport a)
{
ap = a;
name = a.Name();
army = a.Army();
pos = a.Pos();
}
public aAiAirport(maddox.game.world.AiAirport a)
{
ap = a;
name = a.Name();
army = a.Army();
pos = a.Pos();
}
public aAiAirport(string name, int army, Point3d pos
)
{
this.name = name;
this.army = army;
this.pos = pos;
}
public aAiAirport(maddox.game.world.AiAirport ap, string name, int army, Point3d pos
)
{
this.ap = ap;
this.name = name;
this.army = army;
this.pos = pos;
}
/*
public override bool Equals(Object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
else return this == (aPlayer)obj;
}
public override int GetHashCode()
{
return Tuple.Create(name, army).GetHashCode();
}
public static bool operator ==(aPlayer x, aPlayer y)
{
return x.name == y.name && x.army == y.army;
}
public static bool operator !=(aPlayer x, aPlayer y)
{
return !(x == y);
}
public override String ToString()
{
return String.Format("({0}, {1})", name, army);
}
*/
}
public class Mission : AMission, IMainMission
{
public Random random, stb_random;
public string MISSION_ID { get; set; }
public string CAMPAIGN_ID { get; set; }
public string SERVER_ID { get; set; }
public string SERVER_ID_SHORT { get; set; }
public string CLOD_PATH { get; set; }
public string FILE_PATH { get; set; }
public string MISSION_FILE_FULL_PATH { get; set; }
public bool DEBUG { get; set; }
public ABattle gpBattle;
public CoverMission covermission;
public StatsMission statsmission;
public SupplyMission supplymission;
public AIRadarMission airadarmission;
public ASVRadarMission asvradarmission;
public KnickebeinMission knickebeinmission;
public ObjectiveRepairMission objectiverepairmission;
public MoveBombTargetMission movebombtargetmission;
public LandingGroundMission landinggroundmission;
public SkinCheckMission skincheckmission;
public ThreadLoadMission threadloadmission;
public string MISSION_FOLDER_PATH;
public string USER_DOC_PATH;
public string stb_FullPath;
public Dictionary radarpasswords;
public string BOMBERMISSIONS_FILE_PATH;
public string MESSAGE_FILE_NAME;
public string MESSAGE_FULL_PATH;
public string STATS_FILE_NAME;
public string STATS_FULL_PATH { get; set; }
public string LOG_FILE_NAME;
public string LOG_FULL_PATH;
public string STATSCS_FULL_PATH { get; set; }
public int RADAR_REALISM;
public Dictionary MissionObjectivesList { get; set; }
static public List ArmiesL = new List() { "None", "Red", "Blue" };
public bool MISSION_STARTED = false;
public bool WAIT_FOR_PLAYERS_BEFORE_STARTING_MISSION_ENABLED = false;
public int START_MISSION_TICK = -1;
public double START_MISSION_TIME_HRS = 0;
public bool END_MISSION_IF_PLAYERS_INACTIVE = false;
public bool COOP_START_MODE_ENABLED = false;
public bool COOP_START_MODE = false;
public double COOP_MODE_TIME_SEC = 45;
public int START_COOP_TICK = -1;
public double COOP_TIME_LEFT_MIN = 9999;
public int ticksperminute = 1986;
Stopwatch stopwatch;
ConcurrentDictionary>> radar_messages_store;
public ConcurrentDictionary> ai_radar_info_store { get; set; }
public string[] admins_basic = new String[] { "TWC_" };
public string[] admins_full = new String[] { "TWC_Flug", "EvilUg", "TWC_Fatal_Error", "Server" };
public bool ON_TESTSERVER = false;
public bool ON_JUBILEE = false;
int allowedSpitIIas = 4;
int currentSpitIIas = 0;
int allowed109s = 4;
int current109s = 0;
double redMultAdmin = 0;
double blueMultAdmin = 0;
public int numBlueAircraft = 0;
public int numRedAircraft = 0;
public int numTotalAircraft = 0;
public MissionObjectives mission_objectives = null;
public Mission()
{
try {
Console.WriteLine("#1");
TWCComms.Communicator.Instance.WARP_CHECK = false;
statsmission = new StatsMission(this);
airadarmission = new AIRadarMission(this);
asvradarmission = new ASVRadarMission(this);
knickebeinmission = new KnickebeinMission(this);
objectiverepairmission = new ObjectiveRepairMission(this);
movebombtargetmission = new MoveBombTargetMission(this);
if (ON_JUBILEE)
{
radarpasswords = new Dictionary
{
};
} else
{
radarpasswords = new Dictionary
{
};
}
random = new Random();
stb_random = random;
ON_JUBILEE = false;
if (ON_JUBILEE)
{
MISSION_ID = @"Jubilee";
} else
{
}
if (Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToLower().Contains("brent"))
{
ON_TESTSERVER = true;
}
if (Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToLower().Contains("twc_server3") ||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToLower().Contains("twc_server4"))
{
ON_TESTSERVER = true;
ON_JUBILEE = false;
radarpasswords = new Dictionary
{
};
}
MAP_WIN_POINTS = 30000;
if (ON_JUBILEE) MAP_WIN_POINTS = 14000;
DEBUG = false;
LOG = false;
stb_FullPath = CLOD_PATH + FILE_PATH;
MISSION_FILE_FULL_PATH = CLOD_PATH + this.PathMyself;
MESSAGE_FILE_NAME = MISSION_ID + @"_message_log.txt";
MESSAGE_FULL_PATH = CLOD_PATH + FILE_PATH + @"/" + MESSAGE_FILE_NAME;
STATS_FILE_NAME = MISSION_ID + @"_stats_log.txt";
STATS_FULL_PATH = CLOD_PATH + FILE_PATH + @"/" + STATS_FILE_NAME;
LOG_FILE_NAME = MISSION_ID + @"_log_log.txt";
LOG_FULL_PATH = CLOD_PATH + FILE_PATH + @"/" + LOG_FILE_NAME;
stopwatch = Stopwatch.StartNew();
RADAR_REALISM = (int)5;
RESULTS_OUT_FILE = CLOD_PATH + FILE_PATH + @"/" + "MissionResult.txt";
radar_messages_store = new ConcurrentDictionary>>() { };
ai_radar_info_store = new ConcurrentDictionary>() { };
MissionObjectivesList = new Dictionary();
GiantSectorOverview[1] = new int[10, 2];
GiantSectorOverview[2] = new int[10, 2];
landinggroundmission = new LandingGroundMission(this);
}
catch (Exception ex) { Console.WriteLine("ERROR Mission Constructor #!: " + ex.ToString()); }
}
No description available.
{
if (player == null) return;
if (player.Army() != 1 && player.Army() != 2)
{
twcLogServer(new Player[] { player }, "Can't give you the radar password - you haven't chosen an army.");
return;
}
string armyName = "Red";
if (player.Army() == 2) armyName = "Blue";
twcLogServer(new Player[] { player }, ">>>>Visit TWCPilots.com for the link to the General Situation Map/online radar.");
twcLogServer(new Player[] { player }, ">>>>Login using the ENGLISH CHANNEL section and " + SERVER_ID_SHORT.ToUpper() + " SERVER.");
twcLogServer(new Player[] { player }, ">>>>PLEASE keep the password secure and share only with other {0} team members.", new object[] { armyName });
twcLogServer(new Player[] { player }, ">>>>Password for {0} radar is:", new object[] { armyName });
twcLogServer(new Player[] { player }, ">>>> " + radarpasswords[-player.Army()]);
}
public Dictionary SMissionObjectivesList()
{
var ret = new Dictionary();
foreach (string key in MissionObjectivesList.Keys.ToList())
{
ret[key] = MissionObjectivesList[key] as IMissionObjective;
}
return ret;
}
/********************************************************
*
* Save campaign state every 3 minutes or so, so that if
* something messes up before end of mission, we
* don't lose all the campaign developments this mission
*
*******************************************************/
private bool SaveCampaignStateIntermediate_firstRun = true;
Timeout(182.78, () => { SaveCampaignStateIntermediate(); }); //every 3 minutes or so, save if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MOSXX2 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //StartupSave doesn't try to calculate supply adjustments etc //SaveMapState("", intermediateSave: true); //Task.Run(() => MO_WriteMissionObjects()); //no need to run this so early, there is nothing to save yet anyway //SaveMapState("", true);
{
if (!MISSION_STARTED) return;
if (SaveCampaignStateIntermediate_firstRun)
{
Task.Run(() => SaveMapState("", intermediateSave: true));
SaveCampaignStateIntermediate_firstRun = false;
} else
{
Task.Run(() => SaveMapState("", intermediateSave: true));
Task.Run(() => MO_WriteMissionObjects());
}
}
//remove players from aircraft/destroy it, if the aircraft has taken off //If it is too far away from an airport, destroy (this takes care of tanks etc going rogue overland during the coop start period)
{
/************************************************
*
* Check to see if COOP mode is still on & if so,
* make sure that no aircraft or ie tanks have moved
* too far, or have taken off OR are going too fast
*
* If so they will just be destroyed
*
* Recursive function called every X seconds
************************************************/
if (!COOP_START_MODE) return;
Timeout(5, () => { CheckCoop(); });
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player p in GamePlay.gpRemotePlayers())
{
if (p.Place() != null)
{
AiActor act = p.Place();
AiAircraft air = p.Place() as AiAircraft;
if (air != null && air.IsAirborne())
{
Stb_RemoveAllPlayersFromAircraftandDestroy(air, p, 0, 1.0);
twcLogServer(new Player[] { p }, "CO-OP START: You took off before Mission Start Time.", null);
twcLogServer(new Player[] { p }, "Your aircraft was destroyed.", null);
}
else if (Stb_distanceToNearestAirport(act) > 2500)
{
Stb_RemovePlayerFromCart(act as AiCart, p);
twcLogServer(new Player[] { p }, "CO-OP START: You left the airport or spawn point before Mission Start Time; " + Stb_distanceToNearestAirport(act).ToString("n0") + " meters to nearest airport or spawn point", null);
twcLogServer(new Player[] { p }, "You have been removed from your position.", null);
}
}
}
}
}
bool EndMissionIfPlayersInactive_initialized = false;
DateTime LastTimePlayerLoggedIn = DateTime.UtcNow;
DateTime LastTimePlayerInPlace = DateTime.UtcNow;
//Before the mission official starts, we still update the times as though players were in place - reason is, we could get in some weird situation where the mission //was paused because of one of these modes, put we somehow get a sample of the time, then wait 30 minutes, then someone jumps in to play & we restart, //noticing there has a been a 30 minute delay & kill the game. Which would not be good...
{
/************************************************
*
*We check every minute or so to see if any players are logged on
* and if so, if they are actually in a place.
*
* If the mission is active & no one has logged in for 7.5 minutes the mission will end.
*
* If the mission is active & no one been in a place (ie, in an aircraft, tank, etc0 for 15 minutes the mission will end
*
* This is to prevent AI from marching forward & destroying all the mission targets, and thus moving the campaign maps around by huge amounts, when no one is even playing
*
* Also it could potentially ward off some cheating type behaviors, if people realize that AI tends to score more points for one side or the other when no one is playing, then
* they could just start a mission & leave it, just to rack up points for their side.
*
* Recursive function called every X seconds
************************************************/
Timeout(63.25, () => { EndMissionIfPlayersInactive(); });
if (!END_MISSION_IF_PLAYERS_INACTIVE) return;
if (!MISSION_STARTED || COOP_START_MODE)
{
LastTimePlayerLoggedIn = DateTime.UtcNow;
LastTimePlayerInPlace = DateTime.UtcNow;
return;
}
if (!EndMissionIfPlayersInactive_initialized)
{
LastTimePlayerLoggedIn = DateTime.UtcNow;
LastTimePlayerInPlace = DateTime.UtcNow;
EndMissionIfPlayersInactive_initialized = true;
return;
}
if (GamePlay.gpPlayer() != null && GamePlay.gpPlayer().Place() != null)
{
LastTimePlayerLoggedIn = DateTime.UtcNow;
LastTimePlayerInPlace = DateTime.UtcNow;
}
{
LastTimePlayerLoggedIn = DateTime.UtcNow;
if (GamePlay.gpRemotePlayers() != null && GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player p in GamePlay.gpRemotePlayers())
{
if (p.Place() != null)
{
LastTimePlayerInPlace = DateTime.UtcNow;
}
}
}
}
if (LastTimePlayerLoggedIn.AddMinutes(7.5) < DateTime.UtcNow || LastTimePlayerInPlace.AddMinutes(15) < DateTime.UtcNow)
{
EndMission(0);
}
}
bool OnTick_End_Mission_Triggered = false;
public override void OnTickGame()
{
base.OnTickGame();
/* Tick_Mission_Time = 720000 - Time.tickCounter();
var Mission_Time = Tick_Mission_Time / 2000;
TimeSpan Convert_Ticks = TimeSpan.FromMinutes(Mission_Time);
string Time_Remaining = string.Format("{0:D2}:{1:D2}:{2:D2}", Convert_Ticks.Hours, Convert_Ticks.Minutes, Convert_Ticks.Seconds);
*/
if (!MISSION_STARTED)
{
if (Time.tickCounter() % (2 * ticksperminute) == 0)
{
int timewaitingminutes = Convert.ToInt32(((double)Time.tickCounter() / (double)ticksperminute));
DebugAndLog("Waiting for first player to join; waiting " + timewaitingminutes.ToString() + " minutes");
}
return;
}
if (START_COOP_TICK == -1) START_COOP_TICK = Time.tickCounter();
if (COOP_START_MODE)
{
int tickSinceCoopStarted = Time.tickCounter() - START_COOP_TICK;
if (tickSinceCoopStarted >= Convert.ToInt32((COOP_MODE_TIME_SEC * (double)ticksperminute) / 60.0))
{
COOP_START_MODE = false;
Stb_Chat("CO-OP MISSION START NOW!", null);
Stb_Chat("CO-OP START: Pilots, you may take off at will", null);
GamePlay.gpHUDLogCenter("CO-OP MISSION START NOW!");
Timeout(5, () => { GamePlay.gpHUDLogCenter("CO-OP MISSION START NOW!"); });
Timeout(10, () => { GamePlay.gpHUDLogCenter("CO-OP MISSION START NOW!"); });
return;
}
if (tickSinceCoopStarted % (ticksperminute / 4) == 0)
{
COOP_TIME_LEFT_MIN = (COOP_MODE_TIME_SEC / 60 - ((double)tickSinceCoopStarted / (double)ticksperminute));
double timeleftseconds = (COOP_MODE_TIME_SEC - ((double)tickSinceCoopStarted) * 60.0 / (double)ticksperminute);
string s = COOP_TIME_LEFT_MIN.ToString("n2") + " MINUTES";
if (timeleftseconds < 120) s = timeleftseconds.ToString("n0") + " SECONDS";
if (tickSinceCoopStarted % ticksperminute == 0)
{
Timeout(7.5, () =>
{
foreach (Player p in GamePlay.gpRemotePlayers())
{
{
twcLogServer(new Player[] { p }, "CO-OP MODE CONTROL: Use chat command { GamePlay.gpHUDLogCenter("CO-OP START: DO NOT TAKE OFF for " + s2); });
Timeout(10, () => { GamePlay.gpHUDLogCenter("CO-OP START: DO NOT TAKE OFF for " + s2); });
}
return;
}
if (START_MISSION_TICK == -1)
{
START_MISSION_TICK = Time.tickCounter();
START_MISSION_TIME_HRS = GamePlay.gpTimeofDay();
}
int tickSinceStarted = Time.tickCounter() - START_MISSION_TICK;
if ((tickSinceStarted) % 2100 == 0 && tickSinceStarted > 0)
{
Task.Run(() => RemoveOffMapAIAircraft());
}
if ((tickSinceStarted) % 10100 == 0)
{
if (LOG)
{
DebugAndLog(calcTimeLeft() + " left in mission " + MISSION_ID);
AiAirGroup[] empty = Array.Empty();
int totalAircraft = (GamePlay.gpAirGroups(1) ?? empty).Length + (GamePlay.gpAirGroups(2) ?? empty).Length;
DebugAndLog(totalAircraft.ToString());
}
}
if ((tickSinceStarted) == 0)
{
twcLogServer(null, "Mission loaded.", new object[] { });
Task.Run(() => WriteResults_Out_File("3"));
Timeout(90, () => { groupAllAircraft_recurs(); });
Timeout(95, () => { aiAirGroupRadarReturns_recurs(); });
MO_ObjectiveUndestroyTimer_recurs();
tempFlakTimer_recurs();
/*Timeout(201.3, () => {
MO_ObjectiveUndestroy_recurs();
*/
}
/*
if (false && tickSinceStarted % 7500 == 1000)
{
gpToArmyLogServer(2, "!!BLUE PILOTS!! Red is attacking Reserve Communications Headquarters BD4.2.7 to win the campaign. Defend that sector above all other priorities!", new object[] { });
}
*/
{
twcLogServer(null, "Completed Red Objectives (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):", new object[] { });
twcLogServer(null, MissionObjectivesCompletedString[ArmiesE.Red], new object[] { });
Timeout(10, () =>
twcLogServer(null, "Completed Blue Objectives (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):", new object[] { }));
Timeout(11, () =>
twcLogServer(null, MissionObjectivesCompletedString[ArmiesE.Blue], new object[] { }));
Timeout(12, () =>
twcLogServer(null, showTimeLeft().Item1, new object[] { }));
Timeout(stb_random.Next(56, 623), () =>
{
if (MO_IntelligenceLeakNearMissionEnd[ArmiesE.Blue] != "") sendChatMessageTo((int)ArmiesE.Blue, MO_IntelligenceLeakNearMissionEnd[ArmiesE.Blue], null);
if (MO_IntelligenceLeakNearMissionEnd[ArmiesE.Red] != "") sendChatMessageTo((int)ArmiesE.Red, MO_IntelligenceLeakNearMissionEnd[ArmiesE.Red], null);
});
}
{
Console.WriteLine("EndMissTick/Time: {0} {1} {2} {3} {4} ", tickSinceStarted, MISSION_LENGTH_HRS, GamePlay.gpTimeofDay(), END_MISSION_TIME_HRS, START_MISSION_TICK);
Task.Run(() => WriteResults_Out_File("3"));
/*
Timeout(10, () =>
{
twcLogServer(null, "The match ends in a tie! Objectives still left for both sides!!!", new object[] { });
GamePlay.gpHUDLogCenter("The match ends in a tie! Objectives still left for both sides!!!");
});
*/
EndMission(70, "");
}
{
if ((Time.tickCounter()) % 1000 == 0)
{
}
if ((Time.tickCounter()) % 1000 == 334)
{
}
if ((Time.tickCounter()) % 1000 == 666)
{
}
if ((Time.tickCounter()) % 1000 == 813)
{
if (GamePlay is object && GamePlay.gpAirGroups(1) == null) Console.WriteLine("!!!!!!!!!!!!!gpAirGroups(1) IS NULL!!!!!!!!!!!!!!!!!!!!!!!!!!!");
if (GamePlay is object && GamePlay.gpAirGroups(2) == null) Console.WriteLine("!!!!!!!!!!!!!gpAirGroups(2) IS NULL!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
}
}
/************************************************************
*
* REMOVE Spawn points & other objects etc that are in enemy territory
*
*************************************************************/
}); //This can can wait a while, and it helps to wait until various initial submissions are loaded bp.destroy(); //THIS needs to happen IMMEDIATELy, no timeout, or else LoadAirfieldObjectives() doesn't work right
{
Console.WriteLine("removeBirthPlacesInEnemyTerritory: Starting . . . ");
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces().ToList())
{
if (bp == null) continue;
int terr = GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y);
if (terr == 0) continue;
if (terr == bp.Army()) continue;
Console.WriteLine("removeBirthPlacesInEnemyTerritory: Removing BP because it is in enemy territory - " + bp.Name());
Point3d p = bp.Pos();
int army = bp.Army();
Timeout(130, () => {
Calcs.removeStatics(GamePlay, this, p.x, p.y, radius_m: 1800, percentToRemove: 100, army: army);
covermission.removeAllGroundActorsNear_clean(p, radius_m: 1800, percentToRemove: 100, armyToRemove: army);
}
}
//"tank." gets Tank.Matilda etc but not Tanker.Medium. Same for car.
{
Console.WriteLine("removeGroundActorsAndStationariesInEnemyTerritory: Starting . . . ");
List typesToRetain = new List() { "ship", "truck", "tank.", "spg", "car.", "jerrycan_ger" };
covermission.removeGroundActorsOnEnemyTerritory_clean(percentToRemove: 100, army: -1, types_to_remove: null, types_to_retain: typesToRetain, preserveOnWater: true);
typesToRetain = new List() { "jerrycan_ger" };
Calcs.removeStaticsOnEnemyTerritory(GamePlay, this, types_to_remove: null, percentToRemove: 100, armyToRemove: -1, types_to_retain: typesToRetain, preserveOnWater: true, replaceThem: true);
}
if (terr != 0) return; //this only works for mos on NEUTRAL terr radius_m *= 1.2; //clear a slightly larger area //i is the army to remove. For temp landing gnd we want to remove anything NOT owner army //for others, remove enemy flak if operative/not destroyed, and friendly flak //if destroyed Calcs.removeStaticsOnEnemyTerritory(GamePlay, this, types_to_remove: null, percentToRemove: 100, armyToRemove: i, types_to_retain: null, preserveOnWater: false, clearNeutral: true, radius_m: radius_m, center: mo.Pos, replaceThem: true, addX: true); //types is a SUBSTRING MATCH and CASE
{
try
{
int terr = GamePlay.gpFrontArmy(mo.Pos.x, mo.Pos.y);
List typesToRetain = new List() { "ship", "truck", "tank.", "spg", "car.", "jerrycan_ger" };
double radius_m = mo.radius;
if (mo.TriggerDestroyRadius > radius_m) radius_m = mo.TriggerDestroyRadius;
for (int i = 1; i <= 2; i++)
{
if (mo.MOTriggerType == MO_TriggerType.TemporaryLandingGround && mo.OwnerArmy == i) continue;
else if (mo.MOTriggerType != MO_TriggerType.TemporaryLandingGround && mo.Destroyed && mo.AttackingArmy == i) continue;
else if (mo.MOTriggerType != MO_TriggerType.TemporaryLandingGround && !mo.Destroyed && mo.OwnerArmy == i) continue;
Console.WriteLine("clearGroundActorsAndStationariesNearAnObjectiveinNeutralTerritory: Removing army {0} ground actors & statics near " + mo.Name + " at ({1:F0},{2:F0})", i, mo.Pos.x, mo.Pos.y);
covermission.removeAllGroundActorsNear_clean(pos: mo.Pos, radius_m: radius_m, percentToRemove: 100, armyToRemove: i, types_to_remove: null, types_to_retain: typesToRetain, preserveOnWater: true);
Console.WriteLine("clearGroundActorsAndStationariesNearAnObjectiveinNeutralTerritory: 2");
}
}
catch (Exception ex) { Console.WriteLine("***************removeEnemyGroundActorsStationariesNearAnObjectiveInNeutralTerritory ERROR: " + ex.Message); };
}
No description available.
{
if (mo.MOObjectiveType != MO_ObjectiveType.Military_Airfield &&
mo.MOObjectiveType != MO_ObjectiveType.Civilian_Airfield &&
mo.MOObjectiveType != MO_ObjectiveType.Airfield_Complex &&
mo.MOObjectiveType != MO_ObjectiveType.TemporaryLandingGround
) return;
Console.WriteLine("clearGroundActorsAndStationariesNearAnAirfieldinNeutralTerritory: Removing enemy ground actors & statics near " + mo.Name);
removeEnemyGroundActorsStationariesNearAnObjectiveInNeutralTerritory(mo);
}
* //Version for -MAIN.cs// //IN THE PAST AirfieldTargets was the way we tracked airport condition and damage. Now that is done via MissionObjectives and the AirfieldTargets Dictionary is more of a handy way to keep a list of airports in-game...
{
foreach(MissionObjective mo in MissionObjectivesList.Values.ToList())
{
Console.WriteLine("clearGroundActorsAndStationariesNearAllObjectivesinNeutralTerritory: Removing enemy ground actors & statics near " + mo.Name);
removeEnemyGroundActorsStationariesNearAnObjectiveInNeutralTerritory(mo);
}
}
/************************************************************
*
* handle airport bombing
* Credit/script idea for airport bombing & destruction goes to reddog/Storm of War
* However the exact code here is so far from that now, and has been worked over so many
* different times that no specific code/bugs/exact implementation remaining can be blamed on reddog
* only that the original idea came from them: To have airports destroyable, closable when
* bombed sufficiently, and have the closures and destruction be retained over mission re-starts
*
* We give credit (points) for any bomb that hits within the radius of an airfield.
* Also, these bomb hits are marked with a plume of smoke and additionally a bomb crater is added that is dangerous/will kill aircraft taxiing on the ground
*
* Craters are different sizes, depending on tonnage of bomb dropped. Also, craters will be repaired, taking a shorter time for smaller craters & a longer time for bigger craters
* Additionally, the more craters dropped on an airport the longer it will take to get to the next crater & repair it.
* Also, if a threshold of tonnage (counted as points, which are proportional to damage done) is reached, the airport is put out of commission by severely cratering it
*
*************************************************************/
public Dictionary>> AirfieldTargets = new Dictionary>>();
//MissionObjectivesList //Add all LGs in the MO list into the airport list, if they exist & non-expired. if (!mo.Destroyed || !mo.TimeToUndestroy_UTC.HasValue || mo.TimeToUndestroy_UTC.Value.CompareTo(DateTime.UtcNow) <= 0) continue; //"destroyed" in this case means the LG is active, ie, "created", ie "MO achieved" int pointstoknockout = 300; //was 180 - needs to match # set in MO_MissionObjectiveAirfieldsSetup 2023/10/28 AirfieldTargets.Add(mo.ID, tup); //Adds foreach (AiAirport ap in GamePlay.gpAirports()) //Loop through all airfields in the game //We're just going to add ALL airfields as targets, but then make sure there are no duplicates (bec...
{
if (MOL != null) foreach (MissionObjective mo in MOL.Values.ToList())
{
if (mo.MOObjectiveType != MO_ObjectiveType.TemporaryLandingGround) continue;
string apName = mo.Name;
int owner_army = mo.OwnerArmy;
double radius = mo.radius;
Point3d center = mo.Pos;
Point3d pos = mo.Pos;
var tup = Tuple.Create(false, apName, (double)(pointstoknockout), (double)(0), DateTime.UtcNow, radius, center, owner_army);
}
{
double radius = (ap.FieldR() + ap.CoverageR())/2;
Point3d center = ap.Pos();
Point3d pos = ap.Pos();
bool add = true;
{
string ap2Name = AirfieldTargets[apID].Item2;
string apKey = ap2Name + "_airfield";
Point3d apPos = AirfieldTargets[apID].Item7;
double apRadius = AirfieldTargets[apID].Item6;
if (Calcs.CalculatePointDistance(apPos, pos) <= apRadius)
{
break;
}
}
int army_perfront = GamePlay.gpFrontArmy(pos.x, pos.y);
int owner_army = army_perfront;
string apName = ap.Name();
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp != null & bp.Pos().distance(ref pos) <= ap.FieldR())
{
if (bp.Name() != null && !(bp.Name().ToUpper().Contains("BIRTHPLACE")))
{
owner_army = bp.Army();
}
break;
}
}
var tup = Tuple.Create(false, apName, (double)(pointstoknockout), (double)(0), DateTime.UtcNow, radius, center, owner_army);
}
Console.WriteLine("SetAirfieldTargets initialized (-main)", null);
}
//Console.WriteLine("LATD starting"); if (!all && PointsTaken == 0 && !disabled) continue; //we'll list only airports damaged or disabled, skipping those with no damage at all, unless called with all=true if (army != -1 & army != ap.Army()) continue; //List only the army requested, skipping the others. army = -1 means list both/all armies //DateTime disabledUntil_DT = AirfieldTargets[ap].Item6; double timetofix = PointsTaken * 20 * 60 - timereduction; //50 lb bomb scores 0.5 so will take 10 minutes to repair...
{
int count = 0;
string returnmsg = "";
double delay = 0.1;
/*
if (AirfieldTargets != null) foreach (AiAirport ap in AirfieldTargets.Keys)
{
double PointsTaken = AirfieldTargets[ap].Item4;
bool disabled = AirfieldTargets[ap].Item1;
count++;
double PointsToKnockOut = AirfieldTargets[ap].Item3;
string Mission = AirfieldTargets[ap].Item2;
DateTime lastBombHit = AirfieldTargets[ap].Item5;
double percent = 0;
if (PointsToKnockOut > 0)
{
percent = PointsTaken / PointsToKnockOut;
}
double timereduction = 0;
if (percent > 0)
{
timereduction = (DateTime.UtcNow.Subtract(lastBombHit)).TotalSeconds;
}
string msg2 = "";
{
percent = 1;
msg2 = " (" + (Math.Ceiling(timetofix / 3600.0 / 24 * 2.0) / 2.0).ToString("F1") + " days)";
}
string msg = Mission + " " + (percent * 100).ToString("n0") + "% destroyed; last hit " + (timereduction / 3600).ToString("n0") + "hr " + ((timereduction % 3600) / 60).ToString("n0") + "min ago" + msg2;
returnmsg += msg + "\n";
if (display)
{
delay += 0.02;
Timeout(delay, () => { twcLogServer(new Player[] { player }, msg, new object[] { }); });
}
}
*/
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
double PointsTaken = mo.AirfieldDamagePoints;
bool disabled = mo.Destroyed;
count++;
double PointsToKnockOut = mo.AirfieldPointsRequired;
TimeSpan lastbombhit_ts = new TimeSpan(0);
if (mo.LastHitTime_UTC.HasValue) lastbombhit_ts = DateTime.UtcNow - mo.LastHitTime_UTC.Value;
int ndf = mo.numDefenseUnits();
string ndfmsg = null;
if (ndf > 0) ndfmsg = String.Format("{0} DUs, {1:f1}X", ndf, mo.defenseUnitsHelpFactor());
double percent = 0;
if (PointsToKnockOut > 0)
{
percent = PointsTaken / PointsToKnockOut;
}
DateTime timetofix_dt = DateTime.UtcNow;
TimeSpan timetofix_ts = new TimeSpan(0);
if (mo.TimeToUndestroy_UTC.HasValue) timetofix_ts = mo.TimeToUndestroy_UTC.Value - DateTime.UtcNow;
string msg2 = "";
if (ndfmsg == null) msg2 += ")";
else msg2 += "; " + ndfmsg + ")";
{
percent = 1;
msg2 = " (closed; " + (Math.Ceiling(timetofix_ts.TotalDays * 2.0) / 2.0).ToString("F1") + " days";
if (ndfmsg == null) msg2 += ")";
else msg2 += "; " + ndfmsg + ")";
}
string sect = " (" + mo.Sector + ") ";
if (forEnemy) sect = " ";
string msg = mo.Name + sect + (Math.Floor(percent * 100)).ToString("n0") + "%";
if (percent > 0 && !condensed) msg += "; last: " + lastbombhit_ts.ToString("h'hr'm'm'");
if (percent > 0) msg += msg2;
returnmsg += msg + "\n";
if (display)
{
delay += 0.08;
if (count % 10 == 0) delay += 3.5;
Timeout(delay, () => { twcLogServer(new Player[] { player }, msg, new object[] { }); });
}
}
if (count == 0)
{
string msg = "No airports damaged or destroyed yet";
if (display) twcLogServer(new Player[] { player }, msg, new object[] { });
}
return returnmsg;
}
//disable any associated birthplace - thus, no spawning here bp.destroy();//Removes the spawnpoint associated with that airport (ie, if located within the field radius of the airport) //for good measure, doing it again a bit later //bps are not being remove @ beginning of mission FOR SOME REASON. 2023/01 bp.destroy();//Removes the spawnpoint associated with that airport (ie, if located within the field radius of the airport) //So TASK.RUN causes problems when accessing airfield targets, and also potentially missionobjectiveslist etc...
{
try
{
Console.WriteLine("Disabling airport {0} {1:F0} {2:F0}", new Object[] { ap.Name(), ap.Pos().x, ap.Pos().y });
if (percent >= 1)
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces().ToList())
{
if (bp == null) continue;
Point3d bp_pos = bp.Pos();
double ap_bp_dist_m = Calcs.CalculatePointDistance(bp_pos, ap.Pos());
if (ap_bp_dist_m <= ap.FieldR() || ap_bp_dist_m <= ap.CoverageR() || ap_bp_dist_m <= 1000)
{
Console.WriteLine("Removing spawn point for {0} bp pos: {1:F0} {2:F0}, distance: {3:F0}, FieldR: {4:F0}, CoverageR: {5:F0}", new Object[] { ap.Name(), bp_pos.x, bp_pos.y, ap_bp_dist_m, ap.FieldR(), ap.CoverageR() });
Timeout(random.NextDouble() * 25, () =>
{
});
Timeout(random.NextDouble() * 150, () =>
{
});
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("*****AirfieldDisable (init) ERROR: " + ex.Message);
if (ap !=null) Console.WriteLine("*****AirfieldDisable (init): Was working on: " + ap.Name());
};
string apName = ap.Name();
double radius = ap.FieldR();
Point3d pos = ap.Pos();
Console.WriteLine("Disabling airport {0} {1:F0} {2:F0}", new Object[] { ap.Name(), ap.Pos().x, ap.Pos().y });
try {
if (AirfieldTargets.ContainsKey(apName))
{
var aft = AirfieldTargets[apName];
apName = aft.Item2;
radius = aft.Item6;
pos = aft.Item7;
}
} catch (Exception ex) { Console.WriteLine("*****AirfieldDisable af targets ERROR: " + ex.Message); }
Task.Run(() =>
{
try
{
if (percent >= 1)
{
{
if (random.Next(3) < 2)
{
Timeout(random.NextDouble() * 40, () =>
{
gg.Destroy();
});
}
}
}
ISectionFile f2 = GamePlay.gpCreateSectionFile();
string sect = "Stationary";
string val1 = "Stationary";
string type = "BombCrater_firmSoil_largekg";
int count = 0;
string value = "";
int rounds = Convert.ToInt32(Math.Ceiling(percent * 8));
int stripesCount = 0;
double craterSpacing_m = 41 + random.NextDouble() * 14;
bool resetCount = true;
int delay = 1;
for (int round = 0; round < rounds; round++)
{
double xpos = pos.x - 430 + 860 * stb_random.NextDouble();
double ypos = pos.y - 390 + 780 * stb_random.NextDouble();
double angle = random.NextDouble() * 2.0 * Math.PI;
Point3d vec = new Point3d(Math.Cos(angle) * craterSpacing_m, Math.Sin(angle) * craterSpacing_m, 0);
int stripes = random.Next(4) + 1;
for (int stripe = 0; stripe < stripes; stripe++)
{
Point3d startPos = new Point3d(xpos + 150 - 300 * stb_random.NextDouble(), ypos + 150 - 300 * stb_random.NextDouble(), vec.z);
int craters = random.Next(10) + 12;
for (int crater = 0; crater < craters; crater++)
{
double randAdd = random.NextDouble() * 2.6 - 1.3;
Point3d craterPos = new Point3d(startPos.x + vec.x * (crater + randAdd), startPos.y + vec.y * (crater + randAdd) + random.NextDouble() * craterSpacing_m / 10, vec.z);
if (Calcs.isPointOnWaterSimple(GamePlay, craterPos)) continue;
string key = "Static_TWC_AD_" + count.ToString();
value = val1 + ".Environment." + type + " nn " + craterPos.x.ToString("0.00") + " " + craterPos.y.ToString("0.00") + " " + stb_random.Next(0, 181).ToString("0.0") + " /hstart " + craterPos.z.ToString("0.00");
f2.add(sect, key, value);
if (random.Next(17) < 1)
{
string s = "BuildingFireSmall";
if (random.Next(35) == 0) s = "BuildingFireBig";
f2 = Calcs.loadSmokeOrFire(GamePlay, this, craterPos.x, craterPos.y, craterPos.z, s, random.Next(5 * 3600) + 3600, f: f2, resetCount: resetCount);
resetCount = false;
}
count++;
}
stripesCount++;
}
}
Timeout(random.NextDouble() * 20 + 10, () =>
{
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: AirfieldDisable");
GamePlay.gpPostMissionLoad(f2);
});
}
catch (Exception ex)
{
Console.WriteLine("*****AirfieldDisable ERROR: " + ex.Message);
if (ap != null) Console.WriteLine("*****AirfieldDisable: Was working on: " + ap.Name());
};
}
return; //Since we can have only 64 working windsocks, THIS DOESN"T WORK. We load our windsocks in a .mis file //that specifies the exact 64 and that's it...
{
try
{
Console.WriteLine("Adding windsocks to all spawn points...");
ISectionFile f = GamePlay.gpCreateSectionFile();
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (bp != null)
{
Point3d pos = bp.Pos();
double radius = 1200;
string wsType = "tobruk:Stationary.Environment.Windsock_v2";
if (random.Next(2) == 0) wsType = "Stationary.Environment.Windsock_Strong";
AiAirport ap = Calcs.nearestAirport(GamePlay, bp.Pos());
if (ap != null)
{
double dist = Calcs.CalculatePointDistance((ap as AiActor).Pos(), bp.Pos());
if (dist < ap.CoverageR() || dist < ap.FieldR())
{
pos = (ap as AiActor).Pos();
radius = ap.FieldR();
}
}
int existingWS = Calcs.CountMatchingGroundObjects(GamePlay, pos, radius + 200, matchTitle: "Windsock", matchAlive: true);
if (existingWS > 0) continue;
for (int i = 0; i < 1; i++)
{
Point3d ws_pos = new Point3d(pos.x + (2 * i - 1) * radius, pos.y, 0);
for (int j = 0; j < 100; j++)
{
Point3d temp_pos = new Point3d(pos.x + ws_dist * Math.Cos(angle), pos.y + ws_dist * Math.Sin(angle), 0);
maddox.game.LandTypes landType = GamePlay.gpLandType(temp_pos.x, temp_pos.y);
if (j < 70 && (landType == maddox.game.LandTypes.WATER
|| landType == maddox.game.LandTypes.HIGHWAY
|| landType == maddox.game.LandTypes.ROAD
|| landType == maddox.game.LandTypes.ROAD_MASK
|| landType == maddox.game.LandTypes.OBJECTS_MASK
|| landType == maddox.game.LandTypes.RAIL)) continue;
if (j < 90 && (landType == maddox.game.LandTypes.WATER
|| landType == maddox.game.LandTypes.HIGHWAY
|| landType == maddox.game.LandTypes.ROAD)) continue;
if (landType == maddox.game.LandTypes.WATER) continue;
ws_pos = temp_pos;
break;
}
f = Calcs.makeStatic(f, GamePlay, this, ws_pos.x, ws_pos.y, 0, wsType, random.Next(0, 360), staticprefix: "windsock_" + bp.Name() + "_");
}
}
}
string saveName = "windsocks.mis";
GamePlay.gpPostMissionLoad(f);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Loaded windsocks");
} catch (Exception ex) { Console.WriteLine("ERROR Place Windsocks: " + ex.ToString()); }
}
/*****************************************************************************
*
* OnStationaryKilled - handling routines for when a stationary/static object is killed
*
*****************************************************************************/
public override void OnStationaryKilled(int missionNumber, maddox.game.world.GroundStationary stationary, maddox.game.world.AiDamageInitiator initiator, int eventArgInt)
{
#region stb
base.OnStationaryKilled(missionNumber, stationary, initiator, eventArgInt);
try
{
if (initiator == null)
{
if (stationary != null) Console.WriteLine("main_PointArea_stationary " + stationary.Name + " killed but no initiator, probably just script killing an objective, not counting, returning.");
return;
}
double wait = stb_random.NextDouble() * 45;
Timeout(wait, () =>
{
MO_HandlePointAreaObjectives(stationary, initiator);
MO_makeAllObjectivesScoutedAndLaunchDefenseFromPos(stationary.pos, initiator.Player);
});
Player player = null;
if (initiator != null && initiator.Player != null) player = initiator.Player;
}
catch (Exception ex) { Console.WriteLine("OnStationaryKilled -main: " + ex.ToString()); }
#endregion
}
/*****************************************************************************
*
* OnBombExplosion - handling routines for area bombing, bombing of civilian areas, and bombing of airports
*
*****************************************************************************/
public override void OnBombExplosion(string title, double mass_kg, Point3d pos, AiDamageInitiator initiator, int eventArgInt)
{
base.OnBombExplosion(title, mass_kg, pos, initiator, eventArgInt);
double wait = stb_random.NextDouble() * 90;
Timeout(wait, () =>
OnBombExplosion_DoWork(title, mass_kg, pos, initiator, eventArgInt)
);
}
public class Bomberdata
{
private const double ju88_kg = 2400;
private const double ju88_num = 32;
private double capacity_kg;
public double Capacity_kg
{
get { return capacity_kg; }
}
private double capacity_lb;
public double Capacity_lb
{
get { return capacity_lb; }
}
private int bombs_num;
public int Bombs_Num
{
get { return bombs_num; }
}
private double correction_factor;
public double Correction_Factor
{
get { return correction_factor; }
}
public Bomberdata()
{
capacity_kg = 2400;
bombs_num = 32;
_calc_correction_factor();
}
public Bomberdata(double cap_kg = 2400, int bbs_num = 32)
{
capacity_kg = cap_kg;
capacity_lb = Calcs.kg2lb(capacity_kg);
bombs_num = bbs_num;
_calc_correction_factor();
}
public Bomberdata(int bbs_num = 32, double cap_lb = 5291.094 )
{
capacity_lb = cap_lb;
capacity_kg = Calcs.lb2kg(capacity_lb);
bombs_num = bbs_num;
_calc_correction_factor();
}
private void _calc_correction_factor()
{
correction_factor = ju88_kg / capacity_kg * Math.Pow(ju88_num / (double)bombs_num, 0.35);
}
}
Dictionary Bombers_data = new Dictionary
{
{ "Ju-88", new Bomberdata( cap_kg: 2400, bbs_num:32) },
{ "Wellington", new Bomberdata( cap_lb: 4500, bbs_num:18) },
{ "He-111", new Bomberdata( cap_kg: 2000, bbs_num:8) },
{ "BR-20", new Bomberdata( cap_kg: 1200, bbs_num:12) },
{ "FW-200", new Bomberdata( cap_kg: 1500, bbs_num:4) },
{ "Do-17", new Bomberdata( cap_kg: 1000, bbs_num:20) },
{ "Do-215", new Bomberdata( cap_kg: 500, bbs_num:10) },
{ "Sunderland", new Bomberdata( cap_lb: 1000, bbs_num:8) },
};
//TODO. Bomb/exploded & airport bombing is unnecessarily complicated now we are meshing the OLD airport damage system & this new Mission Objectives system...
{
string acName_tl = acName.ToLower();
foreach (string key in Bombers_data.Keys)
{
if (acName.ToLower().Contains(key.ToLower()))
{
if (ON_TESTSERVER) Console.WriteLine("bomberCorrectionFactor: {0} matched {1}, BCF: {2:F3}", key, acName, Bombers_data[key].Correction_Factor);
return Bombers_data[key].Correction_Factor;
}
}
if (ON_TESTSERVER) Console.WriteLine("bomberCorrectionFactor: NO match for {0}, BCF: {1:F3}", acName, 1);
return 1;
}
double lastBombMessageTime_sec = 0;
//Console.WriteLine("main_bombexp_DoWork"); //twcLogServer(null, "bombe 1", null); //twcLogServer(null, string.Format("bombe {0:N0} {1:N0} {2:N0}", pos.x, pos.y, pos.z), null); //twcLogServer(null, "bombe 2", null); int isEnemy = 1; //0 friendly, 1 = enemy, 2 = neutral //twcLogServer(null, "bombe 3", null); //twcLogServer(null, "bombe 4", null); //TF_GamePlay.gpIsLandTypeCity(maddox.game.IGamePlay, pos); //twcLogServer(null, "bombe 5", null); //For now, all things we handle below are on land, so if the land type is water we just //get out of here immediately //2021 update: Water airports now possible!!! //if (landType == maddox.game.LandTypes.WATER) return; //twcLogServer(null, "bombe 6", null); //so these are all compared with a JU88 which carries 4X250kg + 28X50KG which is 2400kg or 5291 lb. //So these correction figures bring all these bombers up to par with the JU88 as far as kg-tonnage is concerned...
{
try
{
if (GamePlay == null) return;
bool ai = true;
if (initiator != null && initiator.Player != null && initiator.Player.Name() != null) ai = false;
int terr = GamePlay.gpFrontArmy(pos.x, pos.y);
if (terr == 00) isEnemy = 2;
if (!ai && initiator.Player.Army() == terr) isEnemy = 0;
MO_makeAllObjectivesScoutedAndLaunchDefenseFromPos(pos, initiator.Player);
MO_HandlePointAreaObjectives(title, mass_kg, pos, initiator);
/********************
*
* Handle airport bombing
*
*******************/
var apkeys = new List(AirfieldTargets.Keys.Count);
apkeys = AirfieldTargets.Keys.ToList();
maddox.game.LandTypes landType = GamePlay.gpLandType(pos.x, pos.y);
string acType = "";
if (initiator != null)
{
AiAircraft aircraft = initiator.Actor as AiAircraft;
acType = Calcs.GetAircraftType(aircraft);
if (ON_TESTSERVER) Console.WriteLine("Bomb Hit: {0:N0} {1:N0} {2:N0} {3}", pos.x, pos.y, pos.z, acType);
}
double aircraftCorrection = bomberCorrectionFactor(acType);
DateTime currTime_dt = DateTime.UtcNow;
double repairSpeedupFactor = 1;
if (terr > 0 && terr < 3 && MissionObjectivesTimes[(ArmiesE)terr].ContainsKey("RepairCrewEndTime_dt") && MissionObjectivesTimes[(ArmiesE)terr]["RepairCrewEndTime_dt"] > currTime_dt) repairSpeedupFactor = 4;
{
/* if (!AirfieldTargets[ap].Item1)
}
else
{ */
/*double radius = AirfieldTargets[ap].Item6;
Point3d APPos = AirfieldTargets[ap].Item7;
string apName = AirfieldTargets[ap].Item2;
*/
string apName = AirfieldTargets[apID].Item2;
string apKey = apName + "_airfield";
MissionObjective mo = null;
if (MissionObjectivesList.ContainsKey(apKey)) { mo = MissionObjectivesList[apKey]; }
double radius = mo.radius;
Point3d APPos = mo.Pos;
double distFromCenter = 1000000000;
distFromCenter = APPos.distance(ref pos);
/* if (distFromCenter > radius * 1.25 && (distFromCenter <= radius * 2.5) )
{
if (ON_TESTSERVER) Console.WriteLine("BombExpl: Just missed! {0} distFromAP {1:f1}", apName, distFromCenter);
}*/
{
mo.fixDestructionValues();
double multiplier = 0.3;
if (distFromCenter <= 4 * radius / 5) multiplier = 1.2;
else if (distFromCenter <= radius) multiplier = 1.0;
else if (distFromCenter <= radius * 1.25) multiplier = 0.9;
else if (distFromCenter <= radius * 1.5) multiplier = 0.7;
else if (distFromCenter <= radius*2) multiplier = 0.5;
if (landType == maddox.game.LandTypes.ROAD || landType == maddox.game.LandTypes.ROAD_MASK || landType == maddox.game.LandTypes.HIGHWAY)
{
multiplier = 1.6;
}
double destruction_radius_m = 10.05* Math.Pow(mass_kg * aircraftCorrection, 0.35);
int numNearbyObjects = 3 * Calcs.CountGroundActors(GamePlay, this, AllGroundDict, pos, destruction_radius_m, matcharmy: 0, type: "");
numNearbyObjects += Calcs.CountMatchingGroundObjects(GamePlay, pos, destruction_radius_m, matchTitle: "crater", matchName: "crater", matcharmy: 0, matchAlive: false, antiMatch: true);
if (ON_TESTSERVER) Console.WriteLine("BombExpl: num nearby ground objects: {0}, multiplier: {1:f3}", numNearbyObjects, numNearbyObjects_mult);
multiplier *= numNearbyObjects_mult;
if (landType == maddox.game.LandTypes.WATER) multiplier = multiplier / 1.2;
scoreBase *= multiplier;
double score = scoreBase * Math.Pow(mass_kg * aircraftCorrection, 0.67);
if (ON_TESTSERVER) Console.WriteLine("BombExpl: mass_kg {0:F0}, aircraft correction {1:F2}, scoreBase {2:f3}, score {3:f3}, multiplier {4:f3}, distfromAP {5:f1} {6} {7}", mass_kg, aircraftCorrection, scoreBase, score, multiplier, distFromCenter, apID, acType);
/* Another way to reach the same end- probably quicker but less flexible & doesn't interpolate:
*
*/
double timeout = 0;
if (TimeNow_sec - lastBombMessageTime_sec < 0.3333) timeout = lastBombMessageTime_sec - TimeNow_sec + 0.333;
if (timeout < 0) { timeout = 0; }
double individualscore = score;
{
if (initiator.Player != null)
{
bool nearbyTargs = Calcs.anyEnemyStationaries(GamePlay, pos.x, pos.y, 2000, initiator.Player.Army());
int matcharmy = initiator.Player.Army();
int numberNearbyEnemyGroundActors = Calcs.CountGroundActors(GamePlay, this, AllGroundDict, pos, 2500, matcharmy: 3 - matcharmy, type: "");
if (!nearbyTargs && numberNearbyEnemyGroundActors == 0)
{
Timeout(timeout * 12, () =>
{
GamePlay.gpLogServer(null, initiator.Player.Name() + " has bombed a friendly airport. Serious repercussions for player AND team.", new object[] { });
});
}
}
}
string firetype = "BuildingFireSmall";
string cratertype = "BombCrater_firmSoil_mediumkg";
double PointsToKnockOut = mo.AirfieldPointsRequired;
double PointsTaken = mo.AirfieldDamagePoints + score;
double percent = 0;
double prev_percent = 0;
double points_reduction_factor = 1;
if (PointsToKnockOut > 0)
{
percent = PointsTaken / PointsToKnockOut;
prev_percent = mo.AirfieldDamagePoints / PointsToKnockOut;
if (prev_percent > 1) prev_percent = 1;
}
PointsTaken = mo.AirfieldDamagePoints + score;
mo.AirfieldDamagePoints = PointsTaken;
bool disabled = mo.Destroyed;
if (ON_TESTSERVER) Console.WriteLine("BombExpl: score {0:F4}, total AF damage pts {1:F2}, final damage percent {2:f3}, points reduction factor {3:f3}, prev_percent {4:f3}, individualscore {5:f4}, pointstoknockout {6:f1}", score, PointsTaken, percent, points_reduction_factor, prev_percent, individualscore, PointsToKnockOut);
DateTime lastBombHit = DateTime.UtcNow;
if (mo.LastHitTime_UTC.HasValue) lastBombHit = mo.LastHitTime_UTC.Value;
mo.LastHitTime_UTC = DateTime.UtcNow;
double timereduction = 0;
if (prev_percent > 0)
{
timereduction = (DateTime.UtcNow.Subtract(lastBombHit)).TotalSeconds;
}
double PointsTakenReduction = 0;
double defenseUnits_speedup = mo.defenseUnitsHelpFactor();
double repairTimeMultFactor = 20 * 60 * 3 / defenseUnits_speedup;
if (timereduction > 0)
{
}
{
percent = 1;
MO_addInitiatorToListOfPlayersWhoContributed(initiator, apKey);
if (!ai)
Timeout(timeout, () =>
{
});
Timeout(timeout + 0.15, () => { if (percent * 100 % 25 < prev_percent * 100 % 25) twcLogServer(null, mo.AirfieldName + " " + (Math.Floor(percent * 100)).ToString("n0") + "% destroyed ", new object[] { }); });
Timeout(timeout * 3, () =>
{
Calcs.loadCratersAndSmoke(GamePlay, this, pos.x, pos.y, 0, type: firetype, type2: cratertype, duration_s: timeToFixFromNow_sec);
});
{
{
int arm = mo.OwnerArmy;
if (arm != 1 && arm != 2)
{
}
/*
else if (arm == 2) CampaignMapRedPoints += 5;
*/
try
{
}
catch (Exception ex) { Console.WriteLine("OnExplosion_DoWork error1: " + ex.ToString()); };
/*
* The additional score & adding points for knocking out an airport have been moved to the MissionObjectives section with MO_DestroyObjective
if (arm == 1)
{
MissionObjectivesCompletedString[ArmiesE.Blue] += " - " + apName;
}
else if (arm == 2)
{
MissionObjectiveScore[ArmiesE.Red]++;
MissionObjectivesCompletedString[ArmiesE.Red] += " - " + apName;
}
Console.WriteLine("Airport destroyed, awarding points to destroying army; airport owned by army: " + arm.ToString());
*/
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces().ToList())
{
if (bp == null) continue;
Point3d bp_pos = bp.Pos();
}
}
}
else
{
MO_DestroyObjective_addTimeOrPoints(mo.ID, percentdestroyed: percent, timetofixFromNow_sec: timeToFixFromNow_sec, TimeLastHit_UTC: DateTime.UtcNow, AirfieldDamagePoints: PointsTaken, AirfieldDamagePointsAdded: score, messageDelay_sec: timeout);
double prev_percent_exact = (PointsTaken - score) / PointsToKnockOut;
{
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces().ToList())
{
if (bp == null) continue;
Point3d bp_pos = bp.Pos();
}
}
}
}
/*AirfieldTargets.Remove(ap);
AirfieldTargets.Add(ap, new Tuple(disabled, Mission, PointsToKnockOut, PointsTaken, DateTime.UtcNow, radius, APPos));
*/
mo.DestroyedPercent = percent;
break;
if (ON_TESTSERVER) Console.WriteLine("BombExpl: mo.destroyedpercent {0:F4}, mo.total AF damage pts {1:F2}, mo.destroyed? {2}", mo.DestroyedPercent, mo.AirfieldDamagePoints, mo.Destroyed);
}
}
}
catch (Exception ex) { Console.WriteLine("On Bomb Explosion do_work: " + ex.ToString()); }
}
bool final_SaveMapState_completed = false;
bool final_MO_WriteMissionObjects_completed = false;
int currentEndMission = 0;
int thisEndMission = currentEndMission; //Allows possibility to cancel/abort EndMission by incrementing currentEndMission, or, more importantly, if EndMission is called 2X (specifically if one side turns the map after EndMission has already started but before the mission has actually closed down) the 2nd time will supersede. //All players who are lucky enough to still be in a plane at this point have saved their plane/it's returned to their team's supply //Save map state & data double misResult = SaveMapState(winner); //here is where we save progress/winners towards moving the map & front one way or the other; also saves the Supply State CheckStatsData(winner); //Save campaign/map state just before final exit...
{
currentEndMission++;
if (winner == "")
{
twcLogServer(null, "Mission is restarting soon!!!", new object[] { });
GamePlay.gpHUDLogCenter("Mission is restarting soon!!!");
}
else
{
if (endseconds > 60)
{
Timeout(endseconds + 40, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, winner + " has turned the map!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has turned the map. Congratulations, " + winner + "!");
}
});
}
Timeout(endseconds / 2, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, winner + " has turned the map!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has turned the map. Congratulations, " + winner + "!");
}
});
Timeout(endseconds + 15, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, winner + " has turned the map!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has turned the map - mission ending soon!");
}
});
Timeout(endseconds + 45, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, winner + " has turned the map!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has turned the map - mission ending soon!");
}
});
Timeout(endseconds + 61, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, "Congratulations " + winner + " for turning the map!", new object[] { });
}
});
}
Timeout(endseconds, () =>
{
twcLogServer(null, "Mission is restarting in 1 minute!!!", new object[] { });
GamePlay.gpHUDLogCenter("Mission is restarting in 1 minute!!!");
});
Timeout(endseconds + 30, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, "Server Restarting in 30 seconds!!!", new object[] { });
GamePlay.gpHUDLogCenter("Server Restarting in 30 seconds!!!");
MO_WriteMissionObjects(wait: true);
final_SaveMapState_completed = true;
final_MO_WriteMissionObjects_completed = true;
}
});
Timeout(endseconds + 50, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, "Server Restarting in 10 seconds!!!", new object[] { });
GamePlay.gpHUDLogCenter("Server Restarting in 10 seconds!!!");
}
});
Timeout(endseconds + 60, () =>
{
if (currentEndMission == thisEndMission)
{
twcLogServer(null, "Mission ended. Please wait 2 minutes to reconnect!!!", new object[] { });
GamePlay.gpHUDLogCenter("Mission ended. Please wait 2 minutes to reconnect!!!");
DebugAndLog("Mission ended.");
if (GamePlay is GameDef)
{
(GamePlay as GameDef).gameInterface.CmdExec("exit");
}
}
});
{
if (currentEndMission == thisEndMission)
{
System.Environment.Exit(1);
Process.GetCurrentProcess().Kill();
}
});
}
/****************************************
* LOADRANDOMSUBMISSION
*
* Finds all files in the FILE_PATH whose filenames match the pattern (anything or nothing) + fileID + (anything or nothing) + .mis
* and randomly selects ONE of them to load.
*
* This can be used in mission to, e.g., have a fighter sweep that always launches 12 minutes into the mission. Instead of
* running the same mission each time, you can
* have 5 different variants of the mission available, and one of them is selected randomly each time.
*
* subdir is relative to the FILE_PATH and should not include a leading or trailing / or \
*
* Examples:
*
*
*
* **************************************/
//int endsessiontick = Convert.ToInt32(ticksperminute*60*HOURS_PER_SESSION); //When to end/restart server session //GamePlay.gpHUDLogCenter("Respawning AI air groups"); //twcLogServer(null, "RESPAWNING AI AIR GROUPS. AI Aircraft groups re-spawn every " + RESPAWN_MINUTES + " minutes and have a lifetime of " + RESPAWN_MINUTES + "-" + 2*RESPAWN_MINUTES + " minutes...
{
bool ret = false;
if (check)
{
if (RandomMissions.Count > 0) return true;
else return false;
}
if (fileID.StartsWith(MISSION_ID + "-" + "randsubmission") && !fileID.StartsWith(MISSION_ID + "-" + "randsubmissionINITIALSHIPS") && random.Next(100) > PERCENT_SUBMISSIONS_TO_LOAD)
{
Console.WriteLine("Skipping load of " + fileID + " to reduce submission files loaded.");
return ret;
}
DebugAndLog("Debug: Choosing from " + RandomMissions.Count + " missions to spawn. " + fileID + " " + CLOD_PATH + FILE_PATH);
if (RandomMissions.Count > 0)
{
string RandomMission = RandomMissions[random.Next(RandomMissions.Count)];
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: LoadRandomSubmissions");
GamePlay.gpPostMissionLoad(RandomMission);
ret = true;
DebugAndLog("Loading mission " + RandomMission);
Console.WriteLine("Loading mission " + Path.GetFileName(RandomMission));
DebugAndLog("Current time: " + DateTime.UtcNow.ToString("O"));
}
return ret;
}
No description available.
{
List list = new List() { };
string[] filenames = Directory.GetFiles(dirPath, "*" + mask + "*.mis");
list = new List(filenames);
DebugAndLog("Num matching submissions found in directory: " + list.Count);
return list;
}
//if (!aircraft.IsAirborne()) //{get aircraft.cutLimb(part.LimbNames.WingL2); // Spit2a //aircraft.cutLimb(part.LimbNames.Engine7); //part.LimbNames.ElevatorL0 //part.LimbNames.ElevatorL1 //part.LimbNames.ElevatorR0 //part.LimbNames.ElevatorR1 //part.LimbNames.Engine0 - 7 //part.LimbNames.AileronL0 //part.LimbNames.AileronL1 //part.LimbNames.AileronR0 //part.LimbNames.AileronR1 aircraft.cutLimb(part.LimbNames.WingR4); // 109 //// // plane in Air Tail cut off /// //Singleplayer or Dedi Server } // Multiplayer //Singleplayer or Dedi Server } // Multiplayer /// REARM/REFUEL: cancel possibly pending request of player // ManageRnr.cancelOfPlayer(GamePlay, player); //OK, we have to wait a bit here bec. some ppl use ALT-F11 (ALT-F2) for 'external view' which allows to leave two positions //inhabited by bomber pilot & just return to the one position...
{
Timeout(waittime_s, () =>
{
if (aircraft != null)
{
aircraft.cutLimb(part.LimbNames.AileronL0);
aircraft.cutLimb(part.LimbNames.AileronR0);
aircraft.cutLimb(part.LimbNames.ElevatorL0);
aircraft.cutLimb(part.LimbNames.ElevatorR0);
aircraft.cutLimb(part.LimbNames.Rudder0);
if (severe)
{
aircraft.cutLimb(part.LimbNames.WingL0);
aircraft.cutLimb(part.LimbNames.WingR0);
aircraft.cutLimb(part.LimbNames.WingR2);
aircraft.cutLimb(part.LimbNames.Engine0);
aircraft.cutLimb(part.LimbNames.Tail0);
aircraft.cutLimb(part.LimbNames.WingL1);
aircraft.cutLimb(part.LimbNames.WingL3);
aircraft.cutLimb(part.LimbNames.WingL4);
aircraft.cutLimb(part.LimbNames.WingL5);
aircraft.cutLimb(part.LimbNames.WingL6);
aircraft.cutLimb(part.LimbNames.WingL7);
aircraft.cutLimb(part.LimbNames.WingR1);
aircraft.cutLimb(part.LimbNames.WingR3);
aircraft.cutLimb(part.LimbNames.WingR5);
aircraft.cutLimb(part.LimbNames.WingR6);
aircraft.cutLimb(part.LimbNames.WingR7);
aircraft.cutLimb(part.LimbNames.Tail0);
aircraft.cutLimb(part.LimbNames.Tail1);
aircraft.cutLimb(part.LimbNames.Tail2);
aircraft.cutLimb(part.LimbNames.Tail3);
aircraft.cutLimb(part.LimbNames.Tail4);
aircraft.cutLimb(part.LimbNames.Tail5);
aircraft.cutLimb(part.LimbNames.Tail6);
aircraft.cutLimb(part.LimbNames.Tail7);
aircraft.cutLimb(part.LimbNames.Engine1);
}
}
});
}
private void destroyPlayerPlane(AiAircraft aircraft)
{
if (aircraft != null)
aircraft.Destroy();
}
private void damagePlayerGroup(AiActor actorMain)
{
foreach (AiActor actor in actorMain.Group().GetItems())
{
if (actor == null)
return;
AiAircraft aircraft = (actor as AiAircraft);
if (aircraft != null)
{
DoDamageToAirplane(aircraft);
}
}
}
private void sendScreenMessageTo(int army, string msg, object[] parms)
{
List Players = new List();
if (GamePlay.gpPlayer() != null)
{
if (GamePlay.gpPlayer().Army() == army || army == -1)
Players.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player p in GamePlay.gpRemotePlayers())
{
if (p.Army() == army || army == -1)
Players.Add(p);
}
}
if (Players != null && Players.Count > 0)
GamePlay.gpHUDLogCenter(Players.ToArray(), msg, parms);
}
private void sendChatMessageTo(int army, string msg, object[] parms)
{
List Players = new List();
if (GamePlay.gpPlayer() != null)
{
if (GamePlay.gpPlayer().Army() == army || army == -1)
Players.Add(GamePlay.gpPlayer());
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player p in GamePlay.gpRemotePlayers())
{
if (p.Army() == army || army == -1)
Players.Add(p);
}
}
if (Players != null && Players.Count > 0)
twcLogServer(Players.ToArray(), msg, parms);
}
/************************************************************
* ONPLACELEAVE
* *********************************************************/
public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceLeave(player, actor, placeIndex);
if (actor != null && actor is AiAircraft)
{
Timeout(0.5f, () =>
{
if (player != null)
{
if ((actor as AiAircraft) != null &&
GamePlay.gpFrontArmy(actor.Pos().x, actor.Pos().y) == actor.Army() &&
Calcs.CalculatePointDistance((actor as AiAircraft).AirGroup().Vwld()) < 2 &&
actor.IsAlive()
)
MO_RecordPlayerScoutPhotos(player);
}
string pName = "";
if (player != null) pName = player.Name();
if (actor is AiAircraft)
{
if (isAiControlledPlane2(actor as AiAircraft))
{
{
if (isAiControlledPlane2(actor as AiAircraft))
{
damageAiControlledPlane(actor);
/* this is now handled by -supply.cs system
switch ((actor as AiAircraft).InternalTypeName())
{
case "bob:Aircraft.SpitfireMkIIa":
currentSpitIIas--;
break;
case "bob:Aircraft.Bf-109E-4N":
current109s--;
break;
}
*/
}
}
);
}
}
DateTime utcDate = DateTime.UtcNow;
}
);
}
}
/************************************************************
* ONPLACEENTER
* *********************************************************/
public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
{
base.OnPlaceEnter(player, actor, placeIndex);
if (player != null)
{
setMainMenu(player);
/*
* TESTING STUFF FOR aPlayer Player extension
aPlayer p = new aPlayer();
Player p1 = p as Player;
Console.WriteLine("Player bugablug" + p1.Name());
Console.WriteLine("Player bugablug" + p1.Name() + p1.Army().ToString());
gpLogServerAndLog(null, "Player bugablug" + p1.Name(), null);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddSessStat(p1, 798, 5321);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddToMissionStat(player, 848, 1);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddToMissionStat(player, 849, 1);
MO_AddPlayerStatsScoresForObjectiveDestruction(p1, MissionObjectivesList["RTarget28R"], 10);
*/
}
/* handling this via -supply.cs now
if (actor != null && actor is AiAircraft)
{
switch ((actor as AiAircraft).InternalTypeName())
{
case "bob:Aircraft.SpitfireMkIIa":
{
currentSpitIIas++;
if (currentSpitIIas > allowedSpitIIas)
{
damagePlayerGroup(actor);
GamePlay.gpHUDLogCenter(new Player[] { player }, "SpitIIa aircraft limit reached. Choose a different plane! Plane disabled in 10 seconds!");
}
break;
}
case "bob:Aircraft.Bf-109E-4N":
{
current109s++;
if (current109s > allowed109s)
{
damagePlayerGroup(actor);
GamePlay.gpHUDLogCenter(new Player[] { player }, "109 E-4N aircraft limit reached. Choose a different plane! Plane disabled in 10 seconds!");
}
break;
}
}
}
*/
}
/*************************************************************
* CHECKSTATSDATA
* ***********************************************************/
double RedTotalF = 0;
double BlueTotalF = 0;
double RedAirF = 0;
double RedAAF = 0;
double RedNavalF = 0;
double RedGroundF = 0;
double RedPlanesWrittenOffI = 0;
double RedScoutPhotosI = 0;
double RedScoutedObjectivesI = 0;
double BlueAirF = 0;
double BlueAAF = 0;
double BlueNavalF = 0;
double BlueGroundF = 0;
double BluePlanesWrittenOffI = 0;
double BlueScoutPhotosI = 0;
double BlueScoutedObjectivesI = 0;
//Timeout(188, () => { CheckStatsData(); }); // Read the stats file where we tally red & blue victories for the session //This allows us to make red/blue victories part of our mission objectives & //use the victory tallying mechanism in -stats.cs to do the work of keeping track of that if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MXX1"); //Testing for potential causes of warping //Only if they are recent (less than 125 seconds old) do we accept the numbers. //-stats.cs generally writes this data every 2 minutes, so older than that is an old mission or something //twcLogServer(null, "Read SessStats.txt: Times MATCH", null); //twcLogServer(null, string.Format("RED session total: {0:0.0} BLUE session total: {1:0.0} Time1: {2:R} Time2 {3:R}", // (double)(RedTotalF) / 100, (double)(BlueTotalF) / 100, Time.ToUniversalTime(), DateTime.Now.ToUniversalTime()), null); //twcLogServer(null, string.Format("RED session total: {0:0.0} BLUE session total: {1:0.0} ", // (double)(RedTotalF) / 100, (double)(BlueTotalF) / 100), null); //twcLogServer(null, "Read SessStats.txt: Times MATCH", null); //twcLogServer(null, string.Format("RED session total: {0:0.0} BLUE session total: {1:0.0} Time1: {2:R} Time2 {3:R}", // (double)(RedTotalF) / 100, (double)(BlueTotalF) / 100, Time.ToUniversalTime(), DateTime.Now.ToUniversalTime()), null); //twcLogServer(null, string.Format("RED session total: {0:0.0} BLUE session total: {1:0.0} ", // (double)(RedTotalF) / 100, (double)(BlueTotalF) / 100), null); //Get the current campaign state //sw.Write(res.Item2); //Item2 is a detail breakout of current campaign score...
{
/************************************************
*
* Check/download/transfer stats data
* Recursive function called every X seconds
************************************************/
Timeout(188, () => { Task.Run(() => CheckStatsData()); });
/*
* THIS is the old method were we wrote values to a file from -stats.cs and read them from the file for -main.cs
* Now that we can easily communicate between the two classes there is no reason to do this.
try
{
using (StreamReader sr = new StreamReader(STATSCS_FULL_PATH + "SessStats.txt"))
{
string RedTotalS = sr.ReadLine();
string BlueTotalS = sr.ReadLine();
string TimeS = sr.ReadLine();
string RedAirS = sr.ReadLine();
string RedAAS = sr.ReadLine();
string RedNavalS = sr.ReadLine();
string RedGroundS = sr.ReadLine();
string RedPlanesWrittenOffS = sr.ReadLine();
string BlueAirS = sr.ReadLine();
string BlueAAS = sr.ReadLine();
string BlueNavalS = sr.ReadLine();
string BlueGroundS = sr.ReadLine();
string BluePlanesWrittenOffS = sr.ReadLine();
DateTime Time = Convert.ToDateTime(TimeS);
if (Time.AddSeconds(125).ToUniversalTime() > DateTime.UtcNow)
{
RedTotalF = Convert.ToDouble(RedTotalS) / 100;
BlueTotalF = Convert.ToDouble(BlueTotalS) / 100;
RedAirF = Convert.ToDouble(RedAirS) / 100;
RedAAF = Convert.ToDouble(RedAAS) / 100;
RedNavalF = Convert.ToDouble(RedNavalS) / 100;
RedGroundF = Convert.ToDouble(RedGroundS) / 100;
RedPlanesWrittenOffI = Convert.ToInt32(RedPlanesWrittenOffS);
BlueAirF = Convert.ToDouble(BlueAirS) / 100;
BlueAAF = Convert.ToDouble(BlueAAS) / 100;
BlueNavalF = Convert.ToDouble(BlueNavalS) / 100;
BlueGroundF = Convert.ToDouble(BlueGroundS) / 100;
BluePlanesWrittenOffI = Convert.ToInt32(BluePlanesWrittenOffS);
}
}
}
catch (Exception ex) { System.Console.WriteLine("Main mission - read sessstats.txt - Exception: " + ex.ToString()); }
*/
StatsMission.Stb_PlayerSessStat BS = statsmission.stb_SaveIPlayerStat.BlueSessStats;
StatsMission.Stb_PlayerSessStat RS = statsmission.stb_SaveIPlayerStat.RedSessStats;
RedTotalF = RS.getSessStat(798) / 100;
BlueTotalF = BS.getSessStat(798) / 100;
RedAirF = RS.getSessStat(802) / 100;
RedAAF = RS.getSessStat(806) / 100;
RedNavalF = RS.getSessStat(810) / 100;
RedGroundF = RS.getSessStat(814) / 100;
RedPlanesWrittenOffI = RS.getSessStat(845);
BlueAirF = BS.getSessStat(802) / 100;
BlueAAF = BS.getSessStat(806) / 100;
BlueNavalF = BS.getSessStat(810) / 100;
BlueGroundF = BS.getSessStat(814) / 100;
BluePlanesWrittenOffI = BS.getSessStat(845);
Tuple res = CalcMapMove(winner, false, false, null);
double newMapState = CampaignMapState + res.Item1 + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0;
string campaign_summary = summarizeCurrentMapstate(newMapState, false, null);
try
{
string outputmsg = "";
if (RedPlanesWrittenOffI >= 2)
{
string msg = "Red has lost " + RedPlanesWrittenOffI.ToString() + " aircraft in battle.";
outputmsg += msg + "
" + Environment.NewLine;
}
if (BluePlanesWrittenOffI >= 2)
{
string msg = "Blue has lost " + BluePlanesWrittenOffI.ToString() + " aircraft in battle.";
outputmsg += msg + "
" + Environment.NewLine;
}
if (BluePlanesWrittenOffI >= 2 || RedPlanesWrittenOffI >= 2) outputmsg += "
" + Environment.NewLine;
if (RedScoutPhotosI >= 1 || RedScoutedObjectivesI >= 0)
{
string msg = "Red has taken " + RedScoutPhotosI.ToString() + " reconnaissance photos of " + RedScoutedObjectivesI.ToString() + " mission objectives.";
outputmsg += msg + "
" + Environment.NewLine;
}
if (BlueScoutPhotosI >= 1 || BlueScoutedObjectivesI >= 0)
{
string msg = "Blue has taken " + BlueScoutPhotosI.ToString() + " reconnaissance photos of " + BlueScoutedObjectivesI.ToString() + " mission objectives.";
outputmsg += msg + "
" + Environment.NewLine;
}
if (BlueScoutPhotosI >= 1 || BlueScoutedObjectivesI >= 0 || RedScoutPhotosI >= 1 || RedScoutedObjectivesI >= 0) outputmsg += "
" + Environment.NewLine;
outputmsg = "Blue Objectives complete (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Blue]) + "
" + Environment.NewLine + "
" + Environment.NewLine;
outputmsg += "Red Objectives complete (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Red]) + "
" + Environment.NewLine;
outputmsg += "
" + Environment.NewLine + "
" + Environment.NewLine;
if (winner != "")
{
outputmsg += "
" + Environment.NewLine + "
" + Environment.NewLine;
outputmsg += winner.ToUpper() + " HAS WON THE BATTLE & COMPLETED ALL OBJECTIVES! Congratulations, " + winner + "
" + Environment.NewLine + "
" + Environment.NewLine;
outputmsg += winner.ToUpper() + " players who contributed to this historic victory by scouting high priority areas identified by HQ:
" + Environment.NewLine;
outputmsg += MO_PlayersWhoScoutedObjectivesList(winner) + "
" + Environment.NewLine;
outputmsg += winner.ToUpper() + " players who contributed to this historic victory by assisting in the destruction of the objectives identified by HQ:
" + Environment.NewLine;
outputmsg += MO_PlayersWhoContributedToObjectivesList(winner) + "
" + Environment.NewLine;
string pwrol = MO_PlayersWhoRepairedObjectivesList(winner);
if (pwrol.Length > 0)
{
outputmsg += winner.ToUpper() + " players who contributed to this historic victory by helping to repair their military assets:
" + Environment.NewLine;
outputmsg += pwrol + "
" + Environment.NewLine;
}
}
Calcs.WriteAllTextAsync(STATSCS_FULL_PATH + "CampaignSummary.txt", outputmsg);
}
catch (Exception ex) { Console.WriteLine("CampaignSummary Write: " + ex.ToString()); }
/*
if (!osk_Red50Kills && RedTotalF >= 50)
{
osk_RedObjCompleted += "50 total Team Kills - ";
osk_Red50Kills = true;
twcLogServer(null, "RED reached 50 Team Kills. Well done Team Red!", new object[] { });
GamePlay.gpHUDLogCenter("RED reached 50 Team Kills. Well done Red!");
}
if (!osk_Blue50Kills && BlueTotalF >= 50)
{
osk_BlueObjCompleted += "50 total Team Kills - ";
osk_Blue50Kills = true;
twcLogServer(null, "BLUE reached 50 Team Kills. Well done Team Blue!", new object[] { });
GamePlay.gpHUDLogCenter("BLUE reached 50 Team Kills. Well done Blue!");
}
if (!osk_Red10AirKills && RedAirF >= 10)
{
osk_RedObjCompleted += "10 total Air Kills - ";
osk_Red10AirKills = true;
twcLogServer(null, "Red reached 10 total Air Kills. Well done Team Red!", new object[] { });
GamePlay.gpHUDLogCenter("Red reached 10 total Air Kills. Well done Red!");
}
if (!osk_Blue10AirKills && BlueAirF >= 10)
{
osk_BlueObjCompleted += "10 total Air Kills - ";
osk_Blue10AirKills = true;
twcLogServer(null, "BLUE reached 10 total Air Kills. Well done Team Blue!", new object[] { });
GamePlay.gpHUDLogCenter("BLUE reached 10 total Air Kills. Well done Blue!");
}
if (!osk_Red10GroundKills && (RedAAF + RedNavalF + RedGroundF) >= 10)
{
osk_RedObjCompleted += "10 total AA/Naval/Ground Kills - ";
osk_Red10GroundKills = true;
twcLogServer(null, "Red reached 10 total AA/Naval/Ground Kills. Well done Team Red!", new object[] { });
GamePlay.gpHUDLogCenter("Red reached 10 total AA/Naval/Ground Kills. Well done Red!");
}
if (!osk_Blue10GroundKills && (BlueAAF + BlueNavalF + BlueGroundF) >= 10)
{
osk_BlueObjCompleted += "10 total AA/Naval/Ground Kills - ";
osk_Blue10GroundKills = true;
twcLogServer(null, "BLUE reached 10 total AA/Naval/Ground Kills. Well done Team Blue!", new object[] { });
GamePlay.gpHUDLogCenter("BLUE reached 10 total AA/Naval/Ground Kills. Well done Blue!");
}
{
osk_RedObjCompleted += "10 more Team Kills than Blue - ";
osk_MapTurned = true;
EndMission(300, "RED");
}
if (!osk_MapTurned && osk_HambleDam_destroyed && osk_CowesDam_destroyed && osk_PortsmouthFuelStorage_destroyed && osk_Blue10AirKills && osk_Blue10GroundKills && BlueTotalF >= 50 && BlueTotalF > RedTotalF + 10)
{
osk_BlueObjCompleted += "10 more Team Kills than Red - ";
osk_MapTurned = true;
EndMission(300, "BLUE");
}
*/
}
No description available.
{
string StringToReturn = "";
StringToReturn = "Red Objectives complete (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):\n";
StringToReturn = StringToReturn + MissionObjectivesCompletedString[ArmiesE.Red];
return StringToReturn;
}
//CalcMapMove - returns a double with DOUBLE the current mission score and STRING the text message detailing the score //This figures the score at intermediate points during the session, but also the final score at end of session or when //one team or the other turns the map //msg01 = "Use command
{
string StringToReturn = "";
StringToReturn = "Blue Objectives complete (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):\n";
StringToReturn = StringToReturn + MissionObjectivesCompletedString[ArmiesE.Blue];
return StringToReturn;
}
/*************************************************************
* END - CHECKSTATSDATA
* ***********************************************************/
/******************************************************************************
*
* LONG-TERM CAMPAIGN METHODS
*
* Routines dealing with the LONG TERM CAMPAIGN and calculating the points
* for each team that determine the current campaign status
* and which map will be used next mission
*
******************************************************************************/
public Tuple CalcMapMove(string winner, bool final = true, bool output = true, Player player = null)
{
double MapMove = 0;
string msg = "";
string outputmsg = "";
Player[] recipients = null;
if (player != null) recipients = new Player[] { player };
double delay_s = 0;
double military_strength_red = MO_AllMilitaryStrength_averaged(ArmiesE.Red);
double military_strength_blue = MO_AllMilitaryStrength_averaged(ArmiesE.Blue);
string msg0 = "****Overall Campaign Objective: Push front line across Channel onto enemy territory and capture any enemy airfield. Push your front line fully past the";
outputmsg += msg0 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg0, null); });
delay_s += 0.04;
string msg01 = "target airfield and simultaneously claim it as an active airfield (use command { gpLogServerAndLog(recipients, msg01, null); });
delay_s += 0.04;
if (winner == "Red")
{
double military_strength_factor = 1;
if (military_strength_red < 0.5) military_strength_factor = 0.9;
if (military_strength_red < 0.1) military_strength_factor = 0.8;
if (military_strength_red < 0.05) military_strength_factor = 0.7;
double map_add_points = (3 + 3.0 * MissionObjectiveScore[ArmiesE.Red] / 100.0 + 36 * RedTotalF / 1000.0) * military_strength_factor;
string msg10 = winner + " has moved the front line forward - " + Math.Abs((map_add_points * 100)).ToString("n0") + " points";
outputmsg += msg10 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg10, null); });
delay_s += 0.04;
if (military_strength_factor < 1)
{
string msg11 = winner + "'s military strength was so weak, it had difficulty fully taking advantage of this victory.";
outputmsg += msg11 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg11, null); });
delay_s += 0.04;
}
}
if (winner == "Blue")
{
double military_strength_factor = 1;
if (military_strength_blue < 0.5) military_strength_factor = 0.9;
if (military_strength_blue < 0.1) military_strength_factor = 0.8;
if (military_strength_blue < 0.05) military_strength_factor = 0.7;
double map_add_points = (-3.0 - 3.0 * MissionObjectiveScore[ArmiesE.Blue] / 100.0 - 36 * BlueTotalF / 1000.0) * military_strength_factor;
string msg10 = winner + " has moved the front line forward - " + Math.Abs((map_add_points * 100)).ToString("n0") + " points";
outputmsg += msg10 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg10, null); });
delay_s += 0.04;
if (military_strength_factor < 1)
{
string msg11 = winner + "'s military strength was so weak, it had difficulty fully taking advantage of this victory.";
outputmsg += msg11 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg11, null); });
delay_s += 0.04;
}
}
if (RedTotalF > 3)
{
string msg1 = "Red has moved the campaign forward through its " + RedTotalF.ToString("n1") + " total air/ground/naval victories this session!";
outputmsg += msg1 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg1, null); });
delay_s += 0.04;
MapMove += RedTotalF / 1000.0;
}
if (BlueTotalF > 3)
{
string msg2 = "Blue has moved the campaign forward through its " + BlueTotalF.ToString("n1") + " total air/ground/naval victories this session!";
outputmsg += msg2 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg2, null); });
delay_s += 0.04;
MapMove -= BlueTotalF / 1000.0;
}
/*
double difference = RedTotalF - BlueTotalF;
if (Math.Abs(difference) >= 5)
{
if (difference > 0)
{
msg = "Red has moved the campaign forward by getting " + difference.ToString("n1") + " more total victories than Blue!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
if (difference < 0)
{
msg = "Blue has moved the campaign forward by getting " + (-difference).ToString("n1") + " more total victories than Red!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
MapMove += difference / 400;
}
double air_difference = RedAirF - BlueAirF;
if (Math.Abs(air_difference) >= 5)
{
if (air_difference > 0)
{
msg = "Red has moved the campaign forward by getting " + air_difference.ToString("n1") + " more air victories than Blue!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
if (air_difference < 0)
{
msg = "Blue has moved the campaign forward by getting " + (-air_difference).ToString("n1") + " more air victories than Red!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
MapMove += air_difference / 400;
}
double ground_difference = RedAAF + RedNavalF + RedGroundF - BlueAAF - BlueNavalF - BlueGroundF;
if (Math.Abs(ground_difference) >= 5)
{
if (ground_difference > 0)
{
msg = "Red has moved the campaign forward by getting " + ground_difference.ToString("n1") + " more ground victories than Blue!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
if (ground_difference < 0)
{
msg = "Blue has moved the campaign forward by getting " + (-ground_difference).ToString("n1") + " more ground victories than Red!";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
MapMove += ground_difference / 400;
}
*/
{
string msg5 = "Red: " + RedPlanesWrittenOffI.ToString() + " aircraft lost this session";
outputmsg += msg5 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg5, null); });
delay_s += 0.04;
}
{
string msg6 = "Blue: " + BluePlanesWrittenOffI.ToString() + " aircraft lost this session";
outputmsg += msg6 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg6, null); });
delay_s += 0.04;
}
/*
if (final)
{
if (outside > 0.05)
{
string reason = "Help from Allies";
if (random.Next(2) == 1) reason = "A naval victory";
msg = reason + " has strengthened Red's position";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
if (outside < -0.05)
{
string reason = "Help from Allies has";
if (random.Next(3) == 1) reason = "A naval victory has";
else if (random.Next(1) == 1) reason = "Positive developments on the Eastern Front have";
msg = reason + " strengthened Blue's position";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
MapMove += outside;
}
*/
if (MissionObjectiveScore[ArmiesE.Red] > 0)
{
string msg3 = "Red: " + MissionObjectiveScore[ArmiesE.Red].ToString("n0") + " objective points towards turning the map!";
outputmsg += msg3 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg3, null); });
delay_s += 0.04;
}
if (MissionObjectiveScore[ArmiesE.Blue] > 0)
{
string msg4 = "Blue: " + MissionObjectiveScore[ArmiesE.Blue].ToString("n0") + " objective points towards turning the map!";
outputmsg += msg4 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg4, null); });
delay_s += 0.04;
}
double mapMove_withObjectives = MapMove * 100 + MissionObjectiveScore[ArmiesE.Red] - MissionObjectiveScore[ArmiesE.Blue];
string word = "Currently, ";
if (final) word = "Altogether, ";
if (mapMove_withObjectives > 0)
{
string msg7 = word + "Red's campaign position is up " + (mapMove_withObjectives).ToString("n0") + " points since the last time map turns.";
outputmsg += msg7 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg7, null); });
delay_s += 0.04;
}
if (mapMove_withObjectives < 0)
{
string msg7 = word + "Blue's campaign position is up " + (-mapMove_withObjectives).ToString("n0") + " points since the last map turns.";
outputmsg += msg7 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg7, null); });
delay_s += 0.04;
}
if (mapMove_withObjectives == 0)
{
string msg7 = word + "since the last map turns, neither Red nor Blue has the advantage in campaign position!";
outputmsg += msg7 + Environment.NewLine;
if (output) Timeout(delay_s, () => { gpLogServerAndLog(recipients, msg7, null); });
delay_s += 0.04;
}
return new Tuple(MapMove, outputmsg);
}
//saves the current map state to a text file as the first line. Previous mapstates are in reverse order from the top down, each on one line...
{
string outputmsg = "";
string msg = "";
Player[] recipients = null;
if (player != null) recipients = new Player[] { player };
if (ms > 0)
{
msg = "Red stands at +" + (ms * 100).ToString("n0") + " for the entire " + CAMPAIGN_ID + " campaign.";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
else if (ms < 0)
{
msg = "Blue stands at +" + (-ms * 100).ToString("n0") + " for the entire " + CAMPAIGN_ID + " campaign.";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
else
{
msg = "The entire " + CAMPAIGN_ID + " campaign is exactly balanced. Blue stands at +0, Red +0.";
outputmsg += msg + Environment.NewLine;
if (output) gpLogServerAndLog(recipients, msg, null);
}
return outputmsg;
}
public bool MapStateSaved = false;
public bool MapStateBackedUp = false;
//Console.WriteLine("Map Save #0"); Tuple
{
bool disp = false;
if (winner == "Red" || winner == "Blue") disp = true;
try
{
double misResult = res.Item1;
double newMapState = CampaignMapState + misResult;
string outputmsg = res.Item2;
string msg = "";
string turnString = "(none)";
if (winner.Equals("Red") || winner.Equals("Blue")) turnString = winner;
DateTime dt = DateTime.UtcNow;
string date = dt.ToString("u");
bool writeOutput = true;
if (intermediateSave && !intermediateWin) writeOutput = false;
if (winner != "Red" && winner != "Blue") outputmsg += summarizeCurrentMapstate(newMapState + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0, writeOutput);
else outputmsg += summarizeCurrentMapstate(newMapState, writeOutput);
/* (removing this save here since we have it in CheckStatsData();
try
{
File.WriteAllText(STATSCS_FULL_PATH + "CampaignSummary.txt", Regex.Replace(outputmsg, @"\r\n?|\n", "
" + Environment.NewLine));
}
catch (Exception ex) { Console.WriteLine("CampaignSummary Write: " + ex.ToString()); }
*/
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapState.txt";
string filepath_old = STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapState_old.txt";
string currentContent = String.Empty;
try
{
if (File.Exists(filepath_old)) { File.Delete(filepath_old); }
File.Copy(filepath, filepath_old);
}
catch (Exception ex) { Console.WriteLine("MapState Write Inner: " + ex.ToString()); }
sw = fi.CreateText();
sw.WriteLine(newMapState.ToString());
sw.Close(); */
if (File.Exists(filepath))
{
currentContent = File.ReadAllText(filepath);
}
currentContent = String.Join(Environment.NewLine, currentContent.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Where(x => !string.IsNullOrWhiteSpace(x))
Calcs.WriteAllTextAsync(filepath, newMapState.ToString() + Environment.NewLine + turnString + Environment.NewLine + date + Environment.NewLine + currentContent);
if (!intermediateSave) MapStateSaved = true;
if (intermediateWin) CampaignMapState = newMapState;
if (!intermediateSave || intermediateWin)
{
try
{
double pcDone = calcProportionTimeComplete();
int netRedCount = 15;
int netBlueCount = 15;
string netBlue = statsmission.Display_SessionStatsAll(null, 2, false, true);
netRed = netRed.Replace(@"***No Netstats to report***
", "");
netBlue = netBlue.Replace(@"***No Netstats to report***
", "");
netRedCount = netRed.Select((c, i) => netRed.Substring(i)).Count(sub => sub.StartsWith(target)) - 1;
netBlueCount = netBlue.Select((c, i) => netBlue.Substring(i)).Count(sub => sub.StartsWith(target)) - 1;
Console.WriteLine("Main-ReSupply: " + netRedCount.ToString() + " " + netBlueCount.ToString());
if (netRedCount < 0) netRedCount = 0;
if (netBlueCount < 0) netBlueCount = 0;
if (netRedCount > 120) netRedCount = 120;
if (netBlueCount > 120) netBlueCount = 120;
Console.WriteLine("Main-ReSupply: " + netRedCount.ToString() + " " + netBlueCount.ToString() + " " + redMult.ToString() + " " + blueMult.ToString() + " "
+ redMultAdmin.ToString() + " " + blueMultAdmin.ToString() + " ");
else if (winner == "Blue") { blueMult += 4.0; redMult = 0.01; }
else if (misResult > 0) redMult += misResult / 100.0;
else if (misResult < 0) blueMult += (-misResult) / 100.0;
double mProductionStrength_red = MO_CalculateMilitaryStrength(ArmiesE.Red, MO_MilitaryStrengthType.General_Production_And_Supply);
double mProductionStrength_blue = MO_CalculateMilitaryStrength(ArmiesE.Blue, MO_MilitaryStrengthType.General_Production_And_Supply);
redMult *= mProductionStrength_red / par;
blueMult *= mProductionStrength_blue / par;
redMult += redMultAdmin;
blueMult += blueMultAdmin;
double magicNumber = -1000000;
if (winner == "Red") blueMult = magicNumber;
if (winner == "Blue") redMult = magicNumber;
if (TWCSupplyMission != null) TWCSupplyMission.SupplyEndMission(redMult, blueMult);
Console.WriteLine("Main-ReSupply: " + netRedCount.ToString() + " " + netBlueCount.ToString() + " " + redMult.ToString() + " " + blueMult.ToString() + " "
+ redMultAdmin.ToString() + " " + blueMultAdmin.ToString() + " ");
} catch (Exception ex) { Console.WriteLine("MapState Supply Save ERROR: " + ex.ToString()); }
}
if (!MapStateBackedUp || !intermediateSave || intermediateWin)
{
var backPath = STATSCS_FULL_PATH + CAMPAIGN_ID + @" campaign backups\";
string filepath_date = backPath + CAMPAIGN_ID + "_MapState-" + dt.ToString("yyyy-MM-dd-HH-mm-ss") + ".txt";
if (!System.IO.File.Exists(backPath))
{
try
{
System.IO.Directory.CreateDirectory(backPath);
}
catch (Exception ex) { Console.WriteLine("MapState Dir Create Date ERROR: " + ex.ToString()); }
}
try
{
if (File.Exists(filepath_date)) { File.Delete(filepath_date); }
File.Copy(filepath, filepath_date);
MapStateBackedUp = true;
}
catch (Exception ex) { Console.WriteLine("MapState Write Date: " + ex.ToString()); }
}
if (intermediateSave && intermediateWin)
{
CheckStatsData(winner);
Timeout(1, () =>
{
});
}
}
catch (Exception ex) { Console.WriteLine("MapState Write: " + ex.ToString()); }
}
if (MapState_int > 0) return "-R" + MapState_int.ToString("D3"); //3 digits so that our files will be named ie TWC M001-initairports-R002.mis - 002 is 3 digits
{
double MapState = GetMapState();
int MapState_int = Convert.ToInt32(MapState);
if (MapState_int > CampaignMapMaxRedSuffixMax) MapState_int = CampaignMapMaxRedSuffixMax;
if (-MapState_int > CampaignMapMaxBlueSuffixMax) MapState_int = -CampaignMapMaxBlueSuffixMax;
if (MapState_int == 0) return "-0";
else return "-B" + (-MapState_int).ToString("D3");
}
if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MXX2 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping MapState = Convert.ToDouble(res); //Total overall score; 0=tied, + = Red winning, - = Blue winning if (prevWinner == "Red" || prevWinner == "Blue") MapPrevWinner = prevWinner.Trim(); //Winner of previous mission, if there was one.
{
double MapState = 0;
string res = "";
try
{
using (StreamReader sr = new StreamReader(STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapState.txt"))
{
res = sr.ReadLine();
string prevWinner = sr.ReadLine();
}
}
catch (Exception ex)
{
System.Console.WriteLine("Main mission - read mapstate - Exception: " + ex.ToString());
MapState = 0;
}
Console.WriteLine("Main mission - read mapstate: " + MapState.ToString() + " " + res + " : " + STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapState.txt");
if (MapState > 1000000 || MapState < -1000000) MapState = 0;
CampaignMapState = MapState;
return MapState;
}
f2 = DrawFrontLinesPerMapState(-MAP_WIN_POINTS, MAP_WIN_POINTS, i * MAP_WIN_POINTS / 100, saveName: "FrontLines-test_" + (i * 100).ToString("F0") + ".mis", loadSectionFile: false, f2: f2, test: true); //2022-03-21 - WAS 100, NOW 125 f2.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/" + "FrontLines-test_ALL.mis"); //testing // public ISectionFile DrawFrontLinesPerMapState(double minMapState = -25, double maxMapState = 25, double? currMapState = null, string saveName = "frontfile.mis", bool loadSectionFile = true, ISectionFile f = null)
{
try
{
double mapState = CampaignMapState;
var f2 = GamePlay.gpCreateSectionFile();
for (double i = -2; i <= 2; i += 0.1)
{
}
}
catch (Exception ex) { Console.WriteLine("************testfrontlines ERROR: " + ex.ToString()); }
}
/* SAMPLE front markers
FrontMarker0 122130.41 99692.54 1
FrontMarker1 184923.58 199248.64 1
FrontMarker2 151050.02 106909.01 1
FrontMarker3 273615.78 251329.87 1
FrontMarker4 318170.97 309361.61 1
FrontMarker5 355340.23 298205.35 2
FrontMarker6 284329.09 226250.35 2
FrontMarker7 195643.43 103278.12 2
FrontMarker8 88262.03 60001.96 2
FrontMarker9 113282.01 85097.34 2
FrontMarker10 341348.18 266004.67 2
FrontMarker11 225658.13 150675.90 1
FrontMarker12 253901.90 109419.35 2
FrontMarker13 163783.69 109004.79 1
FrontMarker14 189714.23 113052.10 1
FrontMarker15 249954.27 141364.45 2
FrontMarker16 171903.52 90341.35 2
FrontMarker17 102887.45 94353.53 1
FrontMarker18 94502.66 92980.57 1
FrontMarker19 259759.88 188769.38 2
FrontMarker20 230005.07 198916.29 1
*/
//bhugh, XX2021-10, temp, for end of campaign Ultimate Battle we disable this //frontline scheme & use a bespoke one //return; //so because of CloD weirdness, the lines need to go pretty much perpendicular to the dividing line between france & england. //To make the points, go into FMB, choose points WIDE apart, as wide as possible, opposite each other at the furthest //extremes of where the front lines will range--one furthest to the blue side, the other furthest to the red side //Choose the points in pairs (red side/blue side), and make them so that the resulting front line in the middle is //nice and smooth...
{
try
{
List> frontPoints = new List>() {
new List() { new Point2d (10618.9, 166919.1), new Point2d (12535.9, 80190.7)},
new List() { new Point2d (43448.8, 175135.6), new Point2d (45083.8, 77280.9)},
new List() { new Point2d (63424.7, 167041), new Point2d (61680.2, 74914.2)},
new List() { new Point2d (83910.5, 175416.5), new Point2d (78249.5, 58702.7)},
new List() { new Point2d (99733.3, 184877.4), new Point2d (100949.9, 42579.6)},
new List() { new Point2d (112911.9, 190132.5), new Point2d (126336, 42672.0)},
new List() { new Point2d (127340.3, 192076), new Point2d (154214.3, 61859.9)},
new List() { new Point2d (138637.2, 193391.6), new Point2d (159814.7, 76825.1)},
new List() { new Point2d (153984, 192960), new Point2d (180864, 89088.0)},
new List() { new Point2d (163984, 189460), new Point2d (190864, 93588.0)},
new List() { new Point2d (172992, 185856), new Point2d (205056, 97152.0)},
new List() { new Point2d (179601, 194613.4), new Point2d (231006.1, 105485.1)},
new List() { new Point2d (188597.3, 199130.6), new Point2d (248621.3, 119111.7)},
new List() { new Point2d (202752, 202944), new Point2d (258624, 136320.0)},
new List() { new Point2d (204442.8, 215862.6), new Point2d (262080, 165696.0)},
new List() { new Point2d (207682.5, 226905.6), new Point2d (262870, 187072.0)},
new List() { new Point2d (212833.8, 236430.9), new Point2d (265364, 192627.7)},
new List() { new Point2d (221236.8, 243913.7), new Point2d (276436.5, 191778.2)},
new List() { new Point2d (241292.4, 250042.4), new Point2d (291274.8, 199740.2)},
new List() { new Point2d (251381.6, 250029.4), new Point2d (289920, 206705.6)},
new List() { new Point2d (259527.6, 266599.7), new Point2d (294135.2, 209694.2)},
new List() { new Point2d (261626, 284269), new Point2d (294535.8, 220595.1)},
new List() { new Point2d (269631.3, 305857.6), new Point2d (304619.6, 224465.3)},
new List() { new Point2d (289955.1, 307510.1), new Point2d (313366, 227043.5)},
new List() { new Point2d (307159.4, 307233.4), new Point2d (325633.6, 229384.0)},
new List() { new Point2d (317821.9, 306656.9), new Point2d (337857.3, 235244.1)},
new List() { new Point2d (329207.1, 307342.7), new Point2d (347077.2, 240365.3)},
new List() { new Point2d (342760.8, 305927.9), new Point2d (352757.3, 244599.0)},
new List() { new Point2d (354908, 306712.9), new Point2d (358080, 247296.0)},
};
if (ON_JUBILEE)
{
frontPoints = new List>() {
new List() {
},
new List() {
},
new List() {
new Point2d (61680.21,74914.15),
},
new List() {
new Point2d (83910.49,175416.5),
new Point2d (78249.54,58702.71),
},
new List() {
new Point2d (99733.32,184877.35),
new Point2d (100949.88,42579.64),
},
new List() {
new Point2d (110400,190272),
new Point2d (126336,42672),
},
new List() {
new Point2d (118688.29,190680.54),
new Point2d (154214.29,61859.85),
},
new List() {
new Point2d (131659.66,192833.41),
new Point2d (159814.69,76825.13),
},
new List() {
new Point2d (153984,192960),
new Point2d (180864,89088),
},
new List() {
new Point2d (163984,189460),
new Point2d (190864,93588),
},
new List() {
new Point2d (172992,185856),
new Point2d (205056,97152),
},
new List() {
new Point2d (179601.02,194613.41),
new Point2d (231006.05,105485.13),
},
new List() {
new Point2d (188597.32,199130.55),
new Point2d (248621.26,119111.73),
},
new List() {
new Point2d (202752,202944),
new Point2d (258624,136320),
},
new List() {
new Point2d (209664,209580),
new Point2d (262080,165696),
},
/*
new List() {
new Point2d (216576,209088),
new Point2d (262848,180672),
},
*/
new List() {
new Point2d (221076,206088),
new Point2d (262870,187072),
},
new List() {
new Point2d (225385.59,208849.89),
new Point2d (262894.58,192305.62),
},
new List() {
new Point2d (224085.59,220049.89),
new Point2d (263504.58,199305.62),
},
new List() {
new Point2d (227862.38,225744.41),
new Point2d (264038.59,205787.15),
},
new List() {
new Point2d (241004.44,230038.61),
new Point2d (272136.04,212438.45),
},
new List() {
new Point2d (251813.55,235841.49),
new Point2d (281884.35,218378.42),
},
new List() {
new Point2d (252759.67,254935.81),
new Point2d (283874.9,219379.32),
},
new List() {
new Point2d (260042, 284125),
new Point2d (291874.9,221379.32),
},
new List() {
new Point2d (270050, 298601),
new Point2d (305380.94,215076.27),
},
new List() {
new Point2d (288141, 300114),
new Point2d (313365.97,227043.45),
},
new List() {
new Point2d (307299, 299000),
new Point2d (325633.59,229383.98),
},
new List() {
new Point2d (318101, 297028),
new Point2d (337857.27,235244.12),
},
new List() {
new Point2d (328928, 295481),
new Point2d (347077.23,240365.27),
},
new List() {
new Point2d (340528, 299090),
new Point2d (352757.32,244599.01),
},
new List() {
new Point2d (350582, 301410),
new Point2d (358080,247296),
},
};
}
double minMapState_int = minMapState_ext / 100;
double maxMapState_int = maxMapState_ext / 100;
ISectionFile f = GamePlay.gpCreateSectionFile();
if (f2 == null) f2 = GamePlay.gpCreateSectionFile();
string sect;
string key;
string value;
int count = 0;
double mapState = CampaignMapState;
if (currMapState.HasValue) mapState = currMapState.Value;
double neutral = (maxMapState_int - minMapState_int) / 120;
/*
if (mapState < 0.85 * minMapState) mapState = minMapState + (minMapState - 0.9 * mapState) / 4;
*/
Console.WriteLine("Frontline: mapState {0:F2} maxMapState_ext {1:F2} minMapState_ext {2:F2}", mapState, maxMapState_ext, minMapState_ext);
double slowdownpoint = 1;
double slowdownrate = 3;
if (mapState < slowdownpoint * minMapState_int) mapState = minMapState_int * slowdownpoint + (mapState - slowdownpoint * minMapState_int) / slowdownrate;
Console.WriteLine("Frontline: mapState corrected {0:F2} maxMapState_int {1:F2} minMapState_int {2:F2}", mapState, maxMapState_int, minMapState_int);
Console.WriteLine("Frontline: mult_north {0:F2} mult_south {1:F2} mult_neut {2:F2}", mult_north, mult_south, mult_neut);
if (mult < 0) mult = 0;
if (mult2 < 0) mult2 = 0;
*/
/* Now we're doing this with mapState instead of here
if (mult < 0) mult = mult/20;
if (mult2 < 0) mult2 = mult2/20;
*/
List> newPoints = new List>();
List lastPoints = null;
foreach (List initpoints in frontPoints)
{
if (lastPoints != null)
{
double french_dist = Calcs.CalculatePointDistance(initpoints[1], lastPoints[1]);
double brit_dist = Calcs.CalculatePointDistance(initpoints[0], lastPoints[0]);
double ave_dist = (french_dist + brit_dist) / 2;
if (mult_neut > 0.4) numPointsToInterpolate = french_dist / 4000;
else if (mult_neut < -0.4) numPointsToInterpolate = brit_dist / 4000;
else numPointsToInterpolate = ave_dist / 4000;
for (int i = 1; i < numPointsToInterpolate - 1 ; i++)
{
double id = (double)i;
List newPoint = new List();
newPoint.Add(new Point2d(id * (initpoints[0].x - lastPoints[0].x) / numPointsToInterpolate + lastPoints[0].x, id * (initpoints[0].y - lastPoints[0].y) / numPointsToInterpolate + lastPoints[0].y));
newPoint.Add(new Point2d(id * (initpoints[1].x - lastPoints[1].x) / numPointsToInterpolate + lastPoints[1].x, id * (initpoints[1].y - lastPoints[1].y) / numPointsToInterpolate + lastPoints[1].y));
newPoints.Add(newPoint);
}
}
newPoints.Add(initpoints);
lastPoints = initpoints;
}
var Point1 = new Point3d();
var Point2 = new Point3d();
var Point3 = new Point3d();
var oldBauv = new Point3d();
int pointCount = 0;
foreach (List points in newPoints)
{
double dist = Calcs.CalculatePointDistance(points[0], points[1]);
double y_neut = mult_neut * points[1].y + (1 - mult_neut) * points[0].y;
Point3d Point = new Point3d(x_neut, y_neut, 0);
if (pointCount == 0)
{
Point1 = Point;
pointCount++;
continue;
}
else if (pointCount == 1)
{
Point2 = Point;
pointCount++;
continue;
}
Point3 = Point;
Point3d bauv = Calcs.bisectAngleUnitVectorXY(Point1, Point2, Point3, Point2);
/*
{
if (bauv.y < 0) bauv = Calcs.reverseVectorXY(bauv);
{
if (bauv.y < 0 && bauv.x > bauv.y) bauv = Calcs.reverseVectorXY(bauv);
else if (bauv.y >= 0 && bauv.x >= bauv.y) bauv = Calcs.reverseVectorXY(bauv);
}
*/
/*
double theta = Calcs.angleBetweenVectorsXY_rad(bauv, new Point3d (points[0].x-points[1].x, points[1].y-points[0].y, 0));
if (theta < Math.PI / 2) bauv = Calcs.reverseVectorXY(bauv);
*/
double theta = Calcs.angleBetweenVectorsXY_rad(bauv, Calcs.unitNormalVectorCCWXY( Point1, Point3));
if (theta > Math.PI / 2 && !double.IsNaN(theta)) bauv = Calcs.reverseVectorXY(bauv);
double theta2 = Calcs.angleBetweenVectorsXY_rad(bauv, oldBauv);
if (theta2 > Math.PI / 2) Console.WriteLine("!!!!!!! FRONTINELINE: BAUV reversed!!!!!! {0:f2} {1:f2} {2:f2} {3:f2} theta2 {4:f3}", bauv.x, bauv.y, oldBauv.x, oldBauv.y, theta2);
if (double.IsNaN(theta) && theta2 > Math.PI/2 ) bauv = Calcs.reverseVectorXY(bauv);
if (!test) Console.WriteLine("Frontline: Point: ({0:F0}, {1:F0}) - BAUV: ({2:F2}, {3:F2}) theta: {4}", Point2.x, Point2.y, bauv.x, bauv.y, theta);
oldBauv = bauv;
Point3d bluePos = Calcs.addVectorwithScalarMultXY(Point2, bauv, -neutral_width_m);
Point3d blueNeutPos = Calcs.addVectorwithScalarMultXY(Point2, bauv, -neutral_width_m + 250);
Point3d redPos = Calcs.addVectorwithScalarMultXY(Point2, bauv, neutral_width_m);
Point3d redNeutPos = Calcs.addVectorwithScalarMultXY(Point2, bauv, neutral_width_m - 250);
Point3d neutPos = Point2;
/*
double y = mult * points[1].y + (1 - mult) * points[0].y;
double y2 = mult2 * points[1].y + (1 - mult2) * points[0].y;
*/
sect = "FrontMarker";
key = "FrontMarker" + count.ToString();
f.add(sect, key, value);
f2.add(sect, key, value);
count++;
key = "FrontMarker" + count.ToString();
f.add(sect, key, value);
f2.add(sect, key, value);
count++;
key = "FrontMarker" + count.ToString();
f.add(sect, key, value);
f2.add(sect, key, value);
count++;
key = "FrontMarker" + count.ToString();
value = bluePos.x.ToString("F2") + " " + bluePos.y.ToString("F2") + " 2";
f.add(sect, key, value);
f2.add(sect, key, value);
count++;
Point1 = Point2;
Point2 = Point3;
pointCount++;
}
int countFP = 0;
foreach (List initpoints in frontPoints)
{
f = Calcs.makeStatic(f, GamePlay, this, initpoints[0].x, initpoints[0].y, -100, "Stationary.Environment.Ladder_UK1_DMG1", 0, staticprefix: "frontmarker_setpoint_red_" + countFP.ToString() + "_");
f = Calcs.makeStatic(f, GamePlay, this, initpoints[1].x, initpoints[1].y, -100, "Stationary.Environment.Ladder_UK1_DMG1", 0, staticprefix: "frontmarker_setpoint_blue" + countFP.ToString() + "_");
countFP++;
}
if (loadSectionFile)
{
Timeout(12.74, () =>
{
GamePlay.gpPostMissionLoad(f);
});
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Drew current frontline");
}
return f2;
}
catch (Exception ex)
{
Console.WriteLine("******************Frontline ERROR: " + ex.ToString());
return f2;
}
}
/******************************************************************************
*
* END - LONG-TERM CAMPAIGN METHODS
*
******************************************************************************/
/*************************
* ONACTORDEAD
* **********************/
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List damages)
{
base.OnActorDead(missionNumber, shortName, actor, damages);
try
{
if (actor != null)
{
try
{
/*
try {
Console.WriteLine("OnActorDead OAD: Shortname {0} Name {1} Army {2} InternalTypeName {3}", shortName, actor.Name(), actor.Army(), (actor as AiCart).InternalTypeName());
}
catch (Exception ex) { Console.WriteLine("OAD ERROR0: " + ex.ToString()); }
*/
/*
if (damages != null) foreach (DamagerScore ds in damages)
{
if (ds == null) continue;
try
{
if (ds != null && ds.initiator != null && ds.initiator.Tool != null && ds.initiator.Tool.Name != null) Console.WriteLine(" OAD: Damage Toolname: " + ds.initiator.Tool.Name);
}
catch (Exception ex) { Console.WriteLine("OAD ERROR1: " + ex.ToString()); }
try
{
if (ds != null && ds.initiator != null && ds.initiator.Tool != null && ds.initiator.Tool.Type != null) Console.WriteLine(" OAD: Damage Tooltype: " + ds.initiator.Tool.Type.ToString());
}
catch (Exception ex) { Console.WriteLine("OAD ERROR2: " + ex.ToString()); }
try
{
if (ds != null && ds.initiator != null && ds.initiator.Actor != null && ds.initiator.Actor.Name() != null) Console.WriteLine(" OAD: Damage Actor name: " + ds.initiator.Actor.Name());
}
catch (Exception ex) { Console.WriteLine("OAD ERROR3: " + ex.ToString()); }
try
{
if (ds != null && ds.initiator != null && ds.initiator.Player != null && ds.initiator.Player.Name() != null) Console.WriteLine(" OAD: Damage Player name: " + ds.initiator.Player.Name());
}
catch (Exception ex) { Console.WriteLine("OAD ERROR4: " + ex.ToString()); }
}
*/
}
catch (Exception ex) { Console.WriteLine("OAD ERROR: " + ex.ToString()); }
}
if (actor as Player != null)
{
MO_SpoilPlayerScoutPhotos(actor as Player);
}
try
{
MO_makeAllObjectivesScoutedAndLaunchDefenseFromPos(actor.Pos(), null);
}
catch (Exception ex) { Console.WriteLine("OnActorDead - HandlePAO: " + ex.ToString()); }
if (actor != null && actor is AiAircraft)
{
AiAircraft aircraft = actor as AiAircraft;
MO_SpoilPlayerScoutPhotos(playersInPlane(aircraft));
string pName = actor.Name();
if (aircraft != null)
{
{
if (aircraft.Places() > 0) for (int i = 0; i < aircraft.Places(); i++)
{
if (aircraft.Player(i) != null) aircraft.Player(i).PlaceLeave(i);
}
Timeout(0.5, () =>
{
});
});
}
}
if (actor != null && actor is AiGroundActor)
{
Timeout(30 * 60, () =>
{
(actor as AiGroundActor).Destroy();
});
}
}
catch (Exception ex) { Console.WriteLine("OPD: " + ex.ToString()); }
}
/*************************
* ONPERSONHEALTH
* **********************/
public override void OnPersonHealth(maddox.game.world.AiPerson person, maddox.game.world.AiDamageInitiator initiator, float deltaHealth)
{
#region stats
base.OnPersonHealth(person, initiator, deltaHealth);
try
{
if (person != null)
{
Player player = person.Player();
if (player != null && player.Name() != null)
{
if (DEBUG) twcLogServer(null, "Main: OnPersonHealth for " + player.Name() + " health " + player.PersonPrimary().Health.ToString("F2"), new object[] { });
if (player.PersonPrimary() != null && player.PersonPrimary().Health == 0
&& (player.PersonSecondary() == null
|| (player.PersonSecondary() != null && player.PersonSecondary().Health == 0)))
{
if (DEBUG) twcLogServer(null, "Main: 2 OnPersonHealth for " + player.Name(), new object[] { });
{
if (DEBUG) twcLogServer(null, "Main: 3 OnPersonHealth for " + player.Name(), new object[] { });
if (player.PersonPrimary() != null && player.PersonPrimary().Health == 0
&& (player.PersonSecondary() == null
|| (player.PersonSecondary() != null && player.PersonSecondary().Health == 0)))
{
if (DEBUG) twcLogServer(null, "Main: 4 OnPersonHealth for " + player.Name(), new object[] { });
if (player.PersonPrimary() != null) player.PlaceLeave(player.PersonPrimary().Place());
if (player.PersonSecondary() != null) player.PlaceLeave(player.PersonSecondary().Place());
}
if (DEBUG) twcLogServer(null, player.Name() + " died and was forced to leave player's current place.", new object[] { });
if (DEBUG) twcLogServer(null, "Main: OnPersonHealth for " + player.Name() + " health1 " + player.PersonPrimary().Health.ToString("F2")
+ " health2 " + player.PersonSecondary().Health.ToString("F2"), new object[] { });
});
}
}
}
}
catch (Exception ex)
{
System.Console.WriteLine("Main.OnPersonHealth - Exception: " + ex.ToString());
}
#endregion
}
public override void OnAircraftCrashLanded(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
MO_SpoilPlayerScoutPhotos(playersInPlane(aircraft));
Timeout(300, () =>
{ destroyAiControlledPlane(aircraft); }
);
}
public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftLanded(missionNumber, shortName, aircraft);
Timeout(300, () =>
{ destroyAiControlledPlane(aircraft); }
);
try
{
if (GamePlay == null) return;
if (GamePlay.gpFrontArmy((aircraft as AiActor).Pos().x, (aircraft as AiActor).Pos().y) == (aircraft as AiActor).Army())
MO_RecordPlayerScoutPhotos(playersInPlane(aircraft));
}
catch (Exception ex) { System.Console.WriteLine("Main mission OnAircraftLanded recon record - Exception: " + ex.ToString()); }
}
public override void OnPersonParachuteFailed(maddox.game.world.AiPerson person)
{
base.OnPersonParachuteFailed(person);
if (person.Player() != null) MO_SpoilPlayerScoutPhotos(person.Player());
}
public override void OnPersonParachuteLanded(maddox.game.world.AiPerson person)
{
base.OnPersonParachuteLanded(person);
if (person.Player() != null) MO_SpoilPlayerScoutPhotos(person.Player());
}
public override void OnAircraftTookOff(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftTookOff(missionNumber, shortName, aircraft);
MO_SpoilPlayerScoutPhotos(playersInPlane(aircraft));
}
//Task.Run(() => //List
{
{
/*
if (GamePlay != null && GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
if (GamePlay.gpAirGroups(army) != null && GamePlay.gpAirGroups(army).Length > 0)
{
foreach (AiAirGroup airGroup in GamePlay.gpAirGroups(army))
{*/
var arms = new List() { 1, 2 };
if (GamePlay != null) foreach (int army in arms)
{
var airGroups = GamePlay.gpAirGroups(army);
if (airGroups != null && airGroups.Length > 0)
foreach (AiAirGroup airGroup in airGroups)
{
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
foreach (AiActor actor in airGroup.GetItems())
{
if (actor is AiAircraft)
{
AiAircraft a = actor as AiAircraft;
if (a != null && isAiControlledPlane2(a))
{
/* if (DEBUG) twcLogServer(new Player[] { player }, "DEBUG: Destroying: Airgroup: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID(), new object[] { });
*/
Timeout(random.NextDouble() * 10, () =>
{
a.Destroy();
});
}
}
}
}
}
}
#region onbuildingkilled
/*
*
* SUMMARY OF ONBUILDINGKILLED AND TRIGGER (VIA BUILDINGS, DIFFERENT SUBMISSIONS) SITUATION AS OF 2020/02 - TF4.57
*
TWC_Flug: #1. OnBuildingKilled only works with AI aircraft. Works perfectly with them. Anything I killed--never reported. I have it turned on in the server now (it would, for example, save stats for a player who took out a certain building) but it won't report anything except AI kills as near as I can see.
OnBuildingKilled() Issues
So with reference to the repaired OnBuildingKilled() script function and the usage of the following script:
public override void OnBuildingKilled(string title, Point3d pos, AiDamageInitiator initiator, int eventArgInt) {
string parts = title.Split(new string { SEP...
[1:42 AM] TWC_Flug: #2. Building kills definitely do not count towards setting off a trigger. Even when the AI hit it and it registers. Still, no matter how hard you hit it, no trigger.
[1:43 AM] TWC_Flug: #3. Also I tried putting stationary objects in an area, using a submission. I tried putting the trigger in the submission and seeing if the -main.cs script would detect it. No.
[1:43 AM] TWC_Flug: (Presumably you could put a little trigger detector in -submission.cs, that would detect it, then you could pass it to -main.cs. So, possibly but painful.)
[1:45 AM] TWC_Flug: #3. Then I tried putting the stationary objects in the submission but the trigger in the main.mis file. I was hoping the trigger would trigger off of ANY stationary or other object in its radius, no matter what submission it was loaded from. But no dice. It doesn't respond even if you have killed every last one of those objects, if they are loaded from a submission file rather than the main mission file.
[1:45 AM] TWC_Flug: So all that is kind of disappointing. Our -stats script works by detecting any and all stationaries from any and all missions, and it works just fine. But the built-in triggers just don't do that.
[1:47 AM] TWC_Flug: That's one reason I think it might be better to just roll our own "simulated trigger" using some special object to indicate where the trigger area is. You could detect any and all stationaries, buildings, or just ground explosions that happen within X distance of that special object and then that works exactly like a trigger but we're in control of exactly how it works.
[1:48 AM] TWC_Flug: We couldn't have to keep track of the object's ID# as we were doing before. Instead, you just keep track of it's X/Y position. Which you want/need to know anyway.
*/
public override void OnBuildingKilled(string title, Point3d pos, AiDamageInitiator initiator, int eventArgInt)
{
base.OnBuildingKilled(title, pos, initiator, eventArgInt);
{
double wait = stb_random.NextDouble() * 25;
Timeout(wait, () =>
);
string BuildingName = title;
string BuildingArmy = "";
string PlayerArmy = "Unknown/AI";
string sectorTitle = "";
string sectorName = GamePlay.gpSectorName(pos.x, pos.y);
if (GamePlay.gpFrontArmy(pos.x, pos.y) == 1)
{
BuildingArmy = "England";
}
else if (GamePlay.gpFrontArmy(pos.x, pos.y) == 2)
{
BuildingArmy = "France";
}
else
{
BuildingArmy = "Neutral";
}
if (initiator != null && initiator.Player as Player != null)
{
if (initiator.Player.Army() == 1)
{
PlayerArmy = "RAF";
}
else if (initiator.Player.Army() == 2)
{
PlayerArmy = "Luftwaffe";
}
else
{
PlayerArmy = "Unknown";
}
}
else if (initiator != null && initiator.Actor as AiActor != null)
{
if (initiator.Actor.Army() == 1)
{
PlayerArmy = "RAF";
}
else if (initiator.Actor.Army() == 2)
{
PlayerArmy = "Luftwaffe";
}
else
{
PlayerArmy = "Unknown (AI)";
}
}
string killerName = "(AI)";
if (initiator != null && initiator.Player != null) killerName = initiator.Player.Name();
else if (initiator != null && initiator.Actor != null) killerName = initiator.Actor.Name();
}
}
#endregion
double nearAirGroupThreshhold_m = 7500;
double nearAirGroupAltThreshhold_m = 2000;
public class AirGroupInfo : IAirGroupInfo
{
public Point3d pos { get; set; }
public Point3d vel { get; set; }
public bool belowRadar { get; set; }
public double altAGL_ft { get; set; }
public double altAGL_m { get; set; }
public int count { get; set; }
public string type { get; set; }
public bool isHeavyBomber { get; set; }
public bool isAI { get; set; }
public string playerNames { get; set; }
public AiActor actor { get; set; }
public AiAirGroup airGroup { get; set; }
public bool isLeader { get; set; }
public AiAirGroup leader { get; set; }
public string sector { get; set; }
public string sectorKeyp { get; set; }
public int giantKeypad { get; set; }
public string AGGsector { get; set; }
public string AGGsectorKeyp { get; set; }
public int AGGgiantKeypad { get; set; }
public Point3d AGGvel { get; set; }
public int AGGcountBelowRadar { get; set; }
public bool AGGradarDropout { get; set; }
public double AGGminAlt_m { get; set; }
public double AGGmaxAlt_m { get; set; }
public double AGGaveAlt_m { get; set; }
public double AGGavealtAGL_ft { get; set; }
public string AGGtypeNames { get; set; }
public string AGGplayerNames { get; set; }
public aiorhuman AGGAIorHuman { get; set; }
public bool AGGisHeavyBomber { get; set; }
public AMission mission { get; set; }
public AirGroupInfo()
{
}
public AirGroupInfo(AiActor a, AiAirGroup aag, Point3d p, Point3d v, int c, string ty, bool i, HashSet nag, Mission msn, double tm)
{
actor = a;
pos = p;
vel = v;
count = c;
type = ty;
isHeavyBomber = i;
nearbyAirGroups = nag;
time = tm;
}
public AirGroupInfo(AiActor act, AiAirGroup ag, Mission msn, double tm)
{
if (ag == null || act == null || act as AiAircraft == null) return;
try
{
AiAircraft a = act as AiAircraft;
actor = act;
airGroup = ag;
time = tm;
isAI = msn.isAiControlledPlane2(a);
if (isAI) AGGAIorHuman = aiorhuman.AI;
else AGGAIorHuman = aiorhuman.Human;
AGGcount = count;
mission = msn;
if (isAI)
{
playerNames = actor.Name();
AGGplayerNames = actor.Name();
}
else
{
bool first = true;
string aplayername = "";
/*
if (a.Player(0) != null && a.Player(0).Name() != null)
{
aplayername = a.Player(0).Name();
}
*/
for (int i = 0; i < a.Places(); i++)
{
if (a.Player(i) != null && a.Player(i).Name() != null)
{
if (!first) aplayername += " - ";
aplayername += a.Player(i).Name();
first = false;
}
}
playerNames = aplayername;
AGGplayerNames = playerNames;
}
AGGtypeNames = Calcs.GetAircraftType(actor as AiAircraft);
string acType = Calcs.GetAircraftType(a);
isHeavyBomber = false;
if (acType.Contains("Ju-88") || acType.Contains("He-111") || acType.Contains("BR-20") || acType.Contains("BlenheimMk") || acType.Contains("Wellington")) isHeavyBomber = true;
AGGisHeavyBomber = isHeavyBomber;
string t = a.Type().ToString().ToUpper();
if (t.Contains("FIGHTER") || t.Contains("JABO") || t.Contains("SCOUT")) t = "F";
else if (t.Contains("BOMBER") || t.Contains("AMPHIB") || t.Contains("BLENHEIM")) t = "B";
type = t;
AGGtype = t;
/* if (DEBUG) twcLogServer(new Player[] { player }, "DEBUG: Destroying: Airgroup: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID(), new object[] { });
*/
pos = a.Pos();
AGGpos = pos;
sector = Calcs.correctedSectorName(mission as Mission, pos);
AGGsector = sector;
sectorKeyp = Calcs.correctedSectorNameKeypad(mission as Mission, pos);
AGGsectorKeyp = sectorKeyp;
giantKeypad = Calcs.giantkeypad(pos);
AGGgiantKeypad = giantKeypad;
AGGmaxAlt_m = pos.z;
AGGminAlt_m = pos.z;
AGGaveAlt_m = pos.z;
altAGL_ft = Calcs.meters2feet(altAGL_m);
AGGavealtAGL_ft = altAGL_ft;
Vector3d Vwld = ag.Vwld();
/*
vel_mps = Calcs.CalculatePointDistance(Vwld);
vel_mph = Calcs.meterspsec2milesphour(vel_mps);
vel_mph_10 = Calcs.RoundInterval(vel_mph, 10);
heading = (Calcs.CalculateBearingDegree(Vwld));
heading_10 = Calcs.GetDegreesIn10Step(heading);
dis_m = Calcs.CalculatePointDistance(a.Pos(), p.Pos());
dis_mi = Calcs.meters2miles(dis_m);
dis_10 = (int)dis_mi;
if (dis_mi > 20) dis_10 = Calcs.RoundInterval(dis_mi, 10);
bearing = Calcs.CalculateGradientAngle(p.Pos(), a.Pos());
bearing_10 = Calcs.GetDegreesIn10Step(bearing);
longlat = Calcs.Il2Point3dToLongLat(a.Pos());
*/
/* alt_km = a.Pos().z / 1000;
alt_ft = Calcs.meters2feet(a.Pos().z);
altAGL_ft = Calcs.meters2feet(altAGL_m);
alt_angels = Calcs.Feet2Angels(alt_ft);
sector = GamePlay.gpSectorName(a.Pos().x, a.Pos().y).ToString();
vel = new Point3d(Vwld.x, Vwld.y, Vwld.z);
AGGvel = vel;
double vel_mps = Calcs.CalculatePointDistance(vel);
belowRadar = (mission as Mission).belowRadar(altAGL_ft, vel_mps, airGroup, a);
if (belowRadar) { AGGcountAboveRadar = 0; AGGcountBelowRadar = 1; }
else { AGGcountAboveRadar = 1; AGGcountBelowRadar = 0; }
AGGradarDropout = false;
}
catch (Exception ex)
{ Console.WriteLine("AirgroupInfo ERROR: {0}", ex); }
}
No description available.
{
nearbyAirGroups.Add(ag);
}
//Check if the two a/c are closer than the threshhold and meet other criteria, such as same type of fighter/bomber, within reasonable altitude range and if so add mutually to each other's nearby airgroups list
{
nearbyAirGroups.UnionWith(ags);
}
//Console.WriteLine("AGI: Adding {0} {1:N0} {2:N0}, 1st: {3}, 2nd: {4}, {5}", playerNames, pos.distance(ref tempos), Math.Abs(agi2.pos.z - pos.z), nearbyAirGroups.Count, agi2.nearbyAirGroups.Count, agi2.playerNames); } else { // Console.WriteLine("AGI: NOT Adding {0} {1} {2}", type, pos.distance(ref tempos), mission.nearAirGroupThreshhold_m);
{
if (agi2 == null || airGroup == null) return;
Point3d tempos = agi2.pos;
if (agi2.type == type && pos.distance(ref tempos) <= (mission as Mission).nearAirGroupThreshhold_m && (Math.Abs(agi2.pos.z - pos.z) <= (mission as Mission).nearAirGroupAltThreshhold_m))
{
if (agi2.airGroup == null) return;
addAG(agi2.airGroup);
agi2.addAG(airGroup);
}
}
//Console.WriteLine("AGI: Adding {0} {1} 2nd: {2} {3}", playerNames, nearbyAirGroups.Count, agi2.nearbyAirGroups.Count, agi2.playerNames);
{
addAGs(agi2.nearbyAirGroups);
agi2.addAGs(nearbyAirGroups);
}
//MissionObjective mo; //List
{
if (misformat)
{
return " " + TriggerName + " " + TriggerType + " " + TriggerPercent + " " + Pos.x + " " + Pos.y + " " + TriggerDestroyRadius;
}
else
{
string sn = ""; if (StaticNames != null && StaticNames.Count > 1) sn = string.Join(",", StaticNames);
string srn = ""; if (StaticRemoveNames != null && StaticRemoveNames.Count > 1) sn = string.Join(",", StaticRemoveNames);
/*return ID + " " + Name + " " + AttackingArmy.ToString() + " " + OwnerArmy.ToString() + " " + IsEnabled.ToString() + " " + MOObjectiveType.ToString() + " " + MOTriggerType + " " + IsPrimaryTarget.ToString() + " "
+ PrimaryTargetWeight.ToString() + " " + Points.ToString() + " " + Destroyed.ToString() + " " + Pos.x.ToString() + " " + Pos.y.ToString() + " " + Sector + " " + RadarEffectiveRadius.ToString() + " " + TriggerName + " "
+ TriggerType + " " + TriggerPercent.ToString() + " " + TriggerDestroyRadius.ToString() + " " + StaticPercentageRequired.ToString() + " " + StaticRemoveDelay_sec.ToString() + " " + StaticRemoveSpread_sec.ToString() + " "
+Comment + " " + HUDMessage + " " + LOGMessage
+ " " + sn + " " + srn;*/
return ID + "\t" + Name + "\t" + AttackingArmy.ToString() + "\t" + OwnerArmy.ToString() + "\t" + IsEnabled.ToString() + "\t" + MOObjectiveType.ToString() + "\t" + MOTriggerType + "\t" + IsPrimaryTarget.ToString() + "\t"
+ PrimaryTargetWeight.ToString() + "\t" + Points.ToString() + "\t" + "Destroyed: " + Destroyed.ToString() + "\t" + "Scouted: " + Scouted.ToString() + "\t" + Pos.x.ToString() + "\t" + Pos.y.ToString() + "\t" + Sector + "\t" + RadarEffectiveRadius.ToString() + "\t" + TriggerName + "\t"
+ TriggerType + "\t" + TriggerPercent.ToString() + "\t" + TriggerDestroyRadius.ToString() + "\t" + StaticPercentageRequired.ToString() + "\t" + StaticRemoveDelay_sec.ToString() + "\t" + StaticRemoveSpread_sec.ToString() + "\t"
+ Comment + "\t" + HUDMessage + "\t" + LOGMessage
+ "\t" + sn + "\t" + srn;
}
}
}
public class MissionObjectives
{
private Mission msn;
private maddox.game.IGamePlay gp;
public Dictionary Airfield_to_FlakMissions = new Dictionary();
public MissionObjectives(Mission mission, maddox.game.IGamePlay gameplay)
{
try {
msn = mission;
gp = gameplay;
msn.MO_initializeTurnMapPointsRequired_toLargeDict();
bool[] loadPreviousMission_success = new bool[] { false, false, false, false, false, false, false, false, };
bool loadingFromDiskOK = false;
try
{
loadPreviousMission_success = msn.MO_ReadMissionObjects();
}
catch (Exception ex)
{
Console.WriteLine("MissionObjectives: File Read problem on startup!! Using defaults. Error message: " + ex.ToString());
}
if (!loadPreviousMission_success[7]) {
msn.MO_CalculateTurnMapRequirements(1);
msn.MO_CalculateTurnMapRequirements(2);
msn.MO_initializeTurnMapPointsRequired_toLargeDict();
}
if (!loadPreviousMission_success[0] || !loadPreviousMission_success[3] || !loadPreviousMission_success[4] || !loadPreviousMission_success[5])
Console.WriteLine("File Read problem #2 on startup!! Using defaults.");
Dictionary MissionObjectivesList_OLD = new Dictionary(msn.MissionObjectivesList);
try
{
RadarPositionTriggersSetup();
MissionObjectiveTriggersSetup();
LandingGroundTransferObjectives(MissionObjectivesList_OLD);
}
catch (Exception ex)
{
Console.WriteLine("twc_tobruk_campaign_mission_objectives SETUP MAJOR ERROR: " + ex.ToString());
}
}
else
{
loadingFromDiskOK = true;
}
if (!loadPreviousMission_success[2])
{
Console.WriteLine("Failed to load MissionObjectivesTimes dictionary - generating it fresh.");
msn.MissionObjectivesTimes = new Dictionary>() {
{ArmiesE.Red, new Dictionary() },
{ArmiesE.Blue, new Dictionary() }
};
}
if (!loadPreviousMission_success[1])
{
Console.WriteLine("Failed to load Suggested Objectives - generating them fresh.");
SelectSuggestedObjectives(ArmiesE.Red);
SelectSuggestedObjectives(ArmiesE.Blue);
}
if (msn.MapPrevWinner == "Red")
{
Console.WriteLine("RED turned the map last time - giving reward, selecting new objectives");
msn.MO_SelectPrimaryObjectives(1, 0, fresh: true);
msn.MO_ReadPrimaryObjectives(2);
SelectSuggestedObjectives(ArmiesE.Red);
}
else if (msn.MapPrevWinner == "Blue")
{
Console.WriteLine("BLUE turned the map last time - giving reward, selecting new objectives");
msn.MO_SelectPrimaryObjectives(2, 0, fresh: true);
msn.MO_ReadPrimaryObjectives(1);
SelectSuggestedObjectives(ArmiesE.Blue);
}
else
*/
{
msn.MO_ReadPrimaryObjectives(2);
msn.MO_ReadPrimaryObjectives(1);
}
msn.MO_MissionObjectiveOnStartCheck(msn, gp);
try
{
msn.MO_HandleGeneralStaffPlacement();
}
catch (Exception ex) { Console.WriteLine("MO_init error1! " + ex.ToString()); }
try
{
msn.MO_WritePrimaryObjectives();
}
catch (Exception ex) { Console.WriteLine("MO_init error2! " + ex.ToString()); }
try
{
msn.MO_LoadAllPrimaryObjectiveFlak(FlakMissions);
}
catch (Exception ex) { Console.WriteLine("MO_init error3! " + ex.ToString()); }
try
{
msn.MO_InitializeAllObjectives();
}
catch (Exception ex) { Console.WriteLine("MO_init error3a! " + ex.ToString()); }
try
{
msn.MO_WriteOutAllMissionObjectives(msn.MISSION_ID + "-mission_objectives_mis_format.txt", true);
}
catch (Exception ex) { Console.WriteLine("MO_init error4! " + ex.ToString()); }
try
{
msn.MO_WriteOutAllMissionObjectives(msn.MISSION_ID + "-mission_objectives_complete.txt", false);
}
catch (Exception ex) { Console.WriteLine("MO_init error5! " + ex.ToString()); }
}
catch (Exception ex) { Console.WriteLine("MO_init ERROR (overall initializer)! " + ex.ToString()); }
}
//Timeout(188, () => { CheckStatsData(); }); //Timeout(31, () => { Task.Run(() => groupAllAircraft()); }); if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MRXX2 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //Console.WriteLine("groupAllAircraft: -1"); //OK< if we keep having the HighCPU bug caused by listpositionallaircraft, it is VERY possible that this Task.Run is the cause of it. It will //access/write some of the data structures in parallel & this could cause weird things to happen? (?) 2020/04/07 //groupAllAircraft(); //trying as not task.run as it's already done via a timeout? 2020/04/04 //This is called via Task.Run so no need to re-do that here/
{
/************************************************
*
* Check/download/transfer stats data
* Recursive function called every X seconds
************************************************/
Timeout(31, () => { groupAllAircraft_recurs(); });
Task.Run(() =>
groupAllAircraft()
);
}
if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("GPAAXX2-1 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //First go through & identify which airgroups are nearby to which others individually //List
{
try
{
numBlueAircraft = 0;
numRedAircraft = 0;
numTotalAircraft = 0;
int numBlueAircraft_length = 0;
int numRedAircraft_length = 0;
int numTotalAircraft_length = 0;
Dictionary airGroupInfoDict = new Dictionary();
if (GamePlay != null && GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
CurrentAG[army] = new HashSet();
HashSet doneAG = new HashSet();
AiAirGroup[] aGa = GamePlay.gpAirGroups(army);
if (aGa == null || aGa.Count() == 0) continue;
try
{
foreach (AiAirGroup airGroup in aGa)
{
if (airGroup == null) continue;
doneAG.Add(airGroup);
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
{
bool first = true;
foreach (AiActor actor in airGroup.GetItems())
{
if (actor != null && actor is AiAircraft)
{
if (first)
{
else if (army == 2) numBlueAircraft += airGroup.NOfAirc;
numTotalAircraft += airGroup.NOfAirc;
int num = airGroup.GetItems().Length;
if (army == 1) numRedAircraft_length += num;
else if (army == 2) numBlueAircraft_length += num;
numTotalAircraft_length += num;
first = false;
}
CurrentAG[army].Add(airGroup);
AirGroupInfo tmp = new AirGroupInfo();
/*
if (!airGroupInfoDict.TryGetValue(airGroup, out tmp))
{
Console.WriteLine("groupAllAircraft: 1.3b");
tmp = new AirGroupInfo(actor, airGroup, this, 32);
airGroupInfoDict[airGroup] = tmp;
}*/
if (!(airGroupInfoDict.ContainsKey(airGroup))) airGroupInfoDict[airGroup] = new AirGroupInfo(actor, airGroup, this, Time.current());
AiAirGroup[] aGa2 = GamePlay.gpAirGroups(army);
if (aGa2 == null || aGa2.Count() == 0) continue;
foreach (AiAirGroup airGroup2 in aGa)
{
if (doneAG.Contains(airGroup2)) continue;
if (airGroup2 != null && airGroup2.GetItems() != null && airGroup2.GetItems().Length > 0)
{
foreach (AiActor actor2 in airGroup2.GetItems())
{
if (actor2 != null && actor2 is AiAircraft)
{
if (!airGroupInfoDict.ContainsKey(airGroup2)) airGroupInfoDict[airGroup2] = new AirGroupInfo(actor2, airGroup2, this, Time.current());
/*
AirGroupInfo tmp1 = new AirGroupInfo();
if (!airGroupInfoDict.TryGetValue(airGroup2, out tmp1))
{
Console.WriteLine("groupAllAircraft: 1.7b");
tmp1 = new AirGroupInfo(actor, airGroup2, this, 32);
}
*/
airGroupInfoDict[airGroup2].checkIfNearbyAndAdd(airGroupInfoDict[airGroup]);
}
}
}
}
}
}
}
}
}
catch (Exception ex)
{ Console.WriteLine("GroupAirgroups foreach #4 ERROR: {0}", ex); }
HashSet DoneAGnearby = new HashSet();
try
{
foreach (AiAirGroup airGroup in CurrentAG[army])
{
if (DoneAGnearby.Contains(airGroup))
{
continue;
}
bool complete = false;
int i = 0;
while (!complete && i < 40)
complete = true;
i++;
HashSet nb = new HashSet(airGroupInfoDict[airGroup].nearbyAirGroups);
if (nb != null) foreach (AiAirGroup ag in nb)
{
if (DoneAGnearby.Contains(ag)) continue;
if (airGroupInfoDict.ContainsKey(ag))
{
complete = false;
airGroupInfoDict[ag].leader = airGroup;
airGroupInfoDict[ag].isLeader = false;
}
DoneAGnearby.Add(ag);
}
}
}
}
catch (Exception ex)
{ Console.WriteLine("GroupAirgroups foreach #3 ERROR: {0}", ex); }
*/
Dictionary[] aGICA;
try
{
lock (airGroupInfoCircArr)
{
}
}
catch (Exception ex)
{ Console.WriteLine("GroupAirgroups aGICA ERROR!!!!!!!!!!!!!!! {0}", ex); return; }
CurrentAGGroupLeaders[army] = new HashSet();
HashSet DoneAGgrouped = new HashSet();
try
{
foreach (AiAirGroup airGroup in CurrentAG[army])
{
if (DoneAGgrouped.Contains(airGroup))
{
continue;
}
bool complete = false;
int i = 0;
HashSet nb = airGroupInfoDict[airGroup].nearbyAirGroups;
HashSet grouped = new HashSet(nb);
if (aGICA.Length < maxStack) maxStack = aGICA.Length;
for (i = 0; i < maxStack; i++)
{
HashSet nba = new HashSet();
if (aGICA[i] != null && aGICA[i].ContainsKey(airGroup))
{
nba = new HashSet(aGICA[i][airGroup].nearbyAirGroups);
double time = aGICA[i][airGroup].time;
}
}
/*
HashSet nba = new HashSet();
if (a1 != null && a1.ContainsKey(airGroup))
{
nba = new HashSet(a1[airGroup].nearbyAirGroups);
double time = a1[airGroup].time;
Console.WriteLine("Grouping: Leader {0} step2: {1} groups of {2} ({3}) possible at {4:N0} ", airGroupInfoDict[airGroup].playerNames, grouped.Count, nba.Count, a1[airGroup].nearbyAirGroups.Count, time);
}
HashSet nbb = new HashSet();
if (a2 != null && a2.ContainsKey(airGroup))
{
nbb = new HashSet(a1[airGroup].nearbyAirGroups);
double time = a2[airGroup].time;
Console.WriteLine("Grouping: Leader {0} step3: {1} groups of {2} ({3}) possible at {4:N0} ", airGroupInfoDict[airGroup].playerNames, grouped.Count, nbb.Count, a2[airGroup].nearbyAirGroups.Count, time);
}
*/
/*
HashSet nbb = new HashSet();
if (a2 != null && a2.ContainsKey(airGroup))
{
nbb = a2[airGroup].nearbyAirGroups;
Console.WriteLine("Grouping: Leader {0} step3: {1} groups of {2} possible ", airGroupInfoDict[airGroup].playerNames, airGroupInfoDict[airGroup].groupedAirGroups.Count, nbb.Count);
}
*/
HashSet toremovefrom_gag = new HashSet();
if (grouped != null) foreach (AiAirGroup ag in grouped)
{
if (airGroupInfoDict.ContainsKey(ag))
{
if (DoneAGgrouped.Contains(ag))
{
{
toremovefrom_gag.Add(ag);
}
continue;
}
complete = false;
if (ag != airGroup)
{
airGroupInfoDict[ag].leader = airGroup;
airGroupInfoDict[ag].isLeader = false;
}
}
DoneAGgrouped.Add(ag);
}
else
{
Console.WriteLine("groupAllAircraft ERROR: No AirGroup in the grouping - this should never happen!");
}
foreach (AiAirGroup ai2 in toremovefrom_gag) grouped.Remove(ai2);
}
}
catch (Exception ex)
{ Console.WriteLine("GroupAirgroups foreach #2 ERROR: {0}", ex); }
try {
if (CurrentAGGroupLeaders[army] != null) foreach (AiAirGroup airGroup in CurrentAGGroupLeaders[army])
{
AirGroupInfo agid = airGroupInfoDict[airGroup];
int c = 0;
int cAboveRadar = 0;
int cBelowRadar = 0;
double aveAltAGL_ft = 0;
aiorhuman ah = aiorhuman.Human;
if (agid.isAI) ah = aiorhuman.AI;
double minAlt = agid.pos.z;
double maxAlt = agid.pos.z;
double aveAlt = 0;
Point3d avePos = new Point3d(0, 0, 0);
Point3d vwld = new Point3d(0, 0, 0);
string typeName = "";
string playerNames = "";
bool first = true;
string ids = "";
if (airGroupInfoDict[airGroup].groupedAirGroups != null) foreach (AiAirGroup ag in airGroupInfoDict[airGroup].groupedAirGroups)
{
if (!airGroupInfoDict.ContainsKey(ag)) continue;
AirGroupInfo agid2 = airGroupInfoDict[ag];
c += airGroupInfoDict[ag].count;
if (agid2.belowRadar) cBelowRadar += airGroupInfoDict[ag].count;
else cAboveRadar += airGroupInfoDict[ag].count;
if (agid2.pos.z > maxAlt) maxAlt = agid2.pos.z;
if (agid2.pos.z < minAlt) minAlt = agid2.pos.z;
aveAlt += agid2.pos.z * agid2.count;
aveAltAGL_ft += agid2.altAGL_ft * agid2.count;
if (!first)
{
playerNames += " - ";
typeName += " - ";
ids += " - ";
}
else first = false;
playerNames += agid.playerNames;
typeName += Calcs.GetAircraftType(agid2.actor as AiAircraft);
ids += agid2.actor.Name();
if (!agid2.isAI && (agid2.actor as AiAircraft).Player(0) != null) playerNames += (agid2.actor as AiAircraft).Player(0).Name() + " - ";
if (airGroupInfoDict[ag].isAI)
{
if (ah == aiorhuman.Human) ah = aiorhuman.Mixed;
}
else if (ah == aiorhuman.AI) ah = aiorhuman.Mixed;
}
agid.AGGcount = c;
agid.AGGisHeavyBomber = agid.isHeavyBomber;
agid.AGGpos = agid.pos;
agid.AGGtype = agid.type;
agid.AGGminAlt_m = minAlt;
agid.AGGmaxAlt_m = maxAlt;
agid.AGGaveAlt_m = aveAlt / (double)c;
agid.AGGavealtAGL_ft = aveAltAGL_ft / (double)c;
agid.AGGcountBelowRadar = cBelowRadar;
agid.AGGcountAboveRadar = cAboveRadar;
agid.AGGtypeNames = typeName;
agid.AGGplayerNames = playerNames;
agid.AGGids = ids;
agid.AGGAIorHuman = ah;
agid.AGGmixupType = agid.AGGtype;
if (random.Next(21) == 1)
agid.AGGmixupType = "U";
}
if (aGICA[0] != null && aGICA[0].ContainsKey(airGroup))
{
AiAirGroup oldLeader = aGICA[0][airGroup].leader;
if (aGICA[0].ContainsKey(oldLeader)) {
if (agid.AGGtype != aGICA[0][oldLeader].AGGmixupType && random.Next(4) < 3)
{
agid.AGGmixupType = aGICA[0][oldLeader].AGGmixupType;
}
}
}
/*
int aGICAindex = 4;
bool useAGICA = false;
for (int i = 0; i <= aGICAindex; i++)
{
if (aGICA[i] != null && aGICA[i].ContainsKey(airGroup) && aGICA[i][airGroup].leader == airGroup) useAGICA = true;
else
{
useAGICA = false;
break;
}
}
a1[airGroup].leader == airGroup && a2[airGroup].leader == airGroup && a3[airGroup].leader == airGroup)
if (useAGICA)
{
Point3d p2 = agid.pos;
double timeDiff = Time.current() - aGICA[aGICAindex][airGroup].time;
Point3d vel2 = new Point3d ((p2.x-p1.x)/timeDiff, (p2.y - p1.y) / timeDiff, 0 );
agid.AGGvel = vel2;
}
*/
agid.AGGradarDropout = false;
int dropoutValue = 14;
if (agid.AGGcount > 5) dropoutValue = Convert.ToInt32(11 * agid.AGGcount * agid.AGGcount / 25);
if (random.Next(dropoutValue) == 1)
{
agid.AGGradarDropout = true;
}
{
agid.AGGradarDropout = true;
}
{
agid.AGGradarDropout = true;
}
airGroupInfoDict[airGroup] = agid;
}
}
catch (Exception ex)
{ Console.WriteLine("GroupAirgroups foreach #1 ERROR: {0}", ex); }
}
AiAirGroup[] empty = Array.Empty();
Console.WriteLine("groupAllAircraft: Number of aircraft NOfAc: red:{0} blue:{1} total:{2}", numRedAircraft, numBlueAircraft, numTotalAircraft);
Console.WriteLine("groupAllAircraft: Number of aircraft .length: red:{0} blue:{1} total:{2}", numRedAircraft_length, numBlueAircraft_length, numTotalAircraft_length);
Console.WriteLine("groupAllAircraft: Number of airgroups: red:{0} blue:{1} total:{2}", (GamePlay.gpAirGroups(1) ?? empty).Length, (GamePlay.gpAirGroups(2) ?? empty).Length, (GamePlay.gpAirGroups(1) ?? empty).Length + (GamePlay.gpAirGroups(2) ?? empty).Length);
}
lock (airGroupInfoCircArr) {
}
} catch (Exception ex) { Console.WriteLine("GroupAirgroups ERROR: {0}", ex); }
}
//Console.WriteLine("Giant: " + GiantSectorOverview.ToString());
{
try
{
double delay = 8;
Player[] to = null;
if (player != null) to = new Player[] { player };
string newline = Environment.NewLine;
if (html) newline = "
" + Environment.NewLine;
string retmsg = "";
if (display) Timeout(0.4, () => twcLogServer(to, "Requesting Map Overview summary from headquarters, please stand by . . . ", null));
string msg = "***Schematic Map Overview of Enemy Activity***";
retmsg += msg + newline;
string msg2 = "Airgroups:Aircraft in each Large Map Keypad Area";
retmsg += msg2 + newline;
string msg3 = "For more details, ask your Commander or Radar Operator to consult the Contact Plotting Table - or simply patrol the area, use Tab-4-1";
retmsg += msg3 + newline;
/*for (int i = 1; i < 10; i++)
{
string tild = "~";
if (GiantSectorOverview[player.Army()][i, 1] == 0) tild = "";
twcLogServer(new Player[] { player }, "Sector {0}: {1} enemy airgroups, {2}{3} aircraft",new object [] { i, GiantSectorOverview[player.Army()][i, 0], tild, GiantSectorOverview[player.Army()][i, 1] });
}*/
Timeout(delay, () =>
{
if (display)
{
twcLogServer(to, msg, null);
twcLogServer(to, msg2, null);
twcLogServer(to, msg3, null);
}
});
var msgList = new List();
for (int i = 2; i > -1; i--)
{
string msg4 = string.Format("{0:D3}:{1:D3} {2:D3}:{3:D3} {4:D3}:{5:D3} ",
GiantSectorOverview[army][i * 3 + 1, 0], GiantSectorOverview[army][i * 3 + 1, 1],
GiantSectorOverview[army][i * 3 + 2, 0], GiantSectorOverview[army][i * 3 + 2, 1],
GiantSectorOverview[army][i * 3 + 3, 0], GiantSectorOverview[army][i * 3 + 3, 1]
);
retmsg += msg4 + newline;
msgList.Add(msg4);
}
if (display) Timeout(delay, () => { foreach (string m in msgList) { twcLogServer(to, m, null); } });
return retmsg;
}
catch (Exception ex)
{ Console.WriteLine("showGiantSectorOverview ERROR: {0}", ex); return ""; }
}
/************************************************
* Get radar returns for each AI aircraft group
* Can be used to, ie, reprogram the flight plans for aiairgroups so they intercept any
* enemies in their area
* Recursive function called every X seconds
************************************************/
//Console.WriteLine("groupAllAircraft: -1"); if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MRXX3 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //aiAirGroupRadarReturns(); //Called via Task.Run so don't need to do it in the method here.
{
Timeout(127, () => { aiAirGroupRadarReturns_recurs(); });
aiAirGroupRadarReturns();
}
//NEW here to make a separate copy of this & not touch the existing airGroupInfoCircArr.Get(0); //so lock airGroupInfoCircArrf PLUS making a copy of airGroupInfoCircArr.Get(0) rather than just directly referencing it, SHOULD (?!?) make this thread safe? airGroupInfoDict = new Dictionary
{
Dictionary airGroupInfoDict;
lock (airGroupInfoCircArr) {
}
if (airGroupInfoDict != null) foreach (AiAirGroup airGroup in airGroupInfoDict.Keys)
{
AirGroupInfo agi = airGroupInfoDict[airGroup];
listPositionAllAircraft(player: null, playerArmy: airGroup.getArmy(), inOwnArmy: false, radar_realism: RADAR_REALISM, aiairgroup: airGroup);
}
}
public class AiAirGroupRadarInfo : IAiAirGroupRadarInfo
{
public AMission mission { get; set; }
public AiAirGroupRadarInfo(Mission msn, IAirGroupInfo AGI, IAirGroupInfo PAGI, Point3d InterceptPoint, bool ClimbPossible, double tm = 0)
{
mission = msn;
if (tm != 0) time = tm;
else time = mission.Time.current();
interceptPoint = InterceptPoint;
climbPossible = ClimbPossible;
agi = AGI;
pagi = PAGI;
}
}
No description available.
{
if (player == null || player.Place() == null || player.Army() == null || !MO_isRadarEnabledByArea_TOBRUK(player.Place().Pos(), radarArmy: player.Army())) return true;
if (belowRadar(player)) return true;
return false;
}
//So mostly flying "below radar" is quite safe and undetected. But in some cases there will be a detection, either because radar got a return somehow, or (far //more likely) the aircraft was spotted by an observer or some other way...
{
try {
bool onEnemyGround = false;
bool nearMissionObjective = false;
bool isAI = false;
int aircraftArmy = (aircraft as AiActor).Army();
int enemyArmy = 3 - aircraftArmy;
if (aircraft != null && (aircraft as AiActor != null))
{
bool onEnemyTerritory = false;
int terr = GamePlay.gpFrontArmy(aircraft.Pos().x, aircraft.Pos().y);
if ((terr == 1 || terr == 2) && (aircraft as AiActor).Army() != terr) onEnemyTerritory = true;
maddox.game.LandTypes landType = GamePlay.gpLandType(aircraft.Pos().x, aircraft.Pos().y);
if (onEnemyTerritory && landType != maddox.game.LandTypes.WATER) onEnemyGround = true;
int numMissionObjectivesNear = 0;
if (onEnemyGround && MO_MissionObjectivesNear(aircraft.Pos(), dist_m: 8000) > 1) nearMissionObjective = true;
isAI = isAiControlledPlane2(aircraft);
}
double below250LeakageRate = 0.35;
if (onEnemyGround)
{
below250LeakageRate = 0.45;
double systemStrength = MO_AllMilitaryStrength_averaged((ArmiesE)enemyArmy);
if (systemStrength < 0.9)
{
below250LeakageRate = 0.45 * systemStrength / 0.9;
}
}
if (nearMissionObjective)
{
below250LeakageRate = 0.90;
}
if (random.NextDouble() < (1 - leakageRate) || (altAGL_ft < 250 && random.NextDouble() < (1 - below250LeakageRate))) return below;
}
catch (Exception ex) { Console.WriteLine("ERROR belowRadar()! " + ex.ToString()); return false; }
}
private void fixRadarMessagesStore(string playername_index, SortedDictionary radar_messages, int wait_s, long currtime_ms)
{
Timeout(wait_s + 5, () =>
{
if (radar_messages_store.ContainsKey(playername_index) && radar_messages_store[playername_index].Item1 == -1)
radar_messages_store[playername_index] = new Tuple>(currtime_ms, radar_messages);
});
}
public System.IO.StreamWriter sw;
// int radar_realism; //realism = 0 gives exact position, bearing, velocity of each a/c. We plan to make various degrees of realism ranging from 0 to 10...
{
try
{
if (radar_realism == -10000000) radar_realism = RADAR_REALISM;
DateTime d = DateTime.UtcNow;
if (player != null && objectiverepairmission != null && objectiverepairmission.orm_isPlayerOnRepairMission(player) && Convert.ToInt32((double)Math.Round((double)d.Minute)) % 10 != 9)
{
string rdr = "Chain Home";
if (player.Army() == 2) rdr = "radar";
twcLogServer(new Player[] { player }, ">>>Sorry, " + rdr + " operators are busy helping combat pilots and cannot help ferry & repair delivery pilots.");
return;
}
Dictionary airGroupInfoDict;
lock (airGroupInfoCircArr)
{
}
bool display = true;
string posmessage = "";
int poscount = 0;
int totalcount = 0;
int belowradarcount = 0;
AiAircraft p = null;
AiActor pa = null;
AirGroupInfo padig = null;
Point3d pos1;
Point3d pos2;
Point3d VwldP, intcpt, longlat;
Point3d ppos = new Point3d(0, 0, 0);
Vector3d Vwld, player_Vwld;
double player_vel_mps = 0;
double player_vel_mph = 0;
double player_alt_m = 0;
string type, player_sector;
string playertype = "";
bool player_place_set = false;
bool isHeavyBomber = false;
double vel_mps = 0;
double vel_mph = 0;
int vel_mph_10 = 0;
double heading = 0;
int heading_10 = 0;
double dis_m = 0;
double dis_mi = 0;
int dis_10 = 0;
double bearing = 0;
int bearing_10 = 0;
double alt_ft = 0;
double alt_km = 0;
double altAGL_m = 0;
double altAGL_ft = 0;
int alt_angels = 0;
string sector = "";
double intcpt_heading = 0;
double intcpt_time_min = 0;
string intcpt_sector = "";
bool intcpt_reasonable_time = false;
bool climb_possible = true;
int aigroup_count = 0;
string playername = "TWC_server_159273";
string playername_index;
bool playerOffRadar = true;
string enorfriend;
long currtime_ms = 0;
long storedtime_ms = -1;
bool savenewmessages = true;
Tuple> message_data;
SortedDictionary radar_messages =
SortedDictionary ai_radar_info =
int wait_s = 0;
long refreshtime_ms = 0;
if (radar_realism >= 1) { wait_s = 1; refreshtime_ms = 60 * 1000; }
if (radar_realism >= 5) { wait_s = 10; refreshtime_ms = 2 * 60 * 1000; }
if (radar_realism >= 9) { wait_s = 30; refreshtime_ms = 5 * 60 * 1000; }
bool admin = false;
if ((radar_realism == 0) || (radar_realism == -1 && playerArmy == -3) || (radar_realism == -1 && playerArmy == -4)) admin = true;
int radarArmy = Math.Abs(playerArmy);
if (radarArmy > 2) radarArmy = 0;
enorfriend = "ENEMY";
if (inOwnArmy) enorfriend = "FRIENDLY";
if (playerArmy < 0) enorfriend = "BOTH ARMIES";
try
{
if (player != null && player.Place() != null && (player.Place() is AiAircraft))
p = player.Place() as AiAircraft;
pa = player.Place();
if (airGroupInfoDict != null && p.AirGroup() != null && airGroupInfoDict.ContainsKey(p.AirGroup()))
{
padig = airGroupInfoDict[p.AirGroup()];
player_Vwld = new Vector3d(padig.vel.x, padig.vel.y, padig.vel.z);
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
if (Double.IsInfinity(player_vel_mps) || Double.IsNaN(player_vel_mps)) player_vel_mps = 0;
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = padig.pos.z;
player_sector = Calcs.correctedSectorName(this, padig.pos);
player_place_set = true;
playername = player.Name();
playertype = padig.type;
ppos = padig.pos;
}
else
{
player_Vwld = p.AirGroup().Vwld();
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
if (Double.IsInfinity(player_vel_mps) || Double.IsNaN(player_vel_mps)) player_vel_mps = 0;
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = p.Pos().z;
player_sector = Calcs.correctedSectorName(this, p.Pos());
player_place_set = true;
playername = player.Name();
playertype = p.Type().ToString().ToUpper();
if (playertype.Contains("FIGHTER") || playertype.Contains("JABO") || playertype.Contains("SCOUT")) playertype = "F";
else if (playertype.Contains("BOMBER") || playertype.Contains("AMPHIB") || playertype.Contains("BLENHEIM")) playertype = "B";
ppos = p.Pos();
}
string posmessageCSP;
string speedMsg = player_vel_mph.ToString("F0") + "mph ";
if (playerArmy == 2 || playerArmy == -2) speedMsg = (player_vel_mps * 3.6).ToString("F0") + "km/h ";
playerOffRadar = offRadar(player);
posmessageCSP = "Radar intercepts are based on your speed/position as last detected at the command center: ";
if (playerOffRadar) posmessageCSP += "Unknown!";
else posmessageCSP += speedMsg + player_sector.ToString();
gpLogServerAndLog(new Player[] { player }, posmessageCSP, null);
}
{
if (airGroupInfoDict != null && airGroupInfoDict.ContainsKey(aiairgroup))
{
padig = airGroupInfoDict[aiairgroup];
if (aiairgroup != null && aiairgroup.GetItems().Length > 0) pa = aiairgroup.GetItems()[0];
else { Console.WriteLine("AIAGRRR: No a/c in this airgroup, returning"); return; }
p = pa as AiAircraft;
player_Vwld = new Vector3d(padig.vel.x, padig.vel.y, padig.vel.z);
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
if (Double.IsInfinity(player_vel_mps) || Double.IsNaN(player_vel_mps)) player_vel_mps = 0;
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = padig.pos.z;
player_sector = Calcs.correctedSectorName(this, padig.pos);
player_place_set = true;
playertype = padig.type;
ppos = padig.pos;
}
else
{
}
}
}
catch (Exception ex)
{
Console.WriteLine("Radar ERROR5: " + ex.ToString());
}
playername_index = playername + "_0";
if (inOwnArmy) playername_index = playername + "_1";
playername_index = playername_index + "_" + radar_realism.ToString();
if (radar_realism < 0) playername_index = playername_index + "_" + playerArmy.ToString();
currtime_ms = stopwatch.ElapsedMilliseconds;
try
{
if (radar_realism > 0 && radar_messages_store != null && radar_messages_store.ContainsKey(playername_index) && display && player != null)
{
message_data = radar_messages_store[playername_index];
long time_elapsed_ms = currtime_ms - message_data.Item1;
long time_until_new_s = (long)((refreshtime_ms - time_elapsed_ms) / 1000);
long time_elapsed_s = (long)time_elapsed_ms / 1000;
radar_messages = message_data.Item2;
if (time_elapsed_ms < refreshtime_ms || message_data.Item1 == -1)
{
string posmessageIP;
if (message_data.Item1 == -1) posmessageIP = "New radar returns are in process. Your previous radar return:";
else posmessageIP = time_until_new_s.ToString("F0") + "s until " + playername + " can receive a new radar return. Your previous radar return:";
gpLogServerAndLog(new Player[] { player }, posmessageIP, null);
Console.WriteLine("RAD: Giving old message to " + playername_index);
wait_s = 0;
storedtime_ms = message_data.Item1;
Timeout(2, () =>
{
double delay = 0;
foreach (var mess in message_data.Item2)
{
delay += 0.1;
Timeout(delay, () =>
{
if (radar_realism == 0) gpLogServerAndLog(new Player[] { player }, mess.Value + " : " + mess.Key, null);
else gpLogServerAndLog(new Player[] { player }, mess.Value, null);
});
}
});
}
}
}
catch (Exception ex)
{
Console.WriteLine("Radar ERROR4: " + ex.ToString());
}
if (!savenewmessages) return;
{
radar_messages_store[playername_index] = new Tuple>(-1, radar_messages);
if (radar_realism > 0 && display) twcLogServer(new Player[] { player }, "Fetching radar contacts, please stand by . . . ", null);
radar_messages.Add("9999999999", " >>> " + enorfriend + " RADAR CONTACTS <<< ");
if (radar_realism < 0)
{
if (!radarpasswords.ContainsKey(playerArmy))
{
Console.WriteLine("RADAR ERROR: PlayerArmy {0} not in password list, this should never happen. Exiting.", playerArmy);
return;
}
}
var arms = new List() { 1, 2 };
foreach (int army in arms)
{
{
var airGroups = GamePlay.gpAirGroups(army);
if (airGroups != null && airGroups.Length > 0 && (!inOwnArmy ^ (army == playerArmy)))
{
foreach (AiAirGroup airGroup in airGroups)
{
posmessage = "";
aigroup_count++;
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
{
poscount = airGroup.NOfAirc;
foreach (AiActor actor in airGroup.GetItems())
{
if (actor is AiAircraft)
{
AiAircraft a = actor as AiAircraft;
if (!player_place_set)
p = actor as AiAircraft;
player_Vwld = p.AirGroup().Vwld();
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
if (Double.IsInfinity(player_vel_mps) || Double.IsNaN(player_vel_mps)) player_vel_mps = 0;
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = p.Pos().z;
/* player_sector = GamePlay.gpSectorName(p.Pos().x, p.Pos().y).ToString();
player_sector = Calcs.correctedSectorName(this, p.Pos());
ppos = p.Pos();
player_place_set = true;
}
bool isAI = isAiControlledPlane2(a);
string acType = Calcs.GetAircraftType(a);
isHeavyBomber = Calcs.isHeavyBomber(acType);
type = a.Type().ToString().ToUpper();
if (type.Contains("FIGHTER") || type.Contains("JABO") || type.Contains("SCOUT")) type = "F";
else if (type.Contains("BOMBER") || type.Contains("AMPHIB") || type.Contains("BLENHEIM")) type = "B";
else
{
if (type.Length == 0) type = "?";
}
if (a == p && radar_realism >= 0) type = "Your position";
/* if (DEBUG) twcLogServer(new Player[] { player }, "DEBUG: Destroying: Airgroup: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID(), new object[] { });
*/
pos1 = a.Pos();
Vwld = airGroup.Vwld();
vel_mps = Calcs.CalculatePointDistance(Vwld);
if (Double.IsInfinity(vel_mps) || Double.IsNaN(player_vel_mps)) vel_mps = 0;
vel_mph = Calcs.meterspsec2milesphour(vel_mps);
vel_mph_10 = Calcs.RoundInterval(vel_mph, 10);
heading = (Calcs.CalculateBearingDegree(Vwld));
heading_10 = Calcs.GetDegreesIn10Step(heading);
dis_m = Calcs.CalculatePointDistance(a.Pos(), p.Pos());
if (Double.IsInfinity(dis_m) || Double.IsNaN(dis_m)) dis_m = 1000000000;
dis_mi = Calcs.meters2miles(dis_m);
dis_10 = (int)dis_mi;
if (dis_mi > 20) dis_10 = Calcs.RoundInterval(dis_mi, 10);
bearing = Calcs.CalculateGradientAngle(p.Pos(), a.Pos());
bearing_10 = Calcs.GetDegreesIn10Step(bearing);
longlat = Calcs.Il2Point3dToLongLat(a.Pos());
alt_km = a.Pos().z / 1000;
alt_ft = Calcs.meters2feet(a.Pos().z);
altAGL_ft = Calcs.meters2feet(altAGL_m);
alt_angels = Calcs.Feet2Angels(alt_ft);
sector = GamePlay.gpSectorName(a.Pos().x, a.Pos().y).ToString();
VwldP = new Point3d(Vwld.x, Vwld.y, Vwld.z);
intcpt = Calcs.calculateInterceptionPoint(a.Pos(), VwldP, p.Pos(), player_vel_mps);
intcpt_heading = (Calcs.CalculateGradientAngle(p.Pos(), intcpt));
intcpt_time_min = intcpt.z / 60;
/* intcpt_sector = GamePlay.gpSectorName(intcpt.x, intcpt.y).ToString();
intcpt_sector = Calcs.correctedSectorName(this, intcpt);
intcpt_reasonable_time = (intcpt_time_min >= 0.02 && intcpt_time_min < 20);
climb_possible = true;
if (player_alt_m <= a.Pos().z && intcpt_time_min > 1)
{
double altdiff_m = a.Pos().z - player_alt_m;
}
string mi = dis_mi.ToString("F0") + "mi";
string mi_10 = dis_10.ToString("F0") + "mi";
string ft = alt_ft.ToString("F0") + "ft ";
string ftAGL = altAGL_ft.ToString("F0") + "ftAGL ";
string mph = vel_mph.ToString("F0") + "mph";
string ang = "A" + alt_angels.ToString("F0") + " ";
{
mi = (dis_m / 1000).ToString("F0") + "k";
mi_10 = mi;
if (dis_m > 30000) mi_10 = ((double)(Calcs.RoundInterval(dis_m, 10000)) / 1000).ToString("F0") + "k";
ft = alt_km.ToString("F2") + "k ";
ftAGL = altAGL_m.ToString("F0") + "mAGL ";
mph = (Calcs.RoundInterval(vel_mps * 3.6, 10)).ToString("F0") + "k/h";
ang = ((double)(Calcs.RoundInterval(alt_km * 10, 5)) / 10).ToString("F1") + "k ";
}
if (radar_realism < 0)
{
string numContacts = poscount.ToString();
string aircraftType = Calcs.GetAircraftType(a);
string vel = vel_mph.ToString("n0");
string alt = alt_angels.ToString("n0");
string he = heading.ToString("F0");
bool first = true;
string aplayername = "";
HashSet namesHS = new HashSet();
for (int i = 0; i < a.Places(); i++)
{
if (a.Player(i) != null && a.Player(i).Name() != null && a.Player(i).Name() != null && !namesHS.Contains(a.Player(i).Name()))
{
if (!first) aplayername += " - ";
aplayername += a.Player(i).Name();
namesHS.Add(a.Player(i).Name());
first = false;
}
}
if (playerArmy == -1 || playerArmy == -2)
{
numContacts = "~" + Calcs.NoOfAircraft(poscount, airGroup).ToString("F0");
type = "F";
if (random.Next(3) == 1) type = "B";
if (random.Next(8) == 1) type = "U";
} */
aircraftType = "";
aplayername = "";
vel = vel_mph_10.ToString("n0");
alt = alt_angels.ToString("n0");
he = heading_10.ToString("F0");
}
posmessage =
a.Pos().x.ToString()
+ "," + a.Pos().y.ToString() + "," +
longlat.y.ToString()
+ "," + longlat.x.ToString() + "," +
army.ToString() + "," +
type + "," +
he + "," +
vel + "," +
alt + "," +
sector.ToString() + "," +
numContacts + "," +
if ((playerArmy == -1 || playerArmy == -2) && (
)
) { posmessage = ""; }
}
else if (radar_realism == 0)
{
posmessage = poscount.ToString() + type + " " +
mi +
bearing.ToString("F0") + "°" +
ft +
ftAGL +
mph +
heading.ToString("F0") + "° " +
sector.ToString() + " " +
Calcs.GetAircraftType(a);
if (intcpt_time_min > 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min " +
intcpt_sector + " " +
intcpt.x.ToString("F0") + " " + intcpt.y.ToString("F0");
}
/* "(" +
Calcs.meters2miles(a.Pos().x).ToString ("F0") + ", " +
Calcs.meters2miles(a.Pos().y).ToString ("F0") + ")";
*/
}
else if (radar_realism > 0)
{
int dropoutValue = 7;
if (poscount > 5) dropoutValue = Convert.ToInt32(7 * poscount ^ 2 / 25);
type = "F";
if (random.Next(3) == 1) type = "B";
}*/
if (dis_mi <= 2 && a != p && Math.Abs(player_alt_m - a.Pos().z) < 5000)
{
posmessage = type + " nearby";
}
/* wikipedia gives an idea of how rough early CH output & methods were: CH output was read with an oscilloscope. When a pulse was sent from the broadcast towers, a visible line travelled horizontally across the screen very rapidly. The output from the receiver was amplified and fed into the vertical axis of the scope, so a return from an aircraft would deflect the beam upward. This formed a spike on the display, and the distance from the left side – measured with a small scale on the bottom of the screen – would give target range. By rotating the receiver goniometer connected to the antennas, the operator could estimate the direction to the target (this was the reason for the cross shaped antennas), while the height of the vertical displacement indicated formation size. By comparing the strengths returned from the various antennas up the tower, altitude could be gauged with some accuracy.
* Upshot is, exact #, position, no of aircraft, type of aircraft, altitude etc were NOT that precisely known. Rather they were estimates/guesstimates based on strength of pulse of the radar return as viewed on an oscilliscope etc.
* ******************/
(dis_mi >= 25 && poscount < 4 && random.Next(12) > 1 && !intcpt_reasonable_time) ||
(dis_mi >= 15 && poscount <= 2 && random.Next(8) > 1 && !intcpt_reasonable_time) ||
) { posmessage = ""; }
else
{
posmessage = type + " " +
mi_10 +
bearing_10.ToString("F0") + "°" +
ang +
mph +
heading_10.ToString("F0") + "° ";
if (intcpt_time_min >= 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min ";
}
}
}
}
}
if (posmessage.Length > 0)
{
int intcpt_time_index = (int)intcpt_time_min;
if (intcpt_time_min <= 0 || intcpt_time_min > 99) intcpt_time_index = 99;
try
{
string addMess = posmessage;
if (radar_realism > 0) addMess = "~" + Calcs.NoOfAircraft(poscount, airGroup).ToString("F0") + posmessage;
radar_messages.Add(
addMess
);
}
catch (Exception e)
{
Console.WriteLine("RadError: " + e);
}
}
}
}
}
}
else
{
try
{
if (GamePlay.gpAirGroups(army) != null && GamePlay.gpAirGroups(army).Length > 0 && (!inOwnArmy ^ (army == playerArmy)))
{
if (airGroupInfoDict != null) foreach (AiAirGroup airGroup in airGroupInfoDict.Keys)
{
posmessage = "";
if (airGroup == null) continue;
AirGroupInfo agid = airGroupInfoDict[airGroup];
if (agid.actor.Army() != army) continue;
if (!agid.isLeader) continue;
aigroup_count++;
/*
AirGroupInfo agid = new AirGroupInfo();
if (airGroupInfoDict != null && airGroupInfoDict.ContainsKey(airGroup))
{
agid = airGroupInfoDict[airGroup];
}
*/
AiActor actor = agid.actor;
AiAircraft a = actor as AiAircraft;
totalcount = agid.AGGcount;
poscount = agid.AGGcountAboveRadar;
belowradarcount = agid.AGGcountBelowRadar;
if (!MO_isRadarEnabledByArea(agid.AGGavePos, admin, radarArmy)) continue;
if (!player_place_set)
p = actor as AiAircraft;
player_Vwld = p.AirGroup().Vwld();
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
if (Double.IsInfinity(player_vel_mps) || Double.IsNaN(player_vel_mps)) player_vel_mps = 0;
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = p.Pos().z;
/* player_sector = GamePlay.gpSectorName(p.Pos().x, p.Pos().y).ToString();
player_sector = Calcs.correctedSectorName(this, p.Pos());
ppos = p.Pos();
player_place_set = true;
}
bool isAI = (agid.AGGAIorHuman == aiorhuman.AI);
string acType = agid.AGGtypeNames;
isHeavyBomber = agid.AGGisHeavyBomber;
type = agid.AGGtype;
/* if (DEBUG) twcLogServer(new Player[] { player }, "DEBUG: Destroying: Airgroup: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID(), new object[] { });
*/
pos1 = agid.AGGavePos;
Vwld = new Vector3d(agid.AGGvel.x, agid.AGGvel.y, agid.AGGvel.z);
vel_mps = Calcs.CalculatePointDistance(Vwld);
if (Double.IsInfinity(vel_mps) || Double.IsNaN(vel_mps)) player_vel_mps = 0;
vel_mph = Calcs.meterspsec2milesphour(vel_mps);
vel_mph_10 = Calcs.RoundInterval(vel_mph, 10);
heading = (Calcs.CalculateBearingDegree(Vwld));
heading_10 = Calcs.GetDegreesIn10Step(heading);
dis_m = Calcs.CalculatePointDistance(agid.AGGavePos, p.Pos());
if (Double.IsInfinity(dis_m) || Double.IsNaN(dis_m)) dis_m = 1000000000;
dis_mi = Calcs.meters2miles(dis_m);
dis_10 = (int)dis_mi;
if (dis_mi > 20) dis_10 = Calcs.RoundInterval(dis_mi, 10);
bearing = Calcs.CalculateGradientAngle(p.Pos(), agid.AGGavePos);
bearing_10 = Calcs.GetDegreesIn10Step(bearing);
longlat = Calcs.Il2Point3dToLongLat(agid.AGGavePos);
alt_ft = Calcs.meters2feet(agid.AGGmaxAlt_m);
altAGL_ft = agid.AGGavealtAGL_ft;
altAGL_m = Calcs.feet2meters(altAGL_ft);
alt_angels = Calcs.Feet2Angels(alt_ft);
sector = GamePlay.gpSectorName(agid.AGGavePos.x, agid.AGGavePos.y).ToString();
VwldP = new Point3d(agid.AGGvel.x, agid.AGGvel.y, agid.AGGvel.z);
intcpt = Calcs.calculateInterceptionPoint(agid.AGGavePos, VwldP, ppos, player_vel_mps);
intcpt_heading = (Calcs.CalculateGradientAngle(ppos, intcpt));
intcpt_time_min = intcpt.z / 60;
/* intcpt_sector = GamePlay.gpSectorName(intcpt.x, intcpt.y).ToString();
intcpt_sector = Calcs.correctedSectorName(this, intcpt);
intcpt_reasonable_time = (intcpt_time_min >= 0.02 && intcpt_time_min < 25);
climb_possible = true;
if (player_alt_m <= agid.AGGminAlt_m && intcpt_time_min > 1)
{
double altdiff_m = agid.AGGminAlt_m - player_alt_m;
}
string mi = dis_mi.ToString("F0") + "mi";
string mi_10 = dis_10.ToString("F0") + "mi";
string ft = alt_ft.ToString("F0") + "ft ";
string ftAGL = altAGL_ft.ToString("F0") + "ftAGL ";
string mph = vel_mph.ToString("F0") + "mph";
string ang = "A" + alt_angels.ToString("F0") + " ";
{
mi = (dis_m / 1000).ToString("F0") + "k";
mi_10 = mi;
if (dis_m > 30000) mi_10 = ((double)(Calcs.RoundInterval(dis_m, 10000)) / 1000).ToString("F0") + "k";
ft = alt_km.ToString("F2") + "k ";
ftAGL = altAGL_m.ToString("F0") + "mAGL ";
mph = (Calcs.RoundInterval(vel_mps * 3.6, 10)).ToString("F0") + "k/h";
ang = ((double)(Calcs.RoundInterval(alt_km * 10, 5)) / 10).ToString("F1") + "k ";
}
{
string numContacts = poscount.ToString();
string aircraftType = agid.AGGtypeNames;
string vel = vel_mph.ToString("n0");
string alt = alt_angels.ToString("n0");
string he = heading.ToString("F0");
string aplayername = agid.AGGplayerNames;
if (playerArmy == -1 || playerArmy == -2)
{
numContacts = "~" + Calcs.NoOfAircraft(poscount, airGroup).ToString("F0");
aircraftType = "";
aplayername = "";
vel = vel_mph_10.ToString("n0");
alt = alt_angels.ToString("n0");
he = heading_10.ToString("F0");
/*
{
}
*/
}
posmessage =
agid.AGGavePos.x.ToString()
+ "," + agid.AGGavePos.y.ToString() + "," +
longlat.y.ToString()
+ "," + longlat.x.ToString() + "," +
army.ToString() + "," +
he + "," +
vel + "," +
alt + "," +
sector.ToString() + "," +
numContacts + "," +
try
{
if (playerArmy == -4)
{
}
}
catch (Exception ex) { Console.WriteLine("Radar ERROR: GiantSectorOverview (probably exceeded index): " + ex.ToString()); }
if ((playerArmy == -1 || playerArmy == -2) && (
agid.AGGradarDropout
|| (a.Player(0) != null && objectiverepairmission != null && random.NextDouble() > 0.08 && objectiverepairmission.orm_isPlayerOnRepairMission(a.Player(0)) && Math.Abs(playerArmy) == a.Player(0).Army())
|| (covermission != null && objectiverepairmission != null && random.NextDouble() > 0.08 && covermission.coverAircraftActorsCheckedOut.ContainsKey(a as AiActor) && objectiverepairmission.orm_isPlayerOnRepairMission(covermission.coverAircraftActorsCheckedOut[a as AiActor]) && Math.Abs(playerArmy) == a.Player(0).Army())
)
)
{
posmessage = "";
}
if ((playerArmy == -1 || playerArmy == -2) && posmessage.Length > 0)
{
if ((-playerArmy) != army)
{
}
else
{
}
}
}
else if (radar_realism == 1)
{
posmessage = poscount.ToString() + type + " " +
mi +
bearing.ToString("F0") + "°" +
ft +
ftAGL +
mph +
heading.ToString("F0") + "° " +
sector.ToString() + " " +
Calcs.GetAircraftType(a);
if (intcpt_time_min > 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min " +
intcpt_sector + " " +
intcpt.x.ToString("F0") + " " + intcpt.y.ToString("F0");
}
/* "(" +
Calcs.meters2miles(a.Pos().x).ToString ("F0") + ", " +
Calcs.meters2miles(a.Pos().y).ToString ("F0") + ")";
*/
}
else if (radar_realism > 0)
{
int dropoutValue = 7;
if (poscount > 5) { dropoutValue = Convert.ToInt32(7 * poscount ^ 2 / 25); }
if (dis_mi <= 2 && a != p && Math.Abs(player_alt_m - agid.AGGaveAlt_m) < 5000)
{
posmessage = agid.AGGmixupType + " nearby";
}
/* wikipedia gives an idea of how rough early CH output & methods were: CH output was read with an oscilloscope. When a pulse was sent from the broadcast towers, a visible line travelled horizontally across the screen very rapidly. The output from the receiver was amplified and fed into the vertical axis of the scope, so a return from an aircraft would deflect the beam upward. This formed a spike on the display, and the distance from the left side – measured with a small scale on the bottom of the screen – would give target range. By rotating the receiver goniometer connected to the antennas, the operator could estimate the direction to the target (this was the reason for the cross shaped antennas), while the height of the vertical displacement indicated formation size. By comparing the strengths returned from the various antennas up the tower, altitude could be gauged with some accuracy.
* Upshot is, exact #, position, no of aircraft, type of aircraft, altitude etc were NOT that precisely known. Rather they were estimates/guesstimates based on strength of pulse of the radar return as viewed on an oscilliscope etc.
* ******************/
(dis_mi >= 25 && poscount < 4 && random.Next(12) > 1 && !intcpt_reasonable_time) ||
(dis_mi >= 15 && poscount <= 2 && random.Next(8) > 1 && !intcpt_reasonable_time) ||
)
{
posmessage = "";
/*
posmessage = type + " " +
mi_10 +
bearing_10.ToString("F0") + "°" +
ang +
mph +
heading_10.ToString("F0") + "° " + sector.ToString();
if (intcpt_time_min >= 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min ";
}
*/
}
else
{
posmessage = agid.AGGmixupType + " " +
mi_10 +
bearing_10.ToString("F0") + "°" +
ang +
mph +
heading_10.ToString("F0") + "° ";
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min ";
}
}
}
if (posmessage.Length > 0)
{
int intcpt_time_index = (int)intcpt_time_min;
if (intcpt_time_min <= 0 || intcpt_time_min > 99) intcpt_time_index = 99;
try
{
string addMess = posmessage;
if (radar_realism > 0) addMess = "~" + Calcs.NoOfAircraft(poscount, airGroup).ToString("F0") + posmessage;
radar_messages.Add(
addMess
);
if (aiairgroup != null)
{
ai_radar_info.Add(
new AiAirGroupRadarInfo(this, agid, padig, intcpt, climb_possible)
);
}
}
catch (Exception e)
{
Console.WriteLine("RadErrorAdd: " + e);
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Radar ERROR2: " + ex.ToString());
}
}
}
/*
else
{
if (GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
if (GamePlay.gpAirGroups(army) != null && GamePlay.gpAirGroups(army).Length > 0 && (!inOwnArmy ^ (army == playerArmy)))
{
if (airGroupInfoDict != null) foreach (AiAirGroup airGroup in airGroupInfoDict.Keys)
{
Console.WriteLine("LPAA: Processing ag: {0} {1} ", airGroup.getArmy(), airGroup.NOfAirc);
AirGroupInfo agid = airGroupInfoDict[airGroup];
if (agid.actor.Army() != army) continue;
Console.WriteLine("LPAA: Processing ag: {0} {1} ", agid.actor.Army(), agid.actor.Name());
aigroup_count++;
AiActor actor = agid.actor;
AiAircraft a = actor as AiAircraft;
poscount = agid.AGGcount;
if (!MO_isRadarEnabledByArea(agid.AGGavePos, admin, radarArmy)) continue;
if (!player_place_set)
p = actor as AiAircraft;
player_Vwld = p.AirGroup().Vwld();
player_vel_mps = Calcs.CalculatePointDistance(player_Vwld);
player_vel_mph = Calcs.meterspsec2milesphour(player_vel_mps);
player_alt_m = p.Pos().z;
player_sector = Calcs.correctedSectorName(this, p.Pos());
ppos = p.Pos();
player_place_set = true;
}
bool isAI = (agid.AGGAIorHuman == aiorhuman.AI);
string acType = agid.AGGtypeNames;
isHeavyBomber = agid.AGGisHeavyBomber;
type = agid.AGGtype;
if (a == p && radar_realism >= 0) type = "Your position";
pos1 = agid.AGGavePos;
Vwld = new Vector3d(agid.AGGvel.x, agid.AGGvel.y, agid.AGGvel.z);
vel_mps = Calcs.CalculatePointDistance(Vwld);
vel_mph = Calcs.meterspsec2milesphour(vel_mps);
vel_mph_10 = Calcs.RoundInterval(vel_mph, 10);
heading = (Calcs.CalculateBearingDegree(Vwld));
heading_10 = Calcs.GetDegreesIn10Step(heading);
dis_m = Calcs.CalculatePointDistance(agid.AGGavePos, p.Pos());
dis_mi = Calcs.meters2miles(dis_m);
dis_10 = (int)dis_mi;
if (dis_mi > 20) dis_10 = Calcs.RoundInterval(dis_mi, 10);
bearing = Calcs.CalculateGradientAngle(p.Pos(), agid.AGGavePos);
bearing_10 = Calcs.GetDegreesIn10Step(bearing);
longlat = Calcs.Il2Point3dToLongLat(agid.AGGavePos);
alt_km = agid.AGGavePos.z / 1000;
alt_ft = Calcs.meters2feet(agid.AGGavePos.z);
altAGL_ft = Calcs.meters2feet(altAGL_m);
alt_angels = Calcs.Feet2Angels(alt_ft);
sector = GamePlay.gpSectorName(agid.AGGavePos.x, agid.AGGavePos.y).ToString();
VwldP = new Point3d(agid.AGGvel.x, agid.AGGvel.y, agid.AGGvel.z);
intcpt = Calcs.calculateInterceptionPoint(agid.AGGavePos, VwldP, p.Pos(), player_vel_mps);
intcpt_heading = (Calcs.CalculateGradientAngle(agid.AGGavePos, intcpt));
intcpt_time_min = intcpt.z / 60;
intcpt_sector = Calcs.correctedSectorName(this, intcpt);
intcpt_reasonable_time = (intcpt_time_min >= 0.02 && intcpt_time_min < 20);
climb_possible = true;
if (player_alt_m <= agid.AGGminAlt && intcpt_time_min > 1)
{
double altdiff_m = agid.AGGminAlt - player_alt_m;
}
string mi = dis_mi.ToString("F0") + "mi";
string mi_10 = dis_10.ToString("F0") + "mi";
string ft = alt_ft.ToString("F0") + "ft ";
string ftAGL = altAGL_ft.ToString("F0") + "ftAGL ";
string mph = vel_mph.ToString("F0") + "mph";
string ang = "A" + alt_angels.ToString("F0") + " ";
{
mi = (dis_m / 1000).ToString("F0") + "k";
mi_10 = mi;
if (dis_m > 30000) mi_10 = ((double)(Calcs.RoundInterval(dis_m, 10000)) / 1000).ToString("F0") + "k";
ft = alt_km.ToString("F2") + "k ";
ftAGL = altAGL_m.ToString("F0") + "mAGL ";
mph = (Calcs.RoundInterval(vel_mps * 3.6, 10)).ToString("F0") + "k/h";
ang = ((double)(Calcs.RoundInterval(alt_km * 10, 5)) / 10).ToString("F1") + "k ";
}
{
string numContacts = poscount.ToString();
string aircraftType = agid.AGGtypeNames;
string vel = vel_mph.ToString("n0");
string alt = alt_angels.ToString("n0");
string he = heading.ToString("F0");
string aplayername = agid.AGGplayerNames;
if (playerArmy == -1 || playerArmy == -2)
{
numContacts = "~" + Calcs.NoOfAircraft(poscount).ToString("F0");
if (random.Next(8) == 1)
type = "F";
if (random.Next(3) == 1) type = "B";
if (random.Next(8) == 1) type = "U";
}
aircraftType = "";
aplayername = "";
vel = vel_mph_10.ToString("n0");
alt = alt_angels.ToString("n0");
he = heading_10.ToString("F0");
}
posmessage =
agid.AGGavePos.x.ToString()
+ "," + agid.AGGavePos.y.ToString() + "," +
longlat.y.ToString()
+ "," + longlat.x.ToString() + "," +
army.ToString() + "," +
type + "," +
he + "," +
vel + "," +
alt + "," +
sector.ToString() + "," +
numContacts + "," +
if ((playerArmy == -1 || playerArmy == -2) && (
)
) { posmessage = ""; }
}
else if (radar_realism == 0)
{
posmessage = poscount.ToString() + type + " " +
mi +
bearing.ToString("F0") + "°" +
ft +
ftAGL +
mph +
heading.ToString("F0") + "° " +
sector.ToString() + " " +
Calcs.GetAircraftType(a);
if (intcpt_time_min > 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min " +
intcpt_sector + " " +
intcpt.x.ToString("F0") + " " + intcpt.y.ToString("F0");
}
}
else if (radar_realism > 0)
{
if (random.Next(8) == 1)
type = "F";
if (random.Next(3) == 1) type = "B";
}
if (dis_mi <= 2 && a != p && Math.Abs(player_alt_m - agid.AGGaveAlt) < 5000) { posmessage = type + " nearby"; }
(dis_mi >= 25 && poscount < 4 && random.Next(12) > 1 && !intcpt_reasonable_time) ||
(dis_mi >= 15 && poscount <= 2 && random.Next(8) > 1 && !intcpt_reasonable_time) ||
) { posmessage = ""; }
else
{
posmessage = type + " " +
mi_10 +
bearing_10.ToString("F0") + "°" +
ang +
mph +
heading_10.ToString("F0") + "° ";
if (intcpt_time_min >= 0.02)
{
posmessage +=
" Intcpt: " +
intcpt_heading.ToString("F0") + "°" +
intcpt_time_min.ToString("F0") + "min ";
}
}
}
}
}
twcLogServer(new Player[] { player }, "RPT: " + posmessage + posmessage.Length.ToString(), new object[] { });
if (posmessage.Length > 0)
{
gpLogServerAndLog(new Player[] { player }, "~" + Calcs.NoOfAircraft(poscount).ToString("F0") + "" + posmessage, null);
int intcpt_time_index = (int)intcpt_time_min;
if (intcpt_time_min <= 0 || intcpt_time_min > 99) intcpt_time_index = 99;
try
{
string addMess = posmessage;
if (radar_realism > 0) addMess = "~" + Calcs.NoOfAircraft(poscount).ToString("F0") + posmessage;
radar_messages.Add(
addMess
);
}
catch (Exception e)
{
twcLogServer(new Player[] { player }, "RadError: " + e, new object[] { });
}
}
}
}
}
*/
if (radar_messages != null && radar_messages.Count == 1) radar_messages.Add("0000000000", "");
if (radar_realism < 0)
{
try
{
string typeSuff = "";
if (playerArmy == -3) typeSuff = "_ADMIN";
if (playerArmy == -4) typeSuff = "_ADMINGROUP";
if (playerArmy == -1) typeSuff = "_RED";
if (playerArmy == -2) typeSuff = "_BLUE";
string filepath = STATSCS_FULL_PATH + SERVER_ID_SHORT.ToUpper() + typeSuff + "_radar.txt";
if (File.Exists(filepath)) { File.Delete(filepath); }
/*
try
{
foreach (var mess in radar_messages)
{
sw.WriteLine(mess.Value);
}
}
catch (Exception ex) { Console.WriteLine("Radar Write2: " + ex.ToString()); }
sw.Close();
sw.Dispose();
*/
string bigMess = "";
foreach (var mess in radar_messages) bigMess += mess.Value + Environment.NewLine;
Calcs.WriteAllTextAsync(filepath, bigMess);
filepath = STATSCS_FULL_PATH + SERVER_ID_SHORT.ToUpper() + typeSuff + "_players.txt";
if (File.Exists(filepath)) { File.Delete(filepath); }
/*
{
sw.WriteLine("[[" + DateTime.UtcNow.ToString("u").Trim() + "]] " + showTimeLeft(null, false).Item1);
sw.WriteLine();
int pycount = 0;
int pyinplace = 0;
string msg = "";
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player py in GamePlay.gpRemotePlayers())
{
pycount++;
string pl = "(none)";
if (py.Place() != null)
{
pyinplace++;
AiActor act = py.Place();
if (act as AiAircraft != null)
{
AiAircraft acf = act as AiAircraft;
string acType = Calcs.GetAircraftType(acf);
pl = acType;
}
if (playerArmy == -3 || playerArmy == -4)
{
}
}
msg += py.Name() + " " + py.Army() + " " + pl + "\n";
}
}
sw.WriteLine("Players logged in: " + pycount.ToString() + " Active: " + pyinplace.ToString());
sw.WriteLine();
sw.WriteLine(CAMPAIGN_ID.ToUpper() + " MISSION SUMMARY");
sw.WriteLine(string.Format("BLUE session totals: {0:0.0} total points; {1:0.0}/{2:0.0}/{3:0.0}/{4:0.0} Air/AA/Naval/Ground points", BlueTotalF,
BlueAirF, BlueAAF, BlueNavalF, BlueGroundF));
sw.WriteLine(string.Format("RED session totals: {0:0.0} total points; {1:0.0}/{2:0.0}/{3:0.0}/{4:0.0} Air/AA/Naval/Ground points", RedTotalF,
RedAirF, RedAAF, RedNavalF, RedGroundF));
sw.WriteLine();
sw.WriteLine("Blue Objectives complete (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Blue]));
sw.WriteLine();
sw.WriteLine("Red Objectives complete (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Red]));
sw.WriteLine();
/***TODO: Need to include some kind of current mission & campaign summary here
*
* /
sw.WriteLine(CAMPAIGN_ID.ToUpper() + " CAMPAIGN SUMMARY");
Tuple res = CalcMapMove("", false, false, null);
sw.Write(res.Item2);
double newMapState = CampaignMapState + res.Item1;
if (msg.Length > 0)
{
sw.WriteLine();
sw.WriteLine("PLAYER SUMMARY");
sw.WriteLine(msg);
}
{
msg += Environment.NewLine;
if (msg.Length > 0)
{
sw.WriteLine();
sw.WriteLine("RADAR AND AIRFIELD CONDITION SUMMARY");
sw.WriteLine(msg);
}
}
sw.WriteLine();
string netRed = statsmission.Display_SessionStatsAll(null, 1, false, false);
string netBlue = statsmission.Display_SessionStatsAll(null, 2, false, false);
sw.WriteLine("PLAYER ACTIVITY SUMMARY");
sw.WriteLine(netBlue);
sw.WriteLine(netRed);
if (TWCSupplyMission != null)
{
sw.WriteLine();
}
msg = "";
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4) msg += MO_ListScoutedObjectives(null, 2) + Environment.NewLine;
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4) msg += MO_ListScoutedObjectives(null, 1) + Environment.NewLine;
if (msg.Length > 0)
{
sw.WriteLine();
sw.WriteLine(CAMPAIGN_ID.ToUpper() + " RECONNAISSANCE SUMMARY");
sw.WriteLine(msg);
}
msg = "";
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4)
{
if (TWCSupplyMission != null) msg += (TWCSupplyMission.DisplayNumberOfAvailablePlanes(2, null, false)) + Environment.NewLine;
}
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4)
{
if (TWCSupplyMission != null) msg += (TWCSupplyMission.DisplayNumberOfAvailablePlanes(1, null, false)) + Environment.NewLine;
}
if (msg.Length > 0)
{
sw.WriteLine();
sw.WriteLine(CAMPAIGN_ID.ToUpper() + " CURRENT AIRCRAFT STOCK LEVELS");
sw.WriteLine(msg);
}
}
sw.Close();
sw.Dispose();
*/
{
bigMess = "";
bigMess += ("[[" + DateTime.UtcNow.ToString("u").Trim() + "]] " + showTimeLeft(null, false).Item1) + Environment.NewLine;
bigMess += Environment.NewLine;
int pycount = 0;
int pyinplace = 0;
string msg = "";
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
foreach (Player py in GamePlay.gpRemotePlayers())
{
pycount++;
string pl = "(none)";
if (py.Place() != null)
{
pyinplace++;
AiActor act = py.Place();
if (act as AiAircraft != null)
{
AiAircraft acf = act as AiAircraft;
string acType = Calcs.GetAircraftType(acf);
pl = acType;
}
if (playerArmy == -3 || playerArmy == -4)
{
}
}
msg += py.Name() + " " + py.Army() + " " + pl + "\n";
}
}
bigMess += ("Players logged in: " + pycount.ToString() + " Active: " + pyinplace.ToString()) + Environment.NewLine;
if (playerArmy == -3 || playerArmy == -4)
{
int numRedPlayers = Calcs.gpNumberOfPlayers(GamePlay, 1);
int numBluePlayers = Calcs.gpNumberOfPlayers(GamePlay, 2);
bigMess += string.Format("Number of aircraft red:{0} blue:{1} total:{2}", numRedAircraft, numBlueAircraft, numTotalAircraft);
AiAirGroup[] empty = Array.Empty();
bigMess += string.Format("Number of airgroups: red:{0} blue:{1} total:{2}", (GamePlay.gpAirGroups(1) ?? empty).Length, (GamePlay.gpAirGroups(2) ?? empty).Length, (GamePlay.gpAirGroups(1) ?? empty).Length + (GamePlay.gpAirGroups(2) ?? empty).Length);
bigMess += string.Format("Number of Players: red: {0} blue: {1} total: {2}", numRedPlayers, numBluePlayers, numRedPlayers + numBluePlayers);
}
bigMess += Environment.NewLine;
bigMess += (CAMPAIGN_ID.ToUpper() + " CAMPAIGN SUMMARY") + Environment.NewLine;
Tuple res = CalcMapMove("", false, false, null);
double newMapState = CampaignMapState + res.Item1;
bigMess += (res.Item2) + Environment.NewLine;
bigMess += (CAMPAIGN_ID.ToUpper() + " MISSION SUMMARY") + Environment.NewLine;
bigMess += (string.Format("BLUE session totals: {0:0.0} total points; {1:0.0}/{2:0.0}/{3:0.0}/{4:0.0} Air/AA/Naval/Ground points", BlueTotalF,
BlueAirF, BlueAAF, BlueNavalF, BlueGroundF)) + Environment.NewLine;
bigMess += (string.Format("RED session totals: {0:0.0} total points; {1:0.0}/{2:0.0}/{3:0.0}/{4:0.0} Air/AA/Naval/Ground points", RedTotalF,
RedAirF, RedAAF, RedNavalF, RedGroundF)) + Environment.NewLine;
bigMess += Environment.NewLine;
bigMess += MO_AllMilitaryStrength_ToString();
bigMess += Environment.NewLine;
try
{
for (int attackingArmy = 1; attackingArmy < 3; attackingArmy++)
{
Console.WriteLine("Army check radar {0} remain objectives: {1}", attackingArmy, MO_CountRemainingPrimaryObjectives(attackingArmy));
if (MO_CountRemainingPrimaryObjectives(attackingArmy) <= 5)
if (GeneralStaffLocations.ContainsKey((ArmiesE)attackingArmy) && GeneralStaffLocations[(ArmiesE)attackingArmy] != null)
{
leakTo[attackingArmy] = gsl.discovered;
}
}
} catch (Exception ex) { Console.WriteLine("Radar leakTo ERROR: " + ex.ToString()); }
bigMess += ("Blue Objectives complete (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Blue])) + Environment.NewLine;
bigMess += Environment.NewLine;
if (leakTo[1] && playerArmy == -1) bigMess += "(enemy objectives leaked via low-level photo recon of General & staff)" + Environment.NewLine + Environment.NewLine;
bigMess += ("Red Objectives complete (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):" + (MissionObjectivesCompletedString[ArmiesE.Red])) + Environment.NewLine;
bigMess += Environment.NewLine;
if (leakTo[2] && playerArmy == -2) bigMess += "(enemy objectives leaked via low-level photo recon of General & staff)" + Environment.NewLine + Environment.NewLine;
/***TODO: Need to include some kind of current mission & campaign summary here
*
*/
if (msg.Length > 0)
{
bigMess += Environment.NewLine;
bigMess += ("PLAYER SUMMARY") + Environment.NewLine;
bigMess += (msg) + Environment.NewLine;
}
{
for (int armyObj = 1; armyObj < 3; armyObj++)
{
bool forEnemy = true;
if (Math.Abs(playerArmy) == armyObj) forEnemy = false;
msg += Environment.NewLine;
msg += Environment.NewLine;
if (msg.Length > 0)
{
bigMess += Environment.NewLine;
bigMess += ((ArmiesE)armyObj).ToString().ToUpper() + ": RADAR - AIRFIELD - MILITARY ASSET CONDITION SUMMARY" + Environment.NewLine;
bigMess += (msg);
}
}
}
bigMess += Environment.NewLine;
string netRed = statsmission.Display_SessionStatsAll(null, 1, false, false);
string netBlue = statsmission.Display_SessionStatsAll(null, 2, false, false);
bigMess += ("PLAYER ACTIVITY SUMMARY") + Environment.NewLine;
bigMess += (netBlue) + Environment.NewLine;
bigMess += (netRed) + Environment.NewLine;
if (TWCSupplyMission != null)
{
bigMess += Environment.NewLine;
}
msg = "";
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4) msg += MO_ListScoutedObjectives(null, 2) + Environment.NewLine;
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4) msg += MO_ListScoutedObjectives(null, 1) + Environment.NewLine;
if (playerArmy == -2) msg += Environment.NewLine + MO_ListScoutedObjectives(null, 1, forEnemy: true) + Environment.NewLine;
if (playerArmy == -1) msg += Environment.NewLine + MO_ListScoutedObjectives(null, 2, forEnemy: true) + Environment.NewLine;
if (msg.Length > 0)
{
bigMess += Environment.NewLine;
bigMess += (CAMPAIGN_ID.ToUpper() + " RECONNAISSANCE SUMMARY") + Environment.NewLine;
bigMess += (msg) + Environment.NewLine;
}
msg = "";
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4)
{
if (TWCSupplyMission != null) msg += (TWCSupplyMission.DisplayNumberOfAvailablePlanes(2, null, false)) + Environment.NewLine;
}
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4)
{
if (TWCSupplyMission != null) msg += (TWCSupplyMission.DisplayNumberOfAvailablePlanes(1, null, false)) + Environment.NewLine;
}
if (msg.Length > 0)
{
bigMess += Environment.NewLine;
bigMess += (CAMPAIGN_ID.ToUpper() + " CURRENT AIRCRAFT STOCK LEVELS") + Environment.NewLine;
bigMess += (msg) + Environment.NewLine;
}
msg = "";
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4) msg += listWindLayers(null, 2, 1) + Environment.NewLine;
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4) msg += listWindLayers(null, 1, 1) + Environment.NewLine;
if (msg.Length > 0)
{
bigMess += Environment.NewLine;
bigMess += (CAMPAIGN_ID.ToUpper() + " WINDS ALOFT SUMMARY") + Environment.NewLine;
bigMess += (msg) + Environment.NewLine;
}
bigMess += (CAMPAIGN_ID.ToUpper() + " BOMBER SORTIES THIS MISSION") + Environment.NewLine;
if (playerArmy == -1 || playerArmy == -3 || playerArmy == -4 || leakTo[2]) {
string key = "bomber_messages_red";
if (Mission.DataDictionary.ContainsKey(key))
{
bigMess += Environment.NewLine;
bigMess += ((string)Mission.DataDictionary[key]) + Environment.NewLine;
}
}
if (leakTo[2] && playerArmy == -2) bigMess += "(enemy objectives leaked via low-level photo recon of General & staff)" + Environment.NewLine + Environment.NewLine;
if (playerArmy == -2 || playerArmy == -3 || playerArmy == -4 || leakTo[1])
{
string key = "bomber_messages_blue";
if (Mission.DataDictionary.ContainsKey(key))
{
bigMess += Environment.NewLine;
bigMess += ((string)Mission.DataDictionary[key]) + Environment.NewLine;
}
}
if (leakTo[1] && playerArmy == -1) bigMess += "(enemy objectives leaked via low-level photo recon of General & staff)" + Environment.NewLine + Environment.NewLine;
}
Calcs.WriteAllTextAsync(filepath, System.Net.WebUtility.HtmlEncode(bigMess));
}
catch (Exception ex) { Console.WriteLine("Radar Write1: " + ex.ToString()); }
}
TimeSpan timeDiff = DateTime.UtcNow.Subtract(d);
var saveradar_realism = radar_realism;
if (display) Timeout(wait_s, () =>
{
{
try
{
SortedDictionary radar_messages_trim = new SortedDictionary(new ReverseComparer());
int trim = 0;
int c = 0;
if (!admin && playerArmy >= 0 && radar_messages != null && radar_messages.Count > 12) trim = radar_messages.Count - 12;
double delay = 0;
if (radar_messages != null) foreach (var mess in radar_messages)
{
if (c > 0 && c <= trim)
{
c++;
continue;
}
c++;
if (mess.Key == null) continue;
radar_messages_trim.Add(mess.Key, mess.Value);
delay += 0.2;
if (c % 10 == 0) delay += 1.0;
Timeout(delay, () =>
{
if (saveradar_realism == 0 && display) gpLogServerAndLog(new Player[] { player }, mess.Value + " : " + mess.Key, null);
else if (saveradar_realism >= 0 && display) gpLogServerAndLog(new Player[] { player }, mess.Value, null);
});
}
radar_messages_store[playername_index] = new Tuple>(currtime_ms, radar_messages_trim);
if (aiairgroup != null) ai_radar_info_store[aiairgroup] = ai_radar_info;
}
catch (Exception ex)
{
Console.WriteLine("Radar ERROR1 (repairing radar_messages_store: " + ex.ToString());
radar_messages_store[playername_index] = new Tuple>(currtime_ms, radar_messages);
if (aiairgroup != null) ai_radar_info_store[aiairgroup] = ai_radar_info;
}
}
}
/*catch (Exception ex)
{
Console.WriteLine("Radar ERROR37: " + ex.ToString());
}*/
}
} catch (Exception ex)
{
Console.WriteLine("Radar *MAIN* ERROR: " + ex.ToString());
}
/********************************************************************************************************************
* ****END****RADAR
* **********************************************************************************************************************/
public class c1
{
event maddox.game.GameDef.Chat EventChat;
}
public override void OnBattleStarted()
{
base.OnBattleStarted();
try
{
string map = "summer";
MISSION_LENGTH_HRS = 8.0;
END_MISSION_TIME_HRS = 20.05;
EARLIEST_MISSION_START_TIME_HRS = 4.15;
try
{
string filepath_mis = stb_FullPath + @"/" + MISSION_ID + ".mis";
Console.WriteLine("Mission file name: " + MISSION_FILE_FULL_PATH + " : " + this.PathMyself + " : " + this.sPathMyself);
var main_mis = GamePlay.gpLoadSectionFile(filepath_mis);
if (main_mis.exist("MAIN", "MAP"))
{
string map_name = main_mis.get("MAIN", "MAP");
Console.WriteLine("Mission map: " + map_name);
if (map_name.ToLower().Contains("autumn")) map = "autumn";
else if (map_name.ToLower().Contains("winter")) map = "winter";
}
if (map == "autumn")
{
Console.WriteLine("START TIME: Using AUTUMN map & start/end times.");
MISSION_LENGTH_HRS = 6.0;
END_MISSION_TIME_HRS = 17.25;
EARLIEST_MISSION_START_TIME_HRS = 6.15;
}
else if (map == "winter")
{
Console.WriteLine("START TIME: Using WINTER map & start/end times.");
MISSION_LENGTH_HRS = 8.5;
END_MISSION_TIME_HRS = 16.08;
EARLIEST_MISSION_START_TIME_HRS = 7.75;
}
else Console.WriteLine("START TIME: Using SUMMER map & start/end times.");
} catch (Exception ex) { Console.WriteLine ("START TIME: ERROR reading .mis file - Using default SUMMER map & start / end times. Error: " + ex.ToString()); }
/*
Mission mainMission;
public override void OnBattleStarted()
{
mainMission = (Mission)DataDictionary["MAIN.MISSON"];
}
public override void OnTrigger(int missionNumber, string shortName, bool active)
{
mainMission.OnTrigger(missionNumber, shortName, active);
}
*
* Then you can just use triggers from the sub-mission as normal.
*
*
*/
if (Mission.DataDictionary != null) Mission.DataDictionary.Clear();
MISSION_STARTED = true;
if (WAIT_FOR_PLAYERS_BEFORE_STARTING_MISSION_ENABLED) MISSION_STARTED = false;
START_MISSION_TICK = -1;
COOP_START_MODE = false;
if (COOP_START_MODE_ENABLED) COOP_START_MODE = true;
START_COOP_TICK = -1;
testFrontLines();
/*
for (double i = -25; i <= 25; i = i + 12.5)
{
DrawFrontLinesPerMapState(-25, 25, i, "test" + i.ToString("F0") + ".mis");
}
*/
Console.Write("campaign21: pre-sleep... |");
Timeout(8, () =>
{
Console.WriteLine("campaign21: post-sleep...");
Timeout(8, () =>
{
makeWindLayerList();
if (ON_TESTSERVER)
{
Console.WriteLine(listWindLayers(null, 1, 1));
Console.WriteLine(listWindLayers(null, 2, 1));
}
addAirfieldWindsocks();
if (mission_objectives == null) Console.WriteLine("#00.4 Mission Objectives doesn't exist yet!");
if (mission_objectives == null) Console.WriteLine("#00.5 Mission Objectives doesn't exist still!");
if (GamePlay is GameDef)
{
(GamePlay as GameDef).EventChat += new GameDef.Chat(Mission_EventChat);
/*
List cmps = (from field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where typeof(Component).IsAssignableFrom(field.FieldType)
let component = (Component)field.GetValue(this)
where component != null
select component).ToList();
foreach (Component c in cmps) Console.WriteLine("COMP EVENTS PROPS HI!" + c.ToString());
System.Reflection.PropertyInfo eventsProp = typeof(Component).GetProperty("Events", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
Console.WriteLine("COMP EVENTS PROPS " + cmps.ToString());
*/
/*
EventHandlerList events = (EventHandlerList)eventsProp.GetValue((GamePlay as GameDef).EventChat, null);
foreach (EventHandler ehl in eventsProp ){
Console.WriteLine("EVENTS PROPS " + ehl.ToString());
}
*/
/*
Delegate[] dary = (GamePlay as GameDef).EventChat.GetInvocationList();
if (dary != null)
{
foreach (Delegate del in dary)
{
(GamePlay as GameDef).EventChat -= (Action)del;
}
}
*/
}
Timeout(180, () => {
removeGroundActorsAndStationariesInEnemyTerritory();
});
Timeout(205, () => {
clearGroundActorsAndStationariesNearAllObjectivesinNeutralTerritory();
});
}
catch (Exception ex) { Console.WriteLine("MO_Destroy error3: " + ex.Message); };
try
{
File.Delete(STATSCS_FULL_PATH + "CampaignSummary.txt");
}
catch (Exception ex) { Console.WriteLine("CampaignSummary Delete: " + ex.ToString()); }
}
public override void OnBattleStoped()
{
base.OnBattleStoped();
Console.WriteLine("Battle Stopping -- saving map state & current supply status");
tempFlakTimer_dispose();
try
{
if (balanceAILoadTimer != null) balanceAILoadTimer.Dispose();
}
catch (Exception ex) { Console.WriteLine("ERROR OnBattleStoped1! " + ex.ToString()); }
try
{
if (MO_ObjectiveUndestroyTimer != null) MO_ObjectiveUndestroyTimer.Dispose();
}
catch (Exception ex) { Console.WriteLine("ERROR OnBattleStoped1! " + ex.ToString()); }
try {
}
catch (Exception ex) { Console.WriteLine("ERROR OnBattleStoped2! " + ex.ToString()); }
try {
if (!final_MO_WriteMissionObjects_completed) MO_WriteMissionObjects(wait: true);
}
catch (Exception ex) { Console.WriteLine("ERROR OnBattleStoped3! " + ex.ToString()); }
if (GamePlay is GameDef)
{
(GamePlay as GameDef).EventChat -= new GameDef.Chat(Mission_EventChat);
}
}
/****************************************
* READINITIALSUBMISSIONS
*
* Loads any files in the FILE_PATH that match the pattern (anything or nothing) + filenameID + (anything or nothing) + .mis
* wait tells how many seconds to wait before starting to load, timespread will spread multiple initialsubmission loads
* over a certain time period (seconds)
*
* **************************************/
List
{
Console.WriteLine("Debug: Loading " + InitSubMissions.Count + " missions to load. " + filenameID + " " + CLOD_PATH + FILE_PATH);
foreach (string s in InitSubMissions)
{
if ((timespread == 0) && (wait == 0))
{
ISectionFile f = GamePlay.gpLoadSectionFile(s);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: changeArmyToTerritorySectionFile/Initsubmissions");
GamePlay.gpPostMissionLoad(f);
DebugAndLog(s.Replace(CLOD_PATH + FILE_PATH, "") + " file loaded instantly");
Console.WriteLine(s.Replace(CLOD_PATH + FILE_PATH, "") + " file loaded instantly");
}
else
{
Timeout(wait + random.Next(timespread), () =>
{
ISectionFile f = GamePlay.gpLoadSectionFile(s);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: changeArmyToTerritorySectionFile/InitSubmissions");
GamePlay.gpPostMissionLoad(f);
DebugAndLog(s.Replace(CLOD_PATH + FILE_PATH, "") + " file loaded on delay");
Console.WriteLine(s.Replace(CLOD_PATH + FILE_PATH, "") + " file loaded on delay");
});
}
}
return InitSubMissions.Count;
}
/************************************************************
* INIT
* *********************************************************/
public override void Init(maddox.game.ABattle battle, int missionNumber)
{
base.Init(battle, missionNumber);
Console.WriteLine("MI 1");
try
{
gpBattle = battle;
Console.WriteLine("MI 2");
try
{
gpBattle.creatingMissionScript(covermission, missionNumber + 1, "Genghis.cs");
}
catch (Exception ex) { Console.WriteLine("MAIN INIT error 1: " + ex.Message); };
Console.WriteLine("MI 3");
try {
gpBattle.creatingMissionScript(statsmission, missionNumber + 2, CLOD_PATH + FILE_PATH + "/Genghis-Class-StatsMission.cs");
}
catch (Exception ex) { Console.WriteLine("MAIN INIT error 2: " + ex.Message); };
Console.WriteLine("MI 4");
gpBattle.creatingMissionScript(supplymission, missionNumber + 3, "Genghis.cs");
Console.WriteLine("MI 5");
gpBattle.creatingMissionScript(airadarmission, missionNumber + 4, "Genghis.cs");
Console.WriteLine("MI 6");
gpBattle.creatingMissionScript(knickebeinmission, missionNumber + 5, "Genghis.cs");
Console.WriteLine("MI 7");
gpBattle.creatingMissionScript(landinggroundmission, missionNumber + 5, "Genghis.cs");
Console.WriteLine("MI 8");
gpBattle.creatingMissionScript(skincheckmission, missionNumber + 6, "Genghis.cs");
Console.WriteLine("MI 9");
gpBattle.creatingMissionScript(objectiverepairmission, missionNumber + 7, "Genghis.cs");
Console.WriteLine("MI 10");
gpBattle.creatingMissionScript(movebombtargetmission, missionNumber + 8, "Genghis.cs");
Console.WriteLine("MI 11");
gpBattle.creatingMissionScript(asvradarmission, missionNumber + 9, "Genghis.cs");
Console.WriteLine("MI 12");
gpBattle.creatingMissionScript(threadloadmission, missionNumber + 10, "Genghis.cs");
Console.WriteLine("MI 13");
/*
Timeout(30, () => {MO_DestroyObjective("BTarget14R");
MO_DestroyObjective("BTarget22R");
MO_DestroyObjective("RTarget28R");
MO_DestroyObjective("RTarget29R");
});
*/
for (int k = 1; k < 10; k++)
{
}
}
catch (Exception ex) { Console.WriteLine("MAIN INIT error: " + ex.Message); };
}
List> redBomberActions = new List>() {
new List() {"RBomb1", "RBombCover1"},
new List() {"RBomb2", "RBombCover2"},
new List() {"RBomb3", "RBombCover3"},
new List() {"RBomb1_X2", "RBombCover1_X2"},
new List() { "RBomb2_X2", "RBombCover2_X2"},
new List() { "RBomb3_X2", "RBombCover3_X2"},
new List() {"RBomb1_X3", "RBombCover1_X3"},
new List() { "RBomb2_X3", "RBombCover2_X3"},
new List() { "RBomb3_X3", "RBombCover3_X3"},
new List() {"Jabored"},
new List() {"Jabored_X2"},
new List() {"Jabored_X3"},
new List() {"MQWest", "MQWestCover"},
new List() {"action4", "action4cover"},
new List() {"action6", "action6cover"},
new List() {"action14", "action14cover"},
new List() {"action16", "action16cover"},
new List() { "MQWest_X2", "MQWestCover_X2"},
new List() { "action4_X2", "action4cover_X2"},
new List() { "action6_X2", "action6cover_X2"},
new List() { "action14_X2", "action14cover_X2"},
new List() { "action16_X2", "action16cover_X2"},
new List() { "MQWest_X3", "MQWestCover_X3"},
new List() { "action4_X3", "action4cover_X3"},
new List() { "action6_X3", "action6cover_X3"},
new List() { "action14_X3", "action14cover_X3"},
new List() { "action16_X3", "action16cover_X3"},
new List() {"F1", "F1e"},
new List() {"F7_X2", "F7e_X2"},
new List() {"F13_X2", "F13e_X2"},
new List() {"F13_X3", "F13e_X3"},
new List() { "F17_X2", "F18_X2"},
new List() { "F17_X3", "F18_X3"},
new List() {"F6", "F7"},
new List() {"F11", "F12"},
new List() {"F17", "F1e8"},
};
List> blueBomberActions = new List>() {
new List() {"Bomb1", "BombCover1"},
new List() {"Bomb2", "BombCover2"},
new List() {"Bomb3", "BombCover3"},
new List() { "Bomb1_X2", "BombCover1_X2"},
new List() { "Bomb2_X2", "BombCover2_X2"},
new List() { "Bomb3_X2", "BombCover3_X2"},
new List() { "Bomb1_X3", "BombCover1_X3"},
new List() { "Bomb2_X3", "BombCover2_X3"},
new List() { "Bomb3_X3", "BombCover3_X3"},
new List() {"45mincover2", "45minraidCover", "45minraidB"},
new List() {"2hrraid", "2hrraidcover"},
new List() {"4hrraidcover2", "4hrraidcover", "4hrraid"},
new List() {"testbomber", "testcover1", "testcover2"},
new List() {"action5", "action5e"},
new List() {"action7", "action7e"},
new List() {"action13", "action13e", "action13c", "action13cc"},
new List() {"45mincover2_X2", "45minraidCover_X2", "45minraidB_X2",},
new List() {"2hrraid_X2", "2hrraidcover_X2",},
new List() {"4hrraidcover2_X2", "4hrraidcover_X2", "4hrraid_X2",},
new List() {"testbomber_X2", "testcover1_X2", "testcover2_X2",},
new List() {"action5_X2", "action5e_X2",},
new List() {"action7_X2", "action7e_X2",},
new List() {"action13_X2", "action13e_X2", "action13c_X2", "action13cc_X2",},
new List() {"45mincover2_X3", "45minraidCover_X3", "45minraidB_X3",},
new List() {"2hrraid_X3", "2hrraidcover_X3",},
new List() {"4hrraidcover2_X3", "4hrraidcover_X3", "4hrraid_X3",},
new List() {"testbomber_X3", "testcover1_X3", "testcover2_X3",},
new List() {"action5_X3", "action5e_X3",},
new List() {"action7_X3", "action7e_X3",},
new List() {"action13_X3", "action13e_X3", "action13c_X3", "action13cc_X3",},
};
List> blueFighterActions = new List>() {
new List() {"BlueShorePatrol1"},
new List() {"BlueShorePatrol2"},
};
List> redFighterActions = new List>() {
new List() {"RedShorePatrol1"},
new List() {"RedShorePatrol2"},
};
List blueAllActions = new List
{
"action1",
"action1c",
"action1e",
"action3",
"action5",
"action5e",
"action7",
"action7e",
"action9",
"action11",
"action13",
"action13e",
"action13c",
"action13cc",
"action15",
"action17",
"escort2",
"escort3",
"Bomb1",
"BombCover1",
"Bomb2",
"BombCover2",
"Bomb3",
"BombCover3",
"109Cover1",
"109Cover2",
"109Cover3",
"109Cover4",
"110cover1",
"110cover2",
"110cover3",
"110cover4",
"CalaisAAA1",
"CalaisAAA2",
"CalaisAAA3",
"CalaisPropeller",
"CalaisDiesel",
"CalaisTorpedo",
"CalaisLox",
"CalaisMainFuel",
"CalaisHydrogen",
"CalaisTrainStation",
"BluePatrol1",
"BluePatrol2",
"BluePatrol3",
"BluePatrol4",
"BluePatrol5",
"BluePatrol3",
"Newhigh",
"StOmar",
"zonedefenseblue1",
"zonedefenseblue2",
"zonedefenseblue3",
"zonedefenseblue4",
"Rely1",
"Rely2",
"Rely3",
"Rely4",
"Rely5",
"Rely6",
"45mincover2",
"45minraidCover",
"45minraidB",
"2hrraid",
"2hrraidcover",
"4hrraidcover2",
"4hrraidcover",
"4hrraid",
"testbomber",
"testcover1",
"testcover2",
"StOmar2_X2",
"escort2_X2",
"escort3_X2",
"Bomb1_X2",
"BombCover1_X2",
"Bomb2_X2",
"BombCover2_X2",
"Bomb3_X2",
"BombCover3_X2",
"109Cover1_X2",
"109Cover2_X2",
"109Cover3_X2",
"109Cover4_X2",
"110cover1_X2",
"110cover2_X2",
"110cover3_X2",
"110cover4_X2",
"CalaisAAA1_X2",
"CalaisAAA2_X2",
"CalaisAAA3_X2",
"CalaisPropeller_X2",
"CalaisDiesel_X2",
"CalaisTorpedo_X2",
"CalaisLox_X2",
"CalaisMainFuel_X2",
"CalaisHydrogen_X2",
"CalaisTrainStation_X2",
"BluePatrol1_X2",
"BluePatrol2_X2",
"BluePatrol3_X2",
"BluePatrol4_X2",
"BluePatrol5_X2",
"BluePatrol3_X2",
"Newhigh_X2",
"StOmar_X2",
"zonedefenseblue1_X2",
"zonedefenseblue2_X2",
"zonedefenseblue3_X2",
"zonedefenseblue4_X2",
"Rely1_X2",
"Rely2_X2",
"Rely3_X2",
"Rely4_X2",
"Rely5_X2",
"Rely6_X2",
"45mincover2_X2",
"45minraidCover_X2",
"45minraidB_X2",
"2hrraid_X2",
"2hrraidcover_X2",
"4hrraidcover2_X2",
"4hrraidcover_X2",
"4hrraid_X2",
"testbomber_X2",
"testcover1_X2",
"testcover2_X2",
"StOmar2_X3",
"escort2_X3",
"escort3_X3",
"Bomb1_X3",
"BombCover1_X3",
"Bomb2_X3",
"BombCover2_X3",
"Bomb3_X3",
"BombCover3_X3",
"109Cover1_X3",
"109Cover2_X3",
"109Cover3_X3",
"109Cover4_X3",
"110cover1_X3",
"110cover2_X3",
"110cover3_X3",
"110cover4_X3",
"CalaisAAA1_X3",
"CalaisAAA2_X3",
"CalaisAAA3_X3",
"CalaisPropeller_X3",
"CalaisDiesel_X3",
"CalaisTorpedo_X3",
"CalaisLox_X3",
"CalaisMainFuel_X3",
"CalaisHydrogen_X3",
"CalaisTrainStation_X3",
"BluePatrol1_X3",
"BluePatrol2_X3",
"BluePatrol3_X3",
"BluePatrol4_X3",
"BluePatrol5_X3",
"BluePatrol3_X3",
"Newhigh_X3",
"StOmar_X3",
"zonedefenseblue1_X3",
"zonedefenseblue2_X3",
"zonedefenseblue3_X3",
"zonedefenseblue4_X3",
"Rely1_X3",
"Rely2_X3",
"Rely3_X3",
"Rely4_X3",
"Rely5_X3",
"Rely6_X3",
"45mincover2_X3",
"45minraidCover_X3",
"45minraidB_X3",
"2hrraid_X3",
"2hrraidcover_X3",
"4hrraidcover2_X3",
"4hrraidcover_X3",
"4hrraid_X3",
"testbomber_X3",
"testcover1_X3",
"testcover2_X3",
"BlueShorePatrol2",
"BlueShorePatrol1",
};
List redAllActions = new List
{
"action2",
"action4",
"action4cover",
"action4_X2",
"action4cover_X2",
"action4_X3",
"action4cover_X3",
"action6",
"action6cover",
"action6_X2",
"action6cover_X2",
"action6_X3",
"action6cover_X3",
"action10",
"action8",
"action8cover",
"action12",
"action12cover",
"action12_X2",
"action12cover_X2",
"action12_X3",
"action12cover_X3",
"action14cover",
"action14_X2",
"action14cover_X2",
"action14_X3",
"action14cover_X3",
"action16",
"action16cover",
"action16_X2",
"action16cover_X2",
"action16_X2",
"action16cover_X2",
"StOmar2",
"action14",
"action18",
"redspitcover1",
"redspitcover2",
"redhurrycover1",
"redhurrycover2",
"SouthernCover1",
"SouthernCover2",
"SouthernCover3",
"SouthernCover4",
"SouthernCover5",
"RBomb1",
"RBombCover1",
"RBomb2",
"RBombCover2",
"RBomb3",
"RBombCover3",
"Fatal1",
"Fatal2",
"Fatal3",
"Fatal4",
"Fatal5",
"Pegwelldefense1",
"Pegwelldefense2",
"Pegwelldefense3",
"Pegwelldefense4",
"Pegwelldefense5",
"Willmingtondefensered",
"Gladiatorintercept",
"Gladiatorintercept2",
"Redhilldefensered2",
"Beau1",
"MQWest",
"MQWestCover",
"loneglad",
"redspitcover1_X2",
"redspitcover2_X2",
"redhurrycover1_X2",
"redhurrycover2_X2",
"SouthernCover1_X2",
"SouthernCover2_X2",
"SouthernCover3_X2",
"SouthernCover4_X2",
"SouthernCover5_X2",
"RBomb1_X2",
"RBombCover1_X2",
"RBomb2_X2",
"RBombCover2_X2",
"RBomb3_X2",
"RBombCover3_X2",
"Fatal1_X2",
"Fatal2_X2",
"Fatal3_X2",
"Fatal4_X2",
"Fatal5_X2",
"Pegwelldefense1_X2",
"Pegwelldefense2_X2",
"Pegwelldefense3_X2",
"Pegwelldefense4_X2",
"Pegwelldefense5_X2",
"Willmingtondefensered_X2",
"Gladiatorintercept_X2",
"Gladiatorintercept2_X2",
"Redhilldefensered2_X2",
"Beau1_X2",
"MQWest_X2",
"MQWestCover_X2",
"loneglad_X2",
"redspitcover1_X3",
"redspitcover2_X3",
"redhurrycover1_X3",
"redhurrycover2_X3",
"SouthernCover1_X3",
"SouthernCover2_X3",
"SouthernCover3_X3",
"SouthernCover4_X3",
"SouthernCover5_X3",
"RBomb1_X3",
"RBombCover1_X3",
"RBomb2_X3",
"RBombCover2_X3",
"RBomb3_X3",
"RBombCover3_X3",
"Fatal1_X3",
"Fatal2_X3",
"Fatal3_X3",
"Fatal4_X3",
"Fatal5_X3",
"Pegwelldefense1_X3",
"Pegwelldefense2_X3",
"Pegwelldefense3_X3",
"Pegwelldefense4_X3",
"Pegwelldefense5_X3",
"Willmingtondefensered_X3",
"Gladiatorintercept_X3",
"Gladiatorintercept2_X3",
"Redhilldefensered2_X3",
"Beau1_X3",
"MQWest_X3",
"MQWestCover_X3",
"loneglad_X3",
"RedShorePatrol2",
"RedShorePatrol1",
"Jabored",
"Thems1",
"London1air",
"London2air",
"London3air",
"Jabored_X2",
"Thems1_X2",
"London1air_X2",
"London2air_X2",
"London3air_X2",
"Jabored_X3",
"Thems1_X3",
"London1air_X3",
"London2air_X3",
"London3air_X3",
"F1",
"F1e",
"F2",
"F3",
"F6",
"F7",
"F11",
"F12",
"F15",
"F18",
"F1_X2",
"F1e_X2",
"F7_X2",
"F7e_X2",
"F13_X2",
"F13e_X2",
"F17_X2",
"F18_X2",
"F1_X3",
"F1e_X3",
"F2_X3",
"F3_X3",
"F6_X3",
"F7_X3",
"F13_X3",
"F13e_X3",
"F17_X3",
"F18_X3",
};
//BALANCEAILOAD and STOPAI are the two main ways we control how many //AI groups come into the game. //BALANCEAILOAD will load bomber groups periodically //if the action gets too low/boring...
{
foreach (List l in Actions)
{
if (l.Contains(needle)) return true;
}
return false;
}
private DateTime timeLastFighterGroupLoaded = DateTime.UtcNow;
private double fighterGroupLoadInterval_min = 62;
static object balanceAILoad_locker = new object();
if (Monitor.TryEnter(balanceAILoad_locker)) //lock the recursive/timer so that only one instance can run at a time //return; //stop buggy behavior for now //First off we load a new shore patrol/border patrol fighter group every hour or so //double wait = random.Next(0, 90); //2021/07 - was <70 but with the server seeming a bit overloaded at times, //make it <55 instead //2021/08 - the problem with server overload seems to be AA/artillery rather than aircraft //So increasing to 65 for both sides - we'll see how it goes //2022/12 - increasing them all by a bit now //bhugh, temp XX2021-10, cutting bomber missions way down to raise stakes //2021-11 - leaving it this way, we'll see how it works. //2023-01 - moving back to 8%, both R&B, because for some reason //blue bombers missions outnumber Red by a massive percentage //2022-12 - now making this match/be equal for Red & Blue //bhugh, temp XX2021-10, cutting bomber missions way down to raise stakes //2021-11 - leaving it this way for now - 2021-12, putting it back to 65 etc //2022-12 - raising % of fighter missions to 20% from 5%, just to give the bombers //a little more challenge...
{
{
try
{
int numRedPlayers = Calcs.gpNumberOfPlayers(GamePlay, 1);
int numBluePlayers = Calcs.gpNumberOfPlayers(GamePlay, 2);
Console.WriteLine("balanceAILoad: Blue ac/players {0} {1} Red ac/players {2} {3} " + DateTime.UtcNow.ToString("T") + ". Send group?", numBlueAircraft, numBluePlayers, numRedAircraft, numRedPlayers);
if (DateTime.UtcNow > timeLastFighterGroupLoaded.AddMinutes(fighterGroupLoadInterval_min))
{
Timeout(random.Next(0, 240), () =>
{
int randIndex = random.Next(redFighterActions.Count);
foreach (string act in redFighterActions[randIndex])
{
execAction(act, "BalanceAILoad - fighter patrols - Red");
Console.WriteLine("balanceAILoad: Loading " + act);
}
});
Timeout(random.Next(0, 240), () =>
{
int randIndex = random.Next(blueFighterActions.Count);
foreach (string act in blueFighterActions[randIndex])
{
execAction(act, "BalanceAILoad - fighter patrols - Blue");
Console.WriteLine("balanceAILoad: Loading " + act);
}
});
}
/*if ((numBlueAircraft < 65 && numRedPlayers > 9) ||
(numBlueAircraft < 51 && numRedPlayers > 5) ||
(numBlueAircraft < 47 && numRedPlayers > 0)
)
*/
if ((numBlueAircraft < 70 && numRedPlayers > 9) ||
(numBlueAircraft < 56 && numRedPlayers > 5) ||
(numBlueAircraft < 51 && numRedPlayers > 0)
)
/*if ((numBlueAircraft < 28 && numRedPlayers > 9) ||
(numBlueAircraft < 26 && numRedPlayers > 5) ||
(numBlueAircraft < 24 && numRedPlayers > 0)
)*/
{
double wait = random.Next(0, 90);
List> blueActions = blueBomberActions;
if (random.Next(100) < 8) blueActions = blueFighterActions;
Timeout(wait, () =>
{
int randIndex = random.Next(blueActions.Count);
foreach (string act in blueActions[randIndex])
{
execAction(act, "BalanceAILoad Blue");
Console.WriteLine("balanceAILoad: Loading " + act);
}
});
}
/*
if ((numRedAircraft < 55 & numBluePlayers > 9) ||
(numRedAircraft < 51 & numBluePlayers > 5) ||
(numRedAircraft < 47 & numBluePlayers > 0)
)
*/
if ((numRedAircraft < 70 & numBluePlayers > 9) ||
(numRedAircraft < 56 & numBluePlayers > 5) ||
(numRedAircraft < 51 & numBluePlayers > 0)
)
/*if ((numRedAircraft < 28 & numBluePlayers > 9) ||
(numRedAircraft < 26 & numBluePlayers > 5) ||
(numRedAircraft < 24 & numBluePlayers > 0)
)*/
{
List> redActions = redBomberActions;
if (random.Next(100) < 8) redActions = redFighterActions;
double wait = random.Next(0, 90);
Timeout(wait, () =>
{
int randIndex = random.Next(redActions.Count);
foreach (string act in redActions[randIndex])
{
execAction(act, "BalanceAILoad Red");
Console.WriteLine("balanceAILoad: Loading " + act);
}
});
}
}
catch (Exception ex) { Console.WriteLine("BalanceAILoad ERROR: " + ex.ToString()); }
finally
{
Monitor.Exit(balanceAILoad_locker);
}
}
}
public System.Threading.Timer balanceAILoadTimer;
//Console.WriteLine("balanceAILoad: Starting timer! " + DateTime.UtcNow.ToString("T")); dueTime: 30000, //wait time @ startup period: 232453); //periodically call the callback at this interval, every 4-6 minutes say //IKnickebeinMission TWCKnickebeinMission; //GCV.GCVMission gvcmission; //if (TWCStatsMission != null) TWCSaveIPlayerStat = TWCStatsMission.stb_ISaveIPlayerStat; //STATSCS_FULL_PATH = statsmission.stb_FullPath; //for some reason, this doesn't work correctly 2020/02/14 //TWCKnickebeinMission = TWCComms.Communicator.Instance.Knickebein; //TWCStbSaveIPlayerStat = TWCComms.Communicator.Instance.Cover //TWCComms.Communicator.Instance.Main = this; //TWCMainMission = TWCComms.Communicator.Instance.Main; //TWCStatsMission = TWCComms.Communicator.Instance.Stats; //string s1= TWCComms.Communicator.Instance.string1; //Console.WriteLine("Statsstring: " + s1); //Console.WriteLine("GetType1: " + GetType().ToString()); //Console.WriteLine("GetType2: " + s1.GetType().ToString()); //Console.WriteLine("GetType3: " + TWCMainMission.GetType().ToString()); //Console.WriteLine("GetType4: " + (TWCComms.Communicator.Instance.Stats == null).ToString()); //Console.WriteLine("GetType5: " + (TWCComms.Communicator.Instance.Main.GetType().ToString())); //Console.WriteLine("GetType6: " + TWCStatsMission.stb_LocalMissionIniDirectory); //Console.WriteLine("GetType19: " + TWCStatsMission.stb_LocalMissionIniDirectory); //Console.WriteLine("GetType20: " + TWCStatsMission.ot_GetCivilianBombings("TWC_Flug")); //Assembly a = new Assembly(); //Assembly assembly = typeof(maddox.game.AMission).Assembly; //Assembly assembly = Assembly.GetExecutingAssembly(); //Assembly assembly = Assembly.GetCallingAssembly(); //var assemblies = AppDomain.CurrentDomain.GetAssemblies(); //var namespaces = assembly.GetTypes().Select(t => t.Namespace).Distinct(); //coord.Singleton.Instance.Main = this; //String executablePath = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); //Console.WriteLine("NS " + executablePath); //Mission m = Battle.missions[missionNumber]; //GamePlay.gpSetOrderMissionMenu(player, true, 0, new string[] { "Server Options - Users" }, new bool[] { true }); //{true/false bool array}: TRUE here indicates that the choice is a SUBMENU so that when it is selected the user menu will be shown. If FALSE the user menu will disappear...
{
balanceAILoadTimer = new System.Threading.Timer(
new TimerCallback(balanceAILoad),
null,
}
IStatsMission TWCStatsMission;
ISupplyMission TWCSupplyMission;
ICoverMission TWCCoverMission;
IStbSaveIPlayerStat TWCSaveIPlayerStat;
public override void OnMissionLoaded(int missionNumber)
{
base.OnMissionLoaded(missionNumber);
try
{
TWCStatsMission = TWCComms.Communicator.Instance.Stats;
TWCSaveIPlayerStat = statsmission.stb_ISaveIPlayerStat;
if (TWCComms.Communicator.Instance.stb_FullPath != null && TWCComms.Communicator.Instance.stb_FullPath.Length > 0) STATSCS_FULL_PATH = TWCComms.Communicator.Instance.stb_FullPath;
TWCSupplyMission = TWCComms.Communicator.Instance.Supply;
TWCCoverMission = TWCComms.Communicator.Instance.Cover;
/*
foreach (var assembly in assemblies)
{
var namespaces = assembly.GetTypes();
foreach (var n in namespaces)
{
Console.WriteLine("NS " + n.ToString());
}
}*/
/* if (m.stb_StatsINIFilename !=null & m.stb_StatsINIFilename=="stats.ini")
{
TWCStatsMission = m;
Console.WriteLine("StatsMission! " + m.stb_StatsINIFilename);
}*/
/*
* ban LOAD blacklist.txt
* */
}
catch (Exception ex) { Console.WriteLine("OnMission ERROR: " + ex.Message); };
}
/************************************************************
* MENU SYSTEM
* *********************************************************/
bool dmgOn = false;
bool EndMissionSelected = false;
bool debugMenu = false;
bool debugSave;
int radar_realismSave;
private void setMainMenu(Player player)
{
GamePlay.gpSetOrderMissionMenu(player, true, 0, new string[] { "Enemy radar", "Friendly radar", "Enemy Activity Map Overview", "More...", "Objectives Complete", "Objectives Remaining", "Secondary Objectives", "Recon Photo Results with Coordinates", "Take Recon Photo" }, new bool[] { false, false, false, true, false, false, false, false, false });
}
private void setSubMenu1(Player player)
{
if (admin_privilege_level(player) >= 1)
{
string rollovertext = "(admin) End mission now/roll over to next mission";
if (EndMissionSelected) rollovertext = "(admin) CANCEL End mission now command";
if (admin_privilege_level(player) == 2)
GamePlay.gpSetOrderMissionMenu(player, true, 2, new string[] { "(admin) Show detailed damage reports for all players (toggle)", "(admin) Toggle debug mode", "", rollovertext, "Return to User Menu" }, new bool[] { false, false, false, false, true });
else GamePlay.gpSetOrderMissionMenu(player, true, 2, new string[] { "", "", "", rollovertext, "Return to User Menu" }, new bool[] { false, false, false, false, true });
}
else
{
setMainMenu(player);
}
}
private void setSubMenu2(Player player)
{
string ai_mode = "(off)";
if (airadarmission != null) ai_mode = airadarmission.handleAIplusASVTab4StatusString(player);
if (admin_privilege_level(player) >= 1)
{
GamePlay.gpSetOrderMissionMenu(player, true, 2, new string[] { "Your Career Summary", "Your Session Summary", "Netstats/All Player Summary", "More...", "Aerial Intcpt Radar " + ai_mode, "Current Campaign Status", "Detail Campaign Team/Session", "Let AI take over 2nd Position", "Admin Options" }, new bool[] { false, false, false, true, true, false, false, false, true });
}
else
{
GamePlay.gpSetOrderMissionMenu(player, true, 2, new string[] { "Your Career Summary", "Your Session Summary", "Netstats/All Player Summary", "More...", "Aerial Intcpt Radar " + ai_mode, "Current Campaign Status", "Detail Campaign Team/Session", "Let AI take over 2nd Position" }, new bool[] { false, false, false, true, true, false, false, false });
}
}
private void setSubMenu3(Player player)
{
GamePlay.gpSetOrderMissionMenu(player, true, 3, new string[] { "Radar, airport, objective damage summary", "Nearest friendly airfield", "On friendly territory?", "More...", "Aircraft Supply", "Aircraft available to you", "Aircraft lost this mission", "Winds Aloft & Time left", "Online Situation Map/radar password" }, new bool[] { false, false, false, true, false, false, false, false, false });
}
bool covermis_listOn = false;
private void setSubMenu4(Player player)
{
string cover_misListon_string = "(off)";
if (covermission.isOn_Display_listPositionCurrentCoverAircraft(player)) cover_misListon_string = "(on)";
string t = covermission.BAM_getPlayerBombAimMode_string(player);
GamePlay.gpSetOrderMissionMenu(player, true, 4, new string[] { "Knickebein - On/Next", "Knickebein - Off", "Knickebein - Current KB Info", "Back...", "Knickebein - List", "Cover Targeting [" + t + "]", "Cover - List available aircraft", "Cover - Aircraft position " + cover_misListon_string, "Cover - Release Aircraft to land" }, new bool[] { true, true, true, true, true, true, true, true, false });
}
public override void OnOrderMissionMenuSelected(Player player, int ID, int menuItemIndex)
{
AiAircraft aircraft = null;
if (player.Place() as AiAircraft != null) aircraft = player.Place() as AiAircraft;
/*****************************************************
*
* ADMIN SUBMENU (2nd submenu, ID ==1, Tab-4-4-9)
*
*****************************************************/
if (ID == 1)
if (menuItemIndex == 0)
{
setMainMenu(player);
}
else if (menuItemIndex == 1)
{
if (admin_privilege_level(player) == 2)
{
dmgOn = !dmgOn;
if (dmgOn)
{
GamePlay.gpHUDLogCenter("Will show damage on all aircraft");
twcLogServer(new Player[] { player }, "Detailed damage reports will be shown for all players", new object[] { });
}
else
{
GamePlay.gpHUDLogCenter("Will not show damage on all aircraft");
twcLogServer(new Player[] { player }, "Detailed damage reports turned off", new object[] { });
}
}
setMainMenu(player);
}
else if (menuItemIndex == 2)
{
if (admin_privilege_level(player) == 2)
{
debugMenu = !debugMenu;
if (debugMenu)
{
twcLogServer(new Player[] { player }, "Debug & detailed radar ON for all users - extra debug messages & instant, detailed radar", new object[] { });
radar_realismSave = RADAR_REALISM;
DEBUG = true;
RADAR_REALISM = 0;
}
else
{
twcLogServer(new Player[] { player }, "Debug & detailed radar OFF", new object[] { });
RADAR_REALISM = radar_realismSave;
DEBUG = false;
}
}
setMainMenu(player);
}
/*
* else if (menuItemIndex == 3)
{
if (admin_privilege_level(player) == 2)
{
string str = WritePlayerStat(player);
int maxChunkSize = 100;
for (int i = 0; i < str.Length; i += maxChunkSize)
twcLogServer(new Player[] { player }, str.Substring(i, Math.Min(maxChunkSize, str.Length - i)), new object[] { });
}
setMainMenu(player);
}
*/
else if (menuItemIndex == 4)
{
if (admin_privilege_level(player) >= 1)
{
if (EndMissionSelected == false)
{
EndMissionSelected = true;
twcLogServer(new Player[] { player }, "ENDING MISSION!! If you want to cancel the End Mission command, use Tab-4-4-9-4 again. You have 30 seconds to cancel.", new object[] { });
Timeout(30, () =>
{
if (EndMissionSelected)
{
EndMission(0);
}
else
{
twcLogServer(new Player[] { player }, "End Mission CANCELLED; Mission continuing . . . ", new object[] { });
twcLogServer(new Player[] { player }, "If you want to end the mission, you can use the menu to select Mission End again now.", new object[] { });
}
});
}
else
{
twcLogServer(new Player[] { player }, "End Mission CANCELLED; Mission will continue", new object[] { });
EndMissionSelected = false;
}
}
setMainMenu(player);
}
else if (menuItemIndex == 5)
{
setMainMenu(player);
}
else if (menuItemIndex == 9)
{
twcLogServer(new Player[] { player }, "Re-spawn: This option not working yet", new object[] { });
setMainMenu(player);
}
else
setMainMenu(player);
}
/* else if( menuItemIndex == 2 ) {
setSubMenu1( player );
/* if ( player.Name().Substring(0,3) == @"TWC") {
setSubMenu2( player );
} else {
twcLogServer(new Player[] { player }, player.Name() + " is not authorized", new object[] { });
setSubMenu1( player );
}
*/
}
/*****************************************************
*
* USER SUBMENU (4th submenu, ID == 4, Tab-4-4-4-4)
*
*****************************************************/
else if (ID == 4)
if (menuItemIndex == 0)
{
setSubMenu3(player);
}
else if (menuItemIndex == 1)
{
setSubMenu4(player);
if (knickebeinmission != null)
{
knickebeinmission.KniOnStartOrNext(player);
}
Timeout(2, () =>
{
if (!objectiverepairmission.orm_PlayersOnRepairMissionExpiration.ContainsKey(player))
{
string msg6 = "!!!!!Remember to turn on Cover Bomber Aim Mode via Tab-4-4-4-4-6!!!!!!";
twcLogServer(new Player[] { player }, msg6, null);
}
});
}
else if (menuItemIndex == 2)
{
if (knickebeinmission != null)
{
knickebeinmission.KniStop(player);
}
setSubMenu4(player);
}
else if (menuItemIndex == 3)
{
if (knickebeinmission != null)
{
knickebeinmission.KniInfo(player);
}
setSubMenu4(player);
}
{
setMainMenu(player);
}
else if (menuItemIndex == 5)
{
if (knickebeinmission != null)
{
knickebeinmission.KniList(player);
}
setSubMenu4(player);
}
else if (menuItemIndex == 6)
{
if (covermission != null)
{
covermission.BAM_toggleBombAimMode_withmessages(player);
}
}
else if (menuItemIndex == 7)
{
if (covermission != null)
{
covermission.listCoverAircraftCurrentlyAvailable((ArmiesE)player.Army(), player);
}
}
else if (menuItemIndex == 8)
{
if (covermission != null)
{
covermis_listOn = covermission.toggleregularDisplay_listPositionCurrentCoverAircraft(player);
}
}
else if (menuItemIndex == 9)
{
if (covermission != null)
{
covermission.landCoverAircraft(player);
}
}
else
setMainMenu(player);
}
}
/*****************************************************
*
* USER SUBMENU (3rd submenu, ID == 3, Tab-4-4-4)
*
*****************************************************/
else if (ID == 3)
if (menuItemIndex == 0)
{
setSubMenu2(player);
}
else if (menuItemIndex == 1)
{
int ar = 1; ;
if (player != null) ar = player.Army();
List armies = new List { 3 - ar, ar };
int ctr = 0;
foreach (int a in armies)
{
bool forEnemy = true;
if (ar == a) forEnemy = false;
Timeout(ctr * 16 + 0.001, () =>
{
twcLogServerP(player, ((ArmiesE)a).ToString().ToUpper() + " MILITARY ASSETS -----------");
ListAllObjectiveDamage(player, a, all: false, display: true, forEnemy: forEnemy);
});
Timeout(ctr * 16 + 6, () =>
{
twcLogServerP(player, ((ArmiesE)a).ToString().ToUpper() + " AIRFIELDS -----------");
ListAirfieldTargetDamage(player, a, forEnemy: forEnemy);
});
Timeout(ctr * 16 + 10, () =>
{
twcLogServerP(player, ((ArmiesE)a).ToString().ToUpper() + " RADAR -----------");
ListRadarTargetDamage(player, a, forEnemy: forEnemy);
});
ctr++;
}
setMainMenu(player);
}
else if (menuItemIndex == 2)
{
Timeout(0.2, () =>
{
string msg6 = "Checking your position via radar to find nearest friendly airport. Stand by . . . ";
twcLogServer(new Player[] { player }, msg6, null);
});
if (offRadar(player))
{
Timeout(6, () =>
{
string msg6 = "HQ has been unable to locate your position! Sorry and good luck!";
twcLogServer(new Player[] { player }, msg6, null);
});
}
else if (objectiverepairmission != null && objectiverepairmission.orm_isPlayerOnRepairMission(player) && random.NextDouble() < 0.99)
{
Timeout(6, () =>
{
string msg6 = "Radar HQ doesn't have time to help repair cargo and ferry pilots right now! Sorry and good luck!";
twcLogServer(new Player[] { player }, msg6, null);
});
}
else
{
Timeout(12, () =>
{
AiAirport ap = Calcs.nearestAirport(GamePlay, aircraft as AiActor, player.Army());
AiActor a = ap as AiActor;
Point3d aPos = a.Pos();
double distanceToAirport_m = aircraft.Pos().distance(ref aPos);
double bearing_deg = Calcs.CalculateGradientAngle(aircraft.Pos(), a.Pos());
double bearing_deg10 = Calcs.GetDegreesIn10Step(bearing_deg);
string dis_string = (distanceToAirport_m / 1000).ToString("N0") + " km ";
if (player.Army() == 1) dis_string = (Calcs.meters2miles(distanceToAirport_m)).ToString("N0") + " mi ";
string message6 = dis_string + bearing_deg10.ToString("N0") + "° to the nearest friendly airfield";
if (distanceToAirport_m < 2500) message6 = "You are AT the nearest friendly airfield";
if (distanceToAirport_m > 100000000) message6 = "Nearest friendly airfield not found";
twcLogServer(new Player[] { player }, message6, null);
});
}
setMainMenu(player);
}
else if (menuItemIndex == 3)
{
if (player.Army() != null && aircraft != null)
{
Timeout(0.2, () =>
{
string msg6 = "Checking your position via radar. Stand by . . . ";
twcLogServer(new Player[] { player }, msg6, null);
});
Timeout(12, () =>
{
int terr = GamePlay.gpFrontArmy(aircraft.Pos().x, aircraft.Pos().y);
string msg6 = "You are in ENEMY territory";
if (terr == 00) msg6 = "You are in NEUTRAL territory";
if (player.Army() == terr) msg6 = "You are in FRIENDLY territory";
twcLogServer(new Player[] { player }, msg6, null);
});
}
setMainMenu(player);
}
{
setSubMenu4(player);
}
else if (menuItemIndex == 5)
{
if (TWCSupplyMission != null) TWCSupplyMission.DisplayNumberOfAvailablePlanes(player.Army(), player, true);
setMainMenu(player);
}
else if (menuItemIndex == 6)
{
statsmission.Display_AircraftAvailable_ByName(player, nextAC: false, display: true, html: false);
Timeout(2.1, () =>
{
statsmission.Display_AircraftAvailable_ByName(player, nextAC: true, display: true, html: false);
});
Timeout(5.0, () =>
{
twcLogServer(new Player[] { player }, "Note that fighter & bomber pilot careers are separate & aircraft actually available depends on the ace & rank levels in the relevant career for that aircraft", null);
});
setMainMenu(player);
}
else if (menuItemIndex == 7)
{
setMainMenu(player);
if (TWCSupplyMission != null) TWCSupplyMission.ListAircraftLost(player.Army(), player, true, false);
}
else if (menuItemIndex == 8)
{
setMainMenu(player);
listWindLayers(player, player.Army());
showTimeLeft(player);
}
else if (menuItemIndex == 9)
{
setMainMenu(player);
showRadarPassword(player);
}
else
setMainMenu(player);
}
}
/*****************************************************
*
* USER SUBMENU (2nd submenu, ID ==2, Tab-4-4)
*
*****************************************************/
else if (ID == 2)
if (menuItemIndex == 0)
{
setSubMenu1(player);
}
else if (menuItemIndex == 1)
{
/*
* Formerly res = CalcMapMove("", false, false, player);
double score = res.Item1 * 100;
string mes = "Campaign score for this session so far: ";
if (score > 0) mes += "Red +" + score.ToString("n0");
else if (score < 0) mes += "Blue +" + (-score).ToString("n0");
else mes += "A tie!";
twcLogServer(new Player[] { player }, mes, null);
mes = "Objective totals since each side last turned the map: ";
mes += "Red +" + MissionObjectiveScore[ArmiesE.Red].ToString("n0") + ", ";
mes += "Blue +" + MissionObjectiveScore[ArmiesE.Blue].ToString("n0");
twcLogServer(new Player[] { player }, mes, null);
double newMapState = CampaignMapState + res.Item1 + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0;
summarizeCurrentMapstate(newMapState, true, player);
}
else if (menuItemIndex == 7)
{
/*
* Detailed Campaign summary as in res = CalcMapMove("", false, true, player);
double newMapState = CampaignMapState + res.Item1 + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0;
summarizeCurrentMapstate(newMapState, true, player);
}
else if (menuItemIndex == 8)
{
/*
* Let AI take over player's 2nd position - essential for 110, JU-87, etc
*/
letAiTake2ndPosition(player);
}
else if (menuItemIndex == 9)
{
setSubMenu1(player);
}
else
setMainMenu(player);
}
/*****************************************************
*
* USER SUBMENU (1st submenu, ID == 0, Tab-4)
*
*****************************************************/
}
else if (ID == 0)
if (menuItemIndex == 0)
{
setMainMenu(player);
}
else if (menuItemIndex == 1)
{
setMainMenu(player);
Player[] all = { player };
Task.Run(() =>
listPositionAllAircraft(player, player.Army(), false, radar_realism: RADAR_REALISM)
{
DebugAndLog("Total number of AI aircraft groups currently active:");
if (GamePlay.gpAirGroups(1) != null && GamePlay.gpAirGroups(2) != null)
{
int totalAircraft = GamePlay.gpAirGroups(1).Length + GamePlay.gpAirGroups(2).Length;
DebugAndLog(totalAircraft.ToString());
}
}
}
else if (menuItemIndex == 2)
{
setMainMenu(player);
Player[] all = { player };
Task.Run(() =>
listPositionAllAircraft(player, player.Army(), true, radar_realism: RADAR_REALISM)
{
DebugAndLog("Total number of AI aircraft groups currently active:");
if (GamePlay.gpAirGroups(1) != null && GamePlay.gpAirGroups(2) != null)
{
int totalAircraft = GamePlay.gpAirGroups(1).Length + GamePlay.gpAirGroups(2).Length;
DebugAndLog(totalAircraft.ToString());
}
}
}
else if (menuItemIndex == 3)
{
showGiantSectorOverview(player, player.Army());
setMainMenu(player);
}
else if (menuItemIndex == 5)
{
/*
* Display objectives completed
*/
setMainMenu(player);
twcLogServer(new Player[] { player }, "Completed Red Objectives (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):", new object[] { });
twcLogServer(new Player[] { player }, (MissionObjectivesCompletedString[ArmiesE.Red]), new object[] { });
Timeout(3, () =>
twcLogServer(new Player[] { player }, "Completed Blue Objectives (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):", new object[] { }));
Timeout(3.1, () =>
twcLogServer(new Player[] { player }, (MissionObjectivesCompletedString[ArmiesE.Blue]), new object[] { }));
}
else if (menuItemIndex == 6)
{
/*
* Display objectives remaining
*/
setMainMenu(player);
Task.Run(() =>
{
MO_ListRemainingPrimaryObjectives(player, player.Army(), 24);
int enemyArmy = 3 - player.Army();
if (MO_CountRemainingPrimaryObjectives(enemyArmy) <= 5)
{
Timeout(6, () =>
{
MO_ListRemainingPrimaryObjectives(player, enemyArmy, leak: true);
});
}
});
}
else if (menuItemIndex == 7)
{
/*
* Display Suggested Alternate Objectives
*/
setMainMenu(player);
Task.Run(() =>
MO_ListSuggestedObjectives(player, player.Army(), 5)
);
}
else if (menuItemIndex == 8)
{
/*
* List Scouted Objectives
*/
setMainMenu(player);
Task.Run(() =>
MO_ListScoutedObjectives(player, player.Army())
);
}
else if (menuItemIndex == 9)
{
/*
* Take Recon Photo
*/
setMainMenu(player);
MO_TakeScoutPhoto(player, player.Army());
}
{
setSubMenu2(player);
}
else
setMainMenu(player);
}
/****************************************************************
*
* ADMIN PRIVILEGE
*
* Determine if player is an admin, and what level
*
****************************************************************/
//name = "TWC_muggle"; //for testing if (admins_full.Contains(name)) return 2; //full admin - must be exact character match (CASE SENSITIVE) to the name in admins_full if (admins_basic.Any(name.Contains)) return 1; //basic admin - player's name must INCLUDE the exact (CASE SENSITIVE) stub listed in admins_basic somewhere--beginning, end, middle, doesn't matter //INITIATING THE MENUS FOR THE PLAYER AT VARIOUS KEY POINTS //Not starting it here due to Coop Start Mode //if (!MISSION_STARTED) DebugAndLog("First player connected; Mission timer starting"); //MISSION_STARTED = true; //MO_RecordPlayerScoutPhotos(player, false, true); //for testing //twcLogServer(null, "Mission loaded.", new object[] { }); //utcDate.ToString(culture), utcDate.Kind //Write current time in UTC, what happened, player name //INITIATING THE MENUS FOR THE PLAYER AT VARIOUS KEY POINTS //utcDate.ToString(culture), utcDate.Kind //Write current time in UTC, what happened, player name //int p = part.ParameterTypes.I_VelocityIAS; //We re-init menu & mission_started here bec. in some situations OnPlayerConnected never happens...
{
if (player == null || player.Name() == null) return 0;
string name = player.Name();
return 0;
}
/************************************************************
* END - MENU SYSTEM
* *********************************************************/
public override void OnPlayerConnected(Player player)
{
string message;
if (MissionNumber > -1)
{
setMainMenu(player);
twcLogServer(new Player[] { player }, "Welcome to " + CAMPAIGN_ID + ", " + player.Name(), new object[] { });
DateTime utcDate = DateTime.UtcNow;
message = utcDate.ToString("u") + " Connected " + player.Name();
DebugAndLog(message);
if (COOP_START_MODE)
{
Stb_Chat("CO-OP MISSION START MODE", null);
Stb_Chat("CO-OP START: You can spawn on the ground and taxi but", null);
Stb_Chat("DO NOT TAKE OFF OR AIR SPAWN until CO-OP mission start time", null);
}
}
}
public override void OnPlayerDisconnected(Player player, string diagnostic)
{
MO_SpoilPlayerScoutPhotos(player);
string message;
if (MissionNumber > -1)
{
DateTime utcDate = DateTime.UtcNow;
message = utcDate.ToString("u") + " Disconnected " + player.Name() + " " + diagnostic;
DebugAndLog(message);
}
}
public override void OnPlayerArmy(Player player, int Army)
{
if (MissionNumber > -1)
{
/* AiAircraft aircraft = (player.Place() as AiAircraft);
string cs = "";
double ias = (double) aircraft.getParameter(part.ParameterTypes.I_VelocityIAS, -1);
twcLogServer(new Player[] { player }, "Plane: "
+ cs + " " + ias, new object[] { });
*/
setMainMenu(player);
if (!MISSION_STARTED) DebugAndLog("First player connected (OnPlayerArmy); Mission timer starting");
MISSION_STARTED = true;
twcLogServer(new Player[] { player }, "Welcome to " + CAMPAIGN_ID + ", " + player.Name(), new object[] { });
}
}
public override void Inited()
{
try
{
if (MissionNumber > -1)
{
setMainMenu(GamePlay.gpPlayer());
twcLogServer(null, "Welcome to " + CAMPAIGN_ID, new object[] { });
}
}
catch (Exception ex) { Console.WriteLine("MO_Destroy error3: " + ex.Message); };
}
/****************************************
* END - CHAT COMMANDS
* **************************************/
/* public override void OnBattleStarted()
{
base.OnBattleStarted();
if (GamePlay is GameDef)
{
(GamePlay as GameDef).EventChat += new GameDef.Chat(Mission_EventChat);
}
} */
/*
? admin alias ban channel chat
console del deny difficulty exit expel
f file help history host kick
kick# mp_dotrange param sc secure set
show socket timeout
*/
private bool resetmission_requested = false;
void Mission_EventChat(IPlayer from, string msg)
{
string msg_orig = msg;
msg = msg.ToLower();
Player player = from as Player;
if (msg.StartsWith("= 2)
{
double md = redMultAdmin;
string ms = msg.Substring(9).Trim();
try { if (ms.Length > 0) md = Convert.ToDouble(ms); }
catch (Exception ex) { }
twcLogServer(new Player[] { player }, "RedStock admin multiplier set to " + md.ToString("n2") + ". Will add " + md.ToString("n2") + "X the regular mission aircraft stock increase at the end of this mission, plus any stock additions regularly due from mission success", null);
twcLogServer(new Player[] { player }, "To change this value, just re-enter = 2)
{
double md = blueMultAdmin;
string ms = msg.Substring(10).Trim();
try { if (ms.Length > 0) md = Convert.ToDouble(ms); }
catch (Exception ex) { }
twcLogServer(new Player[] { player }, "BlueStock admin multiplier set to " + md.ToString("n2") + ". Will add " + md.ToString("n2") + "X the regular mission aircraft stock increase at the end of this mission, plus any stock additions regularly due from mission success", null);
twcLogServer(new Player[] { player }, "To change this value, just re-enter
{
MO_ListRemainingPrimaryObjectives(player, player.Army());
int enemyArmy = 3 - player.Army();
if (MO_CountRemainingPrimaryObjectives(enemyArmy) <= 5)
{
Timeout(6, () => MO_ListRemainingPrimaryObjectives(player, enemyArmy, leak: true));
}
Timeout(9, () =>
twcLogServer(new Player[] { player }, "Blue Objectives Completed (" + MissionObjectiveScore[ArmiesE.Blue].ToString("F0") + " points):" + MissionObjectivesCompletedString[ArmiesE.Blue], new object[] { }));
});
Timeout(11, () =>
{
twcLogServer(new Player[] { player }, "Red Objectives Completed (" + MissionObjectiveScore[ArmiesE.Red].ToString("F0") + " points):" + MissionObjectivesCompletedString[ArmiesE.Red], new object[] { });
});
}
else
{
twcLogServer(new Player[] { player }, "Please use Tab-4 menu for campaign status", new object[] { });
}
}
{
{
twcLogServer(new Player[] { player }, "***Please use Tab-4 menu for campaign status when possible", new object[] { });
Tuple res = CalcMapMove("", false, true, player);
double newMapState = CampaignMapState + res.Item1 + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0;
summarizeCurrentMapstate(newMapState, true, player);
}
else
{
twcLogServer(new Player[] { player }, "Please use Tab-4 menu for campaign status", new object[] { });
}
}
{
{
twcLogServer(new Player[] { player }, "***Please use Tab-4 menu for campaign status when possible", new object[] { });
Tuple res = CalcMapMove("", false, false, player);
double score = res.Item1 * 100;
string mes = "Campaign score for this mission so far: ";
if (score > 0) mes += "Red +" + score.ToString("n0");
else if (score < 0) mes += "Blue +" + (-score).ToString("n0");
else mes += "A tie!";
twcLogServer(new Player[] { player }, mes, null);
double newMapState = CampaignMapState + res.Item1 + MissionObjectiveScore[ArmiesE.Red] / 100.0 - MissionObjectiveScore[ArmiesE.Blue] / 100.0;
summarizeCurrentMapstate(newMapState, true, player);
}
else
{
twcLogServer(new Player[] { player }, "Please use Tab-4 menu for campaign status", new object[] { });
}
}
{
twcLogServer(new Player[] { player }, "***Please use Tab-4-9 to take recon photos when possible", new object[] { });
MO_TakeScoutPhoto(player, player.Army());
}
{
MO_RecordPlayerScoutPhotos(player, check: true);
}
{
if (landinggroundmission != null) landinggroundmission.createTempLandingGround(player);
}
else if (msg.StartsWith("= 1)
{
if (landinggroundmission != null) landinggroundmission.createTempLandingGround(player, testing: true);
}
{
twcLogServer(new Player[] { player }, "1. Land on friendly or neutral territory, bring at least 2 friends", new object[] { });
twcLogServer(new Player[] { player }, "2. All aircraft must be in good condition - not too damaged - landed, and parked at or very near the airfield.", new object[] { });
twcLogServer(new Player[] { player }, "3. Must be at/near an unused airport/airfield/landing ground", new object[] { });
twcLogServer(new Player[] { player }, "4. Chat command = 1)
{
twcLogServer(new Player[] { player }, "HELP: Use command '= 1)
{
twcLogServer(new Player[] { player }, "HELP: Use command '= 2)
{
/*
* this checks if the plane is near or over enemy teritory
GamePlay.GamePlay.gpFrontDistance(int army, double x, double y);
returns a double that gives the distance to enemy front (if exist)
it returns 0 if you are over enemy teritory or the area you specify.
if you would know the distance to friendly teritory simply set for army the same army you are.
Before you should check with GamePlay.gpFrontExist() (returns bool) if a front (frontmarkers) exist.
public override void OnTickGame()
{
if (!OverEnemyTeritory && GamePlay.gpFrontDistance(1, PlayerPlane.Pos().x, PlayerPlane.Pos().y) <= 0)
{
GamePlay.gpHUDLogCenter("Sie befinden sich nun über Feindgebiet!");
OverEnemyTeritory = true;
}
else
{
OverEnemyTeritory = false;
}
If army==1 and you're in army 1 territory gpFrontDistance(1, will = 0. You would want gpFrontDistance(2, in that case
*/
if (GamePlay == null) return;
double playerFrontDistance_m = GamePlay.gpFrontDistance(player.Army(), player.Place().Pos().x, player.Place().Pos().y);
double playerFrontDistance2_m = GamePlay.gpFrontDistance(3 - player.Army(), player.Place().Pos().x, player.Place().Pos().y);
twcLogServer(new Player[] { player }, "Your distance from your front " + playerFrontDistance_m.ToString("N0") + " " + playerFrontDistance2_m.ToString("N0"), null);
}
else if (msg.StartsWith("= 2)
{
listPositionAllAircraft(player, player.Army(), false, radar_realism: 0);
Timeout(4, () =>
{
listPositionAllAircraft(player, player.Army(), true, radar_realism: 0);
});
}
else if (msg.StartsWith("= 2)
{
listPositionAllAircraft(player, player.Army(), false, radar_realism: 1);
Timeout(4, () =>
{
listPositionAllAircraft(player, player.Army(), true, radar_realism: 1);
});
}
else if (msg.StartsWith("= 2)
{
Dictionary airGroupInfoDict;
lock (airGroupInfoCircArr)
{
}
foreach (AiAirGroup ag in airGroupInfoDict.Keys)
{
Console.WriteLine(airGroupInfoDict[ag].ToString());
}
}
else if (msg.StartsWith("= 2)
{
Task.Run(() =>
{
listPositionAllAircraft(player, player.Army(), false, radar_realism: RADAR_REALISM);
}
else if (msg.StartsWith("= 2)
{
}
else if (msg.StartsWith("= 2)
{
Point3d? test = new Point3d(237074, 243644, 20000);
string[] words = msg_orig.Split(' ');
if (words.Length >= 3 && words[1].Length > 0 && words[2].Length > 0)
{
double x = Convert.ToInt32(words[1]);
double y = Convert.ToInt32(words[2]);
double z = 60000;
test = new Point3d(x, y, z);
}
MO_TakeScoutPhoto(player, player.Army(), 0, test);
}
else if (msg.StartsWith("= 2)
{
Point3d test = new Point3d(237074, 243644, 20000);
string[] words = msg_orig.Split(' ');
if (words.Length >= 3 && words[1].Length > 0 && words[2].Length > 0)
{
double x = Convert.ToInt32(words[1]);
double y = Convert.ToInt32(words[2]);
double z = 60000;
test = new Point3d(x, y, z);
}
Calcs.anyEnemyOrNeutralStationaries(GamePlay, test.x, test.y, 2000, player.Army());
}
else if (msg.StartsWith("= 2)
{
MO_RecordPlayerScoutPhotos(player, true, true);
}
else if (msg.StartsWith("= 2)
{
int army = random.Next(2) + 1;
string[] words = msg_orig.Split(' ');
if (words.Length >= 2 && words[1].Length > 0)
{
army = Convert.ToInt32(words[1]);
}
MO_CheckForGeneralStaffReconPhoto(player, null, army, new Point3d(0, 0, 0), testing: true);
}
else if (msg.StartsWith("= 2)
{
string l = MO_PlayersWhoScoutedObjectivesList("Red");
Console.WriteLine(l);
l = MO_PlayersWhoScoutedObjectivesList("Blue");
Console.WriteLine(l);
}
else if (msg.StartsWith("= 2)
{
twcLogServer(new Player[] { player }, "Destroying a random objective, then a random airport via MO_DestroyObjective. Note this doesn't work perfectly for all objective types ", new object[] { });
var objkeys = MissionObjectivesList.Keys.ToList();
string mokey = objkeys.ElementAt(random.Next(objkeys.Count));
MO_DestroyObjective(mokey, true);
Timeout(3, () =>
{
var apkeys = new List(AirfieldTargets.Keys.Count);
apkeys = AirfieldTargets.Keys.ToList();
string apID = apkeys.ElementAt(random.Next(apkeys.Count));
string aftarget = AirfieldTargets[apID].Item2;
twcLogServer(new Player[] { player }, "Destroying airport " + aftarget, new object[] { });
MO_DestroyObjective(aftarget + "_airfield", true, 2.2, 4 * 24 * 60 * 60, AirfieldDamagePoints: 290);
});
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
string sub = msg_orig.Substring(6).Trim();
if (words[0] == "= 2)
{
string[] words = msg_orig.Split(' ');
string sub = msg_orig.Substring(7).Trim();
string s = CLOD_PATH + FILE_PATH + "/sectionfiles/" + sub;
twcLogServer(new Player[] { player }, "Loading submission from subdirectory /sectionfiles/{0} \n{1}", new object[] { sub, s });
ISectionFile f = GamePlay.gpLoadSectionFile(s);
GamePlay.gpPostMissionLoad(f);
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
twcLogServer(new Player[] { player }, "Destroying all trigger-type objectives for {0} with enemy artillery. Note that this will not drop bombs to test the non-trigger type objectives ", new object[] { words[1], MissionObjectivesList[words[1]].Name });
MO_TestObjectiveWithFlak(MissionObjectivesList[words[1]], 4, 4);
}
else if (msg.StartsWith("= 2)
{
/*
string[] words = msg_orig.Split(' ');
twcLogServer(new Player[] { player }, "Destroying all trigger-type objectives for {0} with enemy artillery. Note that this will not drop bombs to test the non-trigger type objectives ", new object[] { words[1], MissionObjectivesList[words[1]].Name });
MO_TestObjectiveWithFlak(MissionObjectivesList[words[1]], 4, 4);
*/
string[] words = msg_orig.Split(' ');
string sub = msg_orig.Substring(7).Trim();
twcLogServer(new Player[] { player }, "Testing requested ID: {0}", new object[] { sub });
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Dropping bombs on {1}. Requested ID: {0}. Note: Only simulates counting up the results of bomb explosions within -main.cs. Won't destroy statics or do anything else internal to CloD ", new object[] { words[1], MissionObjectivesList[words[1]].Name });
AiDamageInitiator initiator = new AiDamageInitiator(player.Place(), player.PersonPrimary(), player, new AiDamageTool(AiDamageToolType.Ordance, "BrentBomb"));
int howmany = 60;
if (Calcs.GetAircraftType(player.Place() as AiAircraft).Contains("Blenheim")) howmany = 15;
for (int i = 1; i < howmany; i++)
{
Point3d pos = mo.Pos;
pos.x += random.Next(600) - 300;
pos.y += random.Next(600) - 300;
OnBombExplosion_DoWork("Bombe", 500, pos, initiator, 1);
}
}
else if (msg.StartsWith("= 2)
{
string objective = msg_orig.Substring(12).Trim();
twcLogServer(new Player[] { player }, "Places 4 flak guns near the objective, which will shoot/kill it. Good for testing trigger-type objectives, or PointArea. Combine with = 2)
{
string objective = msg_orig.Substring(7).Trim();
twcLogServer(new Player[] { player }, "Calling destroy_objective sperroutine for {0}", new object[] { objective });
if (objective.ToLower() == "red" || objective.ToLower() == "blue")
{
int currArmy = 1;
if (objective.ToLower() == "blue") currArmy = 2;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
string moKey = entry.Key;
if (!MissionObjectivesList.ContainsKey(moKey))
{
twcLogServer(new Player[] { player }, "Couldn't find Objective ID: {0}", new object[] { moKey });
return;
}
if (mo.AttackingArmy == currArmy && mo.IsPrimaryTarget)
{
MO_DestroyObjective(moKey, true);
}
}
}
else
{
twcLogServer(new Player[] { player }, "5", new object[] { });
if (!MissionObjectivesList.ContainsKey(objective))
{
twcLogServer(new Player[] { player }, "6", new object[] { });
twcLogServer(new Player[] { player }, "Couldn't find Objective ID: {0}", new object[] { objective });
return;
}
twcLogServer(new Player[] { player }, "7", new object[] { });
twcLogServer(new Player[] { player }, "Objective ID & Name: {0} {1}", new object[] { objective, MissionObjectivesList[objective].Name });
MO_DestroyObjective(objective, true);
}
}
else if (msg.StartsWith("= 2)
{
/*
string[] words = msg_orig.Split(' ');
twcLogServer(new Player[] { player }, "Destroying all trigger-type objectives for {0} with enemy artillery. Note that this will not drop bombs to test the non-trigger type objectives ", new object[] { words[1], MissionObjectivesList[words[1]].Name });
MO_TestObjectiveWithFlak(MissionObjectivesList[words[1]], 4, 4);
*/
string sub = msg_orig.Substring(9).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Dropping bombs on {1}. Requested ID: {0}. Note: Only simulates counting up the results of bomb explosions within -main.cs. Won't destroy statics or do anything else internal to CloD ", new object[] { sub, MissionObjectivesList[sub].Name });
AiDamageInitiator initiator = new AiDamageInitiator(player.Place(), player.PersonPrimary(), player, new AiDamageTool(AiDamageToolType.Ordance, "BrentBomb"));
int howmany = 60;
if (Calcs.GetAircraftType(player.Place() as AiAircraft).Contains("Blenheim")) howmany = 15;
for (int i = 1; i < howmany; i++)
{
Point3d pos = mo.Pos;
pos.x += random.Next(600) - 300;
pos.y += random.Next(600) - 300;
OnBombExplosion_DoWork("Bombe", 500, pos, initiator, 1);
}
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(11).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Restoring objective {1}. Requested ID: {0}.", new object[] { sub, MissionObjectivesList[sub].Name });
Timeout(2, () =>
{
twcLogServer(new Player[] { player }, "Now restoring/undestroying, {1} . . . ", new object[] { sub, MissionObjectivesList[sub].Name });
mo.Destroyed = true; mo.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(-0.25);
MO_ObjectiveUndestroy(null);
});
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(8).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Restoring airfield {1}. Requested ID: {0}. New spawn point should appear in 30 seconds.", new object[] { sub, MissionObjectivesList[sub].Name });
restoreAirfield(mo);
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(9).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Dropping bombs on, then restoring, {1}. Requested ID: {0}. Note: Only simulates counting up the results of bomb explosions within -main.cs. Won't destroy statics or do anything else internal to CloD ", new object[] { sub, MissionObjectivesList[sub].Name });
AiDamageInitiator initiator = new AiDamageInitiator(player.Place(), player.PersonPrimary(), player, new AiDamageTool(AiDamageToolType.Ordance, "BrentBomb"));
int howmany = 120;
if (Calcs.GetAircraftType(player.Place() as AiAircraft).Contains("Blenheim")) howmany = 30;
for (int i = 1; i < howmany; i++)
{
Point3d pos = mo.Pos;
pos.x += random.Next(600) - 300;
pos.y += random.Next(600) - 300;
OnBombExplosion_DoWork("Bombe", 500, pos, initiator, 1);
}
Timeout(120, () =>
{
twcLogServer(new Player[] { player }, "Now restoring/undestroying, {1} . . . ", new object[] { sub, MissionObjectivesList[sub].Name });
mo.Destroyed = true; mo.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(-0.25);
MO_ObjectiveUndestroy(null);
});
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(5).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Calling DestroyObjective() for {1}.", new object[] { MissionObjectivesList[sub].Name });
MO_DestroyObjective(mo.ID);
}
else if (msg.StartsWith("= 2)
{
/*
string[] words = msg_orig.Split(' ');
twcLogServer(new Player[] { player }, "Destroying all trigger-type objectives for {0} with enemy artillery. Note that this will not drop bombs to test the non-trigger type objectives ", new object[] { words[1], MissionObjectivesList[words[1]].Name });
MO_TestObjectiveWithFlak(MissionObjectivesList[words[1]], 4, 4);
*/
string sub = msg_orig.Substring(9).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
MissionObjective mo1 = MissionObjectivesList[sub];
twcLogServer(new Player[] { player }, "Killing all actors we can find near {0} {1} and any actors anywhere with the 'Chief' name '{2}'. This helps with testing trigger & pointarea type objectives. You may need to ALSO 0) kabnm = Calcs.KillActorsByNameMatch(gpBattle, GamePlay, this, AllActorsDict, mo1.ChiefName);
kgan = Calcs.KillGroundActorsNear(gpBattle, GamePlay, this, AllActorsDict, mo1.returnCurrentPosWithChief(), 3000);
twcLogServer(new Player[] { player }, "Killed {0} actors by match with name {1} and {2} actors near the objectives {3} ", new object[] { kabnm, mo1.ChiefName, kgan, mo1.Name });
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(10).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
twcLogServer(new Player[] { player }, "Launching the Defense Units air response for: {0}", new object[] { sub });
mo.defenseUnitsAttackResponse();
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(6).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
mo.addDefenseUnits(11);
twcLogServer(new Player[] { player }, "Added 11 Defense Units for {0}. Total DUs now {1}", new object[] { sub, mo.numDefenseUnits(), mo.defenseUnitsHelpFactor() });
}
else if (msg.StartsWith("= 2)
{
string sub = msg_orig.Substring(7).Trim();
MissionObjective mo = null;
if (sub.Length > 1 && MissionObjectivesList.ContainsKey(sub)) mo = MissionObjectivesList[sub];
else
{
twcLogServer(new Player[] { player }, "Couldn't find that one. Requested ID: {0}", new object[] { sub });
return;
}
mo.DestroyedPercent -= 0.5;
twcLogServer(new Player[] { player }, "Subtracted 50% destruction from {0}. Current destroyed percent: {1:F0}", new object[] { sub, mo.DestroyedPercent*100 });
}
else if (msg.StartsWith("= 2)
{
if (!resetmission_requested)
{
resetmission_requested = true;
Timeout(30, () => { resetmission_requested = false; });
twcLogServer(new Player[] { player }, "CONFIRMATION REQUIRED!!!!!! To reset all current mission objectives for both sides, objectives scouted, re-read mission objectives afresh, current team scores, enter (MissionObjectivesList);
mission_objectives.RadarPositionTriggersSetup();
mission_objectives.MissionObjectiveTriggersSetup();
mission_objectives.LandingGroundTransferObjectives(MissionObjectivesList_OLD);
MO_SelectPrimaryObjectives(1, 0, fresh: true);
MO_SelectPrimaryObjectives(2, 0, fresh: true);
mission_objectives.SelectSuggestedObjectives(ArmiesE.Blue);
mission_objectives.SelectSuggestedObjectives(ArmiesE.Red);
MissionObjectiveScore[ArmiesE.Red] = 0;
MissionObjectiveScore[ArmiesE.Blue] = 0;
MissionObjectivesCompletedString[ArmiesE.Red] = "";
MissionObjectivesCompletedString[ArmiesE.Blue] = "";
}
else if (msg.StartsWith("= 2)
{
MO_MissionObjectiveRollingWinnerHandler(ArmiesE.Red);
}
else if (msg.StartsWith("= 2)
{
MO_MissionObjectiveRollingWinnerHandler(ArmiesE.Blue);
}
else if (msg.StartsWith("= 2)
{
Point3d p = new Point3d(284703, 125257, 0);
double r = 9000;
string[] words = msg_orig.Split(' ');
if (words.Length > 1)
{
p = new Point3d(Convert.ToDouble(words[1]), Convert.ToDouble(words[2]), 0);
r = Convert.ToDouble(words[3]);
}
removeSmokeFireCraters(p, r);
}
else if (msg.StartsWith("= 1)
{
panicRating = 100;
string[] words = msg_orig.Split(' ');
if (words.Length > 1)
{
int p = Convert.ToInt32(words[1]);
panicRating = p;
}
twcLogServer(new Player[] { player }, "PANIC LEVEL set to {0}. Level 100=all possible CPU-eating options disabled; Level 0=normal operation.", new object[] { panicRating });
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
if (words.Length > 1)
{
int p = Convert.ToInt32(words[1]);
testTempFlakNumPilots = p;
}
twcLogServer(new Player[] { player }, "Flak Pilots TEST level set to {0}. TempFlak will act as though {0} live pilots were online.", new object[] { testTempFlakNumPilots });
twcLogServer(new Player[] { player }, "To disable: = 2)
{
Point3d p = new Point3d(284703, 125257, 0);
double r = 9000;
string[] words = msg_orig.Split(' ');
Calcs.listStatics(GamePlay, new List() { "smoke", "fire", "crater", "jerry" });
}
else if (msg.StartsWith("= 2)
{
Point3d pos = new Point3d(10000, 100000, 0);
if (player.Place() != null) pos = player.Place().Pos();
Calcs.loadSmokeOrFire(GamePlay, this, pos.x + random.Next(100) + 10, pos.y + random.Next(100) + 10, 0, "BuildingFireBig", duration_s: 6 * 3600);
Calcs.loadSmokeOrFire(GamePlay, this, pos.x + random.Next(100) + 10, pos.y + random.Next(100) + 10, 0, "BuildingFireSmall", duration_s: 6 * 3600);
Calcs.loadSmokeOrFire(GamePlay, this, pos.x + random.Next(100) + 10, pos.y + random.Next(100) + 10, 0, "Smoke1", duration_s: 6 * 3600);
}
else if (msg.StartsWith("= 2)
{
AiAirport ap = Calcs.nearestAirport(GamePlay, player.Place().Pos(), player.Army());
AirfieldDisable(ap, 1);
twcLogServer(null, "Destroying the airport nearest where you are currently located: " + (ap as AiActor).Name());
}
else if (msg.StartsWith("= 2)
{
}
/*
Timeout(0.1, () => twcLogServer(new Player[] { player }, "***Schematic Map Overview of Enemy Activity***", null));
Timeout(0.1, () => twcLogServer(new Player[] { player }, "Airgroups:Aircraft in each Large Map Keypad area", null));
Timeout(0.1, () => twcLogServer(new Player[] { player }, "For more details, ask your Commander or Radar Operator to consult the Contact Plotting Table: ", null));
Timeout(0.1, () =>
{
for (int i = 2; i > -1; i--)
{
twcLogServer(new Player[] { player }, "{0:D3}:{1:D3} {2:D3}:{3:D3} {4:D3}:{5:D3} ", new object[] {
GiantSectorOverview[player.Army()][i*3+1, 0], GiantSectorOverview[player.Army()][i*3+1, 1],
GiantSectorOverview[player.Army()][i*3+2, 0], GiantSectorOverview[player.Army()][i*3+2, 1],
GiantSectorOverview[player.Army()][i*3+3, 0], GiantSectorOverview[player.Army()][i*3+3, 1]
});
}
});
*/
}
else if (msg.StartsWith("= 2)
{
}
else if (msg.StartsWith("= 2)
{
ListRadarTargetDamage(player, -1);
Timeout(2, () => { ListAirfieldTargetDamage(player, -1); });
}
else
{
twcLogServer(new Player[] { player }, "Please use Tab-4 menu to check airport status", new object[] { });
}
}
else if (msg.StartsWith("= 2)
{
string tr = msg_orig.Substring(7).Trim();
SERVER_ID_SHORT = tr;
twcLogServer(new Player[] { player }, "Server renamed to " + tr + " for the remainder of this session.", new object[] { });
}
else if (msg.StartsWith("= 2)
{
double old_CampaignMapState = CampaignMapState;
string tr = msg_orig.Substring(12).Trim();
string[] words = msg_orig.Split(' ');
if (words.Length < 2) twcLogServer(new Player[] { player }, "= 3 && words[2] == "do") CampaignMapState = new_cms;
else twcLogServer(new Player[] { player }, "= 2)
{
string tr = msg_orig.Substring(8).Trim();
twcLogServer(new Player[] { player }, "Trying to activate trigger " + tr, new object[] { });
if (GamePlay.gpGetTrigger(tr) != null)
{
GamePlay.gpGetTrigger(tr).Enable = true;
twcLogServer(new Player[] { player }, "Enabled trigger " + tr, new object[] { });
}
Battle.OnEventGame(GameEventId.Trigger, tr, true, 1);
/*
AiAction action = GamePlay.gpGetAction("action1");
if (action != null)
{
action.Do();
}
*/
}
else if (msg.StartsWith("= 2)
{
string tr = msg_orig.Substring(7).Trim();
AiAction action = GamePlay.gpGetAction(tr);
if (action != null)
{
action.Do();
twcLogServer(new Player[] { player }, "Activating action " + tr, new object[] { });
}
else
{
twcLogServer(new Player[] { player }, "Didn't find action " + tr + "! No action taken.", new object[] { });
}
}
else if (msg.StartsWith("= 2)
{
var players = new Player[] { };
if (player != null)
{
players = new Player[] { player };
double alt = Calcs.AltitudeAGL_m(player.Place().Pos());
double elev = twcLandscape.HQ(player.Place().Pos().x, player.Place().Pos().y);
twcLogServer(players, "Altitude: " + zAlt_m.ToString() + " " + alt.ToString() + " " + elev.ToString(), new object[] { });
}
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Replace(",", "").Replace(")", "").Replace("(", "").Split(' ');
int X = Convert.ToInt32(words[1]);
int Y = Convert.ToInt32(words[2]);
int i2X = Convert.ToInt32(X) / 10000;
int i2Y = Convert.ToInt32(Y) / 10000;
int ct = twcLandscape.getBuildingCountInBlock(i2X, i2Y);
Console.WriteLine("Bldg count in block {0:F0}, {1:F0} ({3},{4}): {2}", X, Y, ct, i2X, i2Y);
int gridsize = 32;
int[] saver = new int[gridsize * gridsize];
for (int intx = 0; intx < gridsize; intx++)
for (int inty = 0; inty < gridsize; inty++)
{
int iX = X + 313 * intx;
int iY = Y + 313 * inty;
int num = Calcs.numBuildingsInSector(iX, iY);
saver[intx + gridsize * inty] = num;
}
for (int intx = 0; intx < gridsize; intx++)
{
for (int inty = gridsize - 1; inty >= 0; inty--)
Console.Write("{0} ", saver[intx + gridsize * inty]);
Console.WriteLine();
}
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
int iX = Convert.ToInt32(words[1]);
int iY = Convert.ToInt32(words[2]);
int MinX, MinY, MaxX, MaxY;
int ret = twcLandscape.twcgetMinMax(out MinX, out MinY, out MaxX, out MaxY);
Console.WriteLine("getMinMax: {0} {1} {2} {3} & {4}", MinX, MinY, MaxX, MaxY, ret);
int X = twcLandscape.twcgetSizeX();
int Y = twcLandscape.twcgetSizeY();
int ct = 0;
if (iX > -1 && iY > -1 && iX < 45 && iY < 39)
{
ct = twcLandscape.getBuildingCountInBlock(iX, iY);
Console.WriteLine("getSizeX: {0} getSizeY: {1}; Bldg count in block {3}, {4}: {2}", X, Y, ct, iX, iY);
int[] blockOffset;
int blockCount;
int[] codes;
int codeslength;
int ct2 = twcLandscape.getBuildingBlocks(iX, iY, out blockOffset, out blockCount, out codes, out codeslength);
Console.WriteLine("X: {0} Y: {1}; BlockCount {2}, codeslength {3}, returnvalue: {4}.", iX, iY, blockCount, codeslength, ct2);
for (int i = 0; i < blockOffset.Length; i++)
{
if (i % 32 == 0) Console.Write("\n");
Console.Write("{0}\t", blockOffset[i]);
}
Console.WriteLine();
Console.WriteLine("codes: {0}", String.Join(" ", codes));
}
else Console.WriteLine("Bldg count in block {3}, {4}: Must be between 0,0 and 44,38 - or PROTECTED MEMORY ERROR", X, Y, ct, iX, iY);
}
else if (msg.StartsWith("= 2)
{
int nump = Calcs.gpNumberOfPlayers(GamePlay);
twcLogServer(new Player[] { player }, "stopAI: " + nump.ToString() + " players currently online", new object[] { });
}
else if (msg.StartsWith("= 2)
{
TWCComms.Communicator.Instance.WARP_CHECK = !TWCComms.Communicator.Instance.WARP_CHECK;
twcLogServer(new Player[] { player }, "WARP_CHECK is set to " + TWCComms.Communicator.Instance.WARP_CHECK.ToString(), new object[] { });
}
else if (msg.StartsWith("= 2)
{
twcLogServer(new Player[] { player }, "End test complete savemapstate", new object[] { });
}
else if (msg.StartsWith("= 2)
{
DEBUG = true;
twcLogServer(new Player[] { player }, "Debug is on", new object[] { });
}
else if (msg.StartsWith("= 2)
{
DEBUG = false;
twcLogServer(new Player[] { player }, "Debug is off", new object[] { });
}
else if (msg.StartsWith("= 2)
{
LOG = true;
twcLogServer(new Player[] { player }, "Log is on", new object[] { });
}
else if (msg.StartsWith("= 2)
{
LOG = false;
twcLogServer(new Player[] { player }, "Log is off", new object[] { });
}
else if (msg.StartsWith("= 2)
{
if (EndMissionSelected == false)
{
EndMissionSelected = true;
twcLogServer(new Player[] { player }, "ENDING MISSION!! If you want to cancel the End Mission command, use
{
if (EndMissionSelected)
{
EndMission(0);
}
else
{
twcLogServer(new Player[] { player }, "End Mission CANCELLED; Mission continuing . . . ", new object[] { });
twcLogServer(new Player[] { player }, "If you want to end the mission, you can use the menu to select Mission End again now.", new object[] { });
}
});
}
else
{
twcLogServer(new Player[] { player }, "End Mission CANCELLED; Mission will continue", new object[] { });
EndMissionSelected = false;
}
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
int iter = 100000;
if (words.Length > 1) iter = Convert.ToInt32(words[1]) * 100000;
Console.Write("starting stress test, {0} iterations, no new thread...", iter);
stressTest(iter);
}
else if (msg.StartsWith("= 2)
{
string[] words = msg_orig.Split(' ');
int iter = 100000;
if (words.Length > 1) iter = Convert.ToInt32(words[1]) * 100000;
Console.WriteLine("starting stress test, {0} iterations, new thread...", iter);
Task.Run(() =>
{
Thread thr = Thread.CurrentThread;
thr.Name = "stresstest";
Console.WriteLine("Stress test, thread name: {0}", thr.Name);
thr.Priority = ThreadPriority.BelowNormal;
stressTest(iter);
});
}
else if (msg.StartsWith("= 2)
{
var radar_messages = new Dictionary {
{ "1", "YOU TYPED
{
gpLogServerAndLog(new Player[] { player }, mess.Value, null);
});
}
}
else if (msg.StartsWith("= 2)
{
twcLogServer(new Player[] { player }, "Admin commands:
{
string m = "Commands: = 2) m += ";
//////////////////////////////////////////////////////////////////////////////////////////////////// // destroys aircraft abandoned by a player.
{
DateTime currTime = DateTime.UtcNow;
for (int i = 1; i < iterations; i++)
{
Point3d pos = new Point3d(random.Next(10000, 310000), random.Next(10000, 310000), random.Next(10, 10000));
int terr = GamePlay.gpFrontArmy(pos.x, pos.y);
maddox.game.LandTypes landType = GamePlay.gpLandType(pos.x, pos.y);
}
double timediff_s = DateTime.UtcNow.Subtract(currTime).Seconds;
Console.Write("Finished stress test - {0:n6} seconds...", timediff_s);
}
/****************************************
* END - CHAT COMMANDS
* **************************************/
private bool isAiControlledPlane(AiAircraft aircraft)
{
if (aircraft == null)
{
return false;
}
Player[] players = GamePlay.gpRemotePlayers();
foreach (Player p in players)
{
if (p != null && (p.Place() is AiAircraft) && (p.Place() as AiAircraft) == aircraft)
{
return false;
}
}
return true;
}
private void destroyPlane(AiAircraft aircraft)
{
if (aircraft != null)
{
Timeout (0.1, () => aircraft.Destroy());
}
}
private void explodeFuelTank(AiAircraft aircraft)
{
if (aircraft != null)
{
aircraft.hitNamed(part.NamedDamageTypes.FuelTank0Exploded);
}
}
private void destroyAiControlledPlane(AiAircraft aircraft)
{
if (isAiControlledPlane2(aircraft))
{
destroyPlane(aircraft);
}
}
private void damageAiControlledPlane(AiActor actor)
{
if (actor == null || !(actor is AiAircraft))
{
return;
}
AiAircraft aircraft = (actor as AiAircraft);
if (!isAiControlledPlane2(aircraft))
{
return;
}
if (aircraft == null)
{
return;
}
aircraft.hitNamed(part.NamedDamageTypes.ControlsElevatorDisabled);
aircraft.hitNamed(part.NamedDamageTypes.ControlsAileronsDisabled);
aircraft.hitNamed(part.NamedDamageTypes.ControlsRudderDisabled);
aircraft.hitNamed(part.NamedDamageTypes.FuelPumpFailure);
aircraft.hitNamed(part.NamedDamageTypes.Eng0TotalFailure);
aircraft.hitNamed(part.NamedDamageTypes.ElecPrimaryFailure);
aircraft.hitNamed(part.NamedDamageTypes.ElecBatteryFailure);
aircraft.hitLimb(part.LimbNames.WingL1, -0.5);
aircraft.hitLimb(part.LimbNames.WingL2, -0.5);
aircraft.hitLimb(part.LimbNames.WingL3, -0.5);
aircraft.hitLimb(part.LimbNames.WingL4, -0.5);
aircraft.hitLimb(part.LimbNames.WingL5, -0.5);
aircraft.hitLimb(part.LimbNames.WingL6, -0.5);
aircraft.hitLimb(part.LimbNames.WingL7, -0.5);
int iNumOfEngines = (aircraft.Group() as AiAirGroup).aircraftEnginesNum();
for (int i = 0; i < iNumOfEngines; i++)
{
aircraft.hitNamed((part.NamedDamageTypes)Enum.Parse(typeof(part.NamedDamageTypes), "Eng" + i.ToString() + "TotalFailure"));
}
/***Timeout (240, () =>
{explodeFuelTank (aircraft);}
);
* ***/
Timeout(300, () =>
{ destroyPlane(aircraft); }
);
}
double cloudHeight = 1000;
missionFile = Regex.Replace(missionFile, @"^\s*TIME\s*\d*\.?\d*\s*$", desiredString, ro);//looks for a line with something like
{
try
{
RegexOptions ro = RegexOptions.IgnoreCase | RegexOptions.Multiline;
cloudHeight = random.Next(500, 1500);
string desiredWeatherIndexString = " WeatherIndex " + WeatherIndex.ToString("F0");
return missionFile;
}
catch (Exception ex)
{
Console.WriteLine("updateweather ERROR: " + ex.Message);
return missionFile;
};
}
Dictionary WindsAloft_red = new Dictionary();
Dictionary WindsAloft_blue = new Dictionary();
Dictionary WindsAloftCalc_red = new Dictionary();
Dictionary WindsAloftCalc_blue = new Dictionary();
//printing the linds from the wind layers calculation //double oldAlt = -3000 //Do this one @ beginning of mission
{
var WA = WindsAloft_red;
if (army==2) WA = WindsAloft_blue;
if (calc)
{
WA = WindsAloftCalc_red;
if (army == 2) WA = WindsAloftCalc_blue;
}
double delay = 0;
string nl = Environment.NewLine;
string msg = "";
string newmsg1 = "";
if (player != null) {
newmsg1 = "Winds aloft:";
Timeout(delay, () => { twcLogServer(new Player[] { player }, newmsg1); });
delay += 0.02;
}
int count = 1;
foreach (int alt in WA.Keys)
{
count++;
if ( (count - 1) % delta != 0) continue;
msg += WA[alt] + nl;
if (player != null) Timeout(delay, ()=> { twcLogServer(new Player[] { player }, WA[alt]); });
delay += 0.02;
}
return msg;
}
//var WA = WindsAloft_red; //if (army == 2) WA = WindsAloft_blue; //double oldAlt = -3000 //Timeout(delay, () => { twcLogServer(new Player[] { player }, newmsg1); }); // delay += 0.02; //if (i == 0) alt_m = 5; //bool res = maddox.core.WWeather.windGetStatisticalWindOnHeight(alt_m, out v3d); //bool res = twcWeather.twc_windGetStatisticalWindOnHeight(alt_m, out v3d); //these don't work - just return 0. Not sure why: //double temp = mcWW.weatherAskTemperatureOnHeight(alt_m); //float vis = mcWW.weatherAskVisibilityOnHeight((float)alt_m); //public bool windGetStatisticalWindOnHeight(double dHeight, out maddox.GP.Vector3d v3d) //new List
{
int delta = 1;
double delay = 0;
string msg = "";
string oldLine_red = "";
string oldLine_blue = "";
string newmsg1 = "Winds aloft:";
msg += newmsg1 + Environment.NewLine;
for (int i = 0; i < 15000; i += 100)
{
double alt_m = i;
var v3d = new maddox.GP.Vector3d();
bool res = mcWW.windGetStatisticalWindOnHeight(alt_m, out v3d);
string newmsg2 = "";
if (res)
{
double hdg_deg = Calcs.CalculateGradientAngle(v3d, new Vector3d(0, 0, 0));
double vel_mps = Calcs.CalculatePointDistance(v3d);
/*
newmsg2 = String.Format("{2:F0}ft: Wind from {0:F0} deg {1:F0} mph. Temperature: {3:f0}f. Visibility: {4:f1} miles", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(Calcs.meters2feet(alt_m), 500), Calcs.Celsius2Fahrenheit(temp), Calcs.meters2miles(vis));
if (army == 2) newmsg2 = String.Format("{2:F0}m: Wind from {0:F0} deg {1:F0} mph. Temperature: {3:f0}C. Visibility: {4:f1}km", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(alt_m, 100),temp, vis/1000);
*/
string newLine_red = String.Format("Wind from {0:F0} deg {1:F0} mph.", hdg_deg, Calcs.meterspsec2milesphour(vel_mps), Calcs.RoundInterval(Calcs.meters2feet(alt_m), 100));
string line_red = String.Format("{2:F0}ft: Wind from {0:F0} deg {1:F0} mph.", hdg_deg, Calcs.meterspsec2milesphour(vel_mps), Calcs.RoundInterval(Calcs.meters2feet(alt_m), 100));
if (newLine_red != oldLine_red) WindsAloft_red[i] = line_red;
oldLine_red = newLine_red;
string newLine_blue = String.Format("Wind from {0:F0} deg {1:F0} kph.", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(alt_m, 100));
string line_blue = String.Format("{2:F0}m: Wind from {0:F0} deg {1:F0} kph.", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(alt_m, 100));
if (newLine_blue != oldLine_blue) WindsAloft_blue[i] = line_blue;
oldLine_blue = newLine_blue;
}
}
}
maddox.core.WWeather mcWW = new maddox.core.WWeather();
new List windlayer_alts = new List() { 0, 200, 300,500, 1000,2000, 3000,4000, 6500, 8000, 10000, 15000 };
//var WA = WindsAloft_red; //if (army == 2) WA = WindsAloft_blue; //double oldAlt = -3000 //if (i == 0) alt_m = 5; //bool res = maddox.core.WWeather.windGetStatisticalWindOnHeight(alt_m, out v3d); //bool res = twcWeather.twc_windGetStatisticalWindOnHeight(alt_m, out v3d); //these don't work - just return 0. Not sure why: //double temp = mcWW.weatherAskTemperatureOnHeight(alt_m); //float vis = mcWW.weatherAskVisibilityOnHeight((float)alt_m);
{
if (delta<1) delta = 1;
double delay = 0;
string msg = "";
string newmsg1 = "Winds aloft:";
msg += newmsg1 + Environment.NewLine;
Timeout(delay, () => { twcLogServer(new Player[] { player }, newmsg1); });
delay += 0.02;
for (int i = 0; i < windlayer_alts.Count; i += delta)
{
double alt_m = windlayer_alts[i];
var v3d = new maddox.GP.Vector3d();
bool res = mcWW.windGetStatisticalWindOnHeight(alt_m, out v3d);
string newmsg2 = "";
if (res)
{
double hdg_deg = Calcs.CalculateGradientAngle(v3d, new Vector3d(0,0,0));
double vel_mps = Calcs.CalculatePointDistance(v3d);
/*
newmsg2 = String.Format("{2:F0}ft: Wind from {0:F0} deg {1:F0} mph. Temperature: {3:f0}f. Visibility: {4:f1} miles", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(Calcs.meters2feet(alt_m), 500), Calcs.Celsius2Fahrenheit(temp), Calcs.meters2miles(vis));
if (army == 2) newmsg2 = String.Format("{2:F0}m: Wind from {0:F0} deg {1:F0} mph. Temperature: {3:f0}C. Visibility: {4:f1}km", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(alt_m, 100),temp, vis/1000);
*/
newmsg2 = String.Format("{2:F0}ft: Wind from {0:F0} deg {1:F0} mph.", hdg_deg, Calcs.meterspsec2milesphour(vel_mps), Calcs.RoundInterval(Calcs.meters2feet(alt_m), 500));
if (army == 2) newmsg2 = String.Format("{2:F0}m: Wind from {0:F0} deg {1:F0} kph.", hdg_deg, Calcs.meterspsec2kmphour(vel_mps), Calcs.RoundInterval(alt_m, 100));
}
else newmsg2 = String.Format("No wind/weather information for {0:F0} m", Calcs.RoundInterval(alt_m, 1000));
msg += newmsg2 + Environment.NewLine;
delay += 0.02;
Timeout(delay, () =>
{
twcLogServer(new Player[] { player }, newmsg2);
});
}
return msg;
}
//synchronize one of the layers with the bottom of the cloud layer //choose general wind direction in proportion to those usually found in the channel area //June-Oct //Wind in UK & FR is generally from the west, southwest, south //More precisely, per https://weatherspark.com/d/150362/9/12/Average-Weather-on-September-12-in-Isle-of-Wight-United-Kingdom#Figures-WindDirection on average in months June-Oct // 39% west (7 22 10), 21% south (10 7 4), 22% east (5 12 5), 18% north (4 10 4) // Just to even it up a LITTLE say 35% west (7 20 8), 21% south (10 7 4), 22% east (5 12 5), 22% north (5 12 5) (dividing N into NNE, N, NNW - etc) //heading, weight //winddir at altitude is usually a bit different from ground, and typically winddir //proceeds counterclockwise as it goes down in altitude. It can be (rarely) as far as 270 deg //from jetstream to sea level...
{
try
{
double gwl_cloudHeight = 0;
if (cloudHeight >= 500 && cloudHeight <= 1500) gwl_cloudHeight = cloudHeight;
var winDirWeights = new Dictionary()
{
{0, 12 },
{45, 10 },
{90, 12},
{135, 9 },
{180, 7 },
{225, 18 },
{270, 20 },
{315, 12 }
};
int sumWeight = winDirWeights.Values.Sum();
double windir_main = 0;
int windir_choice = random.Next(0, sumWeight);
int sum = 0;
foreach(double d in winDirWeights.Keys)
{
sum += winDirWeights[d];
if (sum > windir_choice) { windir_main = d; break; }
}
double windir_alt_hdg_deg = windir_main + (random.NextDouble() - 0.5) * 45;
if (windir_alt_hdg_deg < 0) windir_alt_hdg_deg += 360;
int leftOrRight = random.Next(2);
double windir_adder_deg = 30 + (random.NextDouble() * random.NextDouble() * random.NextDouble()) * 225 * (leftOrRight) - (random.NextDouble() * random.NextDouble() * random.NextDouble()) * 90 * (1 - leftOrRight);
double windir_gnd_hdg_deg = windir_alt_hdg_deg - windir_adder_deg;
if (lowlevel_wind_REAL_vel_mps < 0) lowlevel_wind_REAL_vel_mps = 0;
double surface_wind_vel_mps = lowlevel_wind_REAL_vel_mps / 3.5;
{
surface_wind_vel_mps = lowlevel_wind_REAL_vel_mps / 2;
if (surface_wind_vel_mps > 5.5) surface_wind_vel_mps = 5.5;
}
double highlevel_wind_vel_kt = 1 + random.NextDouble() * 100;
if (highlevel_wind_vel_kt <= 41 && highlevel_wind_vel_kt < Calcs.meterspsec2knots(lowlevel_wind_REAL_vel_mps)) highlevel_wind_vel_kt = Calcs.meterspsec2knots(lowlevel_wind_REAL_vel_mps) + random.Next(-1, 5);
if (highlevel_wind_vel_kt < 1) highlevel_wind_vel_kt = 1;
if (ON_JUBILEE && highlevel_wind_vel_kt >22)
{
Console.WriteLine("GenerateWindLayers: Clamping top speed to 22kt for {0:F3} more days", -DateTime.UtcNow.Subtract((new DateTime(2023, 01, 13, 23, 59, 0)).ToUniversalTime()).TotalDays);
highlevel_wind_vel_kt = 22;
}
double highlevel_wind_vel_mps = Calcs.knots2meterspsec(highlevel_wind_vel_kt);
double windir_xy_rad_elev = windir_xy_rad;
double bottomBound = 0;
string nl = Environment.NewLine;
string s = "";
s += "[GlobalWind_0]" + nl;
s += String.Format(" Power {0:F3} {1:F3} 0.000" + nl, surface_wind_vel_mps * Math.Cos(windir_xy_rad), surface_wind_vel_mps * Math.Sin(windir_xy_rad));
s += String.Format(" BottomBound {0:F0}" + nl, bottomBound);
s += String.Format(" TopBound {0:F0}" + nl, topBound);
s += " GustAngle 0" + nl;
WindsAloftCalc_red[0] = String.Format("{0:F0} deg {1:F0} mph at {2:F0}", windir_gnd_hdg_deg, Calcs.meterspsec2milesphour(surface_wind_vel_mps), "sea level");
WindsAloftCalc_blue[0] = String.Format("{0:F0} deg {1:F0} kph at {2:F0}", windir_gnd_hdg_deg, Calcs.meterspsec2kmphour (surface_wind_vel_mps), "sea level");
int maxi = 9;
bool cloudcatch = false;
for (int i = 1; i <= maxi; i++)
{
double oldTopBound = topBound;
if (i < maxi - 1 && !cloudcatch && bottomBound < gwl_cloudHeight + 10 && topBound + 500 > gwl_cloudHeight && gwl_cloudHeight > oldTopBound)
{
topBound = gwl_cloudHeight + 10 + random.Next(-30, 30);
cloudcatch = true;
}
if (topBound < bottomBound + 100) topBound = bottomBound + 200;
double windbasis = (highlevel_wind_vel_mps - lowlevel_wind_vel_mps) * i / (double)maxi + lowlevel_wind_vel_mps;
if (i == 1 && wind_vel_mps > surface_wind_vel_mps && wind_vel_mps - surface_wind_vel_mps > 3.5) wind_vel_mps = surface_wind_vel_mps + 3.5;
double dirbasis_deg = (windir_alt_hdg_deg - windir_gnd_hdg_deg) * i / (double)maxi + windir_gnd_hdg_deg;
double dir_variability = 20 * Math.Pow((maxi - i) / (double)maxi, 1.3) * (random.Next(2)*2 -2);
double windir_curralt_xy_rad = Calcs.DegreesToRadians(270 - windir_curralt_hdg_deg);
double gustpow = 0;
double gustangle = 0;
bool turb = false;
/*
if (i >= 6 && i < maxi && random.Next(30) == 0)
{
topBound = bottomBound + 200 + random.Next(40);
windir_xy_rad_elev += Math.PI + random.NextDouble() * 0.05;
z = random.NextDouble() * 5 + 5;
turb = true;
}*/
s += String.Format("[GlobalWind_{0}]" + nl, i);
s += String.Format(" Power {0:F3} {1:F3} {2:F3}" + nl, wind_vel_mps * Math.Cos(windir_curralt_xy_rad), wind_vel_mps * Math.Sin(windir_curralt_xy_rad), z);
s += String.Format(" BottomBound {0:F0}" + nl, bottomBound);
s += String.Format(" TopBound {0:F0}" + nl, topBound);
s += String.Format(" GustAngle {0:F0}" + nl, gustangle);
WindsAloftCalc_red[Convert.ToInt32(bottomBound)] = String.Format("{0:F0} deg {1:F0} mph at {2:F0}", windir_curralt_hdg_deg, Calcs.meterspsec2milesphour(wind_vel_mps), Calcs.RoundInterval(Calcs.meters2feet((bottomBound)), 100 ));
WindsAloftCalc_blue[Convert.ToInt32(bottomBound)] = String.Format("{0:F0} deg {1:F0} kph at {2:F0}", windir_curralt_hdg_deg, Calcs.meterspsec2kmphour(wind_vel_mps), Calcs.RoundInterval((bottomBound) , 100));
}
if (ON_TESTSERVER)
{
Console.WriteLine(s);
Console.WriteLine(listWindLayers(null, 1, 1, calc: true)); ;
Console.WriteLine( listWindLayers(null, 2, 1, calc: true));
}
return s;
}
catch (Exception ex)
{
Console.WriteLine("***** GenerateWindlayers ERROR: " + ex.Message);
return "[GlobalWind_0]" + Environment.NewLine;
}
}
static Dictionary RedBombers = new Dictionary() { { "bob:Aircraft.BlenheimMkIV", 10 }, { "bob:Aircraft.BlenheimMkIV_Late", 10 } };
static Dictionary RedBombers3 = new Dictionary() {
{"bob:Aircraft.HurricaneMkI_FB", 30},
{ "tobruk:Aircraft.HurricaneMkIIb", 20 },
{ "tobruk:Aircraft.HurricaneMkIIb-Late", 10 },
{ "tobruk:Aircraft.HurricaneMkIIc", 15 },
{ "tobruk:Aircraft.HurricaneMkIIc-Late", 5 },
};
static Dictionary BlueBombers = new Dictionary() {
{ "bob:Aircraft.He-111H-2", 10 },
{ "bob:Aircraft.He-111H-6", 10 },
{"tobruk:Aircraft.Ju-88A-5",6},
{"tobruk:Aircraft.Ju-88A-5Late",4},
};
static Dictionary BlueBombers2 = new Dictionary() {
{ "bob:Aircraft.He-111P-2", 10 },
{"bob:Aircraft.Ju-88A-1", 12 },
};
static Dictionary BlueDO215_BR20 = new Dictionary() {
{ "bob:Aircraft.Do-215B-1", 10 },
{ "bob:Aircraft.BR-20M", 10 },
{"bob:Aircraft.Ju-87B-2", 7},
static Dictionary BlueE4s = new Dictionary() {
{ "bob:Aircraft.Bf-109E-4N_Late", 30 },
{ "bob:Aircraft.Bf-109E-4N", 20 },
{ "bob:Aircraft.Bf-109E-4_Late", 20 },
{ "bob:Aircraft.Bf-109E-4", 35 },
{ "bob:Aircraft.Bf-109E-3", 40 },
{ "bob:Aircraft.Bf-109E-1", 25 },
{"tobruk:Aircraft.Bf-109E-7",25},
{"tobruk:Aircraft.Bf-109E-7N",20},
{"tobruk:Aircraft.Bf-109E-7Z",15},
{"tobruk:Aircraft.Bf-109F-1", 10},
{"tobruk:Aircraft.Bf-109F-2", 7 },
{"tobruk:Aircraft.Bf-109F-2_Late",5},
{"tobruk:Aircraft.Macchi-C202-SeriesVII",10},
{"tobruk:Aircraft.Macchi-C202-SeriesVII-AltoQuota",5},
{"tobruk:Aircraft.D520_Serie1", 25},
{"bob:Aircraft.DH82A-2", 4 },
};
static Dictionary BlueItalians = new Dictionary() {
{ "bob:Aircraft.G50", 10 },
{ "tobruk:Aircraft.Macchi-C202-SeriesIII-AltoQuota", 6 },
{ "tobruk:Aircraft.Macchi-C202-SeriesIII", 3 },
};
static Dictionary Blue110s = new Dictionary() {
{ "bob:Aircraft.Bf-110C-2", 10 },
{ "bob:Aircraft.Bf-110C-4", 10 },
{ "bob:Aircraft.Bf-110C-4-NJG", 10 },
{ "bob:Aircraft.Bf-110C-6", 5 },
{ "bob:Aircraft.Bf-110C-4N", 8 },
};
static Dictionary RedBlenheimFs = new Dictionary() { { "bob:Aircraft.BlenheimMkIF", 10 }, { "bob:Aircraft.BlenheimMkINF", 10 },
{ "bob:Aircraft.BlenheimMkIVF", 10 },
{ "bob:Aircraft.BlenheimMkIVNF", 10 },
{ "bob:Aircraft.BlenheimMkIVF_Late", 10 },
{ "bob:Aircraft.BlenheimMkIVNF_Late", 10 } };
static Dictionary RedFighters = new Dictionary() { { "bob:Aircraft.HurricaneMkI_100oct-NF", 20 }, { "bob:Aircraft.HurricaneMkI_100oct", 20 },
{ "bob:Aircraft.HurricaneMkI", 15 },
{ "bob:Aircraft.HurricaneMkI_dH5-20_100oct", 15 },
{ "bob:Aircraft.HurricaneMkI_dH5-20", 10 },
{ "bob:Aircraft.SpitfireMkIa_100oct", 20 },
{ "bob:Aircraft.SpitfireMkIa", 10 },
{ "bob:Aircraft.SpitfireMkI", 10 },
{ "bob:Aircraft.SpitfireMkI_100oct", 35 },
{ "bob:Aircraft.SpitfireMkIIa", 25 },
{ "tobruk:Aircraft.HurricaneMkIIa", 45 },
{ "tobruk:Aircraft.HurricaneMkIIb", 45 },
{ "tobruk:Aircraft.HurricaneMkIIb-Late", 35 },
{ "tobruk:Aircraft.HurricaneMkIId", 25 },
{ "tobruk:Aircraft.SpitfireMkVa", 15 },
{ "tobruk:Aircraft.KittyhawkMkIA", 5 },
{ "tobruk:Aircraft.MartletMkIII", 5 },
{ "tobruk:Aircraft.TomahawkMkII", 5 },
{ "tobruk:Aircraft.TomahawkMkII-Late", 5 },
{ "bob:Aircraft.DefiantMkI", 25 },
{ "bob:Aircraft.SpitfireMkIIb", 45 },
};
static Dictionary RedFighters2 = new Dictionary() {
{ "bob:Aircraft.AnsonMkI", 35 },
{ "bob:Aircraft.BeaufighterMkINF",10},
{ "tobruk:Aircraft.BeaufighterMkIF_Late", 7},
{ "tobruk:Aircraft.BeaufighterMkINF_Late", 5},
{ "tobruk:Aircraft.GladiatorMkII_trop", 13 },
{"tobruk:Aircraft.SpitfireMkIIb", 65},
{"tobruk:Aircraft.SpitfireMkVb", 25},
{"tobruk:Aircraft.SpitfireMkVb-HF", 3},
{"tobruk:Aircraft.SpitfireMkVb-HF-Late", 2},
{"tobruk:Aircraft.SpitfireMkVbLate", 12},
};
List> PlaneReplacementDictionarys = new List>() { RedBombers, RedBombers2, RedBombers3, BlueBombers, BlueBombers2, BlueDO215_BR20, BlueE4s, BlueItalians, Blue110s, RedBlenheimFs, RedFighters, RedFighters2 };
//var pattern = @"^\s*Class Aircraft\..?$"; //var pattern = @"^\s*Class Aircraft\..*$"; missionFile = missionFile.Replace("\r\n", "\n").Replace('\r', '\n'); //change all newlines to \n //missionFile = missionFile.Replace("HUNTING", "PUNTING"); //Build up the list to choose from. We weight it by the value given by simply adding that item to the list repeatedly //We want to avoid assigning the two different aircraft in the current .mis file to the same aircraft in the result .mis...
{
RegexOptions ro = RegexOptions.IgnoreCase | RegexOptions.Multiline;
/*
var pattern = @" Class Aircraft.*";
var stringVariableMatches = Regex.Replace(missionFile, pattern,
m => replacements.ContainsKey(m.Value) ? replacements[m.Value] : m.Value, ro);
*/
string newline = "\n";
foreach (string key in replacements.Keys)
{
missionFile = missionFile.Replace(key + newline, replacements[key] + newline);
Console.WriteLine("Replacing: {0} : {1}", key, replacements[key]);
}
return missionFile;
}
public Dictionary makePlaneExchangeDictionary(Dictionary dict, string prefix = "Class Aircraft.")
{
var ret = new Dictionary();
var chooseList = new List();
var chosenList = new HashSet();
foreach (string ap in dict.Keys)
{
chooseList.AddRange(Enumerable.Repeat(ap, dict[ap]));
}
foreach (string ap in dict.Keys) {
int count = 0;
string choice = Calcs.randSTR(chooseList);
while (chosenList.Contains(choice) && count < 2000) { choice = Calcs.randSTR(chooseList); count++; }
chosenList.Add(choice);
ret[prefix + ap] = prefix + choice;
Console.WriteLine("D: " + prefix + ap + " : " + prefix + choice);
}
return ret;
}
//missionFile = updatePlanesFromDictionaryMatch(missionFile, makePlaneExchangeDictionary(RedBombers)); //missionFile = updatePlanesFromDictionaryMatch(missionFile, makePlaneExchangeDictionary(BlueBombers)); //missionFile = updatePlanesFromDictionaryMatch(missionFile, makePlaneExchangeDictionary(RedFighters)); //missionFile = updatePlanesFromDictionaryMatch(missionFile, makePlaneExchangeDictionary(BlueFighters));
{
foreach (var prd in PlaneReplacementDictionarys)
{
missionFile = updatePlanesFromDictionaryMatch(missionFile, makePlaneExchangeDictionary(prd));
}
return missionFile;
}
RegexOptions ro = RegexOptions.IgnoreCase | RegexOptions.Singleline; //Singleline makes .* match EOL characters; ie the entire string is one single line, not broken up into many small lines return stringVariableMatches.Value; //Note - returns first match found only.
{
var stringVariableMatches = Regex.Match(missionFile, pattern, ro);
}
RegexOptions ro = RegexOptions.IgnoreCase | RegexOptions.Singleline; //Singleline makes .* match EOL characters; ie the entire string is one single line, not broken up into many small lines return stringVariableMatches; //Note - returns first match found only.
{
var stringVariableMatches = Regex.Replace(missionFile, pattern, replacement, ro);
}
List
{
Console.WriteLine("Replacement Airgroup and Triggers: Using file " + RandomMission);
string ret = null;
if (File.Exists(RandomMission))
{
ret = File.ReadAllText(RandomMission);
}
return ret;
}
//If we do windlayers first, it replaces everything globalwind->splines but then leaves //[WeatherFront] and [splines] to be replaced by any weather
{
string saveMissionFile = missionFile;
try
{
string replacementFile = getReplacementAirgroupAndTriggerFile(MISSION_ID + "-airgroup-");
string weatherReplacementFile = getReplacementAirgroupAndTriggerFile(MISSION_ID + "-randsubmission-weather-", "Weather");
string airgroupssec = @"\[AirGroups\].*\[Stationary\]";
string triggerssec = @"\[Trigger\].*\[Birthplace\]";
string replacementFile_airgroups = getSection(replacementFile, airgroupssec);
string replacementFile_triggers = getSection(replacementFile, triggerssec);
string weatherSUBMISSIONsec = @"\[WeatherFront\].*";
string weatherMAINMISSIONsec = @"\[WeatherFront\].*\[splines\]";
string replacementFile_weather = getSection(weatherReplacementFile, weatherSUBMISSIONsec) + Environment.NewLine + "[splines]";
string windLayersMAINMISSIONsec = @"\[GlobalWind_0\].*\[splines\]";
string desiredWindLayersString = generateWindLayers() + Environment.NewLine + "[WeatherFront]" +Environment.NewLine + "[splines]";
missionFile = replaceSection(missionFile, replacementFile_airgroups, airgroupssec);
missionFile = replaceSection(missionFile, replacementFile_triggers, triggerssec);
missionFile = replaceSection(missionFile, desiredWindLayersString, windLayersMAINMISSIONsec);
missionFile = replaceSection(missionFile, replacementFile_weather, weatherMAINMISSIONsec);
return missionFile;
}
catch (Exception ex)
{
Console.WriteLine("updateAirgroup_Trigger_WeatherFront_Sections ERROR: " + ex.Message);
return saveMissionFile;
};
}
//https://www.trevorharley.com/1941.html //https://www.trevorharley.com/1940.html //Winters of 1940-41 were among the coldest of the century Britain, with several //feet of snow and giant ice storms Jan 1940 etc //Generally Nov-Dec were rainy/mild but we're going to say there is a certain chance of //snow just so we can get more use out of our winter maps //Snow in Oct has happened in GB once in a while: https://en.wikipedia.org/wiki/October_2008_United_Kingdom_cold_wave //The problem we have is, this must turn up true TWICE IN A ROW in order to get the winter //because it re-starts, and so it will re-choose the map. //Point is, if we want 10/100 chance of snow in Oct, we have to enter (sqrt(10/100) = 31/100 here...
{
int doy = inGameTime_dt.DayOfYear;
Console.WriteLine("{0} {1}", doy, random.Next(100));
return true;
}
//generateWindLayers(); //rem out the following line to make it: testing, don't skip //if (ON_TESTSERVER && !DISABLE_TESTING_MODS) return; //if running on test server, just keep time unchanged //MO_WriteMissionObject(GamePlay.gpTimeofDay(), "MissionCurrentTime", wait); if (mo != null) ret = double.TryParse(mo.ToString(), out lastMissionCurrentTime_hr); //var d = double.TryParse(o.ToString(), out d); //Change to Autumn (or even Winter) map according to the in-game DATE //testing //inGameTime_dt = new DateTime(1942, 12, 25, 12, 01, 0); //inGameTime_dt = new DateTime(1980, 4, 25, 01, 01, 0); //inGameTime_dt = new DateTime(1950, 2, 2, 01, 01, 0); //inGameTime_dt = new DateTime(1921, 9, 11, 01, 01, 0); //inGameTime_dt = new DateTime(1931, 7, 25, 01, 01, 0); //inGameTime_dt = new DateTime(1940, 10, 25, 01, 01, 0); //SUMMER values //adding .DayOfYear to the compares here make it compare on the month/day only, ignoring year (and hours/minutes) //These are guesses - not yet tested. 2023/01 //if the last saved mission time is a long ways from the current mission time, AND there is still more than 5 hrs //left before the preferred end mission time, //AND the last save mission time is later than the earliest allowed mission start time, //THEN we'll restart the mission at/near our last desired start time //Otherwise stick with EARLIEST_MISSION_START_TIME //So once in a while we restart the mission simply to change the weather, aircraft, etc...
{
try
{
bool ret = true;
double lastMissionCurrentTime_hr = 0;
object mo = MO_ReadMissionObject(lastMissionCurrentTime_hr, "MissionCurrentTime");
if (mo != null) Console.WriteLine("Read " + mo.GetType().ToString());
else Console.WriteLine("No read of " + "MissionCurrentTime");
else ret = false;
var stl = showTimeLeft(null, showMessage: false, inGameTimeOnly: true);
var inGameTime_dt = stl.Item2;
Console.WriteLine("Day of year: {0} - {1}", inGameTime_dt.DayOfYear, new DateTime(1940, 12, 24, 01, 01, 0).DayOfYear);
string map = "summer";
string map_value = "Land$English_Channel_1940";
MISSION_LENGTH_HRS = 8.0;
END_MISSION_TIME_HRS = 20.05;
EARLIEST_MISSION_START_TIME_HRS = 4.15;
if (inGameTime_dt.DayOfYear >= new DateTime(1940, 12, 24, 01, 01, 0).DayOfYear ||
inGameTime_dt.DayOfYear < new DateTime(1940, 3, 1, 01, 01, 0).DayOfYear || snowInOctNovDec(inGameTime_dt))
{
Console.WriteLine("START TIME: Using WINTER map & start/end times.");
map = "winter";
map_value = "Land$English_Channel_1940_Winter";
MISSION_LENGTH_HRS = 8.5;
END_MISSION_TIME_HRS = 16.08;
EARLIEST_MISSION_START_TIME_HRS = 7.75;
}
/* 2023/10 - due to AUTUMN FLOOD event the Autumn map was eliminated. Now Flood Bug fixed, it is BACK */
else if (inGameTime_dt.DayOfYear >= new DateTime(1940, 09, 5, 01, 01, 0).DayOfYear &&
inGameTime_dt.DayOfYear < new DateTime(1940, 12, 24, 01, 01, 0).DayOfYear )
{
Console.WriteLine("ChangeTime: Using AUTUMN map");
map = "autumn";
map_value = "Land$English_Channel_1940_Autumn";
MISSION_LENGTH_HRS = 6.0;
END_MISSION_TIME_HRS = 17.25;
EARLIEST_MISSION_START_TIME_HRS = 6.15;
}
else Console.WriteLine("START TIME: Using SUMMER map & start/end times.");
bool restartToChangeMap = false;
if (map != current_map) restartToChangeMap = true;
Console.WriteLine("MIS 1");
double currTime = GamePlay.gpTimeofDay();
double desiredStartTime_hrs = EARLIEST_MISSION_START_TIME_HRS;
Console.WriteLine("MIS 2");
twcLogServer(null, String.Format("CheckStartTime: curr/desired start time: {0:F3} {1:F3} ", currTime, desiredStartTime_hrs));
if (ret && Math.Abs(lastMissionCurrentTime_hr - currTime) < 30 && END_MISSION_TIME_HRS - lastMissionCurrentTime_hr > 5
&& lastMissionCurrentTime_hr >= EARLIEST_MISSION_START_TIME_HRS)
desiredStartTime_hrs = lastMissionCurrentTime_hr;
twcLogServer(null, String.Format("CheckStartTime: curr/desired start time: {0:F3} {1:F3} ", currTime, desiredStartTime_hrs));
Console.WriteLine("MIS 3");
bool restartToChangeWeather = false;
if (random.NextDouble() < 0.333 && !ON_TESTSERVER) restartToChangeWeather = true;
bool restartToChangeTime = true;
if (Math.Abs(desiredStartTime_hrs - currTime) < 0.5 || ON_TESTSERVER) restartToChangeTime = false;
Console.WriteLine("MIS 4, restartToChangeTime: {0}", restartToChangeTime);
string desiredString = " TIME " + desiredStartTime_hrs.ToString("F5");
Console.WriteLine("MIS 5");
twcLogServer(null, String.Format("CheckStartTime: curr/desired start time: {0:F3} {1:F3}; Changing to {2} - {3}. Restart to change weather? {4} restart to change map {5}", currTime, desiredStartTime_hrs, desiredString, map_value, restartToChangeWeather, restartToChangeMap));
Console.WriteLine("MIS 4");
string filepath_mis = stb_FullPath + @"/" + MISSION_ID + ".mis";
string filepath_mis_save = stb_FullPath + @"/" + MISSION_ID + ".mis_save";
var backPath = STATSCS_FULL_PATH + CAMPAIGN_ID + @" campaign backups/";
DateTime dt = DateTime.UtcNow;
string filepath_misback_date = backPath + MISSION_ID + ".mis-" + dt.ToString("yyyy-MM-dd-HHmmss");
try
{
Console.WriteLine("MO_Write MIS #1a " + filepath_mis + " " + filepath_mis_save);
if (File.Exists(filepath_mis_save)) { File.Delete(filepath_mis_save); }
Console.WriteLine("MO_Write MIS #1a");
}
catch (Exception ex) { Console.WriteLine("MO_Copy MIS Inner ERROR: " + ex.ToString()); return; }
Console.WriteLine("MIS 6");
string missionFile = File.ReadAllText(filepath_mis);
missionFile = updateTimeAndWeather(missionFile, desiredString, map_value);
missionFile = updateAirgroup_Trigger_WeatherFront_Sections(missionFile);
missionFile = updatePlanes(missionFile);
try
{
}
catch (Exception ex) { Console.WriteLine("MO_Move MIS currTime 1.5 ERROR: " + ex.ToString()); return; }
try
{
Console.WriteLine("MO_Write MIS #2a");
}
catch (Exception ex) { Console.WriteLine("MO_Move MIS Inner2 ERROR: " + ex.ToString()); return; }
try
{
File.WriteAllText(filepath_mis, missionFile, Encoding.UTF8);
Console.WriteLine("MO_Write MIS #3a");
}
catch (Exception ex)
{
Console.WriteLine("MO_Write MIS Inner3 ERROR: " + ex.ToString());
try
{
Console.WriteLine("MO_Write MIS #3b");
}
catch (Exception ex1) { Console.WriteLine("MO_CheckAndChangeStartTime !!!!!!!!!!!!!!!!!!!!SERIOUS ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!! rewrite of .mis file failed and couldn't copy the backup to replace it!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + Environment.NewLine + ex1.ToString()); return; }
}
twcLogServer(null, "Restarting Mission to change start time of day . . . ", new object[] { });
GamePlay.gpHUDLogCenter("Restarting Mission to change start time of day . . . ");
DebugAndLog("Restarting Mission to change start time of day to " + desiredString);
Console.WriteLine("Restarting Mission to change start time of day to " + desiredString);
/*if (GamePlay is GameDef)
{
(GamePlay as GameDef).gameInterface.CmdExec("exit");
}*/
Console.WriteLine("MIS 7");
if (!ON_TESTSERVER)
{
Console.WriteLine("STOPPING TO CHANGE TIME/DATE/WEATHER and NOT ON_TESTSERVER");
Process.GetCurrentProcess().Kill();
System.Environment.Exit(1);
}
else
{
Thread.Sleep(2075);
Console.WriteLine("STOPPING TO CHANGE TIME/DATE/WEATHER and ON_TESTSERVER");
(GamePlay as GameDef).gameInterface.BattleStop();
}
}
catch (Exception ex) { Console.WriteLine("MO_Move MIS main ERROR: " + ex.ToString()); }
}
//double perc = tickSinceStarted / ((double)MISSION_LENGTH_HRS); //returns true if there is enough time left (possibly after the adjustment) //false if NOT enough time left //If true & not enough time left, adjusts the end mission time to accommodate the extra time requested exactly. //TODO: Can use values for latest allowed time etc to figure out if we can do it or not //We have to change/adjust two things here: // - time left in mission (MISSION_LENGTH_HRS) // - latest time mission is allowed to run (ie, sunset or whatever) (END_MISSION_TIME_HRS)
{
double timeSinceStarted_hrs = GamePlay.gpTimeofDay() - START_MISSION_TIME_HRS;
double perc = timeSinceStarted_hrs / ((double)MISSION_LENGTH_HRS);
if (perc < 0) perc = 0;
if (perc > 1) perc = 1;
return perc;
}
//END_MISSION_TIME_HRS double timeLeft_EMT_hr = END_MISSION_TIME_HRS - GamePlay.gpTimeofDay(); //End_Mission_Time is the last time of day allowed. //Tick_Mission_Time = - ; if (extraTimeNeeded_min > 0) MISSION_LENGTH_HRS = MISSION_LENGTH_HRS + extraTimeNeeded_min / 60.0; ; //2000 ticks/min - see note below //double timeLeft_EMT_hr = END_MISSION_TIME_HRS - GamePlay.gpTimeofDay(); //Calcs minutes left as an int
{
int timeLeft_min = calcTimeLeft_min();
double extraTimeNeeded_min = timeNeeded_min - timeLeft_min;
double timeLeft_EMT_min = timeLeft_EMT_hr * 60.0;
if (extraTimeNeeded_min <= 0 && timeNeeded_min <= timeLeft_EMT_min) return true;
if ((extraTimeNeeded_min >= cutoff_min || timeNeeded_min > timeLeft_EMT_min) && !force) return false;
if (timeNeeded_min > timeLeft_EMT_min) END_MISSION_TIME_HRS = GamePlay.gpTimeofDay() + timeNeeded_min / 60.0;
Console.WriteLine("Extended mission time left to {0:N0} from now, {1:N0} extra minutes", timeNeeded_min, extraTimeNeeded_min);
return true;
}
//var Mission_Time_TF = Time.TicksToSecs(Tick_Mission_Time)/60; //Console.WriteLine("tick/sec" + Time.SecsToTicks(1) + " /2000 method: {0:N2} TF method: {1:N2}", Mission_Time, Mission_Time_TF); //So it appears that the server always SHOOTS FOR 33 tick/sec or 2000 ticks/min. But, if things are slow etc sometimes it doesn't quite meet that...
{
double Mission_Timeleft_hrs = MISSION_LENGTH_HRS - (GamePlay.gpTimeofDay() - START_MISSION_TIME_HRS);
double Mission_Timeleft_min = Mission_Timeleft_hrs * 60;
TimeSpan Mission_Timeleft_ts = TimeSpan.FromMinutes(Mission_Timeleft_min);
double timeLeft_tilsunset_hrs = END_MISSION_TIME_HRS - GamePlay.gpTimeofDay();
TimeSpan timeLeft_tilsunset_ts = TimeSpan.FromHours(timeLeft_tilsunset_hrs);
else return Convert.ToInt32(Mission_Timeleft_ts.TotalMinutes);
}
//Displays time left to player & also returns the time left message as a string & DateTime //Calling with (null, false) will just return the message rather than displaying it diff_days = Math.Abs(diff_days % HISTORIC_CAMPAIGN_LENGTH_DAYS); //After the # of days in the historic campaign has elapsed, we roll over & restart with day 0. Thus, we always have a historic //date within the range of the actual historic campaign //% can be negative, so Abs() of result needed...
{
int timeLeft_min = calcTimeLeft_min();
TimeSpan timeLeft_ts = TimeSpan.FromMinutes(timeLeft_min);
string Time_Remaining_hours_str = string.Format("{0:D2}hr {1:D2}min ", timeLeft_ts.Hours, timeLeft_ts.Minutes);
return Time_Remaining_hours_str;
}
public int month = -1;
public int day = -1;
public Tuple showTimeLeft(Player player = null, bool showMessage = true, bool inGameTimeOnly = false)
{
if (month == -1) month = random.Next(7, 10);
if (day == -1) day = random.Next(10, 30);
TimeSpan diff_ts = DateTime.UtcNow - MODERN_CAMPAIGN_START_DATE;
int diff_days = diff_ts.Days;
DateTime inGameTime_dt = HISTORIC_CAMPAIGN_START_DATE.AddDays(diff_days);
string missiontimeleft = calcTimeLeft();
double inGameTime_hours = GamePlay.gpTimeofDay();
inGameTime_dt = inGameTime_dt.AddHours(inGameTime_hours);
string msg = "It's currently " + inGameTime_dt.ToString("d' 'MMMM' 'yyyy', 'HHmm' hours'.") + " Time remaining until end of operations: " + missiontimeleft;
if (inGameTimeOnly) msg = inGameTime_dt.ToString("d' 'MMMM' 'yyyy', 'HHmm' hours'");
/*
*
if (!MISSION_STARTED) msg = "Mission " + MISSION_ID + " not yet started - waiting for first player to enter.";
else if (COOP_START_MODE) msg = "Mission " + MISSION_ID + " not yet started - waiting for Co-op Start.";
*/
if (showMessage && player != null) twcLogServer(new Player[] { player }, msg, new object[] { });
return new Tuple(msg, inGameTime_dt);
}
{ // Purpose: Send specified chat message to all players in specified army. // Use: GamePlay.sendChatMessageTo(); //Source: Salmo, https://theairtacticalassaultgroup.com/forum/showthread.php?t=23542&highlight=salmo+extension // on Dedi the server: } //rest of the crowd { // Purpose: Get full list of players in army, to (for example) send specified chat message to all players in specified army...
ListPlayers = new List (); if (GamePlay.gpPlayer() != null) { if (GamePlay.gpPlayer().Army() == army || army == -1) Players.Add(GamePlay.gpPlayer()); if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0) { foreach (Player p in GamePlay.gpRemotePlayers()) { if (p.Army() == army || army == -1) Players.Add(p); } } if (Players != null && Players.Count > 0) GamePlay.gpLogServer(Players.ToArray(), msg, parms); } public Player[] AllPlayersInArmyArray(int army) List Players = new List (); if (GamePlay.gpPlayer() != null) { if (GamePlay.gpPlayer().Army() == army || army == -1) Players.Add(GamePlay.gpPlayer()); if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0) { foreach (Player p in GamePlay.gpRemotePlayers()) { if (p.Army() == army || army == -1) Players.Add(p); } } return Players.ToArray(); }
if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MXX3 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping
{
try
{
FileInfo fi = new FileInfo(messageLogPath);
StreamWriter sw;
if (fi.Exists) { sw = new StreamWriter(messageLogPath, true, System.Text.Encoding.UTF8); }
else { sw = new StreamWriter(messageLogPath, false, System.Text.Encoding.UTF8); }
sw.WriteLine((string)data);
sw.Flush();
sw.Close();
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
//logToFile(data, MESSAGE_FULL_PATH);
{
Task.Run(() => logToFile(data, MESSAGE_FULL_PATH));
}
//logToFile(data, STATS_FULL_PATH);
{
Task.Run(() => logToFile(data, STATS_FULL_PATH));
}
if (!DEBUG && LOG) Console.WriteLine((string)data); //We're using the regular logs.txt as the logfile now logToFile (data, LOG_FULL_PATH);
{
if (DEBUG) twcLogServer(null, (string)data, new object[] { });
}
//this is already logged to logs.txt so no need for this: if (LOG) logToFile (data, LOG_FULL_PATH); //there are 1986 or ~2000 gameticks per second //The timeticks are different, 10,000,000 per second. //That means 5000 timeticks per gametick //At 60fps this is 166,667 timeticks per frame //If we say we can send up to 3 messages per frame, that is 55555.5556 timeticks between messages public Int64 GpLogServerMsgDelay_tick = 55555; //1 mill ticks or 0.1 second public Int64 GpLogServerMsgOffset_tick = 5000; //Different modules or submissions can use a different offset to preclude sending gplogservermessages @ the same moment; 500K ticks or 0.05 second //If you're sending to just one recipient, just swap the string & the player & use the "P" version
{
twcLogServer(to, (string)data, third);
}
public Int64 lastGpLogServerMsg_tick = 0;
//Should replace ALL twcLogServer usage with twcLogServer instead to avoid line overflow etc. //wrapper for twcLogServer so that we can do things to it, like log it, suppress all output, delay successive messages etc.
{
var plAr = new Player[] { player };
if (player == null) plAr = null;
twcLogServer(plAr, data, third);
}
//this is already logged to logs.txt so no need for this: if (LOG) logToFile (data, LOG_FULL_PATH); //gpLogServerWithDelay(to, (string)data, third); //gplogserver chokes on long chat messages, so we will break them up into chunks . ...
{
string str = (string)data;
int maxChunkSize = 200;
IEnumerable lines = Calcs.SplitToLines(str, maxChunkSize);
double delay = 0.01;
foreach (string line in lines)
{
Timeout(delay, () =>
{
GamePlay.gpLogServer(to, line, third);
});
delay += (double)GpLogServerMsgDelay_tick / (double)20000000;
}
}
//defined above: //public Int64 lastGpLogServerMsg_tick = 0; //public Int64 GpLogServerMsgDelay_tick = 1000000; //1 mill ticks or 0.1 second //public Int64 GpLogServerMsgOffset_tick = 500000; //Different modules or submissions can use a different offset to preclude sending gplogservermessages @ the same moment; 500K ticks or 0.05 second //currentDate.Ticks //Int64 roundTo = 500000; //round nextMsg_tick UP to the next 1/10 second. This is to allow different missions/modules to output at different portions of the 0.1 second interval, with the objective of avoiding stutters when messages from different .mis files or modules pile up //nextMsg_tick = (Math.DivRem(nextMsg_tick - 1, roundTo, out remainder) + 1) * roundTo; // -1 handles the specific but common situation where we want a 0.1 sec delay but it always rounds it up to 0.2 sec...
{
DateTime currentDate = DateTime.UtcNow;
Int64 nextMsg_tick = Math.Max(currentDate.Ticks, lastGpLogServerMsg_tick + GpLogServerMsgDelay_tick);
Int64 remainder;
double nextMsgDelay_sec = (double)(nextMsg_tick - currentDate.Ticks) / (double)10000000;
string msg = (string)data;
Timeout(nextMsgDelay_sec, () => { twcLogServer(to, msg, third); });
}
public HashSet AllActorsName = new HashSet();
public Dictionary AllActorsDict = new Dictionary();
public Dictionary AllAircraftDict = new Dictionary();
public Dictionary AllGroundDict = new Dictionary();
//Kill off AI aircraft after a pre-set length of time. Stops AI aircraft from hanging around too long after they have //crashlanded, landed in the water, wandered off the map, etc //You can CHANGE the amount of time here depending on the type of AI aircraft you plan to use in your missions //Reason for this is #1...
{
try
{
return Calcs.GetActorsByNameMatch(GamePlay, this, AllActorsDict, name, matcharmy, type, onlyArtilleryAndVehicles: onlyArtilleryAndVehicles, completeList: completeList );
}
catch (Exception ex)
{
Console.WriteLine("main.GetActorsByNameMatch ERROR: " + ex.ToString());
return new List() { };
}
}
/*****************************************************
* ONACTORCREATED
* ***************************************************/
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
handleTempflakSpawn(shortName, actor);
AiAircraft a = actor as AiAircraft;
AiGroundActor g = actor as AiGroundActor;
try
{
try
{
if (ON_TESTSERVER && missionNumber > 20 )
{
if (actor != null && (actor as AiCart) != null ) Console.WriteLine("New Actor Created: {0} {1} {2} {3}", missionNumber, shortName, actor.Name(), (actor as AiCart).InternalTypeName());
else Console.WriteLine("New Actor Created: {0} {1}", missionNumber, shortName);
}
}
catch (Exception ex)
{
if (ON_TESTSERVER) Console.WriteLine("New Actor Created: error printing actor info {0} {1}", missionNumber, shortName);
}
bool add = true;
string ID = actor.Name();
if (AllActorsName.Contains(ID) && AllActorsDict[ID] == actor) add = false;
if (!AllActorsName.Contains(ID)) AllActorsName.Add(ID);
else
{
if (add)
{
for (int i = 1; i <= 1500; i++)
{
if (!AllActorsName.Contains(ID + i.ToString()))
{
ID = ID + i.ToString();
break;
}
}
AllActorsName.Add(ID);
}
}
if (add)
{
AllActorsDict.Add(ID, actor);
if (a != null) AllAircraftDict.Add(ID, actor);
if (g != null) AllGroundDict.Add(ID, actor);
if (!actor.Name().Contains("Static")) for (int i = 1; i < 11; i++)
{
string name = actor.Name() + i.ToString();
AiActor temp = GamePlay.gpActorByName(name);
if (temp != null)
{
if (!AllActorsDict.ContainsKey(ID))
{
AllActorsDict.Add(ID, temp);
}
if (temp as AiAircraft != null && !AllAircraftDict.ContainsKey(ID)) AllAircraftDict.Add(ID, temp);
if (temp as AiGroundActor != null && !AllGroundDict.ContainsKey(ID)) AllGroundDict.Add(ID, temp);
}
}
}
}
catch (Exception ex) { Console.WriteLine("ERROR OnActorCreated save! " + ex.ToString()); }
{
/* if (DEBUG) twcLogServer(null, "DEBUGC: Airgroup: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID(), new object[] { });
*/
if (a == null) return;
bool iACP = isAiControlledPlane2(a);
if (!iACP)
{
if (a as AiAircraft == null) return;
string type = Calcs.GetAircraftType(a as AiAircraft);
if (type.Contains("110") || type.Contains("Ju-87"))
{
Player[] playersInPlane = this.playersInPlane(a as AiAircraft).ToArray();
Timeout(1.732, () => { twcLogServer(playersInPlane, "JU-87 & 110 PILOTS: Use Tab-4-4-8 or chat command
{
if (actor != null && isAiControlledPlane2(actor as AiAircraft))
{
}
}
);
*/
{
Console.WriteLine("DEBUG: Removing old spawned-in aircraft: " + a.AirGroup() + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID() + " timeout: " + ot);
if (actor != null && isAiControlledPlane2(actor as AiAircraft))
{ (actor as AiAircraft).Destroy(); }
}
);
}
});
}
/*****************************************************
* END - ONACTORCREATED
* ***************************************************/
#region Returns whether aircraft is an Ai plane (no humans in any seats)
{ // returns true if specified aircraft is AI controlled with no humans aboard, otherwise false //check if a player is in any of the "places"
if (aircraft == null) return false;
for (int i = 0; i < aircraft.Places(); i++)
{
if (aircraft.Player(i) != null) return false;
}
return true;
}
#endregion
{ // returns list of players in the aircraft (unique list - no duplicates) //check if a player is in any of the "places"
HashSetplayers = new HashSet (); if (aircraft == null) return players; for (int i = 0; i < aircraft.Places(); i++) { if (aircraft.Player(i) != null) players.Add(aircraft.Player(i)); } return players; }
//Console.WriteLine("lAT2P: {0} {1}", player.PlaceSecondary(), player.PlacePrimary()); //Console.WriteLine("lAT2P: {0} {1} {2} ", player.PersonPrimary().Place(), player.PlaceSecondary(), player.PlacePrimary()); //Console.WriteLine("lAT2P: {0} {1} {2} {3}", player.PersonSecondary().Place(), player.PersonPrimary().Place(), player.PlaceSecondary(), player.PlacePrimary()); //Console.WriteLine("lAT2P: {0} {1} {2} {3}", player.PersonSecondary().Place(), player.PersonPrimary().Place(), player.PlaceSecondary(), player.PlacePrimary()); //whichever place they are NOT currently in, remove them from //if (player.PersonSecondary() != null && player.Place() != (player.PersonSecondary()).Place()) player.PlaceLeave((player.PersonSecondary()).Place()); //else if (player.PersonPrimary() != null && player.Place() != (player.PersonPrimary()).Place()) player.PlaceLeave((player.PersonPrimary()).Place()); //Ok, that didn't work. Just leave them in the pilot's seat always...
{
if (player == null || player.Place() == null) return;
twcLogServer(new Player[] { player }, "AI has taken over your gunner position.", null);
}
//The map parameters - if an ai a/c goes outside of these, it will be de-spawned. You need to just figure these out based on the map you are using...
{
int numremoved = 0;
if (GamePlay == null) return;
double minX = 6666;
double minY = 6666;
double maxX = 362000;
double maxY = 312000;
/*
if (GamePlay != null && GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
if (GamePlay.gpAirGroups(army) != null && GamePlay.gpAirGroups(army).Length > 0)
foreach (AiAirGroup airGroup in GamePlay.gpAirGroups(army))
{*/
var arms = new List() { 1, 2 };
if (GamePlay != null) foreach (int army in arms)
{
var airGroups = GamePlay.gpAirGroups(army);
if (airGroups != null && airGroups.Length > 0)
foreach (AiAirGroup airGroup in airGroups)
{
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
foreach (AiActor actor in airGroup.GetItems())
{
if (actor != null && actor is AiAircraft)
{
AiAircraft a = actor as AiAircraft;
/* if (DEBUG) DebugAndLog ("DEBUG: Checking for off map: " + Calcs.GetAircraftType (a) + " "
+ a.AirGroup().ID() + " Pos: " + a.Pos().x.ToString("F0") + "," + a.Pos().y.ToString("F0")
);
*/
if (a != null && isAiControlledPlane2(a))
{
double Z_AltitudeAGL = a.getParameter(part.ParameterTypes.Z_AltitudeAGL, 0);
double Z_VelocityTAS = a.getParameter(part.ParameterTypes.Z_VelocityTAS, 0);
AiAirGroupTask aagt = airGroup.getTask();
/*if (Z_VelocityTAS < 0)
Console.WriteLine("DEBUG: Off Map or landed/Checking: " + Calcs.GetAircraftType(a) + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID() + " Pos: " + a.Pos().x.ToString("F0") + "," + a.Pos().y.ToString("F0") + " {0:N0} {1:N0} {2} ",
Z_AltitudeAGL, Z_VelocityTAS, aagt
);
*/
if
(
a.Pos().x >= maxX + 12500 ||
a.Pos().y <= minY - 12500 ||
a.Pos().y >= maxY + 12500
)
{
Console.WriteLine("DEBUG: Off Map or landed/Destroying: " + Calcs.GetAircraftType(a) + " "
+ a.Type() + " "
+ a.TypedName() + " "
+ a.AirGroup().ID() + " Pos: " + a.Pos().x.ToString("F0") + "," + a.Pos().y.ToString("F0") + " {0:N0} {1:N0} {2} ",
Z_AltitudeAGL, Z_VelocityTAS, aagt
);
numremoved++;
}
}
}
}
}
}
private bool putPlayerIntoAircraftPosition(Player player, AiActor actor, int place)
{
if (player != null && actor != null && (actor as AiAircraft != null))
{
AiAircraft aircraft = actor as AiAircraft;
player.PlaceEnter(aircraft, place);
return true;
}
return false;
}
private void Stb_DestroyPlaneUnsafe(AiAircraft aircraft)
{
try
{
if (aircraft != null)
{
aircraft.Destroy();
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
}
{
try
{
if (cart == null)
return;
for (int i = 0; i < cart.Places(); i++)
{
if (cart.Player(i) == null) continue;
if (player != null)
{
}
else
{
cart.Player(i).PlaceLeave(i);
}
}
}
catch (Exception ex) { Console.WriteLine("ERROR removeoffmapplayers (main): " + ex.ToString()); }
}
private void Stb_RemoveAllPlayersFromAircraftandDestroy(AiAircraft aircraft, Player player, double timeToRemove_sec = 1.0, double timetoDestroy_sec = 3.0)
{
Timeout(timeToRemove_sec, () =>
{
Timeout(timetoDestroy_sec, () =>
{
});
}
private void Stb_RemoveAllPlayersFromAircraft(AiAircraft aircraft, double timeToRemove_sec = 1.0)
{
Timeout(timeToRemove_sec, () =>
{
for (int place = 0; place < aircraft.Places(); place++)
{
if (aircraft.Player(place) != null)
{
}
}
});
}
double d2 = 10000000000000000; //we compare distanceSQUARED so this must be the square of some super-large distance in meters && we'll return anything closer than this. Also if we don't find anything we return the sqrt of this number, which we would like to be a large number to show there is nothing nearby...
{
double d2Min = d2;
try
{
if (GamePlay == null) return d2;
if (actor == null) return d2Min;
Point3d pd = actor.Pos();
int n = GamePlay.gpAirports().Length;
for (int i = 0; i < n; i++)
{
AiActor a = (AiActor)GamePlay.gpAirports()[i];
if (a == null) continue;
if (GamePlay.gpFrontArmy(a.Pos().x, a.Pos().y) != actor.Army()) continue;
Point3d pp;
pp = a.Pos();
pd.z = pp.z;
d2 = pd.distanceSquared(ref pp);
if (d2 < d2Min)
{
d2Min = d2;
}
}
foreach (AiBirthPlace a in GamePlay.gpBirthPlaces())
{
if (a == null) continue;
if (a.Army() != actor.Army()) continue;
Point3d pp;
pp = a.Pos();
pd.z = pp.z;
d2 = pd.distanceSquared(ref pp);
if (d2 < d2Min)
{
d2Min = d2;
}
}
return Math.Sqrt(d2Min);
}
catch (Exception ex)
{
Console.WriteLine("Stb_distanceToNearestAirport ERROR!!!!!!!!!!!!! " + ex.Message);
return Math.Sqrt(d2Min);
}
}
//was InitialBlueObjectiveCount }; //reference as MissionObjectiveScore[ArmiesE.Red] MissionObjectiveScore[ArmiesE.Blue] //was Objective_Total_Blue //was osk_BlueObjDescription //What percent of primary targets is actually required ot turn the map //If you make it 100% you have to get them all, but if some are difficult or impossible then that army will be stuck //TODO: Use similar scheme for total points, objectives completed list, objectives completed //Points required, assuming they are doing it entirely with Primary Targets; ie, secondary or other targets do not count towards this total //at all //This is used to determine how many primary objectives to select (points) {ArmiesE.Red, 180 }, //bhugh, temp XX2021-10, was 55, now doubling raise stakes //2021-10-30 probs, switching back {ArmiesE.Blue, 180 } //bhugh, temp XX2021-10, was 110 but for Ultimate Battle raising stakes to 300. 2023/10/28 - changing from 200 to 180 to make map moves a bit more frequent //////////////////////******************************************///////////////////////////// //Amount of points require in case percent of primary is less than 100% but more than MO_PercentPrimaryTargetsRequired //This allows mission to be turned in case one objective is malfunctioning or super-difficult - by hitting some other alternate targets //So this is like a consolation prize...
{
string to = " TO ";
if (player != null && player.Name() != null) to += player.Name();
if (GamePlay is GameDef)
{
(GamePlay as GameDef).gameInterface.CmdExec("chat " + line + to);
}
}
/*******************************************************************************
*******************************************************************************
* METHODS DIFFERENT FOR DIFFERENT CAMPAIGNS
*
* Below we're collecting the methods that are wildly different between different TWC
* campaigns so that we can more easily use comparison tools on the similar portions above.
*
* *******************************************************************************
* *****************************************************************************/
/********************************************************************************************************************
* MISSION OBJECTIVES CLASSES & METHODS
*
* Methods & classes for dealing with objectives, messages & other results of destroying objectives, awarding points, dealing with disabled radar, etc
*
* All Mission Objectives should be listed & handled here, then a simple routine below can be called from OnTrigger, OnBombExploded, etc
* rather than having code & variables related to objectives scattered hither & yon across the entire file
*
* ******************************************************************************************************************/
/* points to turn map**********************************************
public double InitialBlueObjectiveCount = 0;
public double InitialRedObjectiveCount = 0;
public string Objective_Total_Blue = "";
public string Objective_Total_Red = "";
osk_BlueObjDescription
*/
Dictionary MissionObjectiveScore = new Dictionary()
{ {ArmiesE.Red, 0 },
{ArmiesE.Blue, 0 }
Dictionary MissionObjectivesCompletedString = new Dictionary()
{ {ArmiesE.Red, "" },
{ArmiesE.Blue, "" }
};
Dictionary MissionObjectivesCompleteContributors_thisStatsPeriod = new Dictionary()
{ {ArmiesE.Red, "" },
{ArmiesE.Blue, "" }
};
/* NO LONGER NEEDED! Replaced by MO_ListRemainingPrimaryObjectives(player, player.Army()); which is better & also does the sector/recon/exact position thing
Dictionary MissionObjectivesString = new Dictionary()
{ {ArmiesE.Red, "" },
{ArmiesE.Blue, "" }
};
*/
public Dictionary MO_PercentPrimaryTargetsRequired = new Dictionary() {
{ArmiesE.Red, 65 },
{ArmiesE.Blue, 65 }
};
public Dictionary MO_PrimaryPointsRequired = new Dictionary() {
{ArmiesE.Red, 30 },
{ArmiesE.Blue, 30 }
};
public Dictionary MO_PointsRequired = new Dictionary() {
};
public Dictionary MO_PointsRequiredWithMissingPrimary = new Dictionary() {
};
public Dictionary MO_PointsRequiredWithNoPrimary = new Dictionary() {
{ArmiesE.Blue, 400 }
};
public Dictionary> MO_TurnMapPointsRequired;
No description available.
{
MO_TurnMapPointsRequired = new Dictionary>() {
{ "MO_PercentPrimaryTargetsRequired", MO_PercentPrimaryTargetsRequired },
{ "MO_PrimaryPointsRequired", MO_PrimaryPointsRequired },
{ "MO_PointsRequired", MO_PointsRequired },
{ "MO_PointsRequiredWithMissingPrimary", MO_PointsRequiredWithMissingPrimary },
{ "MO_PointsRequiredWithNoPrimary", MO_PointsRequiredWithNoPrimary },
};
}
public double MO_MinMaxPolarization = 1; // A number 0-1 is chosen and then raised to this power to create the polarizing factor. {ArmiesE.Red, "" }, //the leak FOR red army (about something Blue is doing) {ArmiesE.Blue, "" } //the leak FOR blue army (about something Red is doing) //Dictionary
{
MO_PercentPrimaryTargetsRequired = MO_TurnMapPointsRequired["MO_PercentPrimaryTargetsRequired"];
MO_PrimaryPointsRequired = MO_TurnMapPointsRequired["MO_PrimaryPointsRequired"];
MO_PointsRequired = MO_TurnMapPointsRequired["MO_PointsRequired"];
MO_PointsRequiredWithMissingPrimary = MO_TurnMapPointsRequired["MO_PointsRequiredWithMissingPrimary"];
MO_PointsRequiredWithNoPrimary = MO_TurnMapPointsRequired["MO_PointsRequiredWithNoPrimary"];
}
public double MO_MaxPrimariesRequired = 30;
public double MO_MinPrimariesRequired = 25;
public Dictionary MO_IntelligenceLeakNearMissionEnd = new Dictionary() {
};
Dictionary> DestroyedObjectives = new Dictionary>() {
{ArmiesE.Red, new List() },
{ArmiesE.Blue, new List() }
Dictionary> DestroyedRadar = new Dictionary>() {
{ArmiesE.Red, new List() },
{ArmiesE.Blue, new List() }
Dictionary> MissionObjectivesSuggested = new Dictionary>() {
{ArmiesE.Red, new List() },
{ArmiesE.Blue, new List() }
};
Dictionary> MissionObjectivesTimes = new Dictionary>() {
{ArmiesE.Red, new Dictionary() },
{ArmiesE.Blue, new Dictionary() }
};
public enum MO_TriggerType { Trigger, Static, Airfield, PointArea, TemporaryLandingGround };
public enum MO_ProducerOrStorageType { None, Beaufighter, SpitfireII, SpitfireIa, Spitfire, Blenheim, Wellington, Hurricane, BF109_3, BF109_1, BF109_4, BF109, BF110, HE111, G50, JU88, JU87, fighter, bomber, fuel, bullets_shells, bombs, Knickebein_beams };
public HashSet MO_Naval_Ship_ObjectiveTypes = new HashSet { MO_ObjectiveType.Ship, MO_ObjectiveType.Naval_Convoy, MO_ObjectiveType.Naval_Freighter_Convoy, MO_ObjectiveType.Naval_Ship, MO_ObjectiveType.Naval_Tanker_Convoy, MO_ObjectiveType.Freighter_Ship, MO_ObjectiveType.Tanker_Ship };
public HashSet MO_Naval_Vessel_ObjectiveTypes = new HashSet { MO_ObjectiveType.Ship, MO_ObjectiveType.Naval_Convoy, MO_ObjectiveType.Naval_Freighter_Convoy, MO_ObjectiveType.Naval_Ship, MO_ObjectiveType.Naval_Tanker_Convoy, MO_ObjectiveType.Freighter_Ship, MO_ObjectiveType.Tanker_Ship, MO_ObjectiveType.Submarine };
public Dictionary, double> MO_MilitaryStrengths = new Dictionary, double>() { };
public Dictionary> MO_objectivetype_by_strengthtype =
new Dictionary> {
{MO_MilitaryStrengthType.Military, new List { MO_ObjectiveType.Radar, MO_ObjectiveType.RadioCommunications, MO_ObjectiveType.Communications, MO_ObjectiveType.KnickebeinHQ, MO_ObjectiveType.Artillery_and_AA,MO_ObjectiveType.Ship, MO_ObjectiveType.Naval_Ship, MO_ObjectiveType.Freighter_Ship, MO_ObjectiveType.Tanker_Ship, MO_ObjectiveType.Submarine, MO_ObjectiveType.Naval_Convoy,MO_ObjectiveType.Naval_Freighter_Convoy,MO_ObjectiveType.Naval_Tanker_Convoy,
MO_ObjectiveType.Military_Building,MO_ObjectiveType.Military_Airfield,MO_ObjectiveType.Ground_Aircraft,
MO_ObjectiveType.Military_Vehicles, MO_ObjectiveType.Military_Armored_Vehicles,MO_ObjectiveType.Military_Convoy, MO_ObjectiveType.Naval_Dock_Area, MO_ObjectiveType.Airfield_Complex, MO_ObjectiveType.ArmyBase,MO_ObjectiveType.MilitaryArea, MO_ObjectiveType.MilitaryHeadquarters, MO_ObjectiveType.MilitaryRepairFacility, MO_ObjectiveType.WeaponsStorage,MO_ObjectiveType.AmmunitionStorage }
},
{ MO_MilitaryStrengthType.Military_Leadership,
},
{ MO_MilitaryStrengthType.Military_Fuel_Supply, new List {MO_ObjectiveType.MilitaryFuelStorage, MO_ObjectiveType.MilitaryFuelProduction, MO_ObjectiveType.Tanker_Ship, MO_ObjectiveType.Naval_Tanker_Convoy, }
},
{ MO_MilitaryStrengthType.General_Production_And_Supply, new List { MO_ObjectiveType.Military_Convoy, MO_ObjectiveType.Freighter_Ship, MO_ObjectiveType.Ship, MO_ObjectiveType.Tanker_Ship, MO_ObjectiveType.Naval_Freighter_Convoy, MO_ObjectiveType.Naval_Tanker_Convoy, MO_ObjectiveType.Bridge, MO_ObjectiveType.Dam, MO_ObjectiveType.Naval_Dock_Area, MO_ObjectiveType.Railroad_Yard, MO_ObjectiveType.Railroad, MO_ObjectiveType.Railroad_Bridge, MO_ObjectiveType.Road, MO_ObjectiveType.Factory_Complex, MO_ObjectiveType.MilitaryProductionArea, MO_ObjectiveType.MilitaryHeadquarters, MO_ObjectiveType.ProductionFacility, MO_ObjectiveType.MilitaryProductionFacility, MO_ObjectiveType.CivilianStorageFacility, MO_ObjectiveType.MilitaryStorageFacility, MO_ObjectiveType.CivilianFuelStorage, MO_ObjectiveType.Civilian_Building, MO_ObjectiveType.Civilian_Vehicles, MO_ObjectiveType.MilitaryFuelStorage, MO_ObjectiveType.MilitaryFuelProduction, MO_ObjectiveType.MilitaryRepairFacility, MO_ObjectiveType.WeaponsStorage, MO_ObjectiveType.AmmunitionStorage }
}
};
public enum MO_MobileObjectiveType { None, ArmyEncampment, MobileRadar1, MobileRadar2, DesertRadar, KnickebeinHQ, CamoGroup, SmallCamoGroup, SmallArmourGroup, LargeArmourGroup, SmallTruckConvoy, LargeTruckConvoy, SecretAirbaseGB, SecretAirbaseDE, SecretAircraftResearchGB, SecretAircraftResearchDE, FreighterShipGroup_GB, FreighterShipGroup_DE, TankerShipGroup_GB, TankerShipGroup_DE, LargeTankerShipGroup_GB, LargeTankerShipGroup_DE, SmallShipGroup_GB, SmallShipGroup_DE, OneShipGroup_GB, OneShipGroup_DE, OneMTBGroup_GB, OneMTBGroup_DE, OneSubmarineGroup_GB, OneSubmarineGroup_DE, FuelDump };
public enum MO_MobileObjectiveThings { Humans, Items, Trucks, Tents, Tables, Buildings, Radar, Small_Radar, Sentry, Trenches, Sandbags, Armor_Tanks, Cars, Jerrycans, ExplodeyThings, GBFighters, GBBombers, DEFighters, DEBombers, Hedgehogs, Misc, Camo, Detritus, MO_Military_Ships_GB, MO_Military_Ships_DE, MO_Military_Ships_VeryLarge_GB, MO_Military_Ships_VeryLarge_DE, MO_Military_Ships_Large_GB, MO_Military_Ships_Large_DE, MO_Military_Ships_Medium_GB, MO_Military_Ships_Medium_DE, MO_Military_Ships_MTB_GB, MO_Military_Ships_MTB_DE, MO_Military_Ships_Submarine_GB, MO_Military_Ships_Submarine_DE, MO_Military_Ships_Escort_GB, MO_Military_Ships_Escort_DE, MO_Military_Cargo_Tanker_Ships_Large_GB, MO_Military_Cargo_Tanker_Ships_Small_GB, MO_Military_Cargo_Tanker_Ships_Large_DE, MO_Military_Cargo_Tanker_Ships_Small_DE, MO_FuelStorage };
public List MO_All_Military_Navy_Ships = new List() { MO_MobileObjectiveThings.MO_Military_Ships_GB, MO_MobileObjectiveThings.MO_Military_Ships_DE, MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_GB, MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_DE, MO_MobileObjectiveThings.MO_Military_Ships_Large_GB, MO_MobileObjectiveThings.MO_Military_Ships_Large_DE, MO_MobileObjectiveThings.MO_Military_Ships_Medium_GB, MO_MobileObjectiveThings.MO_Military_Ships_Medium_DE, MO_MobileObjectiveThings.MO_Military_Ships_MTB_GB, MO_MobileObjectiveThings.MO_Military_Ships_MTB_DE, MO_MobileObjectiveThings.MO_Military_Ships_Submarine_GB, MO_MobileObjectiveThings.MO_Military_Ships_Submarine_DE, MO_MobileObjectiveThings.MO_Military_Ships_Escort_GB, MO_MobileObjectiveThings.MO_Military_Ships_Escort_DE };
public List MO_All_VeryDangerous_Military_Navy_Ships = new List() { MO_MobileObjectiveThings.MO_Military_Ships_GB, MO_MobileObjectiveThings.MO_Military_Ships_DE, MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_GB, MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_DE, MO_MobileObjectiveThings.MO_Military_Ships_Large_GB, MO_MobileObjectiveThings.MO_Military_Ships_Large_DE, MO_MobileObjectiveThings.MO_Military_Ships_Medium_GB, MO_MobileObjectiveThings.MO_Military_Ships_Medium_DE, };
[DataContract()]
public class MissionObjective : IMissionObjective
{
[DataMember] public int NumFlakBatteries { get; set; }
[DataMember] public int NumInFlakBattery { get; set; }
public int AutoFlak_locations_pointer { get; set; }
[DataMember] public Mission.MO_ObjectiveType MOObjectiveType { get; set; }
[DataMember] public Mission.MO_TriggerType MOTriggerType { get; set; }
[DataMember] public bool Destroyed { get; set; }
[DataMember] public string Sector { get; set; }
[DataMember] public string HUDMessage { get; set; }
[DataMember] public string LOGMessage { get; set; }
[DataMember] public double RadarEffectiveRadius { get; set; }
[DataMember] public string TriggerName { get; set; }
[DataMember] public string TriggerType { get; set; }
[DataMember] public double TriggerPercent { get; set; }
[DataMember] public double ActorsDestroyed_num { get; set; }
[DataMember] public Point3d MobileNEPoint { get; set; }
public Mission msn;
private Random ran = new Random();
public MissionObjective()
{
}
public MissionObjective(Mission m)
{
msn = m;
}
public MissionObjective(Mission m, string objectiveKey, string objectiveName, string flak, int ownerarmy, double pts, double repairdays, string mission_trigger_type, double trigger_percent, double x, double y, double trigger_destroy_radius, double radar_effective_radius, bool is_primary_target, double primary_target_weight, string comment, MO_ObjectiveType MObjType = MO_ObjectiveType.Radar, MO_TriggerType MOTrigType = MO_TriggerType.Trigger, string init_submission_filename = "", double orttkg = 100, double orttn = 2, double arttn = 0, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, string chief_name = "")
{
msn = m;
MOObjectiveType = MObjType;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MOTrigType;
TriggerName = objectiveKey;
ID = objectiveKey;
Name = objectiveName;
FlakID = flak;
InitSubmissionName = init_submission_filename;
AutoFlakIfPrimary = true;
AutoFlak = true;
NumFlakBatteries = 3;
NumInFlakBattery = 4;
MOMobileObjectiveType = MO_MobileObjectiveType.None;
MobileMaxMoveDist_km = 0;
MobileMinMoveDist_km = 0;
MobileSWPoint = Pos;
MobileNEPoint = Pos;
IsEnabled = true;
TimetoRepairIfDestroyed_hr = repairdays * 24;
OwnerArmy = ownerarmy;
OriginalOwnerArmy = ownerarmy;
AttackingArmy = 3 - ownerarmy;
if (AttackingArmy > 2 || AttackingArmy < 1) AttackingArmy = 0;
Pos = new Point3d(Pos.x, Pos.y, z);
if (AttackingArmy != 0)
{
HUDMessage = ArmiesL[AttackingArmy] + " destroyed " + Name;
LOGMessage = "Heavy damage to " + Name + " - out of action about " + this.TimetoRepairIfDestroyed_hr.ToString("F0") + " hours. Good job " + ArmiesL[AttackingArmy] + "!!!";
}
else
{
HUDMessage = Name + " was destroyed";
LOGMessage = Name + " was destroyed, " + this.TimetoRepairIfDestroyed_hr.ToString("F1") + " hours to repair. " + pts + " awarded " + ArmiesL[AttackingArmy];
}
Points = pts;
TriggerPercent = trigger_percent;
/* string keyp = Calcs.doubleKeypad(Pos);
Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
TriggerDestroyRadius = trigger_destroy_radius;
RadarEffectiveRadius = radar_effective_radius;
radius = trigger_destroy_radius;
OrdnanceRequiredToTrigger_kg = orttkg;
ObjectsRequiredToTrigger_num = orttn;
ObjectsDestroyed_num = 0;
ActorsDestroyed_num = 0;
Destroyed = false;
DestroyedPercent = 0;
ObjectiveAchievedForPoints = false;
TimeToUndestroy_UTC = null;
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = is_primary_target;
PrimaryTargetWeight = primary_target_weight;
Comment = comment;
}
public MissionObjective(Mission m, double pts, double ptp, AiAirport airport, int ownerarmy, Tuple> tup, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, bool is_focus = false, string chief_name = "")
{
msn = m;
MOObjectiveType = MO_ObjectiveType.Military_Airfield;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MO_TriggerType.Airfield;
ID = tup.Item2 + "_airfield";
string adder = " Airfield";
string matcher = tup.Item2.ToLower();
var descList = new List { "airfield", "airport", "fliegerhorst", "aerodrome", "airdrome", "aéroport", "aérodrome", "raf ", "airbase", "landing field", "air station", "air strip", "flugplatz", "flughafen", "lufthafen", "aerodrom", "flugfeld", "luftverkehrszentrum", "sonderlandeplatz", "landeplatz", "luftstützpukt", "flugstation", "luftwaffenstützpunkt", "lg", "landing ground" };
if (descList.Any(s => matcher.Contains(s))) adder = "";
Name = tup.Item2 + adder;
AutoFlakIfPrimary = true;
AutoFlak = false;
NumFlakBatteries = 3;
NumInFlakBattery = 3;
Pos = tup.Item7;
MOMobileObjectiveType = MO_MobileObjectiveType.None;
MobileMaxMoveDist_km = 0;
MobileMinMoveDist_km = 0;
MobileSWPoint = Pos;
MobileNEPoint = Pos;
IsEnabled = true;
OwnerArmy = ownerarmy;
OriginalOwnerArmy = ownerarmy;
AttackingArmy = 3 - OwnerArmy;
if (AttackingArmy > 2 || AttackingArmy < 1) AttackingArmy = 0;
Pos = new Point3d(Pos.x, Pos.y, z);
LOGMessage = null;
Points = pts;
string keyp = Calcs.doubleKeypad(Pos);
/* Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
Destroyed = false;
DestroyedPercent = 0;
ObjectiveAchievedForPoints = false;
TimeToUndestroy_UTC = null;
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = false;
PrimaryTargetWeight = ptp;
IsFocus = is_focus;
Comment = "Auto-generated from in-game airports list";
fixDestructionValues();
}
public MissionObjective(Mission m, string objective_id, string name, Point3d pos, double radius_m, double objective_points, double primaryobjective_weight, double timeToRemainActive_hrs, string flak_file, int ownerarmy, bool auto_flak = true, bool auto_flak_ifprimary = true, int flak_numbatteries = 7, int flak_numberinbattery = 8, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, string chief_name = "", HashSet planeset = null)
{
msn = m;
MOObjectiveType = MO_ObjectiveType.TemporaryLandingGround;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MO_TriggerType.TemporaryLandingGround;
ID = objective_id;
Console.WriteLine("Creating NEW MissionObjective Temporary Landing Ground: " + ID);
Name = name;
if (planeset is object) Console.WriteLine("Landingground: Making MissionObjective, adding planeset with {0} aircraft", planeset.Count);
else Console.WriteLine("Landingground: Making MissionObjective, planeset was NULL!!!");
if (BirthplaceACTypes is object) Console.WriteLine("Landingground: Making MissionObjective, adding planeset with {0} aircraft: {1}", BirthplaceACTypes.Count, string.Join("", BirthplaceACTypes) );
else Console.WriteLine("Landingground: Making MissionObjective, planeset was NULL!!!");
AutoFlakIfPrimary = true;
AutoFlak = true;
NumFlakBatteries = 2;
NumInFlakBattery = 2;
Pos = pos;
MOMobileObjectiveType = MO_MobileObjectiveType.None;
MobileMaxMoveDist_km = 0;
MobileMinMoveDist_km = 0;
MobileSWPoint = Pos;
MobileNEPoint = Pos;
IsEnabled = true;
OriginalOwnerArmy = ownerarmy;
Pos = new Point3d(Pos.x, Pos.y, z);
Points = objective_points;
string keyp = Calcs.doubleKeypad(Pos);
/* Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
HUDMessage = ArmiesL[ownerarmy] + " created a Landing Ground - " + Name;
LOGMessage = "New Landing Ground " + Name + " created by " + ArmiesL[ownerarmy] + " - active for " + (this.TimetoRepairIfDestroyed_hr / 24.0).ToString("F1") + " days.";
Destroyed = false;
DestroyedPercent = 0;
ObjectiveAchievedForPoints = false;
DateTime currTime_dt = DateTime.UtcNow;
TimeToUndestroy_UTC = currTime_dt.AddHours(timeToRemainActive_hrs);
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = false;
PrimaryTargetWeight = primaryobjective_weight;
IsFocus = false;
}
public MissionObjective(Mission m, MO_ObjectiveType mot, string tn, string n, string flak, string init_submission_filename, string chief_name, int ownerarmy, double pts, string trigger_type, double percentageToTrigger, double x, double y, double trigger_destroy_radius, bool pt, double ptp, double ttr_hr, string comment, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, int numHitsToTrigger= 0, int numObjectsInRadius= 0)
{
Console.WriteLine("Initiating Trigger objective " + tn + " submission file: " + init_submission_filename);
msn = m;
Pos = new Point3d(x, y, 0);
MOObjectiveType = mot;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MO_TriggerType.Trigger;
TriggerName = tn;
ID = tn;
Name = n;
FlakID = flak;
InitSubmissionName = init_submission_filename;
AutoFlakIfPrimary = true;
AutoFlak = false;
NumFlakBatteries = 2;
NumInFlakBattery = 6;
MOMobileObjectiveType = MO_MobileObjectiveType.None;
MobileMaxMoveDist_km = 0;
MobileMinMoveDist_km = 0;
MobileSWPoint = Pos;
MobileNEPoint = Pos;
IsEnabled = true;
OwnerArmy = ownerarmy;
OriginalOwnerArmy = ownerarmy;
AttackingArmy = 3 - ownerarmy;
if (AttackingArmy > 2 || AttackingArmy < 1) AttackingArmy = 0;
Pos = new Point3d(Pos.x, Pos.y, z);
if (AttackingArmy != 0)
{
HUDMessage = ArmiesL[AttackingArmy] + " destroyed " + Name;
LOGMessage = "Heavy damage to " + Name + " - good job " + ArmiesL[AttackingArmy] + "!!!";
}
else
{
HUDMessage = Name + " was destroyed";
LOGMessage = Name + " was destroyed";
}
Points = pts;
TriggerType = trigger_type;
TriggerPercent = percentageToTrigger;
string keyp = Calcs.doubleKeypad(Pos);
/* Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
TriggerDestroyRadius = trigger_destroy_radius;
TimetoRepairIfDestroyed_hr = ttr_hr;
Destroyed = false;
DestroyedPercent = 0;
if (numObjectsInRadius > 0) TotalInitialObjects_num = numObjectsInRadius;
else
{
int num = msn.GamePlay.gpGroundStationarys(Pos.x, Pos.y, trigger_destroy_radius).ToList().Count;
if (num < 10) num = 10;
TotalInitialObjects_num = num;
}
ObjectsRequiredToTrigger_num = (double)TotalInitialObjects_num * (double)percentageToTrigger / 100.0;
ObjectiveAchievedForPoints = false;
TimeToUndestroy_UTC = null;
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = pt;
PrimaryTargetWeight = ptp;
Comment = comment;
}
public MissionObjective(Mission m, MO_ObjectiveType objective_type, string objective_ID, string objective_name, string flak, string init_submission_filename, int ownerarmy, double points, double x, double y, double rad, double trigrad, double orttkg, double orttn, double arttn, double primary_target_weight, double ttr_hr, bool auto_flak, bool auto_flak_ifprimary, int num_flakbatteries, int num_in_eachbattery, string comment, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, string chief_name = "", bool canBeDisabled = true)
{
Console.WriteLine("Initiating PointArea objective " + objective_ID);
msn = m;
Pos = new Point3d(x, y, 0);
MOObjectiveType = objective_type;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MO_TriggerType.PointArea;
TriggerName = objective_ID;
ID = objective_ID;
Name = objective_name;
FlakID = flak;
InitSubmissionName = init_submission_filename;
AutoFlakIfPrimary = auto_flak_ifprimary;
AutoFlak = auto_flak;
NumFlakBatteries = num_flakbatteries;
NumInFlakBattery = num_in_eachbattery;
ChiefName = IDtoCleanChiefName(chief_name);
MOMobileObjectiveType = MO_MobileObjectiveType.None;
MobileMaxMoveDist_km = 0;
MobileMinMoveDist_km = 0;
MobileSWPoint = Pos;
MobileNEPoint = Pos;
IsEnabled = true;
CanBeDisabled = canBeDisabled;
OwnerArmy = ownerarmy;
OriginalOwnerArmy = ownerarmy;
AttackingArmy = 3 - ownerarmy;
if (AttackingArmy > 2 || AttackingArmy < 1) AttackingArmy = 0;
Pos = new Point3d(Pos.x, Pos.y, z);
if (AttackingArmy != 0)
{
HUDMessage = ArmiesL[AttackingArmy] + " destroyed " + Name;
LOGMessage = "Heavy damage to " + Name + " - good job " + ArmiesL[AttackingArmy] + "!!!";
}
else
{
HUDMessage = Name + " was destroyed";
LOGMessage = Name + " was destroyed";
}
Points = points;
Pos = new Point3d(x, y, 0);
string keyp = Calcs.doubleKeypad(Pos);
/* Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
radius = rad;
TriggerDestroyRadius = trigrad;
OrdnanceRequiredToTrigger_kg = orttkg;
ObjectsDestroyed_num = 0;
ActorsDestroyed_num = 0;
TimetoRepairIfDestroyed_hr = ttr_hr;
Destroyed = false;
DestroyedPercent = 0;
ObjectiveAchievedForPoints = false;
TimeToUndestroy_UTC = null;
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = false;
PrimaryTargetWeight = primary_target_weight;
Comment = comment;
}
public MissionObjective(Mission m, MO_ObjectiveType objective_type, string objective_ID, string objective_name, string flak, int ownerarmy,
double points, double x, double y, double rad, double trigrad, double orttkg, double orttn, double arttn, double primary_target_weight, double ttr_hr, bool auto_flak, bool auto_flak_ifprimary,
int num_flakbatteries, int num_in_eachbattery,
MO_MobileObjectiveType mobile_objective_type,
double mobile_hours_between_moves,
Point3d mobile_SW_point,
Point3d mobile_NE_point,
double min_move_dist_km,
double max_move_dist_km,
MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None,
string comment = "", double radar_effective_radius_m = 20000,
string chief_name = "", bool canbedisabled = true)
{
Console.WriteLine("Initiating PointArea/Mobile objective " + objective_ID);
msn = m;
Pos = new Point3d(x, y, 0);
MOObjectiveType = objective_type;
MOProducerOrStorageType = MOProdStorType;
MOTriggerType = MO_TriggerType.PointArea;
TriggerName = objective_ID;
ID = objective_ID;
Name = objective_name;
FlakID = flak;
AutoFlakIfPrimary = auto_flak_ifprimary;
AutoFlak = auto_flak;
NumFlakBatteries = num_flakbatteries;
NumInFlakBattery = num_in_eachbattery;
MOMobileObjectiveType = mobile_objective_type;
MobileMinMoveDist_km = min_move_dist_km;
MobileMaxMoveDist_km = max_move_dist_km;
MobileNEPoint = mobile_NE_point;
IsEnabled = true;
OwnerArmy = ownerarmy;
OriginalOwnerArmy = ownerarmy;
AttackingArmy = 3 - ownerarmy;
if (AttackingArmy > 2 || AttackingArmy < 1) AttackingArmy = 0;
Pos = new Point3d(Pos.x, Pos.y, z);
if (AttackingArmy != 0)
{
HUDMessage = ArmiesL[AttackingArmy] + " destroyed " + Name;
LOGMessage = "Heavy damage to " + Name + " - good job " + ArmiesL[AttackingArmy] + "!!!";
}
else
{
HUDMessage = Name + " was destroyed";
LOGMessage = Name + " was destroyed";
}
Points = points;
Pos = new Point3d(x, y, 0);
string keyp = Calcs.doubleKeypad(Pos);
/* Sector = msn.GamePlay.gpSectorName(x, y).ToString() + "." + keyp;
Sector = Calcs.correctedSectorNameDoubleKeypad(msn, Pos);
bigSector = Calcs.makeBigSector(msn, Pos, Points);
radius = rad;
TriggerDestroyRadius = trigrad;
RadarEffectiveRadius = radar_effective_radius_m;
OrdnanceRequiredToTrigger_kg = orttkg;
ObjectsRequiredToTrigger_num = orttn;
ObjectsDestroyed_num = 0;
ActorsDestroyed_num = 0;
TimetoRepairIfDestroyed_hr = ttr_hr;
Destroyed = false;
DestroyedPercent = 0;
ObjectiveAchievedForPoints = false;
TimeToUndestroy_UTC = null;
LastHitTime_UTC = null;
Scouted = false;
lastScoutedPos = Pos;
lastScoutedSector = Sector;
PlayersWhoScoutedNames = new Dictionary();
PlayersWhoContributedNames = new HashSet();
PlayersWhoRepairedNamesTimes = new Dictionary();
hasGeneralStaff = false;
IsPrimaryTarget = false;
PrimaryTargetWeight = primary_target_weight;
Comment = comment;
}
//ALWAYS use this to load an objective's initial submission - it will do things like making sure //it is appropriate to load, making sure it is set up for the right army, etc.
{
if (Destroyed || !IsEnabled || MOMobileObjectiveType == null || MOMobileObjectiveType == MO_MobileObjectiveType.None) return false;
if (hasChief() && hasChiefGroundactorsButTheyAreDeadOrDestroyed()) msn.MO_HandleMobileObjectivePlacement(this, reestablishObjective: true);
return true;
}
//load submission if requested //ISectionFile printSectionFile(ISectionFile f, maddox.game.IGamePlay GamePlay, AMission mission, int army) f.save(msn.CLOD_PATH + msn.FILE_PATH + "/sectionfiles/" + "printSectionFile-" + ID + ".mis"); //testing //msn.GamePlay.gpPostMissionLoad(s); //
{
if (InitSubmissionName != null && InitSubmissionName.Length > 0 && !Destroyed && IsEnabled)
{
string s = msn.CLOD_PATH + msn.FILE_PATH + "/" + InitSubmissionName;
try
{
msn.Timeout(5, () =>
{
ISectionFile f = msn.GamePlay.gpLoadSectionFile(s);
f = Calcs.changeArmy_Waypoints_SectionFile(f, msn.GamePlay, msn, changeToArmy: OwnerArmy, maxWaypoints_remove: 15, maxPercentWaypoints_remove: 30);
if (msn.ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Objective init submission ");
msn.GamePlay.gpPostMissionLoad(f);
Console.WriteLine(s.Replace(msn.CLOD_PATH + msn.FILE_PATH, "") + " initial submission file loaded for " + ID + " " + Name);
});
return true;
}
catch (Exception ex) { Console.WriteLine("loadInitSubmission ERROR InitSubmission for Objective NOT loaded: {0} \n\n {1}", s, ex.ToString()); return false; }
}
if (Destroyed) Console.WriteLine(Name + ": " + InitSubmissionName + " initsubmission NOT loaded because this objective is destroyed.");
return false;
}
//Return cleaned up ID string that can be used for chief name or (for example) //as static name in .mis files. Returns mo.ID by default or cleaned up for any string.
{
if (ChiefName != null && ChiefName.Length > 0) return true;
return false;
}
//moving is like a train, submarine, convoy, ship that is underway, a "chief" //So now that we have actual "chiefs" on nonmoving objectives we have to differentiate //I'm not really sure how to except that moving things include "chief" in their name //However, AA/artillery & some other things do, too.
{
if (i == "") i = ID;
return i.Replace(' ', '_').Replace('.', '_').Replace('\\', '_');
}
No description available.
{
if (ChiefName == null && ChiefName.Length == 0) return false;
if (ChiefName.ToLower().Contains("chief")) return true;
return false;
}
//msn.AutoFlak_locations is a separate structure so we can lock it & keep //it 'threadsafe'. We hope.
{
try
{
if (AutoFlak_locations_pointer < 0) AutoFlak_locations_pointer = 0;
AutoFlak_locations_pointer++;
lock (msn.AutoFlak_locations_lock)
{
if (msn.AutoFlak_locations == null || !msn.AutoFlak_locations.Keys.Contains(ID) || msn.AutoFlak_locations[ID] == null)
AutoFlak_locations_pointer = 0;
else if (AutoFlak_locations_pointer >= msn.AutoFlak_locations[ID].Count) AutoFlak_locations_pointer = 0;
}
return AutoFlak_locations_pointer;
}
catch (Exception ex)
{
Console.WriteLine("getAndAdvance_AutoFlak_location_pointer ERROR: " + ex.Message);
return 0;
}
}
public Point3d? getNext_AutoFlak_location()
{
try {
var ret = new Point3d();
int i = getAndAdvance_AutoFlak_location_pointer();
lock (msn.AutoFlak_locations_lock)
{
if (msn.AutoFlak_locations == null || !msn.AutoFlak_locations.Keys.Contains(ID) || msn.AutoFlak_locations[ID] == null) return null;
return msn.AutoFlak_locations[ID][i];
}
}
catch (Exception ex)
{
Console.WriteLine("getNext_AutoFlak_location ERROR: " + ex.Message);
return null;
}
}
No description available.
{
try
{
lock (msn.AutoFlak_locations_lock)
{
if (msn.AutoFlak_locations == null || !msn.AutoFlak_locations.Keys.Contains(ID) || msn.AutoFlak_locations[ID] == null) return new List();
return msn.AutoFlak_locations[ID];
}
}
catch (Exception ex)
{
Console.WriteLine("get_AutoFlak_locations ERROR: " + ex.Message);
return new List();
}
}
No description available.
{
if (Double.IsNaN(DestroyedPercent)) DestroyedPercent = 0;
if (Double.IsPositiveInfinity(DestroyedPercent)) DestroyedPercent = 1;
if (Double.IsNegativeInfinity(DestroyedPercent)) DestroyedPercent = -.5;
if (Double.IsNaN(AirfieldDamagePoints)) AirfieldDamagePoints = 0;
if (Double.IsPositiveInfinity(AirfieldDamagePoints)) AirfieldDamagePoints = AirfieldPointsRequired;
if (Double.IsNegativeInfinity(AirfieldDamagePoints)) AirfieldDamagePoints = -.5 * AirfieldPointsRequired;
if (Double.IsNaN(ActorsDestroyed_num)) ActorsDestroyed_num = 0;
if (Double.IsPositiveInfinity(ActorsDestroyed_num)) ActorsDestroyed_num = ActorsRequiredToTrigger_num;
if (Double.IsNegativeInfinity(ActorsDestroyed_num)) ActorsDestroyed_num = -.5 * ActorsRequiredToTrigger_num;
if (Double.IsNaN(ObjectsDestroyed_num)) ObjectsDestroyed_num = 0;
if (Double.IsPositiveInfinity(ObjectsDestroyed_num)) ObjectsDestroyed_num = ObjectsRequiredToTrigger_num;
if (Double.IsNegativeInfinity(ObjectsDestroyed_num)) ObjectsDestroyed_num = -.5 * ObjectsRequiredToTrigger_num;
if (Double.IsNaN(OrdnanceOnTarget_kg)) OrdnanceOnTarget_kg = 0;
if (Double.IsPositiveInfinity(OrdnanceOnTarget_kg)) OrdnanceOnTarget_kg = OrdnanceRequiredToTrigger_kg;
if (Double.IsNegativeInfinity(OrdnanceOnTarget_kg)) OrdnanceOnTarget_kg = -.5 * OrdnanceRequiredToTrigger_kg;
}
//So for actors & objects destroyed, if these numbers become NEGATIVE //the problem is that there may not be enough actors left to kill the target! At all! //So we put a limit. But if we reduce here, we add a bit more to the ordnance requirement...
{
if (Double.IsNaN(newDestroyedPercent)) newDestroyedPercent = 0;
ActorsDestroyed_num = newDestroyedPercent * ActorsRequiredToTrigger_num;
double ordnance_fact = 1;
if (ActorsDestroyed_num< 0)
{
ActorsDestroyed_num = ActorsDestroyed_num / 3;
if (ActorsDestroyed_num < -ActorsRequiredToTrigger_num / 3) ActorsDestroyed_num = -ActorsRequiredToTrigger_num / 3;
ordnance_fact *= 1.3333;
}
ObjectsDestroyed_num = newDestroyedPercent * ObjectsDestroyed_num;
if (ObjectsDestroyed_num < 0)
{
ObjectsDestroyed_num = ObjectsDestroyed_num / 3;
if (ObjectsDestroyed_num < -ObjectsRequiredToTrigger_num / 3) ObjectsDestroyed_num = -ObjectsRequiredToTrigger_num / 3;
ordnance_fact *= 1.3333;
}
OrdnanceOnTarget_kg = newDestroyedPercent * OrdnanceRequiredToTrigger_kg * ordnance_fact;
AirfieldDamagePoints = newDestroyedPercent * AirfieldPointsRequired;
DestroyedPercent = newDestroyedPercent;
if (Destroyed && DestroyedPercent <= 0) TimeToUndestroy_UTC = DateTime.UtcNow;
return DestroyedPercent;
}
public Tuple addDefenseUnits(int numToAdd = 1, double daysUntilExpiration = 13)
{
try
{
int oldDefenseUnits = numDefenseUnits();
DateTime currTime_UTC = DateTime.UtcNow;
if (DefenseUnits == null) DefenseUnits = new SortedDictionary();
DefenseUnits[dt] = numToAdd;
TimeSpan time_remaining = TimeSpan.Zero;
if (TimeToUndestroy_UTC.HasValue) time_remaining = TimeToUndestroy_UTC.Value.Subtract(currTime_UTC);
double hours_left = time_remaining.TotalHours;
double new_hours_left = hours_left;
if (hours_left > 0)
{
double duf_add = Math.Pow(Math.Abs(numToAdd + oldDefenseUnits), 0.7) - Math.Pow(Math.Abs(oldDefenseUnits), 0.7) / Math.Pow(20,0.7);
double newDefenseUnits_factor = 1 + duf_add;
new_hours_left = hours_left / newDefenseUnits_factor;
TimeToUndestroy_UTC = currTime_UTC.AddHours(new_hours_left);
}
return new Tuple(oldDefenseUnits + numToAdd, hours_left - new_hours_left);
} catch (Exception ex) {
Console.WriteLine("MO addDefenseUnits ERROR: " + ex.ToString());
return new Tuple(numToAdd, 0);
}
}
else DefenseUnits.Remove(exp_dt); //remove any old/expired defense units //defense units speed up the OBJ's repairs. But there is a somewhat tricky formula //More defense units have diminishing returns...
{
if (DefenseUnits == null) return 0;
int ndu = 0;
DateTime dt = DateTime.UtcNow;
foreach (DateTime exp_dt in DefenseUnits.Keys.ToList())
{
try
{
if (dt.CompareTo(exp_dt) <= 0) ndu += DefenseUnits[exp_dt];
}
catch (Exception ex) { }
}
return ndu;
}
No description available.
{
return 1 + Math.Pow(Math.Abs(numDefenseUnits()), 0.7) / Math.Pow(10.0, 0.7);
}
DateTime duLastAttackResponseTime_dt = new DateTime();
Dictionary> defenders = new Dictionary>() { {1,new List() {"bob:Aircraft.SpitfireMkIa_100oct","bob:Aircraft.SpitfireMkIa_100oct","bob:Aircraft.SpitfireMkIa_100oct", "tobruk:Aircraft.KittyhawkMkIA","tobruk:Aircraft.HurricaneMkIIc", "tobruk:Aircraft.HurricaneMkIId","bob:Aircraft.BlenheimMkIVF",
"bob:Aircraft.BeaufighterMkINF","tobruk:Aircraft.HurricaneMkIIc", "tobruk:Aircraft.HurricaneMkIId","bob:Aircraft.BlenheimMkIVF",
"bob:Aircraft.BeaufighterMkINF","bob:Aircraft.BeaufighterMkIF"} },
{ 2, new List {
"bob:Aircraft.Bf-109E-4", "bob:Aircraft.Bf-109E-4", "bob:Aircraft.Bf-109E-4","bob:Aircraft.Bf-110C-2", "bob:Aircraft.Bf-110C-2", "bob:Aircraft.Bf-110C-4-NJG","bob:Aircraft.Bf-110C-4-NJG", "bob:Aircraft.Bf-110C-6", "bob:Aircraft.G50", "tobruk:Aircraft.Bf-109F-2", "tobruk:Aircraft.D520_Serie1","tobruk:Aircraft.Macchi-C202-SeriesIII", "bob:Aircraft.Bf-110C-7"
} }};
//do this once every 8 minutes at most int numAC = (ndu + 9) / 10;//So one for each 10 DUs, but round up always. //Timeout(0.15, () => //Stb_LoadSubAircraft(Point3d loc, string type = "SpitfireMkIa_100oct", string callsign = "26", string hullNumber = "3", string serialNumber = "001", string regiment = "gb02", string fuelStr = "", string weapons = "", double velocity_mps = 0, string fighterbomber = "", string skin_filename = "", string delay_sec = "", string escortedGroup = "", int numAC = 2, string formation = "VIC3", Player player = null, Vector3d? vwld = null, bool fromCover = true, Point3d? loc2 = null, int requestedNumInFlight = 0) //Timeout(0.15, () => //AiActor newActor = GamePlay.gpActorByName(newACActorName); //Console.WriteLine("NewActorloaded: " + newActor.Name() + " for " + player.Name()); //If the objective has an associated Chief then we can use that to find it's actual position for scouting/recon purposes...
{
int ndu = numDefenseUnits();
if (testNumNDU > 0) ndu = testNumNDU;
if (ndu < 1) return 0;
if (msn.ON_TESTSERVER) Console.WriteLine("defenseUnitsAttackResponse checking for {0} - {1} Defense Units, DU help factor {2}.", Name, ndu, defenseUnitsHelpFactor());
DateTime currTime = DateTime.UtcNow;
if ((currTime.Subtract(duLastAttackResponseTime_dt)).TotalMinutes < 8) return 0;
double nump = (double)Calcs.gpNumberOfPlayers(msn.GamePlay);
int numDefendingPlayers = Calcs.gpNumberOfPlayers(msn.GamePlay, OwnerArmy);
if (nump > 35 || numDefendingPlayers > 15) return 0;
if (!msn.ON_TESTSERVER && msn.movebombtargetmission.getPlainDistanceToNearestLivePilot(Pos, armyToMatch: AttackingArmy) > 10000) return 0;
duLastAttackResponseTime_dt = currTime;
AiAirport ap = Calcs.nearestAirport(msn.GamePlay, Pos, OwnerArmy);
double spawnAlt_m = Calcs.LandElevation_m(ap.Pos());
if (spawnAlt_m < 0) spawnAlt_m = 0;
spawnAlt_m += 14;
Point3d spawnPos = new Point3d(ap.Pos().x, ap.Pos().y, spawnAlt_m);
Point3d attackPos = new Point3d(Pos.x, Pos.y, 1000);
double wait_s = 10.253;
if (Calcs.CalculatePointDistance(spawnPos, Pos) < 2000) wait_s = 40.3265;
msn.Timeout(wait_s, () =>
{
string regiment = "gb01";
if (OwnerArmy == 1) regiment = "BoB_RAF_F_141Sqn_Early";
if (OwnerArmy == 2) regiment = "BoB_LW_JG77_I";
int numGroups = (numAC + 2) / 3;
int numAC_remaining = numAC;
for (int i = 0; i < numGroups; i++)
{
int numAC_ingroup = numAC_remaining;
if (numAC_ingroup > 3) numAC_ingroup = 3;
if (numAC_ingroup <= 0) break;
numAC_remaining = numAC_remaining - numAC_ingroup;
string acType = Calcs.chooseRandomElement(defenders[OwnerArmy]);
string newACActorName = msn.covermission.Stb_LoadSubAircraft(spawnPos, type: acType, callsign: ran.Next(1, 25).ToString(), hullNumber: ran.Next(1, 100).ToString(), serialNumber: ran.Next(1, 1000).ToString("000"), regiment: regiment, fuelStr: "32", weapons: "", velocity_mps: 120, fighterbomber: "f", numAC: numAC_ingroup, fromCover: false, loc2: attackPos, requestedNumInFlight: 2, army: OwnerArmy);
msn.Timeout(1.05, () =>
{
AiActor newActor = msn.GamePlay.gpActorByName(newACActorName);
AiAircraft newAircraft = newActor as AiAircraft;
AiAirGroup newAirgroup = newAircraft.AirGroup();
Console.WriteLine("defenseUnitsAttackResponse - new Airgroup loaded: " + newAirgroup.Name() + " newACActorName: " + newACActorName);
msn.Timeout(5, () =>
{
msn.movebombtargetmission.interceptNearestEnemyOnRadar(newAirgroup);
});
});
}
Console.WriteLine("defenseUnitsAttackResponse for {0} - just launched {1} defense aircraft.", Name, numAC);
});
return numAC;
}
DateTime chief_cachetime_dt = new DateTime();
Point3d chief_loc_cache = new Point3d();
//cache this for up to 3 mins so we don't have to do the actor search so often Point3d pos = Pos; //Some objectives move now, possibly every time the mission restarts, so this records & savesthe current position/sector at the time scouted. It will report this until re-scouted //Now see if it is a _chief type (mobile) objective and if so, update recon position according to that...
{
try
{
DateTime currTime = DateTime.UtcNow;
if (currTime.Subtract(chief_cachetime_dt).TotalSeconds < 300) return chief_loc_cache;
if (ChiefName != null && ChiefName.Length > 0)
{
List actorList = msn.GetActorsByNameMatch(ChiefName);
if (actorList != null && actorList.Count > 0) foreach (AiActor a in actorList)
{
if ((a as AiActor) != null && a.IsValid() && a.IsAlive())
{
pos = a.Pos();
break;
}
}
}
if (pos.z < 0) pos.z = 0;
/*{
maddox.game.LandTypes landType = msn.GamePlay.gpLandType(pos.x, pos.y);
if (landType == maddox.game.LandTypes.WATER) pos.z = 0;
}*/
chief_loc_cache = pos;
chief_cachetime_dt = currTime;
return pos;
} catch (Exception ex) { Console.WriteLine("returnCurrentPosWithChief ERROR: " + ex.ToString()); return Pos; }
}
//True ONLY IF it is supposed to have a chief, it (one or more) is in the game as a groundactor, BUT all of those // are dead OR destroyed
{
try
{
if (ChiefName != null && ChiefName.Length > 0)
{
List actorList = msn.GetActorsByNameMatch(ChiefName);
if (actorList != null && actorList.Count > 0) foreach (AiActor a in actorList)
{
if ((a as AiActor) != null)
{
if (a.IsAlive()) return true;
break;
}
}
}
return false;
}
catch (Exception ex) { Console.WriteLine("isChiefAlive ERROR: " + ex.ToString()); return false; }
}
if (hasChief() || !IsEnabled ) return false; //at this point, if HASCHIEF is true then it should have SOME matching actors //for this to work, we need the COMPLETE list, not just the live/undestroyed ones //complicated, but: we're not counting artillery as an "actor/chief" (which might need replacing) unless the objective type is artillery/aa //This is only true if there ARE some chiefs AND they are ALL dead. No matching chiefs at //all => false and even one ALIVE matching chief => false //oopse, changing this, as GetActorsByNameMatch doesn't return dead or "invalid" actors anyway...
{
try
{
if (ChiefName == null && ChiefName.Length == 0) return false;
int numValidDeadChiefs = 0;
List actorList = msn.GetActorsByNameMatch(ChiefName, completeList: true);
if (actorList == null || actorList.Count == 0) return false;
foreach (AiActor a in actorList)
{
if ((a as AiActor) != null)
{
if (MOObjectiveType != MO_ObjectiveType.Artillery_and_AA && (a as AiGroundActor) != null && ((a as AiGroundActor).Type() == AiGroundActorType.AAGun || (a as AiGroundActor).Type() == AiGroundActorType.Artillery)) continue;
if (a.IsAlive()) return false;
numValidDeadChiefs++;
}
}
if (numValidDeadChiefs > 0) return true;
Console.WriteLine("hasChiefGroundactorsButTheyAreDeadOrDestroyed - objective {0} should have chiefs but it has NONE - reloading the chiefs for {0}", Name);
}
catch (Exception ex) { Console.WriteLine("hasChiefGroundactorsBut ERROR: " + ex.ToString()); return false; }
}
private void estimateElevationXnumtimesScouted()
{
double elev = lastScoutedPos.z;
Point3d tempPos = lastScoutedPos;
int remainder;
int roundTo = 85 - numTimesScouted * 20;
if (roundTo < 0) return;
elev = Math.DivRem(Convert.ToInt32(elev), roundTo, out remainder) * roundTo;
tempPos.z = elev;
lastScoutedPos = tempPos;
}
//Console.WriteLine("updateCurrentReconPosWithChief() (before) pos | lastscoutedpos : {0:n0} {1:n0} {2:n0} | {3:n0} {4:n0} {5:n0} {6} {7} {8}", Pos.x, Pos.y, Pos.z, lastScoutedPos.x, lastScoutedPos.y, lastScoutedPos.z, Sector, lastScoutedSector, ID); lastScoutedPos = Pos; //Some objectives move now, possibly every time the mission restarts, so this records & savesthe current position/sector at the time scouted. It will report this until re-scouted //TODO: Chief name matching is not thoroughly tested...
{
lastScoutedSector = Sector;
try
{
if (isMoving())
{
string addStr = " ";
List actorList = msn.GetActorsByNameMatch(ChiefName);
if (actorList.Count == 0)
{
if (IsPrimaryTarget)
{
IsPrimaryTarget = false;
msn.MO_SelectPrimaryObjectives(army: OwnerArmy,
totalPoints: msn.MO_PrimaryPointsRequired[(ArmiesE)(OwnerArmy)] - Points, fresh: false);
}
}
else
{
if (actorList[0] == null) return;
if (lastScoutedSector.Contains(addStr)) lastScoutedSector = lastScoutedSector.Replace(addStr, "");
Point3d tempPos = actorList[0].Pos();
tempPos.z = Calcs.LandElevation_m(tempPos);
lastScoutedPos = tempPos;
lastScoutedSector = Calcs.correctedSectorNameDoubleKeypad(msn, lastScoutedPos);
}
}
if (lastScoutedPos.z < 0) lastScoutedPos = new Point3d(lastScoutedPos.x, lastScoutedPos.y, 0);
}
catch (Exception ex) { Console.WriteLine("updateCurrentReconPosWithChief ERROR: " + ex.ToString()); }
}
//lastTimeScouted_hist_dt = msn.showTimeLeft().Item2;//this is a cool idea but there are some issues, for example if we run a mission today until 8pm and then start again it will be 4:30 am **the same day** } else //for disabled objectives (generally those scouted earlier but now re-scouted and disabled) lastScoutedPos = new Point3d(-1, -1, -1); //Some objectives move now, so this records & savesthe current position/sector at the time scouted. It will report this until re-scouted if (PlayersWhoScoutedNames.ContainsKey(player.Name())) return; //they're already in the list //PlayersWhoScoutedNames PlayersWhoScoutedNames[player.Name()] = PlayersWhoScoutedNames.Count; //Add them to the list of players who have scouted; So 0 for the first player to scout, 1 for the 2nd, etc
{
Scouted = true;
numTimesScouted++;
lastTimeScouted_dt = DateTime.UtcNow;
if (IsEnabled)
{
Point3d oldLastScoutedPos = lastScoutedPos;
updateCurrentReconPosWithChief();
estimateElevationXnumtimesScouted();
if (numTimesScouted > 1 && !Calcs.Point3dEqualXY(oldLastScoutedPos, lastScoutedPos)) lastScoutedSector += "!!moved!!";
{
lastScoutedSector = "[Scouted earlier but not found in latest recon of " + Calcs.correctedSectorName(msn, Pos) + "!]";
}
if (player == null || player.Name() == null) return;
PlayersWhoContributedNames.Add(player.Name());
}
if (!lastTimeScouted_dt.HasValue || lastTimeScouted_dt.Value.AddMinutes(15) < now_dt) //do this only if the obj hasn't been scouted before, OR scouted before but more than 15 mins ago.
{
DateTime now_dt = DateTime.UtcNow;
{
if (!IsEnabled)
{
msn.GamePlay.gpHUDLogCenter(new Player[] { player }, Name + " has been abandoned or moved!");
msn.GamePlay.gpLogServer(new Player[] { player }, "You bombed " + Name + " - but it appears to have been abandoned or moved. Check the scouted objectives report.", null);
}
makeScouted(player);
}
}
if (Calcs.CalculatePointDistance(pos, Pos) > 2000) return; //only do this if hit is less than 2km from the objective. if (!lastTimeScouted_dt.HasValue || lastTimeScouted_dt.Value.AddMinutes(15) < now_dt) //do this only if the obj hasn't been scouted before, OR scouted before but more than 15 mins ago.
{
double dist_m = Calcs.CalculatePointDistance(pos, Pos);
if (dist_m < radius * 2 || dist_m < TriggerDestroyRadius * 2) defenseUnitsAttackResponse();
DateTime now_dt = DateTime.UtcNow;
{
if (!IsEnabled && player != null)
{
msn.GamePlay.gpHUDLogCenter(new Player[] { player }, Name + " has been abandoned or moved!");
msn.GamePlay.gpLogServer(new Player[] { player }, "You bombed " + Name + " - but it appears to have been abandoned or moved. Check the scouted objectives report.", null);
}
makeScouted(player);
}
}
No description available.
{
if ((this.MOMobileObjectiveType != null && this.MOMobileObjectiveType != MO_MobileObjectiveType.None)) return true;
else return false;
}
* //Turning this off for now as it seems useless? Not sure what .Enable == false means? //Just because it is disabled doesn't mean we can't include it in our objectives list. Maybe it will be enabled later or whatever...
{
if (msn.MissionObjectivesList.Keys.Contains(tn))
{
Console.WriteLine();
Console.WriteLine("*************MissionObjective initialize WARNING****************");
Console.WriteLine("MissionObjective initialize: Objective Trigger ID " + tn + " : " + n + " IS DUPLICATED in the .cs file. This duplicate occurence will be ignored.");
Console.WriteLine();
return false;
}
if (mtt == MO_TriggerType.Trigger)
{
if (gp == null)
{
Console.WriteLine();
Console.WriteLine("*************MissionObjective initialize WARNING****************");
Console.WriteLine("gp is null!");
Console.WriteLine();
}
if (gp.gpGetTrigger(tn) == null)
{
Console.WriteLine();
Console.WriteLine("*************MissionObjective initialize WARNING****************");
Console.WriteLine("MissionObjective initialize: Objective Trigger " + tn + " : " + n + " DOES NOT EXIST in the MAIN .mis file. It may exist in a sub-mission file; please verify.");
Console.WriteLine();
}
/*
if (gp.gpGetTrigger(tn) != null && gp.gpGetTrigger(tn).Enable !=null && gp.gpGetTrigger(tn).Enable == false )
{
Console.WriteLine("MissionObjective initialize: WARNING: Objective Trigger " + tn + " : " + n + " .Enable=false; including it in the mission objective list nevertheless.");
return true;
}*/
}
return true;
}
//Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(obj_ID, obj_name, MO_TriggerType.Trigger)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point // public MissionObjective(Mission m, string objectiveKey, string objectiveName, string flak, int ownerarmy, double pts, double repairdays, double trigger_percent, double x, double y, double trigger_destroy_radius, double radar_effective_radius, bool is_primary_target, double primary_target_weight, string comment, MO_ObjectiveType MObjType = MO_ObjectiveType.Radar, MO_TriggerType MOTrigType = MO_TriggerType.Trigger, string initSub="", double orttkg = 100, double orttn = 2) //PointArea style radar target.
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(obj_ID))
{
msn.MissionObjectivesList.Add(obj_ID, new MissionObjective(msn, obj_ID, obj_name, flak, ownerarmy, pts, repair_days, mission_trigger_type, trigger_percent, x, y, d, e, pt, ptp, comment));
}
}
//Console.WriteLine("Checking for new/updated RadarPointArea " + objectiveName); //Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(targetKey, objectiveName, MO_TriggerType.PointArea)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point //msn.MissionObjectivesList.Add(targetKey, new MissionObjective(msn, targetKey, objectiveName, flak, ownerarmy, points, repair, missionTriggerType, percentToKill, x, y, siteRadius_m, RadarEffectiveRadius_m, isPrimaryTarget, primaryTargetWeight, comment)); //initsub t, p int targetsRequired = Convert.ToInt32((Math.Floor(numTargets * 0.8))); // require 80% of the groundstationaries in the target area. This should be quite hard...
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(targetKey))
{
Console.WriteLine("Adding new/updated RadarPointArea" + objectiveName);
double numTargets = 0;
GroundStationary[] gs = gp.gpGroundStationarys(x, y, siteRadius_m);
if (gs != null) numTargets = gs.Length;
if (targetsRequired < 5) targetsRequired = orttn;
msn.MissionObjectivesList.Add(targetKey, new MissionObjective(msn, targetKey, objectiveName, flak, ownerarmy, points, repair_days, "PointArea", 100, x, y, siteRadius_m, RadarEffectiveRadius_m, isPrimaryTarget, primaryTargetWeight, comment, MObjType: MO_ObjectiveType.Radar, MOTrigType: MO_TriggerType.PointArea, init_submission_filename: initSub, orttkg: orttkg, orttn: targetsRequired, arttn: arttn, MOProdStorType: MO_ProducerOrStorageType.None, chief_name: ""));
}
}
//Console.WriteLine("Adding Trigger pre " + tn + n + " " + pts.ToString()); //Console.WriteLine("Adding Trigger post1 " + tn + n + " " + pts.ToString()); //MissionObjective (Mission m, MO_ObjectiveType mot, string tn, string n, int ownerarmy, double pts, string t, double p, double x, double y, double d, bool pt, bool ptp, string comment) //Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(tn, n, MO_TriggerType.Trigger)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point //Console.WriteLine("Adding Trigger post2 " + tn + n + " " + pts.ToString()); if (ownerarmy == 1 && x > 210000 && y > 180000 && x < 321000 && y < 270000) ptp *= 1.4; //vastly increase proportion of mission objectives in 'primary' campaign area, and reduce others, for Blue 2020-01
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(tn))
{
else ptp *= 0.8;
msn.MissionObjectivesList.Add(tn, new MissionObjective(msn, mot, tn, n, flak, submissionfile, chiefname, ownerarmy, pts, t, p, x, y, d, pt, ptp, ttr_hours, comment, numHitsToTrigger: numHitsToTrigger, numObjectsInRadius: numObjectsInRadius));
}
}
//Console.WriteLine("Adding Trigger pre " + tn + n + " " + pts.ToString()); //Console.WriteLine("Adding Trigger post1 " + tn + n + " " + pts.ToString()); //MissionObjective (Mission m, MO_ObjectiveType mot, string tn, string n, int ownerarmy, double pts, string t, double p, double x, double y, double d, bool pt, bool ptp, string comment) //Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(tn, n, MO_TriggerType.PointArea)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point //Console.WriteLine("Adding Trigger post2 " + tn + n + " " + pts.ToString()); //public MissionObjective(Mission m, string objective_id, Point3d pos, double radius_m, double objective_points, double primaryobjective_weight, double timeToRemainActive_hrs, string flak_file, int ownerarmy, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, string chief_name = "")
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(tn))
{
msn.MissionObjectivesList.Add(tn, new MissionObjective(msn, mot, tn, n, flak, initSub, ownerarmy, pts, x, y, rad, trigrad, orttkg, ortt, artt, ptp, ttr_hours, auto_flak, auto_flak_ifprimary, flak_numbatteries, flak_numbinbattery, comment, chief_name: chief, canBeDisabled: canBeDisabled));
}
}
//public MissionObjective(Mission m, string objective_id, string name, Point3d pos, double radius_m, double objective_points, double primaryobjective_weight, double timeToRemainActive_hrs, string flak_file, int ownerarmy, bool auto_flak = true, bool auto_flak_ifprimary = true, int flak_numbatteries = 7, int flak_numberinbattery = 8, MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None, string chief_name = "") //Console.WriteLine("Adding Trigger pre " + tn + n + " " + pts.ToString()); //Console.WriteLine("Adding Trigger post1 " + tn + n + " " + pts.ToString()); //MissionObjective (Mission m, MO_ObjectiveType mot, string tn, string n, int ownerarmy, double pts, string t, double p, double x, double y, double d, bool pt, bool ptp, string comment) //Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(objective_id, objective_id, MO_TriggerType.TemporaryLandingGround)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(objective_id))
{
Console.WriteLine("Adding LandingGround post2 " + objective_id + " " + name + " " + objective_points.ToString());
msn.MissionObjectivesList.Add(objective_id, new MissionObjective(m: msn, objective_id: objective_id, name: name, pos: pos, radius_m: radius_m,
objective_points: objective_points, primaryobjective_weight: primaryobjective_weight,
timeToRemainActive_hrs: timeToRemainActive_hrs, flak_file: flak_file, ownerarmy: ownerarmy,
auto_flak: auto_flak, auto_flak_ifprimary: auto_flak_ifprimary = true, flak_numbatteries: flak_numbatteries,
flak_numberinbattery: flak_numberinbattery, MOProdStorType: MOProdStorType, chief_name: chief_name, planeset: planeset));
}
}
//Console.WriteLine("Adding Mobile pre " + tn + n + " " + pts.ToString()); //Console.WriteLine("Adding Trigger post1 " + tn + n + " " + pts.ToString()); //MissionObjective (Mission m, MO_ObjectiveType mot, string tn, string n, int ownerarmy, double pts, string t, double p, double x, double y, double d, bool pt, bool ptp, string comment) //Add the item -always when add==false and if it doesn't already exist, when add==true if (!MO_SanityChecks(tn, n, MO_TriggerType.PointArea)) return; //sanity checks - we're skipping many items with the IF statement, so no need for sanity check before this point //msn.MissionObjectivesList.Add(tn, new MissionObjective(msn, mot, tn, n, flak, initSub, ownerarmy, pts, x, y, rad, trigrad, orttkg, ortt, ptp, ttr_hours, auto_flak, auto_flak_ifprimary, flak_numbatteries, flak_numberinbattery, comment)); //transfer over all Landing Grounds from the disk file restore to the active MissionObjectivesList //They are player-created so will never appear in the .cs list of objectives //(Unless we add a landing ground as an objective in the .cs - which means that //objective is to CREATE a landing ground there, and that is how players get credit //for that objective
double mob_hrsbetweenMoves = 12, double x_sw = 0, double y_sw = 0, double x_ne = 360000, double y_ne = 310000,
double min_move_dist_km = 2,
double max_move_dist_km = 5,
MO_ProducerOrStorageType ProdStorType = MO_ProducerOrStorageType.None,
string comment = "", bool addNewOnly = false, double radar_effective_radius_m = 20000,
bool canbedisabled = false)
{
if (!addNewOnly || !msn.MissionObjectivesList.ContainsKey(tn))
{
Console.WriteLine("Adding Mobile post2 " + tn + n + " " + pts.ToString());
msn.MissionObjectivesList.Add(tn, new MissionObjective(msn, mot, tn, n, flak, ownerarmy, pts, x, y, rad, trigrad, orttkg, ortt, artt, ptp, ttr_hours, auto_flak, auto_flak_ifprimary, flak_numbatteries, flak_numberinbattery, MobObjType, mob_hrsbetweenMoves, new Point3d(x_sw, y_sw, 0), new Point3d(x_ne, y_ne, 0), min_move_dist_km, max_move_dist_km, ProdStorType, comment, radar_effective_radius_m: radar_effective_radius_m, canbedisabled: canbedisabled));
}
}
/*
public MissionObjective(Mission m, MO_ObjectiveType objective_type, string objective_ID, string objective_name, string flak, string init_submission_filename, int ownerarmy,
double points, double x, double y, double rad, double trigrad, double orttkg, double orttn, double primary_target_weight, double ttr_hr, bool auto_flak, bool auto_flak_ifprimary,
int num_flakbatteries, int num_in_eachbattery, string comment,
MO_MobileObjectiveType mobile_objective_type,
double mobile_hours_between_moves,
Point3d mobile_SW_point,
Point3d mobile_NE_point,
MO_ProducerOrStorageType MOProdStorType = MO_ProducerOrStorageType.None)
* */
if (!mo.TimeToUndestroy_UTC.HasValue || mo.TimeToUndestroy_UTC.Value.CompareTo(DateTime.UtcNow) <= 0) continue; //The tempLG lasts until TimeToUndestroy and at that point we drop it from the //objectives list altogether. This prevents player-created LG objectives from persisting forever in the objectives list if (terr != 0 && terr != mo.OwnerArmy) continue; //If the territory of the LG is taken over by the other army, the LG is lost...
{
try
{
Console.WriteLine("Starting LandingGroundTransferObjectives....");
foreach (string key in MissionObjectivesList_OLD.Keys)
{
MissionObjective mo = MissionObjectivesList_OLD[key];
if (mo.MOObjectiveType != MO_ObjectiveType.TemporaryLandingGround) continue;
Console.WriteLine("LandingGroundTransferObjectives: Found an LG! " + key);
if (!mo.TimeToUndestroy_UTC.HasValue) Console.WriteLine("LandingGroundTransferObjectives: The LG's timetoundestroy was NULL");
else Console.WriteLine("LandingGroundTransferObjectives: The LG's timetoundestroy was {0}", mo.TimeToUndestroy_UTC.Value.ToString("yyyy-MM-dd-HHmmss"));
Console.WriteLine("LandingGroundTransferObjectives: The LG had an undestroy time & it is in the future - (ID, army)" + key + " " + mo.OwnerArmy.ToString());
int terr = msn.GamePlay.gpFrontArmy(mo.Pos.x, mo.Pos.y);
Console.WriteLine("LandingGroundTransferObjectives: The LG is on friendly or neutral territory - " + key);
msn.MissionObjectivesList[key] = mo;
Console.WriteLine("LandingGroundTransferObjectives: The LG was added to the objectives list & renewed/a spawn point created - " + key);
}
}
catch (Exception ex) { Console.WriteLine("andingGroundTransferObjectives ERROR: " + ex.ToString()); }
}
//ID is the ID used in the [Trigger] portion of the .mis file. The central portion of the line can be copy/pasted from the .mis file (then lightly edited) //Console.Write("#1a"); //MissionObjective(Name, Flak ID, OwnerArmy,points,ID, Days to repair, Trigger Type,Trigger percentage, location x, location y, trigger radius, radar effective radius, isPrimaryTarget, PrimaryTargetWeight (0-200), comment) { //weights change 0-200, many weights below adjusted, 2020-01 //Prior to 2/15/2020 I had moved most Red Radar trigger % to about 40%...
{
bool add = addNewOnly;
addRadarPointArea("Westgate Radar", "WesR", 1, 5, 2, "WestgateRadar", "", 5000, 13, 0, 244791, 262681, 150, 25000, false, 30, "", add);
addRadarPointArea("Eastbourne Radar", "EasR", 1, 5, 2, "EastbourneRadar", "", 5000, 13, 0, 178778, 197444, 200, 25000, false, 10, "", add);
addRadarPointArea("Littlehampton Radar", "LitR", 1, 5, 2, "LittleHamptonRadar", "", 5000, 13, 0, 123384, 196295, 200, 35000, false, 10, "", add);
addRadarPointArea("Ventnor Radar", "VenR", 1, 5, 2, "VentorRadar", "", 5000, 13, 0, 70423, 171706, 200, 35000, false, 10, "", add);
addRadarPointArea("Radar Communications Center", "HQR", 1, 14, 7, "RAFRadarHQ", "", 20000, 21, 0, 180207, 288435, 250, 20000, false, 40, "", add);
addRadarPointArea("Radar Communications Fallback Center", "HQR", 1, 14, 7, "RAFRadarFallback", "", 9000, 5, 0, 181861, 288173, 130, 20000, false, 60, "", add);
addRadarPointArea("Radar Poole", "PooR", 1, 6, 2, "PooleRadar", "", 5000, 13, 0, 15645, 170552, 200, 35000, false, 5, "", add);
addRadarPointArea("Dover Radar", "DovR", 1, 5, 2, "DoverRadar", "", 5000, 13, 0, 246777, 235751, 200, 25000, false, 50, "", add);
addRadarPointArea("Deal Radar", "DeaR", 1, 5, 2, "DealRadar", "", 5000, 13, 0, 249454, 247913, 200, 25000, false, 50, "", add);
addRadarPointArea("Luftwaffe Reserve Radar Communications HQ", "HQGRR", 2, 14, 7, "RTargetHQRReserve", "Genghis-LOADONCALL-german-radar-ReserveHQ-objective.mis", 25000, 20, 0, 304020, 42462, 400, 250000, false, 2, "", add);
addRadarPointArea("RAF Reserve Radar Communications HQ", "RAFReserveRadarHQ", 1, 14, 7, "BTargetHQRReserve", "Genghis-LOADONCALL-british-radar-ReserveHQ-objective.mis", 25000, 20, 0, 150779, 253805, 400, 100000, false, 2, "", add);
addRadarPointArea("Dungeness Radar", "DunR", 1, 4, 2, "DungenessRadar", "", 6000, 10, 0, 221278, 214167, 200, 25000, false, 50, "", add);
addRadarPointArea("Brookland Radar", "BroR", 1, 4, 2, "BrooklandRadar", "", 6000, 10, 0, 212973, 220079, 200, 25000, false, 50, "", add);
addRadarPointArea("Sandwich Radar", "SanR", 1, 4, 2, "SandwichRadar", "", 6000, 10, 0, 248579, 253159, 200, 25000, false, 50, "", add);
addRadarPointArea("Oye Plage Freya Radar", "OypR", 2, 4, 2, "OyePlageRadar", "", 1000, 4, 0, 294183, 219444, 85, 20000, false, 35, "", add);
addRadarPointArea("Coquelles Freya Radar", "CoqR", 2, 4, 2, "CoquellesRadar", "", 1000, 4, 0, 276566, 214150, 85, 20000, false, 35, "", add);
addRadarPointArea("Dunkirk Radar #2", "DuRN", 2, 4, 2, "DunkirkRadar", "", 1000, 4, 0, 341887, 232695, 85, 20000, false, 35, "", add);
/*
addRadar("Oye Plage Freya Radar", "OypR", 2, 4, 2, "RTarget28R", "TGroundDestroyed", 61, 294183, 219444, 100, 20000, false, 35, "", add);
addRadar("Coquelles Freya Radar", "CoqR", 2, 4, 2, "RTarget29R", "TGroundDestroyed", 63, 276566, 214150, 100, 20000, false, 35, "", add);
addRadar("Dunkirk Radar #2", "DuRN", 2, 4, 2, "RTarget30R", "TGroundDestroyed", 77, 341887, 232695, 100, 20000, false, 35, "", add);
*/
/*
BTarget15R TGroundDestroyed 75 248739 253036 200
BTarget16R TGroundDestroyed 75 249454 247913 200
BTarget17R TGroundDestroyed 75 246777 235751 200
BTarget18R TGroundDestroyed 75 212973 220079 200
BTarget19R TGroundDestroyed 50 221278 214167 200
BTarget20R TGroundDestroyed 75 178778 197288 200
BTarget21R TGroundDestroyed 76 123384 196295 200
BTarget22R TGroundDestroyed 75 70423 171706 200
BTarget28 TGroundDestroyed 61 180207 288435 200
RTarget28R TGroundDestroyed 61 294183 219444 50
RTarget29R TGroundDestroyed 63 276566 214150 50
RTarget30R TGroundDestroyed 77 341887 232695 100
RTarget38R TGroundDestroyed 85 341866 232710 50
RTarget39R TGroundDestroyed 85 276567 214150 50
RTarget40R TGroundDestroyed 86 263234 153713 50
RTarget41R TGroundDestroyed 85 232576 103318 50
RTarget42R TGroundDestroyed 86 250599 116531 50
RTarget43R TGroundDestroyed 86 262560 133020 50
RTarget44R TGroundDestroyed 86 266788 197956 50
RTarget45R TGroundDestroyed 85 264266 188554 50
RTarget46R TGroundDestroyed 66 266625 169936 50
RTarget47R TGroundDestroyed 99 185931 88085 50
RTarget48R TGroundDestroyed 100 195165 93441 50
RTarget49R TGroundDestroyed 100 157636 60683 50
RTarget50R TGroundDestroyed 100 135205 29918 50
RTarget51R TGroundDestroyed 100 103641 36893 50
RTarget52R TGroundDestroyed 100 65637 44013 50
RTarget53R TGroundDestroyed 77 60453 63873 50
RTarget54R TGroundDestroyed 100 17036 77666 50
*/
}
//Format: addTrigger(MO_ObjectiveType.Building (Aircraft, airport, etc), "Name, OwnerArmy,Points,ID,TriggerType,PercRequired,XLoc,YLoc,Radius,IsPrimaryTarget,IsPrimaryTargetWeight,TimeToRepairIfDestroyed_hours,Comment ""); //PercRequired doesn't actually do anything because the perc required is set in the TRIGGER in the .mis file. However if you accurately record here the same //percent to kill value in the .mis file we can do interesting/helpful things with it here...
{
bool add = addNewOnly;
int shipPriority = 70;
var stl = msn.showTimeLeft(null, false);
var inGame_dt = stl.Item2;
if (inGame_dt.CompareTo(new DateTime(1940, 8, 10)) <= 0) shipPriority = 190;
else if (inGame_dt.CompareTo(new DateTime(1940, 9, 13)) <= 0) shipPriority = 110;
/*
addTrigger(MO_ObjectiveType.Naval_Tanker_Convoy, "Berk Tanker Convoy", "", "", "", 2, 4, "Tankers_Berk", "TGroupDestroyed", 26, 258734, 153846, 3600, false, 120, 96, "", add);
addTrigger(MO_ObjectiveType.Naval_Tanker_Convoy, "Wissant Tankers Convoy", "", "", "", 2, 4, "Tankers_Wissant", "TGroupDestroyed", 29, 263046, 213425, 4550, false, 120, 96, "", add);
addTrigger(MO_ObjectiveType.Naval_Freighter_Convoy, "Dunkirk Freighters", "", "", "", 2, 4, "Freighters_Dunkirk", "TGroupDestroyed", 29, 310284, 243264, 5850, false, 80, 96, "", add);
addTrigger(MO_ObjectiveType.Naval_Ship, "Le Havre Kriegsmarine Fleet", "", "", "", 2, 4, "Naval_LeHavre", "TGroupDestroyed", 7, 156521, 51042, 1150, false, 80, 144, "", add);
addTrigger(MO_ObjectiveType.Naval_Tanker_Convoy, "Pigwell Bay Tanker Convoy", "", "", "", 1, 5, "Tankers_PigwellBay", "TGroupDestroyed", 29, 251894, 254841, 2300, false, 120, 96, "", add);
addTrigger(MO_ObjectiveType.Naval_Tanker_Convoy, "Thames River Tankers", "", "", "", 1, 4, "Tankers_Thames", "TGroupDestroyed", 29, 170048, 270059, 3100, false, 120, 120, "", add);
addTrigger(MO_ObjectiveType.Freighter_Ship, "Portsmouth Freighters", "", "", "", 1, 4, "Freighters_Portsmouth", "TGroupDestroyed", 8, 76646, 190424, 1650, false, 80, 170, "", add);
addTrigger(MO_ObjectiveType.Tanker_Ship, "Portsmouth Tanker Fleet", "", "", "", 1, 4, "Tankers_Portsmouth", "TGroupDestroyed", 8, 75880, 194966, 750, false, 80, 160, "", add);
addTrigger(MO_ObjectiveType.Naval_Ship, "Minster Royal Navy Convoy", "", "", "", 1, 4, "Naval_Minster", "TGroupDestroyed", 7, 209572, 268437, 1100, false, 80, 120, "", add);
addTrigger(MO_ObjectiveType.Tanker_Ship, "Canvey Island Tanker Convoy", "", "", "", 1, 4, "Naval_CanveyIsland", "TGroupDestroyed", 7, 191638, 273928, 1700, false, 80, 130, "", add);
*/
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Dover Radar AA #1", "", "Flak areas/DovRflak1.mis", 1, 5, "Dover_Radar_AA1", 245821, 236004, 900, 900, 1000, 7, 0, 150, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Dover Radar AA #3", "", "Flak areas/DovRflak3.mis", 1, 5, "Dover_Radar_AA3", 247398, 235557, 800, 800, 1000, 7, 0, 150, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Sandwich Radar AA #1", "", "Flak areas/SanRflak1.mis", 1, 5, "Sandwich_Radar_AA1", 247229, 251864, 1200, 1200, 1000, 7, 0, 150, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Sandwich Radar AA #2", "", "Flak areas/SanRflak2.mis", 1, 5, "Sandwich_Radar_AA2", 249328, 252080, 1000, 1000, 1000, 6, 0, 150, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Sandwich Radar AA #3", "", "Flak areas/SanRflak3.mis", 1, 5, "Sandwich_Radar_AA3", 249084, 251476, 1000, 1000, 1000, 7, 0, 150, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Dungeness Radar AA #1", "", "Flak areas/DunRflak1.mis", 1, 4, "Dungeness_Radar_AA1", 221234, 214067, 500, 500, 1000, 8, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Dungeness Radar AA #2", "", "Flak areas/DunRflak2.mis", 1, 4, "Dungeness_Radar_AA2", 221902, 214280, 500, 500, 1000, 8, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Dungeness Radar AA #3", "", "Flak areas/DunRflak3.mis", 1, 4, "Dungeness_Radar_AA3", 221448, 215209, 500, 500, 1000, 8, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Boulogne Radar AA", "", "Flak areas/BlgRflak.mis", 2, 4, "Boulogne_Radar_AA", 264469, 188601, 500, 500, 1000, 8, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Ambeteuse Radar AA", "", "Flak areas/AmbRflak.mis", 2, 4, "Ambetuse_Radar_AA", 266865, 197854, 500, 500, 500, 7, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Oye Plage Radar AA #1", "", "Flak areas/OypRflak1.mis", 2, 4, "OyePlage_Radar_AA1", 293354, 219098, 550, 550, 1000, 8, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Oye Plage Radar AA #2", "", "Flak areas/OypRflak2.mis", 2, 4, "OyePlage_Radar_AA2", 295396, 219665, 600, 600, 1000, 7, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Coquelles Radar AA", "", "Flak areas/CoqRflak.mis", 2, 4, "Coquelles_Radar_AA", 276168, 214104, 750, 750, 1000, 7, 0, 140, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Luftwaffe Reserve Communications HQ Radar AA", "", "Flak areas/HQGRRflak.mis", 2, 4, "ReserveGHQ_AA", 304020, 42462, 300, 300, 10000, 10, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Luftwaffe Reserve Communications HQ Radar AA2", "", "Flak areas/HQGRRflak2.mis", 2, 4, "ReserveGHQ_AA2", 301509, 40930, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Luftwaffe Reserve Communications HQ Radar AA3", "", "Flak areas/HQGRRflak3.mis", 2, 4, "ReserveGHQ_AA3", 305757, 41811, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "Luftwaffe Reserve Communications HQ Radar AA4", "", "Flak areas/HQGRRflak4.mis", 2, 4, "ReserveGHQ_AA4", 305087, 42362, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "RAF Reserve Communications HQ Radar AA", "", "Flak areas/HQBRRflak.mis", 2, 4, "ReserveBHQ_AA", 150588, 253363, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "RAF Reserve Communications HQ Radar AA2", "", "Flak areas/HQBRRflak2.mis", 2, 4, "ReserveBHQ_AA2", 149648, 253659, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "RAF Reserve Communications HQ Radar AA3", "", "Flak areas/HQBRRflak3.mis", 2, 4, "ReserveBHQ_AA3", 151102, 255638, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Artillery_and_AA, "RAF Reserve Communications HQ Radar AA4", "", "Flak areas/HQBRRflak4.mis", 2, 4, "ReserveBHQ_AA4", 153623, 253557, 125, 125, 1000, 4, 0, 5, 120, false, false, 0, 0, "", add, canBeDisabled: false);
/*TRIGGERS didn't work here or just unreliable...pointarea works a lot better
* addTrigger(MO_ObjectiveType.Railroad_Yard, "Deal Military Railyard", "Dove", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Red-Deal_Military_Train_Station.mis", "", 1, 3, "Deal_Military_Train_Station", "TGroundDestroyed", 27, 250541, 247155, 150, false, 150, 220, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Deal Military Fuel Transfer Station", "Dove", "", "", 1, 3, "Deal_Fuel_Transfer", "TGroundDestroyed", 22, 251135, 245891, 100, false, 150, 200, "", add);
*/
addPointArea(MO_ObjectiveType.Railroad_Yard, "Deal Military Railyard", "Dove", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Red-Deal_Military_Train_Station.mis", 1, 3, "Deal_Military_Train_Station", 250541, 247155, 150, 175, 5000, 20, 0, 150, 220, true, true, 2, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.MilitaryFuelStorage, "Deal Military Fuel Transfer Station", "Dove", "", 1, 3, "Deal_Fuel_Transfer", 251135, 245891, 100, 150, 5000, 20, 0, 150, 200, true, true, 2, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Military_Convoy, "Hastings-Rye Shore Patrol Convoy", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Red-Hastings_Rye_Convoy.mis", 1, 8, "Hastings_Rye_Convoy", 198944, 206194, 1, 0, 0, 0, 5, 180, 2, false, false, 0, 0, "", add, chief: "2002_Chief");
addPointArea(MO_ObjectiveType.Military_Convoy, "Deal-Sandwich Shore Patrol Convoy", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Red-Deal_Sandwich_Convoy.mis", 1, 8, "Deal_Sandwich_Convoy", 248369, 255048, 1, 0, 0, 0, 5, 180, 2, false, false, 0, 0, "", add, chief: "2003_Chief");
addPointArea(MO_ObjectiveType.Military_Convoy, "Veume-Dunkirk Shore Patrol Convoy", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Blue-Veume_Dunkirk_Convoy.mis", 2, 8, "Veume_Dunkirk_Convoy", 347526, 235085, 1, 0, 0, 0, 5, 180, 2, false, false, 0, 0, "", add, chief: "3002_Chief");
addPointArea(MO_ObjectiveType.Submarine, "Submarine - Belgian Coast", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-BritSubmarine-objective.mis", 1, 8, "RedSubmarine1", 350911, 273606, 1, 0, 0, 0, 1, 180, 4, false, false, 0, 0, "", add, chief: "2001_Chief");
addPointArea(MO_ObjectiveType.Submarine, "Submarine - East Sussex Coast", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-GerSubmarine-objective.mis", 2, 8, "BlueSubmarine1", 9168, 162087, 1, 0, 0, 0, 1, 180, 4, false, false, 0, 0, "", add, true, chief: "3001_Chief");
addPointArea(MO_ObjectiveType.Military_Armored_Vehicles, "Ashford Train Depot Armour", "Ashf", "", 1, 4, "BTarget3", 214639, 235604, 250, 300, 4000, 14, 0, 150, 196, false, true, 2, 2, "", add, true, "");
addTrigger(MO_ObjectiveType.Ground_Aircraft, "Littlestone Bomber Squadron Aircraft", "Litt", "", "", 1, 3, "BTarget1", "TGroundDestroyed", 20, 222303, 221176, 300, false, 100, 196, "", add);
addTrigger(MO_ObjectiveType.Airfield_Complex, "Redhill Bomber Squadron Aircraft ", "Redh", "", "", 1, 5, "BTarget2", "TGroundDestroyed", 20, 143336, 240806, 550, false, 5, 196, "", add);
addTrigger(MO_ObjectiveType.Military_Vehicles, "British Armour @ Dover", "Dove", "", "", 1, 5, "BTarget5", "TGroundDestroyed", 43, 243887, 236956, 200, false, 100, 196, "", add);
addTrigger(MO_ObjectiveType.Military_Vehicles, "British Armour @ CreekMouth", "Bext", "", "", 1, 7, "BTarget6", "TGroundDestroyed", 50, 159687, 275015, 200, false, 15, 400, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Hydrogen Storage @ London South Docks", "Lond", "", "", 1, 4, "BTarget7S", "TGroundDestroyed", 22, 155050, 273258, 50, false, 40, 520, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Ethanol Storage @ London South Docks", "Lond", "", "", 1, 4, "BTarget8S", "TGroundDestroyed", 12, 155823, 273221, 50, false, 40, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Liquid Oxygen @ Beckton", "Bext", "", "", 1, 4, "BTarget9S", "TGroundDestroyed", 22, 157899, 273957, 50, false, 40, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Kerosene Storage @ Beckton", "Bext", "", "", 1, 4, "BTarget10S", "TGroundDestroyed", 23, 157547, 274527, 100, false, 40, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "High Octane Aircraft Fuel @ Beckton", "Bext", "", "", 1, 4, "BTarget11S", "TGroundDestroyed", 45, 158192, 274864, 50, false, 40, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "87 Octane Fuel Storage @ Beckton", "Bext", "", "", 1, 4, "BTarget12S", "TGroundDestroyed", 42, 157899, 275256, 50, false, 40, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Peroxide Storage @ Beckton", "Lond", "", "", 1, 4, "BTarget13S", "TGroundDestroyed", 43, 160567, 275749, 50, false, 4, 600, "", add);
addTrigger(MO_ObjectiveType.Naval_Dock_Area, "Vehicle Departure Docks", "Lond", "", "", 1, 3, "BTarget14A", "TGroundDestroyed", 29, 160025, 273824, 100, false, 4, 450, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Ditton Fuel Dump", "Ditt", "", "", 1, 4, "BTarget25", "TGroundDestroyed", 38, 186057, 251745, 100, false, 15, 270, "", add);
addTrigger(MO_ObjectiveType.MilitaryRepairFacility, "Maidstone Train Repair Station ", "Ditt", "", "", 1, 3, "BTarget26", "TGroundDestroyed", 10, 189272, 249311, 50, false, 100, 210, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Bulford Army Facility", "Bult", "", "", 1, 7, "BTarget29", "TGroundDestroyed", 21, 35872, 236703, 150, false, 10, 230, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Wooleston Spitfire Shop ", "Wool", "", "", 1, 7, "BTarget30", "TGroundDestroyed", 9, 56990, 203737, 50, false, 10, 620, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Swindon Aircraft repair Station", "Swin", "", "", 1, 6, "BTarget31", "TGroundDestroyed", 27, 29968, 279722, 300, false, 3, 590, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Reading Engine Workshop ", "Read", "", "", 1, 7, "BTarget32", "TGroundDestroyed", 11, 84241, 267444, 100, false, 10, 600, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Propeller Repair Portsmouth", "Port", "", "", 1, 6, "BTarget33", "TGroundDestroyed", 11, 76446, 193672, 50, false, 20, 310, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Boiler Repair Shop Portsmouth", "Port", "", "", 1, 5, "BTarget35", "TGroundDestroyed", 8, 76317, 193904, 50, false, 20, 310, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Depth Charge Workshop Portsmouth", "Port", "", "", 1, 5, "BTarget37", "TGroundDestroyed", 8, 76720, 194082, 50, false, 20, 296, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Liquid Oxygen Storage Portsmouth", "Port", "", "", 1, 6, "BTarget38", "TGroundDestroyed", 12, 76805, 193918, 50, false, 20, 570, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Wood Alcohol Fuel Storage Portsmouth", "Port", "", "", 1, 5, "BTarget39", "TGroundDestroyed", 12, 77392, 193942, 50, false, 15, 440, "", add);
addTrigger(MO_ObjectiveType.MilitaryArea, "Broadstairs Train Station Military Complex", "Mans", "", "", 1, 3, "BTargBroadstairsTrainStation", "TGroundDestroyed", 5, 252836, 261369, 50, false, 120, 216, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Brighton Army Recruitment Station", "Shor", "", "", 1, 4, "BTargBrightonMilitaryRecruitment", "TGroundDestroyed", 11, 144654, 198443, 50, false, 120, 236, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Brighton Gasoline Storage", "Shor", "", "", 1, 4, "BTargBrightonFuel", "TGroundDestroyed", 5, 144738, 198233, 50, false, 120, 334, "", add);
addTrigger(MO_ObjectiveType.MilitaryProductionFacility, "Tenterden Chemical Manufacture", "Litt", "", "", 1, 3, "BTargTenterdenChemicalFactory", "TGroundDestroyed", 5, 194591, 220821, 150, false, 120, 196, "", add);
addTrigger(MO_ObjectiveType.MilitaryProductionFacility, "Minster Synthetic Case Oil Manufacture", "Mans", "", "", 1, 3, "BTargMinsterCaseOilManufacturing", "TGroundDestroyed", 10, 240203, 256964, 100, false, 120, 196, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Battle Commando Training Center Shoreham", "Shor", "", "", 1, 3, "BTargBattleCommandoTrainingCenter", "TGroundDestroyed", 5, 185093, 219403, 50, false, 40, 240, "", add);
addPointArea(MO_ObjectiveType.MilitaryFuelProduction, "Wehrmacht Benzin Raffinerie Normandy", "Caen", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-GerOilRefineryCaen-objective.mis", 2, 6, "RTargCaenOilRefinery", 128016, 14843, 450, 500, 16000, 20, 0, 15, 240, true, true, 1, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.MilitaryFuelProduction, "Wehrmacht Kohleverflüssigungsfabrik Hazebrouck", "Haze", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-GerHazebrouckCoalLiquifaction-objective.mis", 2, 10, "RTargHazebrouckCoalLiquifactionFacility", 338117, 188023, 500, 500, 20000, 29, 0, 15, 300, true, true, 1, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.MilitaryFuelProduction, "Gourney-en-Bray Oil Field", "", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-Gournay-en-Bray-OilFields-objective.mis", 2, 10, "GourneyenBrayGrainOilFields", 277697, 60896, 650, 650, 20000, 0, 0, 15, 300, false, false, 0, 0, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.Railroad_Yard, "Billicaray Military Train Station", "RaHQ", "", 1, 4, "BillicarayStation", 181289, 288265, 80, 80, 4500, 1, 0, 80, 200, true, true, 1, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.MilitaryFuelProduction, "Isle of Grain Oil Field", "Quee", "ship-convoy-submarine-objectives/Genghis-LOADONCALL-BritOilFields-objective.mis", 1, 10, "BTargIsleGrainOilFields", 202147, 269152, 650, 650, 20000, 29, 0, 15, 300, true, true, 1, 2, "", add, canBeDisabled: false);
addPointArea(MO_ObjectiveType.MilitaryArea, "Caen Barge Assembly Area", "Caen", "", 2, 5, "RTargetCaenBargeAssemblyArea", 125584, 18893, 150, 200, 5000, 1, 0, 5, 300, false, true, 1, 2, "", add);
addPointArea(MO_ObjectiveType.MilitaryStorageFacility, "Caen Flamethrower Fuel Storage", "Caen", "", 2, 5, "RTargetCaenFlameThrowerFuelStorage", 125906, 18653, 120, 100, 3000, 1, 0, 5, 300, false, true, 1, 2, "", add);
addPointArea(MO_ObjectiveType.Railroad_Bridge, "Caen Rail Bridge", "Caen", "", 2, 6, "RTargetCaenRailBridge", 124228, 17383, 150, 100, 3000, 4, 0, 5, 300, false, true, 1, 2, "", add);
addPointArea(MO_ObjectiveType.Railroad_Yard, "Caen Rail Yard", "Caen", "", 2, 8, "RTargetCaenRailYard", 125917, 18232, 450, 500, 9000, 7, 0, 5, 300, false, true, 1, 2, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Poix Nord SS Headquarters", "Poix", "", "", 2, 3, "8A", "TGroundDestroyed", 75, 294090, 85100, 100, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.MilitaryProductionFacility, "Kriegsmarine Seilfabrik Poix Nord", "Poix", "", "", 2, 3, "7A", "TGroundDestroyed", 66, 293279, 84884, 100, false, 2, 310, "", add);
addTrigger(MO_ObjectiveType.WeaponsStorage, "Waffen- und Rüstungslager Boulogne", "Boul", "", "", 2, 3, "1B", "TGroundDestroyed", 45, 264252, 189991, 50, false, 100, 222, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Fuel Research Facility Boulogne", "Boul", "", "", 2, 3, "2B", "TGroundDestroyed", 47, 265063, 190506, 50, false, 100, 210, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Radio Jamming Transmitter Boulogne", "Boul", "", "", 2, 3, "3B", "TGroundDestroyed", 51, 265251, 190259, 50, false, 110, 222, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Kriegsmarine Research Facility Boulogne", "Boul", "", "", 2, 3, "4B", "TGroundDestroyed", 62, 264692, 189709, 50, false, 110, 222, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Boulogne Army HQ", "Boul", "", "", 2, 3, "5B", "TGroundDestroyed", 54, 265643, 189603, 50, false, 110, 222, "", add);
addTrigger(MO_ObjectiveType.MilitaryProductionFacility, "Propeller Repair Boulogne", "Boul", "", "", 2, 3, "6B", "TGroundDestroyed", 77, 265932, 189324, 50, false, 110, 222, "", add);
addTrigger(MO_ObjectiveType.MilitaryProductionFacility, "E-boat Factory Boulogne", "Boul", "", "", 2, 3, "7B", "TGroundDestroyed", 53, 264849, 189190, 50, false, 110, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Le Havre Kriegsmarine Officer Mess", "Havr", "", "", 2, 4, "LehavNaval2", "TGroundDestroyed", 25, 163447, 49855, 50, false, 2, 320, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Le Havre Kriegsmarine Weapons Training", "Havr", "", "", 2, 4, "LehavNaval3", "TGroundDestroyed", 25, 163313, 50063, 50, false, 2, 320, "", add);
addTrigger(MO_ObjectiveType.MilitaryRepairFacility, "Le Havre Kriegsmarine Underwater Repair Training", "Havr", "", "", 2, 4, "LehavNaval4", "TGroundDestroyed", 25, 163039, 49798, 50, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Le Havre Kriegsmarine Intelligence", "Havr", "", "", 2, 4, "LehavNaval5", "TGroundDestroyed", 25, 163172, 49816, 50, false, 2, 420, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Le Havre Kriegsmarine Meteorology", "Havr", "", "", 2, 4, "LehavNaval6", "TGroundDestroyed", 25, 163470, 49752, 50, false, 2, 350, "", add);
addTrigger(MO_ObjectiveType.MilitaryHeadquarters, "Le Havre Kriegsmarine Cryptologic HQ", "Havr", "", "", 2, 4, "LehavNaval7", "TGroundDestroyed", 25, 162993, 49927, 50, false, 2, 450, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Le Havre Kriegsmarine Diesel Storage", "Havr", "", "", 2, 4, "LehavNavalDiesel", "TGroundDestroyed", 46, 162559, 50082, 100, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Le Havre Kriegsmarine Gear Oil Storage", "Havr", "", "", 2, 4, "LehavNavalGearOil", "TGroundDestroyed", 41, 162668, 50240, 100, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Le Havre Kriegsmarine Benzine", "Havr", "", "", 2, 4, "LehavNavalBenzine", "TGroundDestroyed", 35, 161747, 50094, 50, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.MilitaryFuelStorage, "Le Havre Kriegsmarine LOX", "Havr", "", "", 2, 4, "LehavNavalLOX", "TGroundDestroyed", 41, 162099, 50034, 50, false, 2, 350, "", add);
addTrigger(MO_ObjectiveType.Railroad, "Le Havre Train Station", "Havr", "", "", 2, 4, "LehavTrainStation", "TGroundDestroyed", 37, 159918, 53120, 100, false, 2, 300, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Calais UBoot Repair", "Cala", "", "", 2, 3, "RTargCalaisUBootRepair", "TGroundDestroyed", 10, 284999, 216446, 100, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Calais Jackboot Storage", "Cala", "", "", 2, 2, "RTargCalaisJackbootStorage", "TGroundDestroyed", 12, 284994, 216869, 200, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Dunkirk Weapon Storage & Distribution", "Dunk", "", "", 2, 3, "RTargDunkirkWeaponStoarge", "TGroundDestroyed", 11, 315271, 224033, 200, false, 120, 160, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Dunkirk Radar Manufacture", "Dunk", "", "", 2, 3, "RTargDunkirkRadarManufacturing", "TGroundDestroyed", 10, 315295, 224146, 290, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Dunkirk Military Warehouse", "Dunk", "", "", 2, 3, "RTargDunkirkMilitaryWarehouse", "TGroundDestroyed", 10, 315300, 224265, 200, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Dunkirk Explosives Research", "Dunk", "", "", 2, 3, "RTargDunkirkExplosivesResearch", "TGroundDestroyed", 9, 314884, 223318, 250, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Desvres Aviation Fuel", "", "", "", 2, 3, "RTargDesvresAviationFuel", "TGroundDestroyed", 5, 284580, 182275, 150, false, 120, 222, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Aire-Sur-La-Lys Chemical Refinery", "", "", "", 2, 4, "RTargAireSurLaLysChemicalRefinery", "TGroundDestroyed", 12, 323803, 181252, 220, false, 120, 168, "", add);
addTrigger(MO_ObjectiveType.Military_Building, "Etaple Fuel Refinery/Storage", "", "", "", 2, 3, "RTargEtapleFuelDump", "TGroundDestroyed", 11, 267479, 166274, 100, false, 120, 500, "", add);
addPointArea(MO_ObjectiveType.Railroad_Bridge, "Maromme Rail Bridge", "", "", 2, 6, "RTargMarommeRailBridge", 220000, 59260, 125, 100, 3000, 5, 0, 2, 450, true, true, 1, 2, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionFacility, "Waffen- und Rüstungsfabrik Maromme", "", "", 2, 6, "RTargMarommeRailMunitionsFactory", 226019, 50952, 400, 350, 9000, 10, 0, 2, 550, true, true, 1, 2, "", add);
addPointArea(MO_ObjectiveType.MilitaryHeadquarters, "Dover Navy HQ", "Dove", "", 1, 3, "BTargDoverNavalOffice", 245567, 233499, 50, 50, 800, 4, 0, 125, 200, true, true, 3, 7, "", add);
addPointArea(MO_ObjectiveType.AmmunitionStorage, "Dover Ammo Dump", "Dove", "", 1, 3, "BTargDoverAmmo", 245461, 233488, 50, 50, 800, 4, 0, 125, 200, true, true, 3, 7, "", add);
addPointArea(MO_ObjectiveType.MilitaryFuelStorage, "Dover Navy Operations Fuel", "Dove", "", 1, 3, "BTargDoverFuel", 245695, 233573, 75, 75, 800, 4, 0, 125, 222, true, true, 3, 7, "", add);
addPointArea(MO_ObjectiveType.Ground_Aircraft, "Manston aircraft", "Mans", "", 1, 4, "BTarget4", 247462, 259157, 320, 320, 4500, 25, 0, 100, 196, true, true, 1, 3, "", add, false);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Southhampton Navy Docks Area", "Sout", "", 1, 8, "BTargSouthhamptonDocks", 56298, 203668, 400, 400, 8000, 0, 0, 5, 200, true, true, 2, 10, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionFacility, "Shoreham Artillery Assembly Factory", "", "Genghis-LOADONCALL-shoreham-artillery-assembly-objective.mis", 1, 6, "BTargShorehamArtilleryFactory", 137046, 200038, 150, 90, 3000, 5, 0, 70, 300, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryArea, "Shoreham Navy Submarine Base", "", "", 1, 6, "BTargShorehamSubmarineBase", 137054, 198034, 150, 90, 3000, 3, 0, 70, 310, true, true, 3, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Portsmouth Small Military Manufacturing Area SW", "Port", "", 1, 8, "BTargPortsmouthSmallIndustrialArea", 75235, 193676, 350, 350, 8000, 10, 0, 15, 310, true, true, 1, 10, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Portsmouth Large Military Manufacturing Area NE", "Port", "", 1, 9, "BTargPortsmouthLargeIndustrialArea", 77048, 193985, 850, 850, 10000, 15, 0, 10, 400, true, true, 3, 6, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Poole North Navy Port Area", "Pool", "", 1, 10, "BTargPooleNorthIndustrialPortArea", 14518, 184740, 550, 400, 10000, 9, 0, 15, 410, true, true, 3, 6, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Poole South Navy Port Area", "Pool", "", 1, 8, "BTargPooleSouthIndustrialPortArea", 13734, 183493, 550, 400, 8000, 8, 0, 10, 410, true, true, 3, 6, "", add);
addPointArea(MO_ObjectiveType.MilitaryHeadquarters, "Crowborough Air High Command Bunker", "", "Genghis-LOADONCALL-crowborough-bunker-objective.mis", 1, 6, "CrowboroughBunker", 167289, 224222, 70, 50, 4000, 20, 0, 120, 210, true, true, 2, 10, "", add);
addPointArea(MO_ObjectiveType.MilitaryArea, "Hastings Local Auxiliary Bunker", "", "Genghis-LOADONCALL-hastings-bunker-objective.mis", 1, 6, "HastingsBunker", 196108, 205853, 70, 50, 4000, 20, 0, 120, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Brighton Navy Docks Area", "Dove", "Genghis-LOADONCALL-brighton-naval-docks-objective.mis", 1, 8, "BTargBrightonNavyDocks", 138520, 197736, 1300, 750, 10000, 40, 0, 120, 168, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Dunkirk Kriegsmarine Docks Area", "Dunk", "Genghis-LOADONCALL-dunkirk-naval-docks-objective.mis", 2, 8, "BTargDunkirkNavyDocks", 314227, 225610, 1150, 850, 10000, 40, 0, 160, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Base sous-marine de Boulogne-sur-Mer", "Boul", "Genghis-LOADONCALL-boulognesurmer-submarine-base-objective.mis", 2, 6, "BTargBoulSubmarine", 265859, 192867, 250, 150, 10000, 15, 0, 160, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Boulogne Kriegsmarine Docks Area", "Boul", "Genghis-LOADONCALL-boulogne-naval-docks-objective.mis", 2, 8, "BTargBoulogneNavyDocks", 265531, 190133, 750, 650, 10000, 40, 0, 160, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Dunkirk West Wehrmacht Manufacturing Area", "Dunk", "", 2,4, "BTargDunkirkWestIndustrialArea", 312748, 223035, 850, 750, 1000, 6, 140, 222, true, true, 2, 8, "", add);
*/
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Dunkirk Southwest Wehrmacht Manufacturing Area", "Dunk", "", 2, 8, "BTargDunkirkSouthwestIndustrialArea", 313146, 222107, 500, 450, 10000, 6, 0, 140, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Dunkirk Northeast Wehrmacht Manufacturing Area", "Dunk", "", 2, 8, "BTargDunkirkSoutheastIndustrialArea", 318506, 225750, 500, 450, 10000, 6, 0, 140, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Dunkirk Central-West Wehrmacht Manufacturing Area", "Dunk", "", 2, 8, "BTargDunkirkCentralWestIndustrialArea", 314753, 224055, 1200, 1300, 10000, 15, 0, 130, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Dunkirk East Kriegsmarine Docks Area", "Dunk", "", 2, 8, "BTargDunkirkEastDocksArea", 320103, 225534, 1250, 1200, 10000, 1, 0, 130, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Oostende Wehrmacht Manufacturing Area", "Dunk", "", 2, 8, "BTargOostendeIndustrialArea", 358758, 242945, 800, 700, 10000, 1, 0, 100, 270, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Diksmuide Wehrmacht Manufacturing Area", "Dunk", "", 2, 8, "BTargDiksmuideIndustrialArea", 354946, 223720, 200, 175, 7000, 1, 0, 100, 300, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Calais Wehrmacht Manufacturing Area", "Cala", "", 2, 8, "BTargCalaisIndustrialArea", 284945, 217045, 800, 850, 12000, 15, 0, 140, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Boulogne West Wehrmacht Manufacturing Area", "Boul", "", 2, 8, "BTargBoulogneWestIndustrialArea", 264576, 189495, 650, 700, 11000, 4, 0, 140, 222, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryArea, "Estree Amphibious Landing Training Center", "Estr", "", 2, 6, "RTargEstreeAmphib", 279617, 163616, 250, 200, 3000, 6, 0, 100, 270, true, true, 2, 6, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionFacility, "Etaples Landing Craft Assembly Site", "", "Genghis-LOADONCALL-etaples-landingcraft-objective.mis", 2, 4, "RTargEtaplesLandingCraft", 269447, 166097, 250, 200, 3000, 3, 0, 100, 349, true, true, 2, 6, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionFacility, "Berck Unternehmen Seelöwe Marinefährprahm Assembly Site", "", "Genghis-LOADONCALL-berck-landingcraft-objective.mis", 2, 7, "RTargBerckLandingCraft", 269247, 147771, 250, 200, 3000, 5, 0, 100, 290, true, true, 3, 6, "", add);
addPointArea(MO_ObjectiveType.Naval_Dock_Area, "Calais Kriegsmarine Docks Area", "Cala", "", 2, 8, "RTargCalaisDocksArea", 284656, 217404, 400, 350, 8000, 15, 0, 120, 196, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Veurne Wehrmacht Manufacturing Area", "", "", 2, 8, "RTargVeurneMilitaryManufacturingArea", 342180, 228344, 300, 250, 8000, 15, 0, 90, 246, true, true, 2, 10, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Abbeville Wehrmacht Manufacturing Area", "", "", 2, 8, "RTargAbbevilleMilitaryManufacturingArea", 284898, 121779, 450, 400, 8000, 15, 0, 25, 270, true, true, 2, 10, "", add);
addPointArea(MO_ObjectiveType.MilitaryProductionArea, "Le Crotoy Marinefährprahm Manufacturing Area", "", "Genghis-LOADONCALL-lecrotoyberck-landingcraft-objective.mis", 2, 10, "RTargLeCrotoyLandingCraftManufactureAreaBomb", 271541, 132815, 1200, 1000, 11000, 15, 0, 80, 250, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryHeadquarters, "Le Crotoy Forest Luftwaffe High Command Bunker", "", "Genghis-LOADONCALL-lecrotyoy-forest-bunker-objective.mis", 2, 6, "LeCrotoyForestBunker", 277853, 138221, 70, 50, 4000, 20, 0, 80, 250, true, true, 2, 8, "", add);
addPointArea(MO_ObjectiveType.MilitaryHeadquarters, "Brandenburger Spezialeinheit Command Bunker - Dieppe Cliffs", "", "Genghis-LOADONCALL-Dieppe-shoreline-bunker-objective.mis", 2, 6, "DieppeCliffsBunker", 238972, 107365, 70, 50, 4000, 20, 0, 70, 230, true, true, 2, 8, "", add);
addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "North Sea Tanker Group 1 (sink ~4)", "", 2, 6, "NorthSea_German_Tankers", 260310, 241196, 2500, 9500, 0, 0, 4, shipPriority+15, 12, false, false, 0, 0, MO_MobileObjectiveType.TankerShipGroup_DE, 8, 260310, 241196, 301268, 296717, 5, 20, MO_ProducerOrStorageType.fuel, "", add);
addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "North Sea Tanker Group 2 (sink ~4)", "", 1, 6, "NorthSea_British_Tankers", 292621, 230047, 2500, 9500, 0, 0, 4, shipPriority+15, 12, false, false, 0, 0, MO_MobileObjectiveType.TankerShipGroup_GB, 8, 292621, 230047, 348142, 277376, 5, 20, MO_ProducerOrStorageType.fuel, "", add);
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "Channel Freighter Convoy (sink ~4)", "", 2, 6, "Channel_German_Freighters", 203197, 188179, 2300, 9500, 0, 39, 0, shipPriority+15, 12, false, false, 0, 0, MO_MobileObjectiveType.FreighterShipGroup_DE, 8, 203197, 188179, 253484, 211388, 5, 20, MO_ProducerOrStorageType.bullets_shells, "", add);
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "Channel Freighter Convoy (sink ~4)", "", 1, 6, "Channel_British_Freighters", 228681, 145628, 2300, 9500, 0, 39, 0, shipPriority+15, 12, false, false, 0, 0, MO_MobileObjectiveType.FreighterShipGroup_GB, 8, 228681, 145628, 257579, 202741, 5, 20, MO_ProducerOrStorageType.bullets_shells, "", add);
addMobile(MO_ObjectiveType.Naval_Ship, "Channel Motorized Torpedo Boat", "", 1, 8, "Channel_British_MTB", 150197, 138179, 450, 7500, 0, 0, 1, shipPriority+18, 6, false, false, 0, 0, MO_MobileObjectiveType.OneMTBGroup_GB, 7, 79884, 99545, 220381, 169793, 2, 10, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Naval_Ship, "Channel Motorized Torpedo Boat", "", 2, 8, "Channel_German_MTB", 123197, 108179, 150, 7500, 0, 0, 1, shipPriority+18, 6, false, false, 0, 0, MO_MobileObjectiveType.OneMTBGroup_DE, 7, 80506, 46874, 154174, 185817, 2, 10, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Submarine, "British Attack Submarine", "", 1, 8, "British_Attack_Submarine", 142426, 49568, 250, 7500, 0, 0, 1, shipPriority+20, 6, false, false, 0, 0, MO_MobileObjectiveType.OneSubmarineGroup_GB, 7, 68589, 45820, 155544, 106164, 1, 10, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Submarine, "German Attack Submarine", "", 2, 8, "German_Attack_Submarine", 140927, 187665, 250, 7500, 0, 0, 1, shipPriority+20, 6, false, false, 0, 0, MO_MobileObjectiveType.OneSubmarineGroup_DE, 7, 105695, 137816, 164540, 188415, 1, 10, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Abbeville Mobile Waffen-SS Camp", "", 2, 9, "RLiane-SommeMobileArmyCamp", 270276, 129671, 250, 200, 7000, 15, 0, 20, 320, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 240457, 109967, 290313, 139747, 1, 6, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Pionier-Bataillon Mobiles Armeelager", "", 2, 9, "REstreeMobileArmyCamp", 270276, 169671, 250, 200, 7000, 15, 0, 100, 230, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 270215, 136714, 294585, 197640, 1, 6, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Samer Mobiles Armeelager", "", 2, 9, "RSamerMobileArmyCamp", 275276, 179671, 250, 200, 7000, 15, 0, 100, 230, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 270688, 176759, 294802, 199990, 1, 6, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Hastings Mobile Army Camp", "", 1, 9, "BHastingsMobileArmyCamp", 179965, 204219, 250, 200, 7000, 15, 0, 150, 240, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 154251, 205709, 210342, 242209, 2, 7, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Ashford Mobile Army Group", "", 1, 9, "BAshfordMobileArmyGroup", 205965, 240219, 250, 200, 7000, 15, 0, 150, 240, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 200000, 230000, 213342, 250209, 2, 7, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Willmington Mobile Royal Army Encampment", "", 1, 9, "BWillmingtonMobileArmyCamp", 207965, 229219, 250, 200, 7000, 15, 0, 140, 240, true, true, 1, 8, MO_MobileObjectiveType.ArmyEncampment, 48, 206634, 227611, 233619, 249690, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Airfield, "Hastings Mobile Secret RAF Base", "", 1, 10, "BHastingsSecretAirbase", 189965, 204219, 700, 600, 10000, 10, 0, 150, 290, true, true, 1, 8, MO_MobileObjectiveType.SecretAirbaseGB, 70, 154251, 205709, 210342, 242209, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Airfield, "Samer Secret Mobile Luftwaffe E-Stelle", "", 2, 10, "RSamerSecretAirbase", 275688, 178759, 800, 600, 10000, 10, 0, 140, 230, true, true, 1, 10, MO_MobileObjectiveType.SecretAirbaseDE, 70, 270688, 176759, 294802, 199990, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Airfield, "Oye Plage Secret Mobile Luftwaffe E-Stelle", "", 2, 10, "ROyePlageSecretAirbase", 292450, 253519, 800, 600, 10000, 10, 0, 130, 250, true, true, 1, 8, MO_MobileObjectiveType.SecretAirbaseDE, 70, 287450, 203519, 314504, 218663, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Eastchurch Mobile Intelligence Air Research", "", 1, 10, "BEastchurchAirResearch", 210407, 255687, 550, 450, 10000, 8, 0, 150, 350, true, true, 1, 10, MO_MobileObjectiveType.SecretAircraftResearchGB, 60, 200407, 249687, 224373, 269537, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Mobile Luftfahrtforschungslager Boulogne", "", 2, 10, "RBoulogneAircraftResearch", 274219, 187200, 550, 450, 10000, 8, 0, 150, 260, true, true, 1, 10, MO_MobileObjectiveType.SecretAircraftResearchGB, 60, 264219, 177200, 280099, 200578, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Mobile Luftfahrtforschungslager St Omer", "", 2, 10, "RStOmerAircraftResearch", 295276, 179671, 550, 450, 10000, 10, 0, 160, 930, true, true, 1, 8, MO_MobileObjectiveType.SecretAircraftResearchGB, 60, 270456, 172273, 310329, 209977, 3, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Radar, "RAF Mobile Secret Radar Communications Command", "", 1, 12, "BMobileRadarHQ1", 157880, 274479, 120, 100, 14000, 36, 0, 2, 48, true, true, 1, 10, MO_MobileObjectiveType.KnickebeinHQ, 12, 152438, 271968, 160507, 275830, 3, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 160000);
addMobile(MO_ObjectiveType.Radar, "RAF Mobile Regional Radar Communications Center", "", 1, 12, "BMobileRadarRadarHQ2", 66715, 268861, 120, 100, 12000, 28, 0, 2, 48, true, true, 1, 10, MO_MobileObjectiveType.KnickebeinHQ, 12, 30359, 203270, 192275, 305967, 15, 100
, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 100000);
addMobile(MO_ObjectiveType.Radar, "Le Touquet Mobile Radar", "", 2, 8, "RLeToquetMobileRadar1", 270276, 169671, 200, 150, 7000, 12, 0, 150, 36, true, true, 1, 10, MO_MobileObjectiveType.MobileRadar1, 45, 264215, 151714, 294585, 191640, 2, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 20000);
addMobile(MO_ObjectiveType.Radar, "Hastings Mobile Radar 1", "", 1, 8, "BHastingsMobileRadar1", 179965, 204219, 200, 150, 7000, 12, 0, 150, 36, true, true, 1, 10, MO_MobileObjectiveType.MobileRadar1, 45, 154251, 205709, 210342, 242209, 2, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 30000);
addMobile(MO_ObjectiveType.Radar, "Le Touquet Mobile Radar 2", "", 2, 8, "RLeToquetMobileRadar2", 270276, 179671, 300, 250, 7000, 12, 0, 150, 36, true, true, 1, 10, MO_MobileObjectiveType.MobileRadar1, 45, 270215, 136714, 294585, 197640, 2, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 20000);
addMobile(MO_ObjectiveType.Radar, "Marquise West Mobile Radar", "", 2, 8, "RMarquiseWestMobileRadar2", 270276, 199671, 300, 250, 7000, 12, 0, 150, 36, true, true, 1, 10, MO_MobileObjectiveType.MobileRadar1, 45, 260784, 189776, 280619, 215301, 2, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 20000);
addMobile(MO_ObjectiveType.Radar, "Hastings Mobile Radar 2", "", 1, 8, "BHastingsMobileRadar2", 179965, 214219, 300, 250, 7000, 12, 0, 150, 36, true, true, 1, 10, MO_MobileObjectiveType.MobileRadar1, 45, 154251, 205709, 210342, 242209, 2, 6, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 30000);
addMobile(MO_ObjectiveType.Radar, "Truck-borne Radar", "", 2, 6, "LWTruckRadar1", 183280, 68683, 100, 90, 3000, 3, 0, 110, 48, true, true, 1, 2, MO_MobileObjectiveType.DesertRadar, 24, 174285, 52567, 252619, 78428, 3, 8, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 30000);
addMobile(MO_ObjectiveType.Radar, "Truck-borne Radar", "", 1, 6, "RAFTruckRadar1", 122791, 200946, 100, 90, 3000, 3, 0, 110, 48, true, true, 1, 2, MO_MobileObjectiveType.DesertRadar, 24, 101962, 194891, 150400, 229524, 3, 8, MO_ProducerOrStorageType.None, "", add, radar_effective_radius_m: 30000);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Veurne Gespensterdivision Mobile Panzer Group", "", 2, 8, "RWVeurneMobileArmour", 331978, 220669, 300, 250, 7000, 15, 0, 90, 230, true, true, 1, 10, MO_MobileObjectiveType.SmallArmourGroup, 15, 326050, 196380, 359018, 244017, 2, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryArea, "Calais-Dunkirk Gespensterdivision Mobile Panzer Group", "", 2, 8, "RWCalaisDunkirkMobileArmour", 297538, 218812, 300, 250, 7000, 15, 0, 90, 270, true, true, 1, 24, MO_MobileObjectiveType.SmallArmourGroup, 12, 290538, 208812, 310535, 223074, 2, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Kent Mobile Armour", "", 1, 8, "BKentMobileArmour", 240196, 243824, 300, 250, 7000, 15, 0, 150, 330, true, true, 1, 10, MO_MobileObjectiveType.SmallArmourGroup, 24, 216410, 232331, 247147, 261063, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Dunkirk Gespenster Division Large Mobile Panzer Group", "", 2, 10, "RWDunkirkLargeMobileArmour", 325508, 215881, 300, 250, 9000, 17, 0, 150, 330, true, true, 1, 10, MO_MobileObjectiveType.LargeArmourGroup, 24, 300340, 196608, 330177, 219671, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Panzer-Regiment 25/French Point", "", 2, 10, "RWFrenchPointLargeMobileArmour", 295101, 217196, 300, 250, 9000, 17, 0, 160, 330, true, true, 1, 10, MO_MobileObjectiveType.LargeArmourGroup, 24, 265101, 197196, 280687, 216458, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Kent Large Mobile Armour", "", 1, 10, "BKentLargeMobileArmour", 221410, 236331, 300, 250, 9000, 17, 0, 160, 390, true, true, 1, 10, MO_MobileObjectiveType.LargeArmourGroup, 45, 216410, 232331, 247147, 261063, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.Military_Armored_Vehicles, "Canterbury-Manston Large Mobile Armour", "", 1, 10, "BCanterburyManstonLargeMobileArmour", 237461, 257603, 300, 250, 9000, 17, 0, 160, 450, true, true, 1, 10, MO_MobileObjectiveType.LargeArmourGroup, 45, 227461, 252603, 243340, 260249, 1, 5, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Samer Mobile Aufklärungs-Abteilung HQ", "", 2, 5, "RSamerCamo", 268939, 173597, 250, 200, 4000, 15, 0, 160, 330, true, true, 1, 10, MO_MobileObjectiveType.CamoGroup, 80, 265545, 170079, 300237, 189647, 0.5, 8, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Tripod Aufklärungs-Abteilung Lager", "", 2, 5, "RTripodPlageCamo", 276923, 210710, 250, 200, 4000, 15, 0, 150, 330, true, true, 1, 10, MO_MobileObjectiveType.CamoGroup, 80, 273923, 202710, 282745, 212267, 0.25, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Wissant Mobile Aufklärungs-Abteilung HQ", "", 2, 5, "RWissantSmallCamo", 268939, 203597, 125, 90, 4000, 15, 0, 170, 330, true, true, 1, 10, MO_MobileObjectiveType.SmallCamoGroup, 80, 264085, 199565, 281195, 215701, 1, 8, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Canterbury Mobile Secret Resistance Training Center", "", 1, 5, "BCanterburyCamoGroup", 245118, 253057, 250, 200, 4000, 15, 0, 160, 450, true, true, 1, 10, MO_MobileObjectiveType.CamoGroup, 80, 228118, 240057, 247785, 256399, 1, 9, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "GenMaj Theo Osterkamp & Staff Motorcade", "", 2, 4, "RSeidmanMotorcade", 265508, 195881, 125, 150, 200, 15, 0, 180, 210, false, false, 1, 10, MO_MobileObjectiveType.SmallTruckConvoy, 12, 264479, 192289, 269334, 207743, 1, 2, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Oberst Werner Junck & Staff Motorcade", "", 2, 6, "ROberstMotorcade", 265508, 175881, 150, 175, 200, 18, 0, 180, 210, false, false, 1, 10, MO_MobileObjectiveType.LargeTruckConvoy, 12, 261866, 169448, 268563, 184373, 1, 2, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Army Officers Motorcade", "", 1, 4, "BArmyStaffMotorcade", 211646, 213373, 125, 150, 200, 15, 0, 180, 210, false, false, 1, 10, MO_MobileObjectiveType.SmallTruckConvoy, 12, 208123, 209582, 224459, 215137, 1, 2, MO_ProducerOrStorageType.None, "", add);
addMobile(MO_ObjectiveType.MilitaryHeadquarters, "Navy Officers Motorcade", "", 1, 6, "BRAFMotorcade", 245181, 253793, 150, 175, 200, 18, 0, 180, 210, false, false, 1, 10, MO_MobileObjectiveType.LargeTruckConvoy, 12, 247723, 234422, 252682, 256705, 1, 2, MO_ProducerOrStorageType.None, "", add);
int numX = 6;
int numY = 2;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartY = 279500;
int redendY = 308614;
int redintervalx = (redendX - redstartX) / numX;
int redintervaly = (redendY - redstartY) / numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = (ct * 3 + 1117).ToString("D3") + "-" + (ct * 13 + 342).ToString("D2");
string name2 = "CSS-" + (char)(ct + 79) + (char)(ct + 71) + "-" +(ct * 57 + 73).ToString("D2");
if (ct % 4 !=3)
addMobile(MO_ObjectiveType.Communications, "Communications Bunker " + name1 , "", 1, 5, ("Communications_Bunker_" + name1).Replace(' ', '_'), redinitX, redinitY, 150, 120, 8000, 25, 0, 120, 72, true, true, 1, 1,
MO_MobileObjectiveType.KnickebeinHQ, 72, redLLX, redLLY, redURX, redURY, 7.000, 14.000, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
if (ct % 4 != 1)
addMobile(MO_ObjectiveType.MilitaryArea, "Essex Commando Training Facility " + name2, "", 1, 6, "Essex_Commando_Training_Facility_" + name2, redinitX + 4500, redinitY - 7300, 120, 100, 9000, 25, 0, 120, 72, true, true, 1, 1, MO_MobileObjectiveType.CamoGroup, 96, redLLX, redLLY, redURX, redURY, 6.500, 16.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
numX = 2;
numY = 2;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartY = 178894;
int redendY = 229467;
int redintervalx = (redendX - redstartX) / numX;
int redintervaly = (redendY - redstartY) / numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = (ct * 7 + 2317).ToString("") + "-" + (ct * 6 + 741).ToString("D3");
string name2 = "KL-" + (char)(ct + 78) + (char)(ct + 80) + "-" + (ct * 106 + 51).ToString("D2");
addMobile(MO_ObjectiveType.Communications, "Funkkommunikationszentrum " + name1, "", 2, 5, ("Funkkommunikationszentrum_" + name1).Replace(' ', '_'), redinitX, redinitY, 150, 120, 8000, 25, 0, 120, 72, true, true, 1, 1,
MO_MobileObjectiveType.KnickebeinHQ, 72, redLLX, redLLY, redURX, redURY, 7.000, 14.000, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
addMobile(MO_ObjectiveType.MilitaryArea, "Kommandolager " + name2, "", 1, 6, "Kommandolager_" + name2, redinitX + 4500, redinitY - 7300, 120, 100, 9000, 25, 0, 120, 72, true, true, 1, 1, MO_MobileObjectiveType.CamoGroup, 96, redLLX, redLLY, redURX, redURY, 6.500, 16.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
int redstartX = 200000;
int redstartY = 230000;
int redinterval = 10000;
int ct = i * 5 + j;
int redLLX = redstartX + redinterval * j;
int redLLY = redstartY + redinterval * i;
int redURX = redLLX + redinterval;
int redURY = redLLY + redinterval;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "#A" + (char)(ct + 65) + (ct * 4).ToString("D2");
if (ct % 4 != 3)
addMobile(MO_ObjectiveType.MilitaryFuelStorage, "Temporary Aviation Fuel Dump " + name1, "", 1, 5, "RFuelDump" + name1, redinitX, redinitY, 80, 100, 750, 12, 0, 150, 180, true, true, 1, 2, MO_MobileObjectiveType.FuelDump, 300, redLLX, redLLY, redURX, redURY, 1, 5, MO_ProducerOrStorageType.fuel, "", add);
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
int redstartX = 270000;
int redstartY = 170000;
int redinterval = 10000;
int ct = i * 4 + j;
int redLLX = redstartX + redinterval * j;
int redLLY = redstartY + redinterval * i;
int redURX = redLLX + redinterval;
int redURY = redLLY + redinterval;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = (ct * 3).ToString("N0") + (char)(ct + 73);
if (ct % 4 != 2)
addMobile(MO_ObjectiveType.MilitaryFuelStorage, "Flugbenzinlager " + name1, "", 2, 5, "BFuelDump" + name1, redinitX, redinitY, 80, 100, 750, 12, 0, 150, 180, true, true, 1, 2, MO_MobileObjectiveType.FuelDump, 300, redLLX, redLLY, redURX, redURY, 1, 5, MO_ProducerOrStorageType.fuel, "", add);
}
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
int redstartX = 260000;
int redstartY = 250000;
int redintervalx = 42000;
int redintervaly = 25000;
int ct = i * 2 + j + 1;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "#BB-" + (char)(ct + 72) + (ct * 7).ToString("D2");
string name2 = "#ZZ-" + (char)(ct + 67) + (ct * 13).ToString("D2");
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "North Sea Transport Ships " + name1 + " (sink 2)", "", 1, 4, "British_Transport_Ships_" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 2, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.SmallShipGroup_GB, 3, redLLX, redLLY, redURX, redURY, 1, 6, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
if (ct % 2 == 1)
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "North Sea Transport Ship " + name2, "", 1, 2, "British_Transport_Ship_" + name2, redinitX + 23000, redinitY - 18300, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_GB, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.5, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
int redstartX = 220000;
int redstartY = 265500;
int redintervalx = 18000;
int redintervaly = 16000;
int ct = i * 2 + j + 1;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "#DD-" + (char)(ct + 76) + (ct * 19).ToString("D2");
string name2 = "#VV-" + (char)(ct + 71) + (ct * 136).ToString("D2");
if (ct % 4 != 1)
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "Thames Estuary Transport Ships " + name1 + " (sink 2)", "", 1, 4, "Thames_Transport_Ships_" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 2, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.SmallShipGroup_GB, 3, redLLX, redLLY, redURX, redURY, 1, 6, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
if (ct % 2 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "Thames Estuary Transport Ship " + name2, "", 1, 2, "Thames_Transport_Ship_" + name2, redinitX - 9000, redinitY + 12500, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_GB, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
int redstartX = 80000;
int redstartY = 120000;
int redintervalx = 55000;
int redintervaly = 20000;
int ct = i * 4 + j + 1;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "Sch-" + (ct * 6 + 13).ToString("D2") + (char)(ct + 72);
string name2 = "See-" + (ct * 7 + 211).ToString("D2");
if (ct % 4 != 2)
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "South Channel Transport Ship Group " + name1 + " (sink 2)", "", 2, 4, "South_Channel_Transport_Ships_" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 2, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.SmallShipGroup_DE, 3, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
if (ct % 2 == 1)
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "South Channel Transport Ship " + name2, "", 2, 2, "South_Channel_Transport_Ship_" + name2, redinitX + 15000, redinitY - 9000, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_DE, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
int redstartX = 227841;
int redstartY = 186573;
int redintervalx = 19000;
int redintervaly = 16000;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "SF-" + (ct * 13 + 542).ToString("D2");
string name2 = "MVA-" + (char)(ct + 80) + (ct * 14 + 211).ToString("D2");
if (ct % 4 != 0)
addMobile(MO_ObjectiveType.Naval_Freighter_Convoy, "Channel Transport Ships " + name1 + " (sink 2)", "", 2, 4, "Channel_Transport_Ships_" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 2, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.SmallShipGroup_DE, 3, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
if ((i + j) % 2 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "Channel Transport Ship " + name2, "", 2, 2, "Channel_Transport_Ship_" + name2, redinitX + 9000, redinitY - 11000, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_DE, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
numX = 2;
numY = 1;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartX = 11619;
int redstartY = 131307;
int redendX = 174660;
int redendY = 195024;
int redintervalx = (redendX - redstartX)/numX;
int redintervaly =( redendY - redstartY)/ numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "W.C. " + (ct * 17 + 172).ToString("D2");
string name2 = "MPA-" + (char)(ct + 76) + (ct * 9 + 501).ToString("D2");
addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "West Channel Large Tankers " + name1 + " (sink 2)", "", 1, 5, ("West_Channel_Large_Tankers_" + name1).Replace(' ', '_'), redinitX, redinitY, 1200, 8000, 0, 0, 1, shipPriority, 6, false, false, 0, 0,
MO_MobileObjectiveType.LargeTankerShipGroup_GB, 5, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.fuel, "", add, canbedisabled: false);
if ((i + j) % 2 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "West Channel Transport Ship " + name2, "", 1, 2, "West_Channel_Transport_Ship_" + name2, redinitX + 9000, redinitY - 11000, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_GB, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
numX = 2;
numY = 1;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartX = 12993;
int redstartY = 29485;
int redendX = 182031;
int redendY = 128808;
int redintervalx = (redendX - redstartX) / numX;
int redintervaly = (redendY - redstartY) / numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "S.W. " + (ct * 27 + 312).ToString("D2");
string name2 = "WSA-" + (char)(ct + 71) + (ct * 31 + 5423).ToString("D2");
addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "Normandy Coast Large Tankers " + name1 + " (sink 2)", "", 2, 5, "Normandy_Coast_Large_Tankers_" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 2, shipPriority, 6, false, false, 0, 0,
MO_MobileObjectiveType.LargeTankerShipGroup_DE, 5, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.fuel, "", add, canbedisabled: false);
if ((i + j) % 2 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "Normandy Coast Transport Ship " + name2, "", 2, 2, "Normandy_Coast_Transport_Ship_" + name2, redinitX + 9000, redinitY - 11000, 150, 7000, 0, 0, 2, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneShipGroup_DE, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
numX = 8;
numY = 1;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartX = 11158;
int redstartY = 162429;
int redendX = 193982;
int redendY = 203677;
int redintervalx = (redendX - redstartX) / numX;
int redintervaly = (redendY - redstartY) / numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "B.C.F. " + (ct * 39 + 2034).ToString("D2");
string name2 = "BCP-" + (ct * 11 + 26).ToString("D2");
addMobile(MO_ObjectiveType.Naval_Ship, "British Coastal Freighter " + name1 , "", 1, 2, "British_Coastal_Freighter" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 1, shipPriority, 6, false, false, 0, 0,
MO_MobileObjectiveType.OneShipGroup_GB, 5, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.fuel, "", add, canbedisabled: false);
if ((i + j) % 3 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "British Coastal Patrol " + name2, "", 1, 4, "British_Coastal_Patrol_" + name2, redinitX + 9000, redinitY - 11000, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneMTBGroup_GB, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
numX = 8;
numY = 1;
for (int i = 0; i < numY; i++)
{
for (int j = 0; j < numX; j++)
{
int redstartX = 11078;
int redstartY = 11078;
int redendX = 236876;
int redendY = 110298;
int redintervalx = (redendX - redstartX) / numX;
int redintervaly = (redendY - redstartY) / numY;
int ct = i * 2 + j;
int redLLX = redstartX + redintervalx * j;
int redLLY = redstartY + redintervaly * i;
int redURX = redLLX + redintervalx;
int redURY = redLLY + redintervaly;
int redinitX = (redLLX + redURX) / 2;
int redinitY = (redLLY + redURX) / 2;
string name1 = "F.C.F. " + (ct * 39 + 2034).ToString("D2");
string name2 = "FCP-" + (ct * 7 + 111).ToString("D2");
addMobile(MO_ObjectiveType.Naval_Ship, "French Coastal Freighter " + name1, "", 2, 2, "French_Coastal_Freighter" + name1, redinitX, redinitY, 1200, 8000, 0, 0, 1, shipPriority, 6, false, false, 0, 0,
MO_MobileObjectiveType.OneShipGroup_DE, 5, redLLX, redLLY, redURX, redURY, 1.000, 6.000, MO_ProducerOrStorageType.fuel, "", add, canbedisabled: false);
if ((i + j) % 3 == 0)
addMobile(MO_ObjectiveType.Naval_Ship, "French Coastal Patrol " + name2, "", 1, 4, "French_Coastal_Patrol_" + name2, redinitX + 9000, redinitY - 11000, 150, 7000, 0, 0, 1, shipPriority, 6, false, false, 0, 0, MO_MobileObjectiveType.OneMTBGroup_DE, 4, redLLX + 5000, redLLY + 3000, redURX + 5000, redURY + 3000, 1.500, 7.500, MO_ProducerOrStorageType.None, "", add, canbedisabled: false);
}
}
/*
* addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "North Sea Tanker Group (sink ~4)", "", 2, 6, "NorthSea_German_Tankers", 260310, 241196, 10000, 10000, 0, 30, 0, 120, 12, false, false, 0, 0, MO_MobileObjectiveType.TankerShipGroup_DE, 24, 260310, 241196, 301268, 296717, 5000, 20000, MO_ProducerOrStorageType.fuel, "", add);
addMobile(MO_ObjectiveType.Naval_Tanker_Convoy, "British North Sea Tanker Group (sink ~4)", "", 1, 6, "NorthSea_British_Tankers", 292621, 230047, 10000, 10000, 0, 30, 0, 120, 12, false, false, 0, 0, MO_MobileObjectiveType.TankerShipGroup_GB, 24, 292621, 230047, 348142, 277376, 5000, 20000, MO_ProducerOrStorageType.fuel, "", add);
*/
/* addTrigger(MO_ObjectiveType.Building, "Portsmouth Small Military Manufacturing Area SW", "Port", 1, 4, "BTargPortsmouthSmallIndustrialArea", "TGroundDestroyed", 35, 75235, 193676, 350, false, 120, 24, "", add);
addTrigger(MO_ObjectiveType.Building, "Portsmouth Large Military Manufacturing Area NE", "Port", 1, 5, "BTargPortsmouthLargeIndustrialArea", "TGroundDestroyed", 27, 77048, 193985, 850, false, 120, 24, "", add);
addTrigger(MO_ObjectiveType.Building, "Poole North Industrial Port Area", "Pool", 1, 5, "BTargPooleNorthIndustrialPortArea", "TGroundDestroyed", 33, 14518, 184740, 400, false, 120, 24, "", add);
addTrigger(MO_ObjectiveType.Building, "Poole South Industrial Port Area", "Pool", 1, 4, "BTargPooleSouthIndustrialPortArea", "TGroundDestroyed", 34, 13734, 183493, 400, false, 120, 24, "", add);
*/
/*
*
RTargBerckLandingCraft TGroundDestroyed 14 269247 147771 150
RTargLeCrotoyLandingCraftManufactureAreaBomb TGroundDestroyed 25 271378 132785 1000
RTargEstreeArmyTraining TGroundDestroyed 4 279617 163616 100
RTargEtaplesLandingCraft TGroundDestroyed 7 269447 166097 150
* */
/*41 162099 50034 50
*
***************** add unfinished convoys for british attack here***********
/*
*/
}
public Dictionary FlakMissions = new Dictionary()
{
{ "LondArea", "/Flak areas/LondonFlak.mis" },
{ "Abbe", "/Flak areas/Abbevilleflak.mis" },
{ "Arra", "/Flak areas/Arrasflak.mis" },
{ "Ashf", "/Flak areas/Ashfordflak.mis" },
{ "Bext", "/Flak areas/Bextonflak.mis" },
{ "Boul", "/Flak areas/Boulogneflak.mis" },
{ "Bult", "/Flak areas/Bultonflak.mis" },
{ "Caen", "/Flak areas/Caenflak.mis" },
{ "Cala", "/Flak areas/Calaisflak.mis" },
{ "Diep", "/Flak areas/Dieppeflak.mis" },
{ "Ditt", "/Flak areas/Dittonflak.mis" },
{ "Dove", "/Flak areas/Doverflak.mis" },
{ "Dunk", "/Flak areas/Dunkirkflak.mis" },
{ "Estr", "/Flak areas/Estreeflak.mis" },
{ "Farn", "/Flak areas/Farnflak.mis" },
{ "Guil", "/Flak areas/Guildfordflak.mis" },
{ "Havr", "/Flak areas/LeHavreflak.mis" },
{ "Trep", "/Flak areas/LeTreportflak.mis" },
{ "Litt", "/Flak areas/LittleStoneflak.mis" },
{ "Lond", "/Flak areas/LondonDocksflak.mis" },
{ "Maid", "/Flak areas/Maidstoneflak.mis" },
{ "Mans", "/Flak areas/Manstonflak.mis" },
{ "Poix", "/Flak areas/PoixNordflak.mis" },
{ "Port", "/Flak areas/Portsmouthflak.mis" },
{ "QueR", "/Flak areas/Quervilleflak.mis" },
{ "RaHQ", "/Flak areas/RadarHQflak.mis" },
{ "Read", "/Flak areas/Readingflak.mis" },
{ "Redh", "/Flak areas/RedHillflak.mis" },
{ "Shee", "/Flak areas/Sheernessflak.mis" },
{ "Sout", "/Flak areas/Southhamptonflak.mis" },
{ "Omar", "/Flak areas/Omarflak.mis" },
{ "Ouen", "/Flak areas/Ouenflak.mis" },
{ "Stel", "/Flak areas/Stellingflak.mis" },
{ "Swin", "/Flak areas/Swindonflak.mis" },
{ "Tunb", "/Flak areas/Tunbridgeflak.mis" },
{ "Watt", "/Flak areas/Wattenflak.mis" },
{ "Larr", "/Flak areas/Larrowflak.mis" },
{ "Lblu", "/Flak areas/Lblueflak.mis" },
{ "Lgol", "/Flak areas/Lgoldflak.mis" },
{ "Lgre", "/Flak areas/Lgreyflak.mis" },
{ "Lhyd", "/Flak areas/Lhydrogenflak.mis" },
{ "Lwhi", "/Flak areas/Lwhiteflak.mis" },
{ "Pers", "/Flak areas/Persanflak.mis" },
{ "Dun1", "/Flak areas/Dun1flak.mis" },
{ "Dun2", "/Flak areas/Dun2flak.mis" },
{ "Dun3", "/Flak areas/Dun3flak.mis" },
{ "Peti", "/Flak areas/Petitflak.mis" },
{ "Haze", "/Flak areas/Hazebrouckflak.mis" },
{ "None", "/Flak areas/Noneflak.mis" },
/*
Oye Plage Freya Radar",
Coquelles Freya Radar",
Dunkirk Freya Radar",
Herderlot-Plage Freya Radar
Berck Freya Radar",
Radar Dieppee",
Radar Le Treport",
Radar Somme River",
Radar AMBETEUSE",
Radar BOULOGNE",
Radar Le Touquet",
Veulettes-sur-Mer Radar",
Le Havre Freya Radar",
Ouistreham Freya Radar",
Bayeux Beach Freya Radar",
Beauguillot Beach Freya Rad
Radar Tatihou",
Radar Querqueville",
added Rouen Flak
*/
};
/*
for (int x = 0; x < 1200; x++) //unlikely but possible that we'd need to cycle through the list of targets multiple times to select enough targets to reach the points. Could happen though if PrimaryTargetWeights are set low, or only a few possible objectives available in the list...
{
List keys = new List(msn.MissionObjectivesList.Keys);
Calcs.Shuffle(keys);
int goal = msn.MissionObjectivesList.Count / 2;
int count = 0;
{
foreach (var key in keys)
{
MissionObjective mo = msn.MissionObjectivesList[key];
{
if (mo.AttackingArmy != (int)army) continue;
if (mo.AttackingArmy == 1 || mo.AttackingArmy == 2)
{
if (msn.MissionObjectivesSuggested[(ArmiesE)mo.AttackingArmy].Contains(key)) continue;
msn.MissionObjectivesSuggested[(ArmiesE)mo.AttackingArmy].Add(key);
count++;
if (count > goal) break;
}
}
}
}
}
}
No description available.
{
List keys = new List(MissionObjectivesList.Keys);
if (MissionObjectivesSuggested[(ArmiesE)mo.AttackingArmy].Contains(mo.ID)) ;
{
MissionObjectivesSuggested[(ArmiesE)mo.AttackingArmy].Remove(mo.ID);
}
}
No description available.
{
string winner = ArmiesL[(int)army];
string repairStrength_str = (repairStrength * 100.0).ToString("n0") + "%";
int endseconds = 0;
Timeout(endseconds, () =>
{
twcLogServer(null, winner + " has won this battle and completed all objectives assigned by HQ!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has won this battle. Congratulations, " + winner + "!");
});
Timeout(endseconds + 10, () =>
{
twcLogServer(null, winner + " has won, pushed the front forward, and pushed the enemy back!", new object[] { });
GamePlay.gpHUDLogCenter(winner + " has won the battle & pushed the front forward!");
});
Timeout(endseconds + 20, () =>
{
twcLogServer(null, winner + " HQ is very pleased with their performance and has rushed as many extra repair crews to this sector as possible ({0} available).", new object[] { repairStrength_str });
GamePlay.gpHUDLogCenter(winner + " has won this battle. Congratulations, " + winner + "!");
});
Timeout(endseconds + 30, () =>
{
twcLogServer(null, "Extra repair crews (currently at {1} strength) will be assigned to {0} airfields, radar, and other damaged areas!", new object[] { winner, repairStrength_str });
GamePlay.gpHUDLogCenter(winner + " has won this battle. Repair crews @ " + (repairStrength * 100.0).ToString("F0") + "%");
});
Timeout(endseconds + 40, () =>
{
twcLogServer(null, winner + " has won this battle! All involved have had their contributions recorded at Divisional Headquarters - expect promotions and commendations for all who have fought bravely and well.", new object[] { winner });
GamePlay.gpHUDLogCenter(winner + " has won this battle. Repair crews @ " + repairStrength_str);
});
Timeout(endseconds + 50, () =>
{
twcLogServer(null, "Congratulations " + winner + " for winning this hard-fought battle and carrying the day! Meanwhile, the campaign continues . . . ", new object[] { winner });
GamePlay.gpHUDLogCenter(winner + " has won this battle. Congratulations, " + winner + "!");
});
}
//Task.Run(() => //MO_MilitaryStrengthType { Military, Military_Leadership, Military_Fuel_Supply, General_Production_And_Supply } //We'll have to work on making CalcMapMove work here //And also save the full stats at this point, similar to what we do at end of mission. //Timeout(10, () => { //Can't wait on this one!!! 2023/01 //}); //This calcs the new mapstate & saves to disk...
{
{
Console.WriteLine(ArmiesL[(int)army] + " has turned the battle - giving reward, selecting new objectives");
Console.WriteLine("Rolling Winner Handler: calculating military strength...");
double militaryStrength = MO_CalculateMilitaryStrength((ArmiesE)army, MO_MilitaryStrengthType.Military);
double militaryLeadershipStrength = MO_CalculateMilitaryStrength((ArmiesE)army, MO_MilitaryStrengthType.Military_Leadership);
double generalProductionStrength = MO_CalculateMilitaryStrength((ArmiesE)army, MO_MilitaryStrengthType.General_Production_And_Supply);
double repairStrength = (militaryLeadershipStrength + militaryStrength + generalProductionStrength) / 3.0;
if (repairStrength < 0.15) repairStrength = 0.15;
Console.WriteLine("Rolling Winner Handler: TurnedMapAnnouncements...");
MO_turnedMapAnnouncements(army, repairStrength);
Console.WriteLine("Rolling Winner Handler: SaveMapState...");
SaveMapState(ArmiesL[(int)army], intermediateSave: true, intermediateWin: true);
Console.WriteLine("Rolling Winner Handler: Rolling Winners Reward...");
MO_MissionObjectiveRollingWinnersReward(army, repairStrength);
Timeout(20, () =>
{
Console.WriteLine("Rolling Winner Handler: Select Primary Objectives...");
MO_SelectPrimaryObjectives((int)army, 0, fresh: true);
});
Timeout(30, () => {
Console.WriteLine("Rolling Winner Handler: Write primary objectives ...");
Timeout(40, () => {
Console.WriteLine("Rolling Winner Handler: select suggested objectives...");
mission_objectives.SelectSuggestedObjectives(army); });
{
Task.Run(() =>
{
Console.WriteLine("Rolling Winner Handler: Draw frontlines...");
});
});
}
repairStrength = Math.Sqrt(Math.Sqrt(Math.Sqrt(repairStrength))); //2023/08/21 - bhugh, being nicer on the effect of repairStrength, reducing the effect by quite a bit //minutesLeft = 2;//FOR TESTING //bhugh, temp, XX2021-10, removing ALL repair speedup on turn the map until end of campaign MissionObjectivesTimes[army]["RepairCrewEndTime_dt"] = currTime_dt.AddHours(36 * repairStrength); //So they have repair crews for up to 36 hours depending on military strength etc. Speeds up any repairs (on airports) by 4X...
{
int minutesLeft = calcTimeLeft_min();
int maxUndestroyTime_min = minutesLeft;
if (maxUndestroyTime_min > 4 * 60) maxUndestroyTime_min = 4 * 60;
DateTime currTime_dt = DateTime.UtcNow;
int count = 0;
foreach (string ID in MissionObjectivesList.Keys.ToList())
{
count++;
Timeout(5 + count * 2, () =>
{
MissionObjective mo = MissionObjectivesList[ID];
mo.fixDestructionValues();
if (mo.OwnerArmy == (int)army && (mo.Destroyed || mo.DestroyedPercent > 0 ||
(mo.TimeToUndestroy_UTC.HasValue && mo.MOObjectiveType != MO_ObjectiveType.Military_Airfield)
|| mo.AirfieldDamagePoints >= mo.AirfieldPointsRequired))
{
DateTime timeToRestore_dt = currTime_dt;
DateTime timeToRestoreAlt_dt = currTime_dt;
double timeToUnrestore_hrs = 4 / repairStrength;
/*
if (mo.TimeToUndestroy_UTC.HasValue && mo.TimeToUndestroy_UTC.Value.CompareTo(currTime_dt) > 0)
{
if (timeToRestoreAlt_dt.CompareTo(timeToRestore_dt) < 0) timeToRestore_dt = timeToRestoreAlt_dt;
}
Console.WriteLine("Winner: Setting timetoUnd for {0} to {1} ({2}) ", mo.Name, mo.TimeToUndestroy_UTC.Value.ToString("yyyy-MM-dd-HHmmss"), minutesLeft);
*/
double speedupFactor = 10 * repairStrength;
if (mo.TimeToUndestroy_UTC.HasValue && mo.TimeToUndestroy_UTC.Value.CompareTo(currTime_dt) > 0)
{
}
mo.ActorsDestroyed_num = (3 * mo.ActorsDestroyed_num) / 4;
}
if (mo.OwnerArmy == (int)army && !mo.Destroyed &&
(mo.DestroyedPercent > 0 || mo.AirfieldDamagePoints > 0 || mo.OrdnanceOnTarget_kg > 0
|| mo.ObjectsDestroyed_num > 0 || mo.ActorsDestroyed_num > 0)
)
{
mo.OrdnanceOnTarget_kg = mo.OrdnanceOnTarget_kg / 2;
mo.AirfieldDamagePoints = mo.AirfieldDamagePoints / 2;
Console.WriteLine("Winner: Removing partial damage for {0}", mo.Name);
}
if (mo.OwnerArmy == (int)army)
{
mo.OrdnanceOnTarget_kg = 0;
mo.LastHitTime_UTC = null;
}
});
}
foreach (MissionObjective mo in MissionObjectivesList.Values.ToList())
{
if (mo.AttackingArmy == (int)army)
{
mo.IsPrimaryTarget = false;
mo.PlayersWhoScoutedNames = new Dictionary();
mo.lastScoutedPos = mo.Pos;
mo.lastScoutedSector = mo.Sector;
mo.lastTimeScouted_dt = null;
mo.numTimesScouted = 0;
mo.PlayersWhoContributedNames = new HashSet();
}
}
MissionObjectiveScore[(ArmiesE)army] = 0;
MissionObjectivesCompletedString[(ArmiesE)army] = "";
}
//We don't reset mo.ObjectiveAchievedForPoints here because the other side is still working on their objectives list. So it is restored for use by the winning side but still counts towards objectives/points for the other side...
{
foreach (string ID in MissionObjectivesList.Keys)
{
MissionObjective mo = MissionObjectivesList[ID];
if (mo.OwnerArmy == (int)army)
{
if (mo.MOTriggerType != MO_TriggerType.TemporaryLandingGround)
{
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.TimeToUndestroy_UTC = null;
mo.LastHitTime_UTC = null;
/* hmm, this was a mistake but we **could** really do it. When one side turns the map, the other side loses all of its recon photos. Hmm.
mo.Scouted = false;
mo.PlayersWhoScoutedNames = new Dictionary();
*/
}
}
if (mo.AttackingArmy == (int)army)
{
mo.IsPrimaryTarget = false;
mo.PlayersWhoScoutedNames = new Dictionary();
mo.PlayersWhoRepairedNamesTimes = new Dictionary();
}
}
MissionObjectiveScore[(ArmiesE)army] = 0;
MissionObjectivesCompletedString[(ArmiesE)army] = "";
}
//DON'T RESET isPrimaryTarget here because we're doing this after the primary objectives are chosen & entered into this list. //We will do that needed reset, but earlier in the process //mo.IsPrimaryTarget = false; //we reset this every time we load from disk, because later we'll read the primary objectives file & set this = true if it is a primary objective based on that...
{
foreach (string ID in MissionObjectivesList.Keys)
{
MissionObjective mo = MissionObjectivesList[ID];
if (mo.Destroyed && mo.MOTriggerType != MO_TriggerType.TemporaryLandingGround)
{
if (mo.TimeToUndestroy_UTC.HasValue && DateTime.Compare(mo.TimeToUndestroy_UTC.Value, DateTime.UtcNow) < 0)
{
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.TimeToUndestroy_UTC = null;
{
double hoursSinceHit = 48;
if (mo.LastHitTime_UTC.HasValue) hoursSinceHit = DateTime.UtcNow.Subtract(mo.LastHitTime_UTC.Value).TotalHours;
Calcs.loadSmokeOrFire(GamePlay, this, mo.Pos.x + random.Next(50) - 25, mo.Pos.y + random.Next(50) - 25, 0, smoke, duration_s: 6 * 3600);
if (mo.LastHitTime_UTC != null && (hoursSinceHit < 12)) Calcs.loadSmokeOrFire(GamePlay, this, mo.Pos.x + random.Next(75) - 32.5, mo.Pos.y + random.Next(50) - 25, 0, smoke, duration_s: 6 * 3600);
if (mo.LastHitTime_UTC != null && (hoursSinceHit < 2)) Calcs.loadSmokeOrFire(GamePlay, this, mo.Pos.x + random.Next(150) - 75, mo.Pos.y + random.Next(150) - 75, 0, smoke, duration_s: 6 * 3600);
/*if (mo.MOTriggerType == MO_TriggerType.Trigger && GamePlay.gpGetTrigger(ID) != null)
{
Console.WriteLine("MO_DestroyObjective: Disabling trigger " + ID);
GamePlay.gpGetTrigger(ID).Enable = false;
}
*/
if (mo.MOObjectiveType == MO_ObjectiveType.Radar || mo.MOObjectiveType == MO_ObjectiveType.KnickebeinHQ)
{
if (mo.OwnerArmy == 1) DestroyedRadar[(ArmiesE.Red)].Add(mo);
if (mo.OwnerArmy == 2) DestroyedRadar[(ArmiesE.Blue)].Add(mo);
}
}
}
}
}
//AddNewOnly means only add new aps not already in the file read from disk. addNewOnly=false means, forget about what's on the disk load, just read them all in...
{
Timeout(195, () =>
{
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (mo.MOObjectiveType != MO_ObjectiveType.Airfield_Complex &&
mo.MOObjectiveType != MO_ObjectiveType.Military_Airfield &&
mo.MOObjectiveType != MO_ObjectiveType.Civilian_Airfield) continue;
if (mo.Destroyed || mo.DestroyedPercent >= 1)
{
Console.WriteLine("MO_CheckBirthPlacesRemoved: Airport is destroyed, removing birthplace for " + mo.Name + " " + mo.AirfieldName);
if (mo.aiairport != null) AirfieldDisable(mo.aiairport);
else AirfieldDisable(mo.AirfieldName);
}
}
});
}
//public Dictionary
{
if (GamePlay == null)
{
Console.Write("");
Console.Write("Airfieldsetup: MAJOR ERROR *************************************************** ");
Console.Write("Airfieldsetup: MAJOR ERROR GamePlay not initialized, nothing done. Exiting.");
Console.Write("Airfieldsetup: MAJOR ERROR *************************************************** ");
Console.Write("");
Console.Write("");
EndMission(endseconds: 0);
}
int count = AirfieldTargets.Count;
var stl = showTimeLeft(null, false);
var inGame_dt = stl.Item2;
bool inAirportBombPhase = false;
if (inGame_dt.CompareTo(new DateTime(1940, 8, 10)) <= 0) weight = (double)180 / (double)count;
else if (inGame_dt.CompareTo(new DateTime(1940, 9, 13)) <= 0)
{
weight = (double)750 / (double)count;
inAirportBombPhase = true;
}
int num_added = 0;
int num_updated = 0;
var allKeys = new List(AirfieldTargets.Keys);
if (AirfieldTargets != null) foreach (string apID in allKeys)
{
string af_name = AirfieldTargets[apID].Item2 + "_airfield";
try
{
if (!addNewOnly || !MissionObjectivesList.ContainsKey(af_name))
{
double IndWeight = weight;
if (NumNearbyTargets > 0) IndWeight = weight * 2;
Point3d Pos = AirfieldTargets[apID].Item7;
int army = AirfieldTargets[apID].Rest.Item1;
if (Pos.x > 210000 && Pos.y > 180000 && Pos.x < 321000 && Pos.y < 270000)
{
}
Console.Write("Airfieldsetup: adding new airfield " + af_name + " Army: " + army.ToString() + " PTP weight: " + IndWeight.ToString("F0"));
num_added++;
}
else if (MissionObjectivesList.ContainsKey(af_name))
{
Console.Write("Airfieldsetup: updating existing airfield " + af_name);
Tuple> oldAp = AirfieldTargets[apID];
MissionObjective mo = MissionObjectivesList[af_name];
if (mo.LastHitTime_UTC.HasValue) lastHitTime = mo.LastHitTime_UTC.Value;
PointsTaken = mo.AirfieldDamagePoints;
int army_fromFileOrMap = oldAp.Rest.Item1;
Console.Write("Airfieldsetup: updating airfield " + af_name + " Current Army: " + mo.OwnerArmy.ToString() + " thismapArmy: " + army_fromFileOrMap.ToString()
);
if (mo.OwnerArmy != army_fromFileOrMap)
{
mo.OwnerArmy = army_fromFileOrMap;
mo.AttackingArmy = 3 - army_fromFileOrMap;
if (mo.AttackingArmy > 2 || mo.AttackingArmy < 1) mo.AttackingArmy = 0;
Console.Write("Airfieldsetup: changed army for" + af_name + " New Army: " + mo.OwnerArmy.ToString());
}
if (mo.Destroyed)
{
{
Console.Write("Airfieldsetup: updating airfield; time to undestroy it, " + af_name);
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.TimeToUndestroy_UTC = null;
mo.OrdnanceOnTarget_kg = 0;
mo.ObjectsDestroyed_num = 0;
mo.ActorsDestroyed_num = 0;
PointsTaken = 0;
}
{
Console.Write("Airfieldsetup: updating airfield; it is still destroyed, " + af_name);
Timeout(60, () => {
AirfieldDisable(apID, 1);
if (mo.aiairport != null) AirfieldDisable(mo.aiairport);
});
}
}
{
Console.Write("Airfieldsetup: updating airfield; it is partially destroyed, " + af_name);
double percent = PointsTaken / PointsToKnockout;
Timeout(60, () => { AirfieldDisable(apID, percent); });
}
/*
AirfieldTargets[ap] = new Tuple(
lastHitTime,
mo.OwnerArmy
);
*/
AirfieldTargets[apID] = Tuple.Create(
lastHitTime,
mo.OwnerArmy
);
num_updated++;
}
}
catch (Exception ex) { Console.WriteLine("Update Airfield Targets LOOP ERROR: " + af_name + " #" + num_updated.ToString("n0") + " " + ex.ToString()); }
}
Console.WriteLine("Mission Objectives: Added " + num_added.ToString() + " airports to Mission Objectives, updated " + num_updated.ToString() + " weight " + weight.ToString("N5"));
}
//public Dictionary
{
int num_updated = 0;
var allKeys = new List(AirfieldTargets.Keys);
if (AirfieldTargets != null) foreach (string apKey in allKeys)
{
string af_name = AirfieldTargets[apKey].Item2 + "_airfield";
Tuple> oldAp = AirfieldTargets[apKey];
MissionObjective mo = MissionObjectivesList[af_name];
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.TimeToUndestroy_UTC = null;
mo.ObjectsDestroyed_num = 0;
mo.ActorsDestroyed_num = 0;
mo.OrdnanceOnTarget_kg = 0;
mo.AirfieldDamagePoints = 0;
/*
* AirfieldTargets[ap] = new Tuple(
);
*/
AirfieldTargets[apKey] = Tuple.Create(
);
num_updated++;
}
Console.WriteLine("Mission Objectives: Repaired " + num_updated.ToString() + " airports for army " + army.ToString("F0"));
}
//Console.WriteLine("Main: Removing smokeFireCraters Loc:{0}/{1} r:{2} pctto remove:{3}", new object[] { p.x, p.y, radius_m, percentToRemove }); //"crater", "smoke", "fire" });
{
Calcs.removeStatics(GamePlay, this, p.x, p.y, radius_m, new List {
"Smoke1", "Smoke2", "BuildingFireSmall", "BuildingFireBig", "BigSitySmoke_0", "BigSitySmoke_1", "BombCrater_firmSoil_mediumkg", "BombCrater_firmSoil_largekg", "BombCrater_firmSoil_smallkg" }, percentToRemove);
}
//2021-11 Jubilee: The turn map requirements can vary, sometimes just a few, sometimes many points required to turn the map //This is calculated indpendently for each army, randomly, and saved to disk so that we //know/remember what is required to turn
{
int total = 0;
List keys = new List(MissionObjectivesList.Keys);
foreach (var key in keys)
{
MissionObjective mo = MissionObjectivesList[key];
double d_m = Calcs.CalculatePointDistance(mo.Pos, p);
if (d_m <= dist_m) total++;
}
return total;
}
Console.WriteLine(" MO_CalculateTurnMapRequirements: {0:n0}, {1:n0}, {2:n0}, {3:n0}, {4:n0}", MO_PrimaryPointsRequired[(ArmiesE)army], MO_PointsRequired[(ArmiesE)army], MO_PointsRequiredWithMissingPrimary[(ArmiesE)army], MO_PointsRequiredWithNoPrimary[(ArmiesE)army], MO_PercentPrimaryTargetsRequired[(ArmiesE)army]);//, extraObjectives, noPrimaries ); //write calculation TO DISK/save MO_initializeTurnMapPointsRequired_toLargeDict(); //copies them into the dictionary that is then saved //This creates a randomized list of Blue or Red Primary Objectives totalling (at least) the required point total //And sets the IsPrimaryTarget flag for each in that army, de-selecting the IsPrimaryTarget flag for all others //Only chooses from those in the PrimaryTargetWeight //Will do either army=1 or army=2 or BOTH ARMIES if army=0
{
/*
public double MO_MaxPrimariesRequired 150;
public double MO_MinPrimariesRequired = 10;
public double MO_MinMaxPolarization = 0.8;
*/
double rn = Math.Pow(random.NextDouble(), MO_MinMaxPolarization);
Console.WriteLine(" MO_CalculateTurnMapRequirements: rn = {0:n4}", rn);
if (random.Next(0, 2) == 1) rn = 1 - rn;
Console.WriteLine(" MO_CalculateTurnMapRequirements: rn = {0:n4}", rn);
MO_PrimaryPointsRequired[(ArmiesE)army] = Math.Round((MO_MaxPrimariesRequired - MO_MinPrimariesRequired) * rn + MO_MinPrimariesRequired);
/* 2022/11/25 - with new scheme (fixed # of points required, primaries are a small but flexible part of that) the below calcs are NOT NEEDeD or WANTED
*
double extraObjectives = MO_PointsRequired[(ArmiesE)army] * 0.4;
if (extraObjectives < 10) extraObjectives = 10;
MO_PointsRequiredWithMissingPrimary[(ArmiesE)army] = MO_PointsRequired[(ArmiesE)army] + extraObjectives;
double noPrimaries = MO_PointsRequiredWithMissingPrimary[(ArmiesE)army] * 1.2;
if (noPrimaries < 30) noPrimaries = 30;
MO_PointsRequiredWithNoPrimary[(ArmiesE)army] = MO_PointsRequiredWithMissingPrimary[(ArmiesE)army] + noPrimaries;
MO_PercentPrimaryTargetsRequired[(ArmiesE)army] = 80;
if (MO_PointsRequired[(ArmiesE)army] < 20) MO_PercentPrimaryTargetsRequired[(ArmiesE)army] = 92;
if (MO_PointsRequired[(ArmiesE)army] < 35) MO_PercentPrimaryTargetsRequired[(ArmiesE)army] = 86;
*/
MO_WriteMissionObject(MO_TurnMapPointsRequired, "MO_TurnMapPointsRequired", wait: false);
}
//first, reset all the targets (in this army) to be not primaries. //But ONLY if we are starting fresh; ie, choosing ALL the primaries now //If some have already been chosen, we have to respect the previously chosen IsPrimaryTarget = true; MissionObjectivesList[key].ObjectiveAchievedForPoints = false; //TOBRUK, if you don't zero this out the army can't achieve their //2021-11 Jubilee - targets just stay destroyed until their expiration date //MissionObjectivesList[key].Destroyed = false; //MissionObjectivesList[key].DestroyedPercent =0; for (int x = 0; x < 250; x++) //unlikely but possible that we'd need to cycle through the list of targets multiple times to select enough targets to reach the points...
{
List keys = new List(MissionObjectivesList.Keys);
Calcs.Shuffle(keys);
List arms = new List();
if (army == 0) { arms.Add(1); arms.Add(2); }
else if (army == 1 || army == 2) arms.Add(army);
Console.WriteLine("Selecting new Mission Objectives for " + ArmiesL[army]);
foreach (var a in arms)
{
string objectivesList = "";
if (fresh) foreach (var key in keys)
{
if (MissionObjectivesList[key].AttackingArmy == a)
{
MissionObjectivesList[key].IsPrimaryTarget = false;
if (eraseForPoints)
{
}
}
}
if (eraseOnly) continue;
if (fresh) MO_CalculateTurnMapRequirements(a);
int counter = 1;
{
foreach (var key in keys)
{
bool canChooseDestroyed = false;
if (x > 15) canChooseDestroyed = true;
MissionObjective mo = MissionObjectivesList[key];
if (mo.AttackingArmy == a && mo.PrimaryTargetWeight > 0 && mo.IsEnabled && !mo.IsPrimaryTarget && ((!mo.Destroyed && mo.DestroyedPercent <= 0.25) || canChooseDestroyed) && !mo.ObjectiveAchievedForPoints)
{
/*Console.WriteLine("Select Primary " + mo.PrimaryTargetWeight + " " + r.ToString("N4") + " " + mo.ID + " points req: "
);
*/
Point3d pos = mo.returnCurrentPosWithChief();
double frontDistance = (Calcs.CalculatePointDistance(new Point3d(261615, 224384, 0), pos));
double distanceMult = 1;
/* if (mo.PrimaryTargetWeight < 180)
{
if (frontDistance > 150000) distanceMult = 0.1;
else if (frontDistance > 120000) distanceMult = 0.2;
else if (frontDistance > 100000) distanceMult = 0.3;
else if (frontDistance > 80000) distanceMult = 0.75;
else if (frontDistance > 50000) distanceMult = 0.9;
}*/
if (mo.PrimaryTargetWeight < 180)
{
if (frontDistance > 150000) distanceMult = 0.1;
else if (frontDistance > 120000) distanceMult = 0.3;
else if (frontDistance > 100000) distanceMult = .7;
else if (frontDistance > 80000) distanceMult = 1;
else if (frontDistance > 50000) distanceMult = 0.3;
}
if (totalPoints < MO_PrimaryPointsRequired[(ArmiesE)a])
{
mo.IsPrimaryTarget = true;
totalPoints += mo.Points;
objectivesList += " - " + mo.lastScoutedSector + " " + mo.Name;
Console.WriteLine("Adding new Mission Objective: " + mo.lastScoutedSector + " " + mo.Name + " " + mo.Points.ToString("F0") + " " + totalPoints.ToString("F0"));
counter++;
if (totalPoints >= MO_PrimaryPointsRequired[(ArmiesE)a]) break;
}
else
{
mo.IsPrimaryTarget = false;
}
}
}
if (totalPoints >= MO_PrimaryPointsRequired[(ArmiesE)a]) break;
}
Console.WriteLine("Selecting/adding new Mission Objectives for " + ArmiesL[army] + ":");
}
Timeout(12.354, () => { MO_SelectPrimaryObjectiveForGeneralStaffLocation(army); });
}
//first, reset all the targets (in this army) to be not the General Staff Location. for (int x = 0; x < 50; x++) //unlikely but possible that we'd need to cycle through the list of targets multiple times to select enough targets to reach the points...
{
List keys = new List(MissionObjectivesList.Keys);
Calcs.Shuffle(keys);
List arms = new List();
if (army == 0) { arms.Add(1); arms.Add(2); }
else if (army == 1 || army == 2) arms.Add(army);
Console.WriteLine("Selecting new Mission General Staff Location at a Primary Objective for " + ArmiesL[army]);
foreach (var a in arms)
{
foreach (var key in keys)
{
if (MissionObjectivesList[key].AttackingArmy == a) MissionObjectivesList[key].hasGeneralStaff = false;
}
int counter = 1;
{
bool done = false;
foreach (var key in keys)
{
MissionObjective mo = MissionObjectivesList[key];
{
mo.hasGeneralStaff = true;
done = true;
break;
}
}
if (done) break;
}
}
}
public class GeneralStaffLocationObject
{
public Point3d pos { get; set; }
public string objectiveKey { get; set; }
public string objectiveName { get; set; }
public string staffGroupName { get; set; }
public string sector { get; set; }
public string sectorKeypad { get; set; }
public string sectorDoublekeypad { get; set; }
public bool discovered { get; set; }
public GeneralStaffLocationObject(Point3d p, string o, string on, string sgn, string s, string sk, string sdk, bool d)
{
pos = p;
objectiveKey = o;
objectiveName = on;
staffGroupName = sgn;
sector = s;
sectorKeypad = sk;
sectorDoublekeypad = sdk;
discovered = d;
}
}
{
{ArmiesE.Red, new string [] { "Generalfeldmarschall Kesselring and his staff", "Generalfeldmarschall Sperrle and his staff", "Generalfeldmarschall Kesselring and a few high Luftwaffe officers", "General Jeschonnek and his personal aides", "Luftwaffe General Kreipe and his aides" } },
{ArmiesE.Blue, new string [] {"Air Chief Marshal Dowding and a small staff", "Air Vice-Marshal Park and his aides, checking on fighter preparations,", "Air Chief Marshall Leigh-Mallory and and high-ranking RAF officers", "Air Vice-Marshal Brand and his staff", "Air Chief Marshall Breadner and his aides" }}
};
var gsl = GeneralStaffLocations[(ArmiesE)army]; //Army here is the ATTACKING army, not the OWNER army if (army == 1) af = "Luftwaffe"; //again army is ATTACKING army, so if attacking army =1 then the General being attacked is LW not RAF Mission.DataDictionary[gsl_dictname] = new object { }; //just setting this value lets other submissions (like MoveBomb) know that the gsl has been discovered for that army MissionObjectivesTimes[(ArmiesE)army]["GeneralStaffDiscoveredEndTime_dt"] = DateTime.UtcNow.AddHours(24); //So finding the General gives them the "find the general privileges" for 24 hours from the time of discovery. //string msg2 = "No: " + (Calcs.CalculatePointDistance(pos, mo.Pos)).ToString() + " " + Z_AltitudeAGL_m.ToString(); //twcLogServer(new Player[] { player }, msg2, new object[] { });
{
double Z_AltitudeAGL_m = 1000;
if (!testing && !renewing) Z_AltitudeAGL_m = aircraft.getParameter(part.ParameterTypes.Z_AltitudeAGL, 0);
double dist_m = Calcs.CalculatePointDistance(pos, gsl.pos);
MissionObjective mo = MissionObjectivesList[gsl.objectiveKey];
string af = "RAF";
if ((renewing || testing || Z_AltitudeAGL_m < 200 && dist_m < 300))
{
if (!renewing && gsl.discovered)
{
Timeout(15, () =>
{
string msg = "NOTE: " + gsl.staffGroupName + " have been photographed within the past 24 hours.";
twcLogServer(new Player[] { player }, msg, new object[] { });
msg = "However, your new photo gives us valuable intel covering the next 24 hours!";
twcLogServer(new Player[] { player }, msg, new object[] { });
});
}
gsl.discovered = true;
string gsl_dictname = "generalstaff_discovered_red";
if (army == 2) gsl_dictname = "generalstaff_discovered_blue";
if (!renewing)
{
twcLogServer(null, af + gsl.staffGroupName + " photographed in sector " + gsl.sector + " by " + player.Name(), new object[] { });
GamePlay.gpHUDLogCenter(null, af + " Commander Found, Intel Gathered! Good Job, " + ArmiesL[army] + "!");
Timeout(10, () =>
{
twcLogServer(null, "The General's papers and effects are bound to reveal important intelligence about the enemy's movements over the next 24 hours!", new object[] { });
twcLogServer(null, "Results will be broadcast over the next day as Photo Intelligence analyzes the photos and matches the intel with enemy activity.", new object[] { });
});
}
return true;
}
else if (Calcs.CalculatePointDistance(pos, mo.Pos) < 15000 && Z_AltitudeAGL_m < 300)
{
string msg = "You tried to take a recon photo of the " + af + " commanders who were reported in this area. But there was no trace of them in your photo!";
twcLogServer(new Player[] { player }, msg, new object[] { });
msg = "You must be below 150m AGL and within 150m of the target to take the required photo." + (Calcs.CalculatePointDistance(pos, mo.Pos)).ToString() + " " + Z_AltitudeAGL_m.ToString();
twcLogServer(new Player[] { player }, msg, new object[] { });
return true;
}
return false;
}
var gsl = GeneralStaffLocations[(ArmiesE)attackingArmy]; //army here is the ATTACKING army NOT the army the General is part of/leading.
{
for (int attackingArmy = 1; attackingArmy < 3; attackingArmy++)
{
if (!gsl.discovered) continue;
int ownerArmy = 3 - attackingArmy;
MO_ListRemainingPrimaryObjectives(null, ownerArmy, leak: true);
}
}
//first, reset all the targets (in this army) to be not the General Staff Location. //try to find a place that is not water, not near an airport, outwards at least mo.radius + adder_m from the center of the objective double radius = random.Next(250) + adder_m + mo1.radius + i * 300.0; //try ever-greater distances if it's not working well //Now actually PLACE the general and various items around there...
{
List keys = new List(MissionObjectivesList.Keys);
List arms = new List();
arms.Add(1); arms.Add(2);
DateTime currTime_dt = DateTime.UtcNow;
Console.WriteLine("Handling new Mission General Staff Location at a Primary Objective for both armies");
foreach (var a in arms)
{
int attackingarmy = 3 - a;
bool done = false;
string staffKey = "";
for (int x = 0; x < 10; x++)
{
foreach (var key in keys)
{
MissionObjective mo = MissionObjectivesList[key];
if (mo.AttackingArmy == a && mo.hasGeneralStaff)
{
staffKey = key;
done = true;
}
}
if (done) break;
MO_SelectPrimaryObjectiveForGeneralStaffLocation(a);
}
MissionObjective mo1 = MissionObjectivesList[staffKey];
Point3d newPos = mo1.Pos;
double adder_m = 1200;
for (int i = 0; i < 25; i++)
{
double angle = random.NextDouble() * 2.0 * Math.PI;
newPos.x = mo1.Pos.x + Math.Cos(angle) * radius;
newPos.y = mo1.Pos.y + Math.Sin(angle) * radius;
maddox.game.LandTypes landType = GamePlay.gpLandType(newPos.x, newPos.y);
double dist = 5000;
try
{
AiAirport ap = Calcs.nearestAirport(GamePlay, newPos);
dist = Calcs.CalculatePointDistance(ap.Pos(), newPos);
} catch (Exception ex) { Console.WriteLine("ERROR GENERAL STAFF! " + ex.ToString()); }
if (landType != maddox.game.LandTypes.WATER && dist > 3500) break;
}
var items = new List { "Stationary.Humans.150_cm_SearchLight_Gunner_1", "Stationary.Humans.Soldier_Flak38_Gunner", "Stationary.Humans.RRH_Gunner_1",
"Stationary.Humans.Em_4m_R(H)34_Gunner_3",
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_w_chess_UK-GER_1",
"Stationary.Environment.Table_w_dinner_UK-GER_1",
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_w_chess_UK-GER_1",
"Stationary.Environment.Table_w_dinner_UK-GER_1",
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_w_chess_UK-GER_1",
"Stationary.Environment.Table_w_dinner_UK-GER_1",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",
"tobruk:Stationary.TobrukBuilding.Generic.BoardWithMapT",};
var cars = new List { "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo",
"Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo",
"Stationary.Opel_Blitz_tent",
"Stationary.BMW_R71_w_MG_34",
"Stationary.BMW_R71_w_MG_34",
"Stationary.Scammell_Pioneer_R100",
"Stationary.Scammell_Pioneer_R100",
"Stationary.Scammell_Pioneer_R100",
"Stationary.Scammell_Pioneer_R100",
"Stationary.Horch_830_B1",
"Stationary.Horch_830_B1",
"Stationary.Horch_830_B1" };
string enemy = "de";
if (a == 2) enemy = "gb";
var trucks = new List { "Stationary.Morris_CS8", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Morris_CS8", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Morris_CS8", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Opel_Blitz_tent", };
var camo = new List { "Stationary.Environment.CamoNetCars", "Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer", "Stationary.Environment.CamoNetPlane",
"Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer","Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer",
"Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer","Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer",
"Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer","Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetHowitizer",};
/*Stationary.Albion_AM463
Stationary.Bedford_MW_tent
Stationary.Morris_CS8
*/
ISectionFile f = GamePlay.gpCreateSectionFile();
bool resetCount = true;
f = Calcs.makeStatic(f, GamePlay, this, newPos.x + random.Next(4), newPos.y + random.Next(3), 0, type: "Stationary.Environment.JerryCan_GER1_1", heading: random.Next(360), side: "nn");
resetCount = false;
Calcs.Shuffle(items);
for (int i = 0; i < 9; i++) {
string side = "nn";
f = Calcs.makeStatic(f, GamePlay, this, newPos.x + random.Next(10), newPos.y + random.Next(10), 0, type: items[i], heading: random.Next(360), side: side, resetCount: resetCount);
resetCount = false;
}
double hdg = random.Next(360);
Calcs.Shuffle(cars);
for (int i = 0; i < 4; i++)
{
double angle1 = i * 2.0 / 4.0 * Math.PI + random.NextDouble();
double radius2 = random.Next(8) + 10;
double nex = newPos.x + Math.Cos(angle1) * radius2;
double ney = newPos.y + Math.Sin(angle1) * radius2;
string side = "nn";
if (random.Next(5) == 0) side = enemy;
f = Calcs.makeStatic(f, GamePlay, this, nex, ney, 0, type: cars[i], heading: hdg + random.Next(15), side: side);
}
Calcs.Shuffle(trucks);
for (int i = 0; i < 7; i++)
{
double angle1 = i * 2.0 / 7.0 * Math.PI + random.NextDouble();
double radius2 = random.Next(5) + 12;
double nex = newPos.x + Math.Cos(angle1) * radius2;
double ney = newPos.y + Math.Sin(angle1) * radius2;
string side = "nn";
if (random.Next(6) == 0) side = enemy;
f = Calcs.makeStatic(f, GamePlay, this, nex, ney, 0, type: trucks[i], heading: hdg + random.Next(15), side: side);
}
Calcs.Shuffle(camo);
for (int i = 0; i < 2; i++)
{
double nex = 0;
double ney = 0;
while (Calcs.CalculatePointDistance(new Point3d(nex, ney, 0), newPos) > 20) {
nex = newPos.x + random.Next(40) - 20;
ney = newPos.y + random.Next(40) - 20;
}
f = Calcs.makeStatic(f, GamePlay, this, nex, ney, 0, type: camo[i], heading: hdg + random.Next(15), side: side);
}
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: GeneralStaffPlacement");
GamePlay.gpPostMissionLoad(f);
Console.WriteLine("The general staff near a {0} objective is at {1} - ({2:F0},{3:F0})", new object[] { ArmiesL[a], staffKey, newPos.x, newPos.y });
Console.WriteLine("msn {0} objective)", new object[] { this as Mission != null });
Console.WriteLine("msn {0} {1} {2} {3} {4} {5} {6} {7} objective)", new object[] {newPos, staffKey, mo1.Name, GeneralStaffNames[(ArmiesE)a][1],
Calcs.correctedSectorName(this as Mission, newPos),
Calcs.correctedSectorNameKeypad(this as Mission, newPos),
Calcs.correctedSectorNameDoubleKeypad(this as Mission, newPos),
false
});
GeneralStaffLocationObject gslo = null;
try
{
gslo = new GeneralStaffLocationObject(newPos, staffKey, mo1.Name,
Calcs.correctedSectorName(this as Mission, newPos),
Calcs.correctedSectorNameKeypad(this as Mission, newPos),
Calcs.correctedSectorNameDoubleKeypad(this as Mission, newPos),
false
);
} catch (Exception ex) { Console.WriteLine("gslo error! " + ex.ToString()); }
GeneralStaffLocations[(ArmiesE)a] = gslo;
bool discovered = false;
try
{
if (MissionObjectivesTimes[(ArmiesE)attackingarmy].ContainsKey("GeneralStaffDiscoveredEndTime_dt")
&& MissionObjectivesTimes[(ArmiesE)attackingarmy]["GeneralStaffDiscoveredEndTime_dt"] > currTime_dt)
{
MO_CheckForGeneralStaffReconPhoto(null, null, a, new Point3d(0, 0, 0), testing: false, renewing: true);
discovered = true;
}
} catch (Exception ex) { Console.WriteLine("ERROR2 GENERAL STAFF! " + ex.ToString()); }
Console.WriteLine("The general staff near a {0} objective is at {1} - ({2:F0},{3:F0}). Previously discovered? {4}", new object[] { ArmiesL[a], staffKey, newPos.x, newPos.y, discovered });
}
}
public static List MO_Trucks = new List { "Stationary.Morris_CS8", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Morris_CS8", "Stationary.Matilda_2A", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Morris_CS8", "Stationary.Morris_CS8_tent", "Stationary.Bedford_MW_tent", "Stationary.Albion_AM463", "Stationary.Fordson_Sussex_w_ballon", "Stationary.Panzerbefehlswagen_I", "Stationary.Environment.CamoNetTank", "Stationary.Ammo_Vehicles.10_5cm_LeFH18_Composition3_GER", "Stationary.Ford_G917", "Stationary.Ford_V8_E917_tent", "Stationary.Unic_P107", "Stationary.Fordson_Sussex_w_o_ballon", "Stationary.Guy_Quad-Ant", "Stationary.Horch_108_Typ_1A", "Stationary.Guy_Lizard", "Stationary.GER_Fuel_Column", "Stationary.Kubelwagen", "Stationary.Krupp_L2H43_Protze_Kfz69", "Stationary.Horch_108_Typ_1A_open", "Stationary.Opel_Blitz_radio", "Stationary.SdKfz_9_Crane", "Stationary.FIAT_OCI_708", "Stationary.Truck_Renault_UE", "Stationary.Opel_Blitz_radio", };
public static List MO_Armor_Tanks = new List { "Stationary.SdKfz_10_1", "Stationary.SdKfz_231_6Rad", "Stationary.SdKfz_263_6Rad", "Stationary.SdKfz_263_6Rad", "Stationary.SdKfz_7", "Stationary.SdKfz_9", "Stationary.Thorneycroft_Bison", "Stationary.Bataille_B1_Bis", "Stationary.Breen_Carrier_Mk_I", "Stationary.Cruiser_Mk_IV", "Stationary.Pz_IIIF", "Stationary.Renault_Ft17", "Stationary.Somua_S35", "Stationary.Panzerbefehlswagen_I", "Stationary.SdKfz_232_8Rad", "Stationary.StuG_IIIA", "Stationary.Valentine_I", "Stationary.Vickers_Mk_VIB", "Stationary.Vickers_Mk_VIC", };
public static List MO_Military_Ships_DE = new List {
public static List MO_Military_Ships_GB = new List {
public static List MO_Military_Ships_VeryLarge_DE = new List {
};
public static List MO_Military_Ships_VeryLarge_GB = new List {
};
public static List MO_Military_Ships_Large_DE = new List {
};
public static List MO_Military_Ships_Large_GB = new List {
};
public static List MO_Military_Ships_Medium_DE = new List {
public static List MO_Military_Ships_Medium_GB = new List {
public static List MO_Military_Ships_MTB_DE = new List {
"tobruk:ShipUnit.Schnellboot_30_MTB",
"tobruk:ShipUnit.Schnellboot_38_MTB",
};
public static List MO_Military_Ships_MTB_GB = new List {
"tobruk:ShipUnit.Vosper_M_MTB",
"tobruk:ShipUnit.Vosper_CH_MTB",
};
public static List MO_Military_Ships_Submarine_GB = new List {
"tobruk:ShipUnit.U-class_SS",
};
public static List MO_Military_Ships_Submarine_DE = new List {
"tobruk:ShipUnit.Type_VIIC_SS",
};
public static List MO_Military_Ships_Escort_DE = new List {
};
public static List MO_Military_Ships_Escort_GB = new List {
};
/*
public static List MO_Military_Cargo_Ships_NN = new List {
"tobruk:ShipUnit.Merchant",
"ShipUnit.MotorBarge_Large1",
"ShipUnit.MotorBarge_Small1",
};
public static List MO_Military_Tanker_Ships_NN = new List {
"ShipUnit.Tanker_Medium1",
"ShipUnit.Tanker_Medium2",
"ShipUnit.MotorBarge_Large1",
"ShipUnit.MotorBarge_Small1",
};
*/
public static List MO_Military_Cargo_Tanker_Ships_Large_DE = new List {
};
public static List MO_Military_Cargo_Tanker_Ships_Small_DE = new List {
"ShipUnit.MotorBarge_Small1",
};
public static List MO_Military_Cargo_Tanker_Ships_Large_GB = new List {
};
public static List MO_Military_Cargo_Tanker_Ships_Small_GB = new List {
};
public static List MO_Cars = new List { "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo",
"Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo", "Stationary.Opel_Blitz_cargo",
"Stationary.BMW_R71_w_MG_34","Stationary.BMW_R71_w_MG_34","Stationary.Scammell_Pioneer_R100","Stationary.Scammell_Pioneer_R100","Stationary.Scammell_Pioneer_R100",
"Stationary.Scammell_Pioneer_R100","Stationary.Horch_830_B1","Stationary.Horch_830_B1","Stationary.Horch_830_B1" };
public static List MO_Humans = new List { "Stationary.Humans.150_cm_SearchLight_Gunner_1", "Stationary.Humans.Soldier_Flak38_Gunner", "Stationary.Humans.RRH_Gunner_1",
"Stationary.Humans.Em_4m_R(H)34_Gunner_3", "Stationary.Humans.Soldier_Horch_108_open_Gunner", "Stationary.Humans.Soldier_PaK_35_36_Gunner_1", "Stationary.Humans.Soldier_PaK_35_36_Gunner_2",
"Stationary.Humans.Soldier_10_5_cm_LeFH_18_Gunner_1", "Stationary.Humans.Soldier_10_5_cm_LeFH_18_Gunner_2", "Stationary.Humans.RRH_Gunner_1","Stationary.Humans.RRH_Gunner_2",
"Stationary.Humans.Soldier_40mm_2pdr_AT_Gun_Passenger_1","Stationary.Humans.Soldier_Beaverette_III_Gunner_1","Stationary.Humans.Soldier_AEC_Regent_III_Passenger_2",
"Stationary.Humans.150_cm_Flakscheinwerfer_gunner1","Stationary.Humans.150_cm_Flakscheinwerfer_gunner2","Stationary.Humans.Em_4m_R(H)34_Gunner_1","Stationary.Humans.Em_4m_R(H)34_Gunner_2",
"Stationary.Humans.Em_4m_R(H)34_Gunner_3", "Stationary.Humans.Gulaschkanone_passenger_1","Stationary.Humans.Gulaschkanone_passenger_2","Stationary.Humans.Gulaschkanone_passenger_3",
"Stationary.Humans.Gulaschkanone_passenger_4","Stationary.Humans.Gulaschkanone_passenger_5","Stationary.Humans.Gulaschkanone_passenger_6","Stationary.Humans.Kdo_Hi_Ger35_passenger_1",
"Stationary.Humans.Kdo_Hi_Ger35_passenger_2","Stationary.Humans.Kdo_Hi_Ger35_passenger_3","Stationary.Humans.Kdo_Hi_Ger35_passenger_4",};
public static List MO_Tables = new List() {
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_empty_UK-GER_1",
"Stationary.Environment.Table_w_chess_UK-GER_1",
"Stationary.Environment.Table_w_dinner_UK-GER_1",
};
public static List MO_Radar = new List { "Stationary.RadioBeacon.GenericLongRangeMast", "Stationary.Radar.EnglishRadar1", "Stationary.Radar.EnglishRadar2", "Stationary.Radar.EnglishRadar3", "Stationary.Radar.Wotan_I", "Stationary.Radar.Wotan_II", "Stationary.Radar.Wotan_II_ADD1", "Stationary.Radar.Wotan_II_ADD2", "Stationary.RadioBeacon.GenericLongRangeMast", "Stationary.Opel_Blitz_radio", };
public static List MO_Small_Radar = new List { "Stationary.Radar.Wotan_I", "Stationary.Radar.Wotan_II", "Stationary.Opel_Blitz_radio", };
public static List MO_Jerrycan141 = new List { "Stationary.Environment.JerryCan_GER1_2" };
public static List MO_Jerrycan282 = new List { "Stationary.Environment.JerryCan_GER1_3" };
public static List MO_Jerrycan1410 = new List { "Stationary.Environment.JerryCan_GER1_5" };
public static List MO_GBBombers = new List { "Stationary.WellingtonMkIc", "Stationary.BlenheimMkIV" };
public static List MO_GBFighters = new List { "Stationary.SpitfireMkIa", "Stationary.HurricaneMkI_dH5-20", "Stationary.GladiatorMkII" };
public static List MO_DEFighters = new List { "Stationary.Bf-109E-1", "Static1558 Stationary.Bf-110C-7", "Stationary.Bf-109E-3B" };
public static List MO_DEBombers = new List { "Stationary.Bf-108B-2", "Stationary.Ju-88A-1", "Stationary.Do-17Z-2" };
public static List MO_Buildings = new List { "Stationary.Airfield.Fuel_Storage", "Stationary.Industrial.Railroad.SmallFactory" };
public static List MO_FuelDump = new List { "Stationary.Airfield.Fuel_Storage" };
public static List MO_ExplodeyThings = new List { "Stationary.Environment.TelegaBallon_UK1", "Stationary.Environment.FuelDrum_UK1_9", };
public static List MO_Misc = new List { "Stationary.Environment.CamoNetCrates", "Stationary.Environment.TelegaBallon_UK1", "Stationary.Environment.CamoNetHowitizer", "Stationary.Environment.FuelDrum_UK1_9", "Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetPlane", "Stationary.Environment.Zwillingssockel36_Base_GER1", "Stationary.13T_Flat_ContainerA", "Stationary.13T_Flat_ContainerA", "Stationary.13T_Flat_ContainerBM", "Stationary.13T_Flat_ContainerBM", "Stationary.Morris_CS8-Bedford_MW_CargoAmmo1", "Stationary.Morris_CS8-Bedford_MW_CargoAmmo1", "Stationary.Morris_CS8-Bedford_MW_CargoAmmo2", "Stationary.Morris_CS8-Bedford_MW_CargoAmmo4", "Stationary.Morris_CS8-Bedford_MW_CargoCrate10", "Stationary.Morris_CS8-Bedford_MW_CargoFuel", "Stationary.Morris_CS8-Bedford_MW_CargoFuel", "Stationary.Morris_CS8-Bedford_MW_CargoFuel2", "Stationary.Morris_CS8-Bedford_MW_CargoFuel2", "Stationary.Morris_CS8-Bedford_MW_Cargo2", "Stationary.Morris_CS8-Bedford_MW_Cargo2", "Stationary.Morris_CS8-Bedford_MW_Cargo3", "Stationary.Morris_CS8-Bedford_MW_Cargo4", "Stationary.Renault_UE_Track_CargoSet3", "Stationary.Renault_UE_Track_CargoSet4", "Stationary.Environment.FieldKitchen_UK1", "Stationary.Environment.Gulaschkanone_GER1", };
public static List MO_Camo = new List { "Stationary.Environment.CamoNetCrates", "Stationary.Environment.CamoNetAT", "Stationary.Environment.CamoNetPlane", "Stationary.Environment.CamoNetPlaneBig", "Stationary.Environment.CamoNetTank" };
public static List MO_Tents = new List { "Stationary.Environment.TentTroopLarge_GER1", "Stationary.Environment.TentRidgeTent_UK1", /*"Stationary.Environment.TentMedicLarge_UK1", */ "Stationary.Environment.FieldKitchen_UK1", "Stationary.Environment.TentBell_UK1", "Stationary.Environment.TentBell_UK1", "Stationary.Environment.TentSmall_UK1", "Stationary.Environment.TentStaffBig_GER1", "Stationary.Environment.TentStaffSmall_GER1", "Stationary.Environment.TentTroopLarge_GER1", "Stationary.Environment.TentZeltbahn_GER1", "Stationary.Environment.TentZeltbahnBig_GER1", };
public static List MO_Sandbags = new List { "Stationary.Environment.SandBagWall_Line_12m", "Stationary.Environment.SandBagWall_Line", "Stationary.Environment.SandBagWall_Line_12m", "Stationary.Environment.SandBagWall_Line_4m", "Stationary.Environment.SandBagWall_Line_8m", "Stationary.Environment.SandBagWall_Line_8m", "Stationary.Environment.SandBagWall_Arch", };
public static List MO_Trenches = new List { "Stationary.Trenches.Trench_Front", "Stationary.Trenches.Trench_10m_diameter", "Stationary.Trenches.Trench_3m_diameter", "Stationary.Trenches.Trench_6m_diameter", "Stationary.Trenches.Trench_30_degrees", "Stationary.Trenches.Trench_45_degrees", "Stationary.Trenches.Trench_60_degrees", "Stationary.Trenches.Trench_direct", "Stationary.Trenches.Trench_direct_15m", "Stationary.Trenches.Trench_direct_25m", "Stationary.Trenches.Trench_T_type", "Stationary.Trenches.Trench_T_type", };
public static List MO_Hedgehogs = new List { "Stationary.Environment.Hedgehog_01", "Stationary.Environment.DragonTeethBig", "Stationary.Environment.DragonTeethSmall", "Stationary.Environment.DragonTeethSmall", };
public static List MO_Sentry = new List { "Stationary.Environment.Sentry-Box_UK-GER_1", "Stationary.Environment.GuardTower_UK-GER_1" };
public static List MO_Detritus = new List { "Stationary.Environment.Ladder_UK2_DMG1", "Stationary.Environment.TelegaBallon_UK1_DMG1", "Stationary.Environment.BombSled_GER1_DMG1", "Stationary.Damaged.Airfield.Planelifter_UK2_DMG1", "Stationary.Environment.Ladder_UK1_DMG1", };
public static List MO_Remnants = new List { "Stationary.Environment.TelegaBallon_UK1_DMG1", "Stationary.Environment.TentTroopLarge_GER1_DMG1", "Stationary.Environment.TentZeltbahnBig_GER1_DMG1", "Stationary.Environment.TelegaBallon_UK1", "Stationary.Environment.FuelDrum_UK1_9", "Stationary.Environment.CamoNetPlane", "Stationary.Environment.CamoNetTank", "Stationary.Environment.CamoNetAT", };
public static List MO_BombCraters = new List { "Stationary.Environment.BombCrater_firmSoil_mediumkg", "Stationary.Environment.BombCrater_firmSoil_mediumkg", "Stationary.Environment.BombCrater_firmSoil_mediumkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_smallkg", "Stationary.Environment.BombCrater_firmSoil_largekg", };
public class MO_ThingsTypeNumberRadius
{
public List things { set; get; }
public double orientationAngle_deg { set; get; }
private Random ran = new Random();
public MO_ThingsTypeNumberRadius(List t, int hm = 7, double rm = 25, double rn = 25, double prob = 1, List shps = null, double orient_angle_deg = -1)
{
things = t;
howmany = hm;
howmany_min = hm;
use_howmany_min = false;
radius_m = rm;
range_m = rn;
probability = prob;
if (shps == null) shape = shapeType.StretchedCircle;
else shape = Calcs.chooseRandomElement(shps);
orientationAngle_deg = ran.NextDouble() * 360;
if (orient_angle_deg != -1) orient_angle_deg = orient_angle_deg;
}
public MO_ThingsTypeNumberRadius(List t, bool useHowManyRange, int howMany_Min = 0, int howMany_Max = 7, double rm = 25, double rn = 25, double prob = 1, List shps = null, double orient_angle_deg = -1)
{
things = t;
howmany = howMany_Max;
howmany_min = howMany_Min;
use_howmany_min = useHowManyRange;
radius_m = rm;
range_m = rn;
probability = prob;
orientationAngle_deg = ran.NextDouble() * 360;
if (orient_angle_deg != -1) orient_angle_deg = orient_angle_deg;
if (shps == null) shape = shapeType.StretchedCircle;
else shape = Calcs.chooseRandomElement(shps);
}
public MO_ThingsTypeNumberRadius(MO_ThingsTypeNumberRadius mttnr, double oa_deg = -1)
{
things = mttnr.things;
howmany = mttnr.howmany;
howmany_min = mttnr.howmany_min;
use_howmany_min = mttnr.use_howmany_min;
radius_m = mttnr.radius_m;
range_m = mttnr.range_m;
probability = mttnr.probability;
orientationAngle_deg = mttnr.orientationAngle_deg;
if (oa_deg != -1) orientationAngle_deg = oa_deg;
}
}
public static List shipShapes = new List() { shapeType.Circle, shapeType.StretchedCircle, shapeType.Rectangle, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine };
public static List truckShapes = new List() { shapeType.Circle, shapeType.StretchedCircle, shapeType.Rectangle, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine };
public static List tentShapes = new List() { shapeType.Circle, shapeType.StretchedCircle, shapeType.Rectangle, shapeType.Line, shapeType.DoubleLine, shapeType.Line, shapeType.DoubleLine, shapeType.Rectangle, shapeType.Line, shapeType.DoubleLine, shapeType.Rectangle, };
public static List perimeterShapes = new List() { shapeType.Circle, shapeType.StretchedCircle, shapeType.StretchedCircle, };
public Dictionary> mo_mobileobjectivethings = new Dictionary>()
{
{ MO_MobileObjectiveType.SecretAirbaseGB,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 7, 55, 50) },
{ MO_MobileObjectiveThings.Buildings, new MO_ThingsTypeNumberRadius( MO_Buildings, 2, 20, 17 ) },
{ MO_MobileObjectiveThings.GBFighters, new MO_ThingsTypeNumberRadius( MO_GBFighters, 2, 62, 20 ) },
{ MO_MobileObjectiveThings.GBBombers, new MO_ThingsTypeNumberRadius( MO_GBBombers, 3, 102, 20) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 7, 150, 1) },
{ MO_MobileObjectiveThings.Trenches, new MO_ThingsTypeNumberRadius(MO_Sandbags, 25, 175, 0.25) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 80, 180, 0.2, 0.75) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 200, 20) },
}
},
{ MO_MobileObjectiveType.SecretAirbaseDE,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 8, 30,30) },
{ MO_MobileObjectiveThings.Buildings, new MO_ThingsTypeNumberRadius( MO_Buildings, 2, 20, 20) },
{ MO_MobileObjectiveThings.DEFighters, new MO_ThingsTypeNumberRadius( MO_DEFighters, 3, 65, 20) },
{ MO_MobileObjectiveThings.DEBombers, new MO_ThingsTypeNumberRadius( MO_DEBombers, 3, 95, 20) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 7, 150, 1) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 25, 175, 0.25) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 80, 179, 0.2, 0.75) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 200, 20) },
}
},
{ MO_MobileObjectiveType.SecretAircraftResearchGB,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 7, 15, 12) },
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius( MO_Buildings, 3, 40, 20) },
{ MO_MobileObjectiveThings.DEFighters, new MO_ThingsTypeNumberRadius( MO_DEFighters, 3, 65, 20) },
{ MO_MobileObjectiveThings.DEBombers, new MO_ThingsTypeNumberRadius( MO_DEBombers, 4, 85, 20) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 7, 135, 1) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 35, 155, 0.25) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, true, 10, 70, 162, 3) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar,true, 1, 5, 200, 20) },
}
},
{ MO_MobileObjectiveType.SecretAircraftResearchDE,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 7, 15, 12) },
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius( MO_Buildings, 3, 40, 20) },
{ MO_MobileObjectiveThings.GBFighters, new MO_ThingsTypeNumberRadius( MO_GBFighters, 3, 60, 20) },
{ MO_MobileObjectiveThings.GBBombers, new MO_ThingsTypeNumberRadius( MO_GBBombers, 4, 80, 20) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 7, 135, 1) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 35, 155, 0.25) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs,true, 10, 70, 161, 2) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, true, 1, 7, 200, 20) },
}
},
{ MO_MobileObjectiveType.ArmyEncampment,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 5, 15, 12) },
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius( MO_Tables, 5, 10, 8) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, true, 2, 15, 25, 10, shps: tentShapes) },
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 7, 35, 5, shps: truckShapes) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 5, 50, 2) },
{ MO_MobileObjectiveThings.Trenches, new MO_ThingsTypeNumberRadius(MO_Trenches, 12, 50, 0.2) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, true, 10, 40, 53, 2) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 80, 20) },
}
},
{ MO_MobileObjectiveType.SmallArmourGroup,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 5, 10, 8) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 4, 15, 10, shps: tentShapes) },
{ MO_MobileObjectiveThings.Armor_Tanks, new MO_ThingsTypeNumberRadius(MO_Armor_Tanks, true, 5, 12, 30, 5, shps: truckShapes) },
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 10, 30, 25) },
{ MO_MobileObjectiveThings.Misc, new MO_ThingsTypeNumberRadius(MO_Misc, 7, 22, 18) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 12, 45, 0.5) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 15, 53, 4) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 100, 30) },
}
},
{ MO_MobileObjectiveType.LargeArmourGroup,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 15, 10, 8) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 8, 20, 15, 0.6, shps: tentShapes) },
{ MO_MobileObjectiveThings.Armor_Tanks, new MO_ThingsTypeNumberRadius(MO_Armor_Tanks, true, 12, 21, 40, 5, shps: truckShapes) },
{ MO_MobileObjectiveThings.Misc, new MO_ThingsTypeNumberRadius(MO_Misc, 14, 25, 20) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 22, 60, 0.2) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 32, 67, 3 ) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 120, 30) },
}
},
{ MO_MobileObjectiveType.SmallTruckConvoy,
new Dictionary() {
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 8, 135, 70, shps: truckShapes) },
{ MO_MobileObjectiveThings.Armor_Tanks, new MO_ThingsTypeNumberRadius(MO_Armor_Tanks, 3, 55, 20, shps: truckShapes) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 2, 15, 10, shps: tentShapes) },
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 2, 20, 10, shps: tentShapes) },
}
},
{ MO_MobileObjectiveType.LargeTruckConvoy,
new Dictionary() {
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 12, 145, 70, shps: truckShapes) },
{ MO_MobileObjectiveThings.Armor_Tanks, new MO_ThingsTypeNumberRadius(MO_Armor_Tanks, 3, 55, 25,shps: truckShapes) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 2, 15, 10, shps: tentShapes) },
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 2, 20, 10, shps: tentShapes) },
}
},
{ MO_MobileObjectiveType.CamoGroup,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 10, 15, 12) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 4, 17, 12, shps: tentShapes) },
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 8, 40, 25, shps: tentShapes) },
{ MO_MobileObjectiveThings.Misc, new MO_ThingsTypeNumberRadius(MO_Misc, 12, 40, 35) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 4, 70, 2) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 16, 75, 0.1) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 32, 83, 5) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 2, 140, 30) },
}
},
{ MO_MobileObjectiveType.SmallCamoGroup,
new Dictionary() {
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius( MO_Humans, 6, 12, 10) },
{ MO_MobileObjectiveThings.Tents, new MO_ThingsTypeNumberRadius(MO_Tents, 2, 14, 10,shps: tentShapes) },
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 3, 40, 5, shps: truckShapes) },
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 4, 30, 17) },
{ MO_MobileObjectiveThings.Misc, new MO_ThingsTypeNumberRadius(MO_Misc, 8, 30, 17) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 2, 50, 2) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 12, 45, 0.1) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 15, 60, 5) },
}
},
{ MO_MobileObjectiveType.MobileRadar1,
new Dictionary(){
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius(MO_Humans,5, 12, 7 )},
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 5, 40, 10, shps: truckShapes )},
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius(MO_Tables, 5, 15, 7 )},
{ MO_MobileObjectiveThings.Radar, new MO_ThingsTypeNumberRadius(MO_Radar, 2, 15, 10 )},
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 2, 15, 13) },
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 22, 65, 0.3) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 44, 71, 3) },
}
},
{ MO_MobileObjectiveType.MobileRadar2,
new Dictionary(){
{ MO_MobileObjectiveThings.Buildings, new MO_ThingsTypeNumberRadius(MO_Buildings, 1, 3, 3 )},
{ MO_MobileObjectiveThings.Humans, new MO_ThingsTypeNumberRadius(MO_Humans,8, 25, 20 )},
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks,3, 50, 20, shps: truckShapes )},
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius(MO_Tables, 3, 25, 20 )},
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 2, 30, 25) },
{ MO_MobileObjectiveThings.Radar, new MO_ThingsTypeNumberRadius(MO_Radar, 3, 30, 20 )},
{ MO_MobileObjectiveThings.Sandbags, new MO_ThingsTypeNumberRadius(MO_Sandbags, 22, 75, 0.2) },
{ MO_MobileObjectiveThings.Hedgehogs, new MO_ThingsTypeNumberRadius(MO_Hedgehogs, 44, 85, 7) },
}
},
{ MO_MobileObjectiveType.DesertRadar,
new Dictionary(){
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 2, 40, 20 )},
{ MO_MobileObjectiveThings.Tables, new MO_ThingsTypeNumberRadius(MO_Tables, 4, 4, .3 )},
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 1, 120, 30) },
}
},
{ MO_MobileObjectiveType.KnickebeinHQ,
new Dictionary(){
{ MO_MobileObjectiveThings.Trucks, new MO_ThingsTypeNumberRadius(MO_Trucks, 4, 40, 25, shps: truckShapes )},
{ MO_MobileObjectiveThings.Radar, new MO_ThingsTypeNumberRadius(MO_Radar, 3, 17, 10 )},
{ MO_MobileObjectiveThings.Items, new MO_ThingsTypeNumberRadius(MO_Radar, 8, 30, 10, shps: tentShapes )},
{ MO_MobileObjectiveThings.Misc, new MO_ThingsTypeNumberRadius(MO_Radar, 5, 50, 15 )},
{ MO_MobileObjectiveThings.Camo, new MO_ThingsTypeNumberRadius(MO_Camo, 2, 15, 13) },
{ MO_MobileObjectiveThings.Small_Radar, new MO_ThingsTypeNumberRadius(MO_Small_Radar, 1, 120, 30) },
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Radar, 2, 110, 20) },
}
},
{ MO_MobileObjectiveType.FreighterShipGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Medium_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Medium_GB,true, 1, 1, 2600, 200, 0.0005,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_GB,true, 1, 1, 2600, 200, 0.01,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_GB, 1, 2200, 600, 0.4,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_GB, 6, 1800, 1800, shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.FreighterShipGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Medium_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Medium_DE, true, 1, 1, 2600, 200, 0.0005,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_DE,true, 1, 1, 2600, 200, 0.01,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_DE, true, 1, 1, 2200, 600, 0.4,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_DE, 6, 1800, 1800,shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.TankerShipGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Large_GB, true, 1, 1, 2600, 200, 0.0007,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_GB,true, 1, 1, 2600, 200, 0.015,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_GB, true, 1, 2, 2000, 600, 0.45,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_GB, true, 2, 9, 1500, 1500, 1, shps:shipShapes)},
}
},
{ MO_MobileObjectiveType.TankerShipGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Large_DE, true, 1, 1, 2600, 200, 0.0007,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_DE,true, 1, 1, 2600, 200, 0.015,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_DE, true, 1, 2, 1900, 700, 0.45, shps:shipShapes)},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_DE, true, 2, 9, 1500, 1200, shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.LargeTankerShipGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Large_GB, true, 1, 1, 2600, 200, 0.0007,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_GB,true, 1, 1, 2600, 200, 0.015,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_GB, true, 1, 2, 2400, 2000, 1, shps:shipShapes)},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_GB, true, 1, 7, 1500, 1200, 1, shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.LargeTankerShipGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Large_DE, true, 1, 1, 2600, 200, 0.0007,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_DE,true, 1, 1, 2600, 200, 0.015,shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_DE, true, 1, 2, 2400, 2100, 1, shps:shipShapes)},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_DE, true, 1, 7, 1500, 1200, 1, shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.SmallShipGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_VeryLarge_GB, true, 1, 1, 600, 200, 0.0005, shps: shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_GB,true, 1, 1, 2600, 200, 0.015, shps: shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_GB, true, 1, 1, 450, 250, 0.1, shps: shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_GB, true, 1, 4, 300, 100, shps: shipShapes )},
}
},
{ MO_MobileObjectiveType.SmallShipGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_VeryLarge_DE, true, 1, 1, 600, 200, 0.0005, shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Ships_Escort_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Escort_DE,true, 1, 1, 2600, 200, 0.015, shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Large_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Large_DE, true, 1, 1, 450, 250, 0.2, shps:shipShapes )},
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_DE, true, 1, 4, 300, 100, 1,shps:shipShapes )},
}
},
{ MO_MobileObjectiveType.OneShipGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_GB, true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.OneShipGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE, new MO_ThingsTypeNumberRadius(MO_Military_Cargo_Tanker_Ships_Small_DE,true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.OneMTBGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_MTB_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_MTB_GB, true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.OneMTBGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_MTB_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_MTB_DE,true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.OneSubmarineGroup_GB,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Submarine_GB, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Submarine_GB, true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.OneSubmarineGroup_DE,
new Dictionary(){
{ MO_MobileObjectiveThings.MO_Military_Ships_Submarine_DE, new MO_ThingsTypeNumberRadius(MO_Military_Ships_Submarine_DE, true, 1, 1, 100, 50 )},
}
},
{ MO_MobileObjectiveType.FuelDump,
new Dictionary(){
{ MO_MobileObjectiveThings.Buildings, new MO_ThingsTypeNumberRadius(MO_Buildings, 4, 20, 18 )},
{ MO_MobileObjectiveThings.MO_FuelStorage, new MO_ThingsTypeNumberRadius(MO_FuelDump, 19, 50, 20 )},
{ MO_MobileObjectiveThings.ExplodeyThings, new MO_ThingsTypeNumberRadius(MO_ExplodeyThings, 10, 9, 7 )},
{ MO_MobileObjectiveThings.Sentry, new MO_ThingsTypeNumberRadius(MO_Sentry, 2, 75, 1) },
}
},
};
ISectionFile f_placeCameras = null;
//unfortunately cameras are not really working at all - you just can't get to them any way //MO_MakeCameras(f_placeCameras, mo.returnCurrentPosWithChief(), staticprefix: mo.ID); if (!panic()) f_placeCameras.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/placestaticcameras_"); //testing)
{
return;
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: FinalizePlaceCameras");
GamePlay.gpPostMissionLoad(f_placeCameras);
f_placeCameras = GamePlay.gpCreateSectionFile();
}
//Point3d thingPos = pos; //subHeading -1, choose a random heading for each object //subHeading -2 means align with the circle perimeter, ie tangent to the circle //variance is a random amount the object will be moved inside OR outside the circle radius (up to variance_m distance plus or minus) //orientationAngle is orientation of the square, rectangle, line, double line etc. //for circle, doesn't matter...
{
for (int i = -1; i<6; i++)
{
double height_m = Math.Pow(2, i) * 100;
if (i == -1) height_m = 3;
f = Calcs.makeStatic(f, GamePlay, this, pos.x, pos.y, height_m , type: "StaticCamera" , sect: "StaticCamera", staticprefix: staticprefix);
}
return f;
}
public enum shapeType { Circle, StretchedCircle, Rectangle, Line, DoubleLine };
//Calcs.Shuffle(things); if (randomizeHowmany) howmany += random.Next(howmany / 4) - howmany / 8; //slightly randomize howmany //Console.WriteLine("Cirles: " + howmany.ToString()); if (random.Next(100) <= percentSide) side = ownerside; //setting them as enemy makes them show up as black dots. So some, but not all...
int stretcherType = 0, double stretcherAmt = 0, bool avoidWater = false, bool resetCount = false,
string addString = "", bool randomizeHowmany = true, string staticprefix = "", shapeType shape = shapeType.StretchedCircle, double orientationAngle_deg = -1 )
{
string ownerside = "nn";
if (army == 2) ownerside = "de";
if (army == 1) ownerside = "gb";
double orientationAngle_rad = random.NextDouble() * Math.PI * 2;
if (orientationAngle_deg != -1) orientationAngle_rad = Calcs.DegreesToRadians(orientationAngle_deg);
bool rstCnt = resetCount;
for (int i = 0; i < howmany; i++)
{
string side = "nn";
double angle1 = 0;
Point3d thingPos = new Point3d(newPos.x, newPos.y, newPos.z);
if (radius_m <= 5)
{
thingPos.x = newPos.x + (random.NextDouble() * 2.0 - 1.0) * radius_m;
thingPos.y = newPos.y + (random.NextDouble() * 2.0 - 1.0) * radius_m;
}
else
{
/*
angle1 = i * 2.0 / howmany * Math.PI + random.NextDouble() / howmany * Math.PI * 2.0 / 3.0;
double radius1 = radius_m + (circleStretcher(angle1, stretcherAmt, stretcherType));
thingPos.x = newPos.x + Math.Cos(angle1) * radius2;
thingPos.y = newPos.y + Math.Sin(angle1) * radius2;
*/
switch (shape)
{
case shapeType.Circle:
thingPos = Calcs.pointsOnACircle(newPos, radius_m, howmany, i, 1 / (double)howmany * Math.PI * 2.0 / 3.0, variance_m);
break;
case shapeType.Rectangle:
thingPos = Calcs.pointsOnARectangle(newPos, radius_m, radius_m * variance_m, orientationAngle_rad, howmany, i, radius_m / 8 );
break;
case shapeType.DoubleLine:
thingPos = Calcs.pointsOnADoubleLine(newPos, radius_m, radius_m * variance_m, orientationAngle_rad, howmany, i, radius_m / 8);
break;
case shapeType.Line:
thingPos = Calcs.pointsOnALine(newPos, radius_m, orientationAngle_rad, howmany, i, radius_m / 10);
break;
case shapeType.StretchedCircle:
default:
thingPos = Calcs.pointsOnAStretchedCircle(newPos, radius_m, howmany, i, 1 / (double)howmany * Math.PI * 2.0 / 3.0, variance_m, stretcherAmt, stretcherType);
break;
}
}
double subsubHeading = subHeading_deg + random.Next(24) - 12;
if (subHeading_deg == -1) subsubHeading = random.Next(360);
angle1 = i * 2.0 / howmany * Math.PI + random.NextDouble() / howmany * Math.PI * 2.0 / 3.0;
if (avoidWater) thingPos = MO_FindNoWaterPos(thingPos, radius_m);
int ranThing = random.Next(things.Count);
var moderateMilitaryShips = new List() { "ShipUnit.Rion", "Schnellboot", "Vosper", "Leipzig" };
var hardcoreMilitaryShips = new List() { "Zara", "SanGiorgio", "1936_DD", "Spica", "Minensuchtboote", "Hospital_Ship", "QueenElizabeth", "Revenge", "Leander", "Tribal", "Corvette" };
if (moderateMilitaryShips.Any(things[ranThing].Contains)) addString = "/sleep 2/skill 2/slowfire 80";
if (hardcoreMilitaryShips.Any(things[ranThing].Contains)) addString = "/sleep 2/skill 3/slowfire 1";
f = Calcs.makeStatic(f, GamePlay, this, thingPos.x + random.Next(2), thingPos.y + random.Next(2), 0, type: things[ranThing], heading: subsubHeading, side: side, resetCount: rstCnt, addString: addString, staticprefix: staticprefix);
rstCnt = false;
}
return f;
}
No description available.
{
if (mo.MOMobileObjectiveType != MO_MobileObjectiveType.None)
{
var things = mo_mobileobjectivethings[mo.MOMobileObjectiveType];
double searchRadius_m = 50;
if (mo.radius > 50) searchRadius_m = mo.radius;
foreach (MO_MobileObjectiveThings t in things.Keys)
{
MO_ThingsTypeNumberRadius mttnr = new MO_ThingsTypeNumberRadius(things[t]);
if (mttnr.radius_m + mttnr.range_m > searchRadius_m) searchRadius_m = mttnr.radius_m + mttnr.range_m;
}
return searchRadius_m;
} else
{
return mo.radius;
}
}
double angle1 = i; //radians
{
Point3d testPos = new Point3d(0, 0, 0);
for (int i = 1; i < 300; i++)
{
double radius2 = i * radius_m / 200.0;
testPos.x = p.x + Math.Cos(angle1) * radius2;
testPos.y = p.y + Math.Sin(angle1) * radius2;
maddox.game.LandTypes landType = GamePlay.gpLandType(testPos.x, testPos.y);
if (landType == maddox.game.LandTypes.WATER) return true;
}
return false;
}
double angle1 = i; //radians double radius2 = i * radius_m / (testpoints - 10); //make it go slightly beyond the actual radius //check if the pos is on water and if so try to return a new non-water pos withing the given radius //If it fails thne it just returns the initial point
{
Point3d testPos = new Point3d(0, 0, 0);
int testpoints = 300;
if (radius_m > 2000) testpoints = Convert.ToInt32(300.0 * radius_m / 2000.0);
for (int i = 1; i < testpoints; i++)
{
testPos.x = p.x + Math.Cos(angle1) * radius2;
testPos.y = p.y + Math.Sin(angle1) * radius2;
maddox.game.LandTypes landType = GamePlay.gpLandType(testPos.x, testPos.y);
if (landType != maddox.game.LandTypes.WATER) return true;
}
return false;
}
Point3d testPos = p; //preserves p.z value double angle1 = i; //radians
{
for (int i = 0; i < 300; i++)
{
double radius2 = i * radius_m / 200.0;
testPos.x = p.x + Math.Cos(angle1) * radius2;
testPos.y = p.y + Math.Sin(angle1) * radius2;
maddox.game.LandTypes landType = GamePlay.gpLandType(testPos.x, testPos.y);
if (landType != maddox.game.LandTypes.WATER) return testPos;
}
return p;
}
//7 * Math.Pow(Math.Ceiling(searchRadius_m/1000),2) - say it takes 7 Jerrycan282 to cover 1000m radius, if it is 2000m the amount increases by the ^2, etc //f = PlaceObjectsInCircles(f, MO_Jerrycan282, mo.Pos, searchRadius_m / 2, 4.0 * searchRadius_m / 5.0, 7 * Math.Pow(Math.Ceiling(searchRadius_m/1000),2), mo.OwnerArmy, percentSide: 70, subHeading: -1, stretcherType: 1, stretcherAmt: stretchA); Timeout(55 + random.Next(1, 240), () => //no rush here, better to wait a bit if (!panic()) f.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/detritusobj_" + mo.ID); //testing) Point3d smokePos = new Point3d(mo.Pos.x + (random.NextDouble() * 2.0 - 1.0) * searchRadius_m, mo.Pos.y + (random.NextDouble() * 2.0 - 1.0) * searchRadius_m, -15); //try -z position to see if it will make a diff effect MO_PlaceAppropriateJerrycan(mo); //there is still a jerrycan there so players can get stats points for bombing it, but there is just no objective here any more.
{
Console.WriteLine("Placing detritus field at " + mo.ID + " " + mo.Name);
if (searchRadius_m == 0) searchRadius_m = MO_CalcMobileObjRadius_m(mo);
double stretchA = (searchRadius_m + 40) / 3.0 * random.NextDouble();
int numCrater = (int)Math.Round((double)(numDetrit + random.Next(rangeDetrit)) / 6.0);
if (numCrater < 2) numCrater = 2;
ISectionFile f = GamePlay.gpCreateSectionFile();
if (!minimum) f = PlaceObjectsInCircles(f, MO_Detritus, mo.Pos, searchRadius_m / 2, 4.0 * searchRadius_m / 5.0, numDetrit + random.Next(rangeDetrit), mo.OwnerArmy, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: stretchA, resetCount: true);
if (!minimum && !Calcs.isPointInOrNearWater(GamePlay, mo.Pos, Convert.ToInt32(searchRadius_m / 2)))
{
f = PlaceObjectsInCircles(f, MO_BombCraters, mo.Pos, searchRadius_m / 4, 4.0 * searchRadius_m / 5.0, numCrater, 0, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: stretchA, resetCount: false, staticprefix: "detritus");
f = PlaceObjectsInCircles(f, MO_Remnants, mo.Pos, 10, 10, 3, 0, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: 1, resetCount: false, staticprefix: "detritus");
f = PlaceObjectsInCircles(f, MO_Remnants, mo.Pos, 45, 10, 10, 0, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: 10, resetCount: false, staticprefix: "detritus");
}
{
if (!minimum)
{
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: PlaceDetritus");
GamePlay.gpPostMissionLoad(f);
}
smokePos = MO_FindNoWaterPos(smokePos, searchRadius_m + 40);
if (placeSmoke & !minimum) Calcs.loadSmokeOrFire(GamePlay, this, smokePos.x, smokePos.y, smokePos.z, "BuildingFireSmall", 24 * 3600);
});
}
//2021/07 - removing task.run over concerns it might cause server crashes. //Task.Run(() => //{ //var things = mo_mobileobjectivethings[mo.MOMobileObjectiveType]; //only valid for mobileobjective types , and we're not using it yet...
{
try {
Console.WriteLine("MO_RemoveObjective: Removing/killing objective statics at " + mo.ID + " " + mo.Name);
double searchRadius_m = MO_CalcMobileObjRadius_m(mo);
if (MO_ObjectiveIsNavalVessel(mo))
{
searchRadius_m *= 3;
List gs = new List(GamePlay.gpGroundStationarys(mo.Pos.x, mo.Pos.y, searchRadius_m + 40).ToList());
ISectionFile f = GamePlay.gpCreateSectionFile();
f = Calcs.makeStatic(f, GamePlay, this, mo.Pos.x, mo.Pos.y, 0, "Stationary.Environment.Polotnische_X_white_1", 0, "nn", staticprefix: "remove_destroyed_MO_");
foreach (GroundStationary g in gs)
{
if (mo.hasChief() && !g.Name.ToLower().Contains(mo.ChiefName.ToLower())) continue;
f = MO_HandleGroundThingRemoval(mo, g.Type, groundStationary: g, immediate: immediate, percent: percent, destroyObjects: destroyObjects, sectFile:f);
}
if (!MO_Naval_Vessel_ObjectiveTypes.Contains(mo.MOObjectiveType))
{
Timeout(random.Next(5, 120), () =>
{
GamePlay.gpPostMissionLoad(f);
f.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/destroy_MO_replaced_objects_" + mo.ID +random.Next(1, 10).ToString());
});
}
Timeout(40, () =>
{
if (covermission != null && covermission.allStaticActors != null)
{
var asa = new List();
lock (covermission.allStaticActors_lock)
{
asa = new List(covermission.allStaticActors);
}
List closeStaticActors = new List(CoverCalcs.gpGetAllGroundActorsNear(asa.ToArray(), mo.Pos, searchRadius_m + radiusAdder_m).ToList());
ISectionFile f2 = GamePlay.gpCreateSectionFile();
foreach (AiActor a in closeStaticActors)
{
var ga = a as AiGroundActor;
if (ga != null)
{
if (mo.hasChief() && !a.Name().ToLower().Contains(mo.ChiefName.ToLower())) continue;
double dist_m = Calcs.CalculatePointDistance(mo.Pos, (ga as AiActor).Pos());
if (dist_m < searchRadius_m || ga.Type() == AiGroundActorType.AAGun || ga.Type() == AiGroundActorType.Artillery)
f2 = MO_HandleGroundThingRemoval(mo, ga.Type(), groundActor: ga, immediate: immediate, percent: percent, destroyObjects: destroyObjects, sectFile:f2);
}
}
if (!MO_Naval_Vessel_ObjectiveTypes.Contains(mo.MOObjectiveType))
{
Timeout(random.Next(5, 120), () =>
{
GamePlay.gpPostMissionLoad(f2);
f2.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/destroy_MO_replaced_objects_"+mo.ID + random.Next(1, 10).ToString());
});
}
}
if (percent >= 1 && mo.MOMobileObjectiveType != MO_MobileObjectiveType.None) MO_PlaceDetritusInObjectArea(mo, searchRadius_m: searchRadius_m);
});
}
catch (Exception ex) { Console.WriteLine("MO_RemoveObjective ERROR: " + ex.ToString()); }
}
//If an AA_Artillery objective, when destroyed we remove ONLY artillery & Aa from the area, leaving any other //ground objects. This is because the AA usually surrounds some other objective that might still be in place...
{
try
{
string type_str = type.ToString().ToLower();
if (groundStationary != null)
{
string gst = groundStationary.Title.ToLower();
string gsu = groundStationary.Title;
if (gst.Contains("fire") || gst.Contains("crater") || gst.Contains("_dmg") || gst.Contains("jerrycan") || gst.Contains("smoke")
|| gsu.Contains("AEC_Regent_II") || gsu.Contains("MG_TA") || type_str.ToLower().Contains("unknown")) return sectFile;
}
if (mo.MOObjectiveType == MO_ObjectiveType.Artillery_and_AA && type != AiGroundActorType.AAGun && type != AiGroundActorType.Artillery) return sectFile;
if (percent < 1 && (groundStationary != null || type_str.Contains("ship"))) return sectFile;
if (percent < 1 && mo.MOTriggerType == MO_TriggerType.Trigger) return sectFile;
if (percent < 1 && random.NextDouble() > percent) return sectFile;
if (MO_Naval_Ship_ObjectiveTypes.Contains(mo.MOObjectiveType) && !type_str.Contains("ship")) return sectFile;
if (mo.MOObjectiveType == MO_ObjectiveType.Submarine && !type_str.Contains("shipsubmarine")) return sectFile;
string names = "";
Point3d rpos = new Point3d();
if (groundStationary != null)
{
names = (groundStationary.Type.ToString() + groundStationary.Title).ToLower();
rpos = groundStationary.pos;
}
if (groundActor != null)
{
names = (groundActor.Type().ToString() + groundActor.Name()).ToLower();
rpos = groundActor.Pos();
}
foreach (MissionObjective mo2 in MissionObjectivesList.Values)
{
if (!mo2.IsEnabled || mo2.Destroyed) continue;
if (mo == mo2) continue;
if (names.ToLower().Contains(mo.ChiefName.ToLower()) || names.ToLower().Contains(mo.IDtoCleanChiefName().ToLower()))
{
Console.WriteLine("MO_HandleGroundThingRemoval: This object's name has the ID or Chief name of another OBJ, so NOT removing it: {0} {1} {2} ({3:F0},{4:F0}) stationary names {5} OBJ ID/chief {6} {7}", mo.ID, mo2.ID, names, rpos.x, rpos.y, names, mo.ChiefName, mo.IDtoCleanChiefName());
return sectFile;
}
double radius2 = mo2.radius;
if (mo2.TriggerDestroyRadius > radius2) radius2 = mo.TriggerDestroyRadius;
if (Calcs.CalculatePointDistance(rpos, mo2.Pos) < 1.2 * radius2)
{
Console.WriteLine("MO_HandleGroundThingRemoval: This object was within the radius of another objective, so NOT removing it: {0} {1} {2} ({3:F0},{4:F0})", mo.ID, mo2.ID, names, rpos.x, rpos.y);
return sectFile;
}
}
Console.WriteLine("REMOVEOBJECTIVE: Removing G " + names + " from " + mo.Name + " at ({0:F0}{1:f0})", rpos.x, rpos.y);
string typ = "Stationary.Environment.JerryCan_GER1_2";
if (names.Contains("industrial")) typ = "Stationary.Environment.CamoNetPlaneBig";
else if (names.Contains("airfield")) typ = "Stationary.Environment.CamoNetPlane";
else if (names.Contains("aircraft")) typ = "Stationary.GladiatorMkII";
else if (names.Contains("tent")) typ = "Stationary.Environment.CamoNetTank";
else if (names.Contains("car")) typ = "Stationary.Opel_Blitz_fuel";
else if (names.Contains("tank")) typ = "Stationary.Environment.TelegaBallon_UK1";
else if (names.Contains("truck")) typ = "Stationary.Ford_G917";
else if (random.Next(5) < 1) typ = "Stationary.Environment.CamoNetPlane";
if (sectFile!= null) sectFile = Calcs.makeStatic(sectFile, GamePlay, this, rpos.x, rpos.y, 0, typ, 0, "nn", staticprefix: "remove_destroyed_MO_");
int delay1 = 120;
int delay2 = 1200;
if (immediate)
{
if (groundActor != null)
{
if (destroyObjects) (groundActor as AiCart).Destroy();
else Calcs.KillActor(gpBattle, this, groundActor, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GA " + groundActor.Type().ToString() + " from " + mo.Name + " at ({0:F0}{1:f0})", rpos.x, rpos.y);
}
if (groundStationary != null)
{
if (destroyObjects) groundStationary.Destroy();
else Calcs.KillStationary(gpBattle, this, groundStationary, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GS {0} {1} {2} from " + mo.Name + " at ({3:F0}{4:f0})", groundStationary.Type.ToString(), groundStationary.Name, groundStationary.Title, rpos.x, rpos.y);
}
}
else
{
Timeout(random.Next(delay1, delay2), () =>
{
if (movebombtargetmission.getPlainDistanceToNearestLivePilot(mo.Pos, armyToMatch: 0) > 10000)
{
if (groundActor != null)
{
if (destroyObjects) (groundActor as AiCart).Destroy();
else Calcs.KillActor(gpBattle, this, groundActor, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GA " + groundActor.Type().ToString() + " from " + mo.Name + " at ({0:F0}{1:f0})", rpos.x, rpos.y);
}
if (groundStationary != null)
{
if (destroyObjects) groundStationary.Destroy();
else Calcs.KillStationary(gpBattle, this, groundStationary, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GS {0} {1} {2} from " + mo.Name + " at ({3:F0}{4:f0})", groundStationary.Type.ToString(), groundStationary.Name, groundStationary.Title, rpos.x, rpos.y);
}
}
else Timeout(random.Next(delay1, delay2), () =>
{
if (groundActor != null)
{
if (destroyObjects) (groundActor as AiCart).Destroy();
else Calcs.KillActor(gpBattle, this, groundActor, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GA " + groundActor.Type().ToString() + " from " + mo.Name + " at ({0:F0}{1:f0})", rpos.x, rpos.y);
}
if (groundStationary != null)
{
if (destroyObjects) groundStationary.Destroy();
else Calcs.KillStationary(gpBattle, this, groundStationary, waitTime: 2);
Console.WriteLine("REMOVEOBJECTIVE: Removing GS {0} {1} {2} from " + mo.Name + " at ({3:F0}{4:f0})", groundStationary.Type.ToString(), groundStationary.Name, groundStationary.Title, rpos.x, rpos.y);
}
});
}
return sectFile;
}
catch (Exception ex) { Console.WriteLine("MO_HandleGroundThingRemoval ERROR: " + ex.ToString()); return sectFile; }
}
//ANY ship, submarine, other anyting else floating on the water or under it, and works for ALL objective types
{
bool shipObjective = false;
if (mo.MOMobileObjectiveType == MO_MobileObjectiveType.TankerShipGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.TankerShipGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.LargeTankerShipGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.LargeTankerShipGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.FreighterShipGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.FreighterShipGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.SmallShipGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.SmallShipGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneShipGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneShipGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneMTBGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneMTBGroup_DE ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneSubmarineGroup_GB ||
mo.MOMobileObjectiveType == MO_MobileObjectiveType.OneSubmarineGroup_DE
)
shipObjective = true;
return shipObjective;
}
No description available.
{
if (mo.MOObjectiveType == null) return false;
if (MO_Naval_Vessel_ObjectiveTypes.Contains(mo.MOObjectiveType)) return true;
return false;
}
Timeout(to, () => //no rush here, better to wait a bit if (!panic()) f.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/trigger_objective_refresh_" + mo.ID); //testing) //Designed so that you can send every objective to this routine at the start of the session and several times throughout, and it will //just return on any non-mobile objectives, and do nothing if the objective doesn't need to be changed/updated //On startup it will draw all objectives in place, even if it is not their time to change location. //reestablishObjective = true is used in case all Chiefs/Actors of an objective have been killed & we //need to refresh it mid-session
{
try
{
if (mo.MOTriggerType != MO_TriggerType.Trigger) return f;
if (mo.Destroyed || !mo.IsEnabled) return f;
if (GamePlay.gpLandType(mo.Pos.x, mo.Pos.y) == maddox.game.LandTypes.WATER) return f;
double rad = mo.TriggerDestroyRadius;
if (rad < 10) rad = 10;
int count = 0;
List gs = new List(GamePlay.gpGroundStationarys(mo.Pos.x, mo.Pos.y, rad).ToList());
int foundCount = 0;
if (gs != null) foundCount = gs.Count;
if (mo.TotalInitialObjects_num == 0 ) mo.TotalInitialObjects_num = 25;
if (foundCount >= mo.TotalInitialObjects_num)
{
Console.WriteLine("MO_HandleTriggerObjectiveRefresh: Refreshing objective {0}; found {2} and added {1} statics to the objective area", mo.ID, count, foundCount);
return f;
}
int num_needed = Convert.ToInt32(mo.TotalInitialObjects_num - foundCount);
int x_count = Convert.ToInt32(Math.Sqrt((double)num_needed));
if (x_count < 2) x_count = 2;
int y_count = num_needed / x_count + 1;
if (y_count < 2) y_count = 2;
double stretchA = 1;
if (loadIndividually) f = GamePlay.gpCreateSectionFile();
double sqr_len = Math.Sqrt(2) * rad;
double xStart = mo.Pos.x - sqr_len;
double yStart = mo.Pos.y - sqr_len;
double xStep = 2 * sqr_len / (x_count - 1);
double yStep = 2 * sqr_len / (y_count - 1);
for (double x = xStart; x <= mo.Pos.x + sqr_len + 0.001; x += xStep)
{
for (double y = yStart; y <= mo.Pos.y + sqr_len + 0.001; y += yStep)
{
string sname = "Stationary.Environment.JerryCan_GER1_1";
if (random.Next(0, 4) == 0) sname = "Stationary.Environment.TelegaBallon_UK1";
string armyside = "gb";
if (mo.OwnerArmy == 2) armyside = "de";
string side = "nn";
if (random.Next(0, 9) == 0) side = armyside;
f = Calcs.makeStatic(f, GamePlay, this, x, y, 0, sname, 0, side, staticprefix: "trigger_refresh_" + mo.IDtoCleanChiefName() + "_");
count++;
if (count > num_needed) break;
}
if (count > num_needed) break;
}
Console.WriteLine("MO_HandleTriggerObjectiveRefresh: Refreshing objective {0}; found {2} and added {1} statics to the objective area", mo.ID, count, foundCount);
if (loadIndividually)
{
double to = 30 + random.Next(1, 800);
if (ON_TESTSERVER) to = 5;
{
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: TriggerObjectiveRefresh");
GamePlay.gpPostMissionLoad(f);
});
}
return f;
}
catch (Exception ex) { Console.WriteLine("MO_HandleTriggerObjectiveRefresh ERROR: " + ex.ToString()); return f; }
}
public int num_Capital_Ships_in_Server = 0;
if (mobileShipObjective && !startup && !reestablishObjective) return; //only move ships at start of mission due to, they DRIFT and then don't get removed 100%. 2021-11...
{
if (mo == null || mo.MOMobileObjectiveType == null || mo.MOMobileObjectiveType == MO_MobileObjectiveType.None) return;
bool mobileShipObjective = MO_MobileObjectiveIsShipOrSubmarineObjective(mo);
DateTime currTime = DateTime.UtcNow;
if (!mo.IsEnabled) {
mo.MobileNextMoveTime_dt = null;
return;
}
if (GamePlay == null)
{
Console.Write("");
Console.Write("MO_HandleMobileObjectivePlacement: MAJOR ERROR *************************************************** ");
Console.Write("MO_HandleMobileObjectivePlacement: MAJOR ERROR GamePlay not initialized, nothing done. Exiting routine. " + mo.Name);
Console.Write("MO_HandleMobileObjectivePlacement: MAJOR ERROR *************************************************** ");
Console.Write("");
Console.Write("");
return;
}
Console.WriteLine("MobileObjective: Handling placement of mobile objective ({0}) startup: {1} reestablishObjective: {2}" + mo.Name, ArmiesL[mo.OwnerArmy], startup, reestablishObjective);
if (!startup && mo.MobileNextMoveTime_dt.HasValue && mo.MobileNextMoveTime_dt.Value.CompareTo(currTime) <= 0) {
Console.WriteLine("MobileObjective: It's time to move " + mo.ID + " " + mo.Name);
MO_RemoveObjective(mo);
}
{
Console.WriteLine("Picking a new location for mobile objective ({2}) {0:F0} {1:F0} " + mo.Name, newPos.x, newPos.y, ArmiesL[mo.OwnerArmy]);
mo.MobileNextMoveTime_dt = currTime.AddHours(mo.MobileMoveTime_hrs);
Point3d swPos = mo.MobileSWPoint;
Point3d nePos = mo.MobileNEPoint;
double searchRadius_m = MO_CalcMobileObjRadius_m(mo);
int maxSearchNum = 5000;
for (int i = 0; i < maxSearchNum; i++)
{
if (i > 50) {
double adder = i * 27;
swPos.x -= adder;
swPos.y -= adder;
nePos.x += adder;
nePos.y += adder;
}
*/
bool withinMinMax = false;
Point3d mopos = mo.Pos;
if (mopos.x < swPos.x) mopos.x = swPos.x;
if (mopos.y < swPos.y) mopos.y = swPos.y;
if (mopos.x > nePos.x) mopos.x = nePos.x;
if (mopos.y > nePos.y) mopos.y = nePos.y;
{
newPos.x = mopos.x + (random.NextDouble() * (mo.MobileMaxMoveDist_km - mo.MobileMinMoveDist_km) + mo.MobileMinMoveDist_km) * 1000 * (random.Next(2) * 2 - 1);
newPos.y = mopos.y + (random.NextDouble() * (mo.MobileMaxMoveDist_km - mo.MobileMinMoveDist_km) + mo.MobileMinMoveDist_km) * 1000 * (random.Next(2) * 2 - 1);
Console.WriteLine("MoBileObj: Find Pos {0:F2} {1:F2}", newPos.x, newPos.y);
if (newPos.x < swPos.x) newPos.x = swPos.x;
if (newPos.y < swPos.y) newPos.y = swPos.y;
if (newPos.x > nePos.x) newPos.x = nePos.x;
if (newPos.y > nePos.y) newPos.y = nePos.y;
withinMinMax = true;
}
{
newPos.x = mopos.x + (random.NextDouble() * 3*mo.MobileMaxMoveDist_km + mo.MobileMaxMoveDist_km) * 1000 * (random.Next(2) * 2 - 1);
newPos.y = mopos.y + (random.NextDouble() *3 * mo.MobileMaxMoveDist_km + mo.MobileMaxMoveDist_km) * 1000 * (random.Next(2) * 2 - 1);
Console.WriteLine("MoBileObj: Find Pos 3X {0:F2} {1:F2}", newPos.x, newPos.y);
if (newPos.x < swPos.x) newPos.x = swPos.x;
if (newPos.y < swPos.y) newPos.y = swPos.y;
if (newPos.x > nePos.x) newPos.x = nePos.x;
if (newPos.y > nePos.y) newPos.y = nePos.y;
withinMinMax = true;
}
else
{
newPos.x = swPos.x + random.NextDouble() * (nePos.x - swPos.x);
newPos.y = swPos.y + random.NextDouble() * (nePos.y - swPos.y);
}
double distFromOldPos_m = Calcs.CalculatePointDistance(newPos, mopos);
int terr = GamePlay.gpFrontArmy(newPos.x, newPos.y);
if (i % 500 == 0) Console.WriteLine("Battle begins! \nMOBILE OBJECTIVE PLACEMENT trial #{7} - {0} terr: {1} attacking: {2} Owner: {3} Pos: {4:n0} {5:n0} OnEnemyTerr: {6}", new object[] { mo.Name, terr, mo.AttackingArmy, mo.OwnerArmy, newPos.x, newPos.y, onEnemyTerritory, i});
if (onEnemyTerritory && i < 9 * maxSearchNum / 10) continue;
bool wrongLandOrWaterinObjectiveArea = false;
double sr = searchRadius_m + 5000;
if (i > maxSearchNum / 5.0) sr = searchRadius_m + 2000;
if (i > 2 * maxSearchNum / 5.0) sr = searchRadius_m + 1000;
if (i > 3 * maxSearchNum / 5.0) sr = searchRadius_m + 500;
if (i > 4 * maxSearchNum / 5.0) sr = searchRadius_m + 100;
if (mobileShipObjective)
wrongLandOrWaterinObjectiveArea = MO_LandInRadius(newPos, sr);
else wrongLandOrWaterinObjectiveArea = MO_WaterInRadius(newPos, searchRadius_m);
if (i % 500 == 0) Console.WriteLine("Battle begins! \nMOBILE OBJECTIVE PLACEMENT trial #{7} - {0} terr: {1} attacking: {2} Owner: {3} Pos: {4:n0} {5:n0} OldPos: {9:n0} {10:n0} OnEnemyTerr: {6} flags: wrong land/water - {8} ", new object[] { mo.Name, terr, mo.AttackingArmy, mo.OwnerArmy, newPos.x, newPos.y, onEnemyTerritory, i, wrongLandOrWaterinObjectiveArea, mopos.x, mopos.y });
if (wrongLandOrWaterinObjectiveArea && onEnemyTerritory && i < 19 * maxSearchNum / 20) continue;
double dist = 5000;
bool farEnoughFromAirport = true;
if (i < 2.0 * maxSearchNum / 3.0)
{
try
{
AiAirport ap = Calcs.nearestAirport(GamePlay, newPos);
dist = Calcs.CalculatePointDistance(ap.Pos(), newPos);
}
catch (Exception ex) { Console.WriteLine("ERROR MOBILE OBJECTIVE PLACEMENT! " + ex.ToString()); }
if (dist - searchRadius_m < 3500) farEnoughFromAirport = false;
}
bool tooNearAnotherObjective = false;
if (i < 2.0 * maxSearchNum / 3.0) tooNearAnotherObjective = MO_oneObjectiveTooNearAnother(mo, newPos);
if (i % 500 == 0) Console.WriteLine("Battle begins! \nMOBILE OBJECTIVE PLACEMENT trial #{7} - {0} terr: {1} attacking: {2} Owner: {3} Pos: {4:n0} {5:n0} OldPos: {12:n0} {13:n0} OnEnemyTerr: {6} flags: wrong land/water- {8} farenoughfromairport- {9} withinminmax- {10} too near another- {11}", new object[] { mo.Name, terr, mo.AttackingArmy, mo.OwnerArmy, newPos.x, newPos.y, onEnemyTerritory, i, wrongLandOrWaterinObjectiveArea, farEnoughFromAirport, withinMinMax, tooNearAnotherObjective, mopos.x, mopos.y });
if (!wrongLandOrWaterinObjectiveArea && farEnoughFromAirport && !onEnemyTerritory && withinMinMax && !tooNearAnotherObjective) break;
if (!wrongLandOrWaterinObjectiveArea && farEnoughFromAirport && !onEnemyTerritory && !tooNearAnotherObjective && i >= maxSearchNum / 3.0)
{
Console.WriteLine("MOBILE OBJECTIVE PLACEMENT - PROBLEM! Couldn't find a location within min/max movement parameters. Just picking another location meeting ALL other criteria except it is a big jump. {0} min search, {1} searched, distance from old position: {2:n1}km.", maxSearchNum / 3.0, i, distFromOldPos_m / 1000);
}
{
Console.WriteLine("MOBILE OBJECTIVE PLACEMENT - PROBLEM! Couldn't find a location within min/max movement parameters && outside of airport radius && any other objective radius. Just picking another location meeting all criteria except Big Jump & Close to Airport OR objective. {0} min search, {1} searched.", 2.0 * maxSearchNum / 3.0, i);
}
{
Console.WriteLine("MOBILE OBJECTIVE PLACEMENT - PROBLEM! Couldn't find a location within min/max movement parameters && not on water && outside of airport radius && not too close to another objective. Just picking another location outside of Enemy Territory. {0} min search, {1} searched.", 5.0 * maxSearchNum / 6.0, i);
}
if (i >= maxSearchNum - 1)
{
Console.WriteLine("MOBILE OBJECTIVE PLACEMENT - BIG PROBLEM! Couldn't find a location not too near an airport && another objective, or on water/land (as required) or on enemy territory, and right movement distance. Placing near center of area as last resort.");
newPos.x = (swPos.x + nePos.x) / 2.0 + random.NextDouble() * 10000 - 5000;
newPos.y = (swPos.y + nePos.y) / 2.0 + random.NextDouble() * 10000 - 5000;
}
}
}
var things = mo_mobileobjectivethings[mo.MOMobileObjectiveType];
double masterHeading = random.Next(360);
mo.Pos = newPos;
mo.Sector = Calcs.correctedSectorNameDoubleKeypad(this, newPos);
mo.bigSector = Calcs.makeBigSector(this, newPos, mo.Points);
int stretchType = 1;
double stretchPercent = random.NextDouble() * 0.3;
shapeType perimeterShape = Calcs.chooseRandomElement(perimeterShapes);
ISectionFile f = GamePlay.gpCreateSectionFile();
bool resetCount = true;
foreach (MO_MobileObjectiveThings t in things.Keys)
{
MO_ThingsTypeNumberRadius mttnr = new MO_ThingsTypeNumberRadius(things[t], masterHeading);
double probability_add = 0;
if (ON_TESTSERVER && MO_All_VeryDangerous_Military_Navy_Ships.Contains(t) && num_Capital_Ships_in_Server < 1)
{
}
if (mttnr.probability < 1)
{
if (random.NextDouble() > mttnr.probability + probability_add)
{
Console.WriteLine("Mobile objective {2}: Skipping {0} because of probability setting = {1}", t, mttnr.probability, mo.Name);
continue;
}
}
if (mttnr.probability < 0.01 && (MO_All_VeryDangerous_Military_Navy_Ships.Contains(t)))
{
Console.WriteLine("Mobile objective {2}!!!!!! Massively increasing objective score because Military Ship included! Ship type = {0} Probability setting = {1} - Level 200 AND 25 points/objects required to kill it", t, mttnr.probability, mo.Name);
if (t == MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_DE || t == MO_MobileObjectiveThings.MO_Military_Ships_VeryLarge_GB) mo.Points = 1300;
else if (t == MO_MobileObjectiveThings.MO_Military_Ships_Large_DE || t == MO_MobileObjectiveThings.MO_Military_Ships_Large_GB) mo.Points = 1100;
else if (t == MO_MobileObjectiveThings.MO_Military_Ships_Medium_DE || t == MO_MobileObjectiveThings.MO_Military_Ships_Medium_GB) mo.Points = 800;
mo.radius = 7500;
mo.TriggerDestroyRadius = 7500;
num_Capital_Ships_in_Server++;
}
double subHeading = masterHeading + random.Next(40) - 20;
shapeType shp = mttnr.shape;
if (t == MO_MobileObjectiveThings.Sandbags || t == MO_MobileObjectiveThings.Trenches || t == MO_MobileObjectiveThings.Hedgehogs)
{
shp = perimeterShape;
}
if (t == MO_MobileObjectiveThings.Humans) newPos.z = 1;
else newPos.z = 0;
string addString = "";
if (mobileShipObjective) addString = "/sleep 2/skill 1/slowfire 50";
if (t == MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_GB)
{
addString += "/skin materialSummer1_red";
}
if (t == MO_MobileObjectiveThings.MO_Military_Cargo_Tanker_Ships_Small_DE)
{
addString += "/skin materialSummer2_gray";
}
int howmany = mttnr.howmany;
if (mttnr.use_howmany_min) {
randomizeHowmany = false;
howmany = random.Next(mttnr.howmany_min, mttnr.howmany + 1);
Console.WriteLine("MobileObjective: Using howmany_min - min {0} max {1} num chose: {2}", mttnr.howmany_min, mttnr.howmany, howmany);
}
else
{
howmany = Convert.ToInt32(mttnr.howmany + random.Next(Convert.ToInt32(mttnr.howmany / 4.0)) + mttnr.howmany / 2.0);
if (t == MO_MobileObjectiveThings.MO_Military_Ships_DE || t == MO_MobileObjectiveThings.MO_Military_Ships_GB)
{
howmany = mttnr.howmany;
}
}
if (howmany > 14) percentSide = 14;
if (howmany > 32) percentSide = 6;
if (mobileShipObjective) percentSide = 100;
f = PlaceObjectsInCircles(f, mttnr.things, newPos, mttnr.radius_m, mttnr.range_m, howmany, mo.OwnerArmy, subHeading_deg: subHeading, percentSide: percentSide, stretcherType: stretchType, stretcherAmt: stretchPercent * mttnr.radius_m, avoidWater: !mobileShipObjective, resetCount: resetCount, addString: addString, randomizeHowmany: randomizeHowmany, staticprefix: mo.ChiefName, shape: shp, orientationAngle_deg: masterHeading);
resetCount = false;
}
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: MobileObjectivePlacement");
GamePlay.gpPostMissionLoad(f);
Console.WriteLine("The mobile objective {0} ({3}) is at ({1:F0},{2:F0})", new object[] { mo.Name, mo.Pos.x, mo.Pos.y, ArmiesL[mo.OwnerArmy] });
}
double panicRating = 0;
No description available.
{
if (random.Next(100) < panicRating) return true;
return false;
}
Dictionary MobileConvoyPositionList = new Dictionary();
No description available.
{
try
{
double ret = 9999999999;
if (MobileConvoyPositionList == null || MobileConvoyPositionList.Count == 0) return ret;
foreach (Point3d mcPos in MobileConvoyPositionList.Values)
{
double dist = Calcs.CalculatePointDistance(pos, mcPos);
if (dist < ret) ret = dist;
}
return ret;
}
catch (Exception ex)
{
Console.WriteLine("distanceToNearestMobileConvoy_m ERROR: " + ex.Message);
return 9999999999.0;
}
}
if (!mo.isMoving()) continue; //we want the moving/mobile/CHIEF objectives, like shore patrol convoys if (MO_ObjectiveIsNavalVessel(mo)) continue; //but NOT naval objectives/ships/submarines public double tempFlak_Lifetime_s = 115; //was 125, but seems like they fired a while then sat for a long time, typically. This was with 15 sec runs //int tempflaktoAllocatePerRound = 80; //number to hand out each time tempFlakPlacement runs...
{
try
{
MobileConvoyPositionList = new Dictionary();
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (!mo.IsEnabled || mo.Destroyed) continue;
MobileConvoyPositionList[mo.ID] = mo.returnCurrentPosWithChief();
}
}
catch (Exception ex)
{
Console.WriteLine("updateMobileConvoyPositionList() ERROR: " + ex.Message);
return;
}
}
/*******************************************************************************
* TEMPFLAK - flak that pops up where players are, then disappears when they leave
*
* variables below determine how much tempflak, how long it lasts, when to distribute
* With too many live players online you can't distribute TOO MUCH flak OR
* load section files too often. So as more players, less flak and also slower load times
*
*
* ******************************************************************************/
public string tempFlakPrefix = "tempflak";
public int tempFlak_currentArmy = 1;
double maxACAltitudeforTempflak = 2500;
double minRatingForFlak = 25;
int maxSectionFiles = 16;
int numpToStartReducing = 8;
int numpForMaxReduction = 16;
int numpForCompleteElimination = 50;
int testTempFlakNumPilots = 0;
public System.Threading.Timer tempFlakTimer;
//Console.WriteLine("balanceAILoad: Starting timer! " + DateTime.UtcNow.ToString("T")); dueTime: 300000, //wait time @ startup period: 16342); //periodically call the callback at this interval, every 20 seconds say (it alternates armies, so 40 seconds for each army). That puts up to 4*80 = 320*2 = 640 pieces in play FOR EACH ARMY...
{
tempFlakTimer = new System.Threading.Timer(
new TimerCallback(tempFlak),
null,
}
private int[] sinceLastTempFlakCalledCount = { 1000, 1000, 1000 }; //keep track of how many runs since tempflak was last placed, for each army. We start with a high # so it starts to work on 1st round...
{
try
{
if (tempFlakTimer != null) tempFlakTimer.Dispose();
} catch (Exception ex) { }
}
private int tempflakcounter = 0;
private int tempflakcalledcounter = 0;
if (threadloadmission.recentCPUPercent > 95 || threadloadmission.rollingAverageCPUPercent > 98) return; //prevents again both (adding to) a sudden surge of CPU but also if the long term CPU is getting high, preventively just stop adding more tempflak if (threadloadmission.rollingAverageCPUPercent > 93 && random.NextDouble() > 0.5) return; //start culling tempFlak_Lifetime_s = 95; //default/starting situation maxSectionFiles = 16; //2.5X16 = 40, each army section file is loaded in @ 40 seconds apart. return; //place flak every 2:00 minutes only - meaning 4:00 mins per army wait tempFlak_Lifetime_s = 1000; //but flak lifetime proportionate return; //every 1:20 minutes only - meaning 2:40 mins per army wait tempFlak_Lifetime_s = 500; //but flak lifetime proportionate return; //every 1:00 minute only - meaning 2:00 mins per army wait tempFlak_Lifetime_s = 240; //but flak lifetime proportionate return; //every 40 secs only - meaning 1:20 mins per army wait tempFlak_Lifetime_s = 125; //but flak lifetime proportionate return; //every 40 secs only - meaning 1:20 mins per army wait tempFlak_Lifetime_s = 125; //but flak lifetime proportionate //if num live players is > 16 we reduce the # of available flak down from //80 at 16 players linearly down to 20 when 90 players online...
{
try
{
if (panic()) return;
tempflakcalledcounter++;
Thread thr = Thread.CurrentThread;
thr.Priority = ThreadPriority.BelowNormal;
int currentArmy = 1;
if (tempFlak_currentArmy == 1) currentArmy = 2;
tempFlak_currentArmy = currentArmy;
sinceLastTempFlakCalledCount[tempFlak_currentArmy]++;
int nump = Calcs.gpNumberOfPlayers(GamePlay);
if (testTempFlakNumPilots > 0 && testTempFlakNumPilots > nump) nump = testTempFlakNumPilots;
if (nump > 50) return;
double sectionFileDelay_s = 2.42324;
if (nump > 16)
{
if (sinceLastTempFlakCalledCount[currentArmy] <= 12)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Not long enough since last run for nump: {2} army: {0} cycles since last called: {1}", currentArmy, sinceLastTempFlakCalledCount[currentArmy], nump);
}
minRatingForFlak = 150;
maxACAltitudeforTempflak = 1000;
sectionFileDelay_s = 60;
maxSectionFiles = 1;
}
else if (nump > 12)
{
if (sinceLastTempFlakCalledCount[currentArmy] <= 8)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Not long enough since last run for nump: {2} army: {0} cycles since last called: {1}", currentArmy, sinceLastTempFlakCalledCount[currentArmy], nump);
}
minRatingForFlak = 125;
maxACAltitudeforTempflak = 1000;
sectionFileDelay_s = 40;
maxSectionFiles = 2;
}
else if (nump > 9)
{
if (sinceLastTempFlakCalledCount[currentArmy] <= 6)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Not long enough since last run for nump: {2} army: {0} cycles since last called: {1}", currentArmy, sinceLastTempFlakCalledCount[currentArmy], nump);
}
minRatingForFlak = 100;
maxACAltitudeforTempflak = 1500;
sectionFileDelay_s = 6.5;
}
else if (nump > 6)
{
if (sinceLastTempFlakCalledCount[currentArmy] <= 4)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Not long enough since last run for nump: {2} army: {0} cycles since last called: {1}", currentArmy, sinceLastTempFlakCalledCount[currentArmy], nump);
}
minRatingForFlak = 50;
maxACAltitudeforTempflak = 2500;
sectionFileDelay_s = 3.25;
}
else if (nump > 4)
{
if (sinceLastTempFlakCalledCount[currentArmy] <= 2)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Not long enough since last run for nump: {2} army: {0} cycles since last called: {1}", currentArmy, sinceLastTempFlakCalledCount[currentArmy], nump);
}
minRatingForFlak = 50;
maxACAltitudeforTempflak = 2500;
sectionFileDelay_s = 3.25;
}
int numToDistribute = tempflaktoAllocatePerRound;
int minDistribution = minTempflaktoAllocatePerRound;
int variableNumToDistribute = numToDistribute - minDistribution;
if (variableNumToDistribute < 0) variableNumToDistribute = 0;
if (nump > numpToStartReducing)
{
int numer = numpForMaxReduction - nump;
if (numer < 0) numer = 0;
numToDistribute = variableNumToDistribute * numer / ((numpForMaxReduction - numpToStartReducing)) + minDistribution;
if (numToDistribute <= 0) return;
}
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Calling TempFlak for army: {0} numToDistribute: {1} nump: {2} minRatingforFlak: {3}, maxACAltitudefor flak {4}, section file delay {5}, maxSectionFiles: {6}", currentArmy, numToDistribute, nump, minRatingForFlak, maxACAltitudeforTempflak, sectionFileDelay_s, maxSectionFiles);
int numDistributed = tempFlakPlacement(currentArmy, numToDistribute, nump, minRatingForFlak, maxACAltitudeforTempflak, sectionFileDelay_s, maxSectionFiles);
if (numDistributed > 0) sinceLastTempFlakCalledCount[currentArmy] = 0;
tempflakcounter++;
if (tempflakcounter % 40 == 0)
{
thr.Priority = ThreadPriority.Lowest;
updateMobileConvoyPositionList();
foreach (MissionObjective mo in MissionObjectivesList.Values.ToList())
MO_AutoFlak_selectLocations(mo, refresh: true);
thr.Priority = ThreadPriority.BelowNormal;
}
} catch (Exception ex)
{
Console.WriteLine("tempFlak main ERROR: " + ex.Message);
}
}
No description available.
try
{
if (!shortname.Contains(tempFlakPrefix)) return;
Timeout(tempFlak_Lifetime_s, () =>
{
if (actor != null) (actor as AiCart).Destroy();
});
}
catch (Exception ex)
{
Console.WriteLine("handleTempflakSpawn ERROR: " + ex.ToString());
}
}
double max_altitude_m = maxACAltitudeforTempflak; //above this altitude we'll skip the flak 100%. //For testserver, we'll defend against AI to see how the system works//testing if (!ON_TESTSERVER && (isAiControlledPlane(aircraft) || !aircraft.IsAirborne())) break; //for testserver we count AI planes the same as breathers, for testing purposes...
{
int numDistributed = 0;
try
{
if (ON_TESTSERVER) Console.WriteLine("Main: Starting tempFlakPlacement for defending army {0} ", defendingArmy);
int attackingArmy = 3 - defendingArmy;
int numAttackingPilots = 0;
Dictionary objRating = new Dictionary();
var aaAG = GamePlay.gpAirGroups(attackingArmy);
if (aaAG != null && aaAG.Length > 0)
{
foreach (AiAirGroup airGroup in aaAG)
{
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
{
foreach (AiActor actor in airGroup.GetItems())
{
if (actor is AiAircraft)
{
AiAircraft aircraft = actor as AiAircraft;
if (aircraft != null)
{
double rating = 0;
double pilotAGL_m = aircraft.getParameter(part.ParameterTypes.Z_AltitudeAGL, 0);
if (pilotAGL_m < 12) continue;
numAttackingPilots++;
foreach (MissionObjective mo in MissionObjectivesList.Values.ToList())
{
if(!mo.IsEnabled) continue;
if (MO_ObjectiveIsNavalVessel(mo)) continue;
if (mo.isMoving()) continue;
double dist_m = Calcs.CalculatePointDistance(actor.Pos(), mo.Pos);
double timeSinceLastHit_s = 100000;
if (mo.LastHitTime_UTC.HasValue) timeSinceLastHit_s = DateTime.UtcNow.Subtract(mo.LastHitTime_UTC.Value).TotalSeconds;
if (timeSinceLastHit_s < 45 || timeSinceLastHit_s > 400) {
if (mo.AttackingArmy == attackingArmy) {
if (dist_m > 1000 &&
(pilotAGL_m < 35 ||
(pilotAGL_m < 80 && 80 - pilotAGL_m > random.Next(0, 45))
)) continue;
else if (random.NextDouble() < 0.5 &&
((pilotAGL_m < 35 ||
(pilotAGL_m < 80 && 80 - pilotAGL_m > random.Next(0, 45))
))) continue;
}
double vel_mps = Calcs.CalculatePointDistance(airGroup.Vwld());
if (vel_mps == 0) { continue; }
var ac_to_obj_vwld = new Vector3d(mo.Pos.x - actor.Pos().x, mo.Pos.y - actor.Pos().y, 0);
double ac_to_obj_bearing_deg = Calcs.CalculateBearingDegree(ac_to_obj_vwld);
double ac_current_heading_deg = Calcs.CalculateBearingDegree(airGroup.Vwld());
double heading_different_deg = ac_to_obj_bearing_deg - ac_current_heading_deg;
bool headed_towards = false;
if (heading_different_deg > 300 || heading_different_deg < 60) headed_towards = true;
double pass_distance_m = Math.Abs(Calcs.PointToLineDistance(new Point2d(actor.Pos().x, actor.Pos().y), new Point2d(actor.Pos().x + airGroup.Vwld().x, actor.Pos().y + airGroup.Vwld().y), mo.Pos));
if (dist_m < 1000) rating += 250;
else if (dist_m < 2000) rating += 150;
else rating += (16000 - dist_m) / 14000.0 * 150.0;
if (headed_towards)
{
if (pass_distance_m < 100) rating += 150;
if (pass_distance_m < 1000) rating += 50;
if (pass_distance_m < 2500) rating += 25;
if (pass_distance_m < 5000) rating += 10;
}
double agl_m = Calcs.AltitudeAGL_m(airGroup.Pos());
if (agl_m < 90) rating = 0;
else if (agl_m < 120) rating *= 0.6;
else if (agl_m < 333) rating *= 4.0;
else if (agl_m >= 333 && agl_m < max_altitude_m) rating *= (max_altitude_m - agl_m) / (max_altitude_m - 333) * 4.0;
if (objRating.ContainsKey(mo.ID))
{
double oR = objRating[mo.ID];
if (oR >= rating) rating = oR + rating / 4.0;
else rating = rating + oR / 4.0;
}
double reducPerc = 1.0;
if (mo.DestroyedPercent > 0) reducPerc = 1 - mo.DestroyedPercent / 2.0;
if (reducPerc < 0.01) reducPerc = 0.01;
rating *= reducPerc;
} else
if (dist_m > 4000) continue;
if (pilotAGL_m > 3000) continue;
}
if (objRating.ContainsKey(mo.ID)) {
if (objRating[mo.ID] > rating) objRating[mo.ID] += rating / 2;
else objRating[mo.ID] = rating + objRating[mo.ID] / 2;
}
else objRating[mo.ID] = rating;
}
}
}
}
}
}
}
foreach (string ID in objRating.Keys.ToList())
{
MissionObjective mo = MissionObjectivesList[ID];
double rating = objRating[ID];
if (neb > 20) rating *= 4.0;
else if (neb > 2) rating *= (neb - 2) / 18.0 * 3.0 + 1;
if (mo.IsPrimaryTarget && !mo.ObjectiveAchievedForPoints) rating *= 3;
if (mo.PrimaryTargetWeight < 100) rating *= 0.3;
if (MO_objectivetype_by_strengthtype[MO_MilitaryStrengthType.Military_Leadership].Contains(mo.MOObjectiveType) ||
MO_objectivetype_by_strengthtype[MO_MilitaryStrengthType.Military].Contains(mo.MOObjectiveType) ||
MO_objectivetype_by_strengthtype[MO_MilitaryStrengthType.Military_Fuel_Supply].Contains(mo.MOObjectiveType)
) rating *= 1.3;
else rating *= 0.4;
if (mo.Destroyed) rating *= 0.2;
double defenseUnits_factor = mo.defenseUnitsHelpFactor();
rating *= defenseUnits_factor;
objRating[ID] = rating;
}
double totalRatings = 0;
double totalRatingsOver10 = 0;
double totalRatingsOver100 = 0;
int totalObj = 0;
int totalObjOver10 = 0;
int totalObjOver100 = 0;
var newObjRating = new Dictionary();
foreach (KeyValuePair item in objRating.OrderByDescending(key => key.Value))
{
MissionObjective mo = MissionObjectivesList[item.Key];
double rating = item.Value;
if (rating < minRatingForFlak)
{
if (rating < minRatingForFlak)
{
if (nump < 5 || ON_TESTSERVER) Console.WriteLine("TempFlak Objective Eval - skipping bec rating 800) mo2.defenseUnitsAttackResponse();
double objdist_m = Calcs.CalculatePointDistance(mo.Pos, mo2.Pos);
if (objdist_m < 1200 && rating2 > rating)
{
break;
}
else if (objdist_m < 2400 && rating2 > rating)
{
rating *= 0.2 * mo.defenseUnitsHelpFactor();
break;
}
else if (objdist_m < 3600 && rating2 > rating)
{
rating *= 0.3 * mo.defenseUnitsHelpFactor();
break;
}
}
newObjRating[item.Key] = rating;
totalRatings += rating;
totalObj++;
if (rating >= 100) { totalRatingsOver100 += rating; totalRatingsOver100_sqrt += Math.Sqrt(rating); totalObjOver100++; }
else if (rating >= 10) { totalRatingsOver10 += rating; totalRatingsOver10_sqrt += Math.Sqrt(rating); totalObjOver10++; }
}
double averageRatingOver100 = 500;
if (totalObjOver100 > 0) averageRatingOver100 = totalRatingsOver100 / totalObjOver100;
int maxNumFor100s = numToDistribute / 2;
if (totalObjOver100 > 0 && maxNumFor100s / totalObjOver100 < 8) maxNumFor100s = numToDistribute * 3 / 4;
if (totalObjOver100 > 0 && totalRatingsOver100 / totalObjOver100 > 500 && maxNumFor100s / totalObjOver100 < 10) maxNumFor100s = numToDistribute * 5 / 6;
int numFor100s = 12 * totalObjOver100;
if (numFor100s > numToDistribute / 2) numFor100s = maxNumFor100s;
if (minRatingForFlak >= 100 || maxSectionFiles == 1) numFor100s = numToDistribute;
int leftovers = maxNumFor100s - numFor100s;
if (leftovers <= 0) leftovers = 0;
int maxNumFor10s = numToDistribute * 5 / 8;
int numFor10s = 4 * totalObjOver10;
if (totalObjOver10 > 0)
{
if (numFor10s > maxNumFor10s) numFor10s = maxNumFor10s;
numFor10s += leftovers * 4 / 5;
if (numFor10s > 10 * totalObjOver10) numFor10s = 10 * totalObjOver10;
}
int totalObjOver1 = totalObj - totalObjOver10 - totalObjOver100;
int numFor1s = 0;
if (totalObjOver1 > 0)
{
}
Console.WriteLine("TempFlak: Calculated numAttacking Pilots, totalObj, totalObjOver1, totalObjOver10, totalObjOver100, numFor100s, numFor10s, numFor1s {0:n0} {1:n0} {2:n0} {3:n0} {4:n0} {5:n0} {6:n0} {7:n0} numtoDistribute: {10} leftovers: {8:n0} {9}", new object[] { numAttackingPilots, totalObj, totalObjOver1, totalObjOver10, totalObjOver100, numFor100s, numFor10s, numFor1s, leftovers, DateTime.UtcNow.ToString("[HH:mm:ss]"), numToDistribute });
double delay = 1;
int leftovers2 = 0;
bool hundredsExceptionalRule = false;
bool first = true;
int totalInSectionFile = 0;
int sectionFilesLoaded = 0;
int loop_count = 0;
bool reset_count = true;
var autoFlakF = GamePlay.gpCreateSectionFile();
foreach (KeyValuePair item in newObjRating.OrderByDescending(key => key.Value))
{
loop_count++;
MissionObjective mo = MissionObjectivesList[item.Key];
double rating = item.Value;
int num_aa_forobj = 10;
if (rating >= 100)
{
if (rating >= 1200) hundredsExceptionalRule = true;
{
num_aa_forobj = numFor100s / totalObjOver100;
if (rating > averageRatingOver100 * 1.25) num_aa_forobj = num_aa_forobj * 13 / 10;
if (rating < averageRatingOver100 * 0.75) num_aa_forobj = num_aa_forobj * 8 / 10;
}
else if (hundredsExceptionalRule && totalRatingsOver100 > 0) num_aa_forobj = Convert.ToInt32(numFor100s * Math.Sqrt(rating) / totalRatingsOver100_sqrt);
if (rating < 1200 && num_aa_forobj > 10) { leftovers += num_aa_forobj - 10; num_aa_forobj = 10; }
else if (rating < 900 && num_aa_forobj > 8) { leftovers += num_aa_forobj - 8; num_aa_forobj = 8; }
else if (rating < 600 && num_aa_forobj > 5) { leftovers += num_aa_forobj - 5; num_aa_forobj = 5; }
else if (rating < 300 && num_aa_forobj > 4) { leftovers += num_aa_forobj - 4; num_aa_forobj = 4; }
if (first && rating >= 1000 && num_aa_forobj < 8 && numToDistribute > 27) num_aa_forobj = 8;
else if (first && rating >= 700 && num_aa_forobj < 6 && numToDistribute > 22) num_aa_forobj = 6;
first = false;
}
else if (rating >= 10)
{
if (num_aa_forobj > 9) { leftovers += num_aa_forobj - 9; num_aa_forobj = 9; }
if (numDistributed > numToDistribute)
}
else
{
num_aa_forobj = (numFor1s + leftovers) / totalObjOver1;
if (num_aa_forobj < 1) num_aa_forobj = 1;
if (num_aa_forobj > 8) num_aa_forobj = 8;
}
numDistributed += num_aa_forobj;
int count_aa_forobj = 0;
count_aa_forobj += nib;
if (nump < 5 || ON_TESTSERVER) Console.WriteLine("TempFlak Objective Eval: {0} Rating: {1:n0} Num: {2:n0} Batteries: {3} Numdistributed so far: {4}", mo.ID, rating, num_aa_forobj, nfb, numDistributed);
totalInSectionFile += num_aa_forobj;
autoFlakF = MO_AutoFlakPlacement(mo, autoFlakF, reset_count, tempFlak: true, nfb_temp: nfb, nib_temp: nib, total_flak_temp: num_aa_forobj, prefix_replace: tempFlakPrefix + "_" + mo.IDtoCleanChiefName().Substring(1) + "_");
reset_count = false;
if (totalInSectionFile >= 10 || numDistributed >= numToDistribute || loop_count >= newObjRating.Count())
{
{
GamePlay.gpPostMissionLoad(autoFlakF);
reset_count = true;
}
totalInSectionFile = 0;
autoFlakF = GamePlay.gpCreateSectionFile();
sectionFilesLoaded++;
if (sectionFilesLoaded >= maxSectionFiles)
{
if (ON_TESTSERVER) Console.WriteLine("TempFlak: Completed max section files allowed - Exiting. {0} Rating: {1:n0} Num: {2:n0} Batteries: {3} Numdistributed so far: {4}, sectionFilesLoaded: {5}, maxSectionFiles: {6}", mo.ID, rating, num_aa_forobj, nfb, numDistributed, sectionFilesLoaded, maxSectionFiles);
break;
}
delay += sectionFileDelay_s;
}
}
Console.WriteLine("TempFlak: Complete. Numdistributed: {0} over the past {1} seconds", numDistributed, delay);
if (leftoverTempflak[defendingArmy] < 0) leftoverTempflak[defendingArmy] = 0;
return numDistributed;
}
catch (Exception ex)
{
Console.WriteLine("tempflakSpawnPlacement ERROR: " + ex.ToString()); return numDistributed;
}
}
int tempFlakTotal = 0;
int autoFlakTotal = 0;
int autoFlakChiefNum = 0;
int autoFlakRun = 0;
//return; //testing // //Console.WriteLine("Handling autoFlakPlacement for {0} {1} {2} {3}", mo.ID, mo.Pos.x, mo.Pos.y, mo.OwnerArmy); //Console.WriteLine("Auto/TempFlak Radiushide: {0:n0} Distenemy: {1:n0} Dist Neutral {2:n0}", radiusHide, distanceToEnemyFront, distanceToNeutralFront); //TESTING!!!! //Below will apply to primary targets, others are overridden below //2023-01, now setting ALL OBJ to 1x2, the rest is supplied via tempflak //2022-12, was 2x4, but with tempflak system reducing to 1x2. That frees up about //24 flak guns for tempflak use (even with reduced primaries of the 2022 Jubilee campaign // - about 4x2 primaries only) //bhugh, temp, XX2021-10, for final rush increasing # of primaries so decreasing primary autoflak...
{
try
{
List keys = new List(MissionObjectivesList.Keys);
if (!mo.IsEnabled) return f;
autoFlakRun++;
Point3d newPos = mo.Pos;
newPos.z = Math.Round(newPos.z);
double radiusHide = 6000;
double distanceToEnemyFront = GamePlay.gpFrontDistance(mo.AttackingArmy, mo.Pos.x, mo.Pos.y);
double distanceToNeutralFront = GamePlay.gpFrontDistance(0, mo.Pos.x, mo.Pos.y);
if (distanceToEnemyFront < 8000 && distanceToEnemyFront > 1000) radiusHide = distanceToEnemyFront * 0.75;
else if (distanceToEnemyFront <= 1000) radiusHide = 750;
if (radiusHide > 1000 && distanceToNeutralFront < 4000) radiusHide = 1000;
int nfb = mo.NumFlakBatteries;
int nib = mo.NumInFlakBattery;
nfb = 1;
nib = 2;
if (ON_TESTSERVER)
{
nfb = 0;
nib = 0;
}
if (MO_ObjectiveIsNavalVessel(mo) || mo.MOObjectiveType == MO_ObjectiveType.Submarine) return f;
if (!mo.IsEnabled || !mo.IsPrimaryTarget)
{
{
/*nfb = nfb / 3;
nib = nib;
if (nfb < 2) nfb = 2;
if (nib < 2) nib = 2;
*/
nfb = 1;
nib = 2;
if (ON_TESTSERVER)
{
nfb = 1;
nib = 1;
}
}
{
nfb = 1;
nib = 1;
if (ON_TESTSERVER)
{
nfb = 0;
nib = 0;
if (random.NextDouble() > 0.98)
{
nfb = 1;
nib = 1;
}
}
}
}
if (!tempFlak)
{
int nibAdd = 0;
try
{
double du = mo.numDefenseUnits();
if (ON_TESTSERVER) Console.Write("Autoflak: numdefenseunits {0:f6} nfb {1} ", du, nfb);
if (nfb == 0) nfb = 1;
double defenseUnits_add = du / (10.0 * nfb) + 0.1;
if (du >= 10 & defenseUnits_add < 1) defenseUnits_add = 1;
nib += Convert.ToInt32(Math.Round(defenseUnits_add));
}
catch (Exception ex) { Console.WriteLine("Autoflak INT32 conv ERROR: " + ex.ToString()); nibAdd = 0; }
nib += nibAdd;
}
if (tempFlak)
{
nfb = nfb_temp;
nib = nib_temp;
}
if (f == null) f = GamePlay.gpCreateSectionFile();
int flakType = 0;
int totalFlakPlaced = 0;
for (int j = 0; j < nfb; j++)
{
/*
*/
Point3d? temp = mo.getNext_AutoFlak_location();
if (!temp.HasValue) {
Console.WriteLine("AutoFlak: No AutoFlak location for {0} - exiting ({1})", mo.ID, mo.Name);
return GamePlay.gpCreateSectionFile();
}
newPos = temp.Value;
newPos.x += random.Next(12) - 6;
newPos.y += random.Next(12) - 6;
string owner = "nn";
if (mo.OwnerArmy == 1) owner = "gb";
else if (mo.OwnerArmy == 2) owner = "de";
else Console.WriteLine("Autoflak Placement ARMY ERROR for {0} objective - Owner Army was not 1 or 2", new object[] { mo.Name });
var flak = new List { "Artillery.Flak30_Shield", "Artillery.Flak30_Shield",
"Artillery.Flak30_Shield",
"Artillery.Flak30_Shield","Artillery.Flak30_Shield","Artillery.Flak30_Shield",
"Artillery.Flak30_Shield","Artillery.Flak30_Shield","Artillery.Flak30_Shield",
"Artillery.Bofors_StandAlone", };
string staticprefix = "autoflak_" + mo.ID.Substring(1).Replace(' ', '_');
if (tempFlak) staticprefix = tempFlakPrefix;
if (prefix_replace != null) staticprefix = prefix_replace;
autoFlakChiefNum++;
f = Calcs.makeAIChief(f, GamePlay, this, newPos.x, newPos.y, newPos.z, 10 + nfb * 2 + 50, chiefNum: autoFlakChiefNum, resetCount: resetCount, chiefprefix: staticprefix);
resetCount = false;
double hdg = random.Next(360);
Calcs.Shuffle(flak);
var newPoint = new Point3d();
int formation = random.Next(4);
int orientation = random.Next(360);
for (int i = 0; i < nib; i++)
{
double radius2 = 10 + 2 * nib;
if (formation == 0)
{
newPoint = Calcs.pointsOnACircle(newPos, radius2, nib, i, 1 / (2.0 * nib), 1);
} else if (formation == 1)
{
newPoint = Calcs.pointsOnALine(newPos, 10 + 7 * nib, orientation, nib, i, 1);
}
else if (formation == 2)
{
newPoint = Calcs.pointsOnADoubleLine(newPos, 5 + 3.5 * nib, 8, orientation, nib, i, 1);
} else
{
newPoint = Calcs.pointsOnARectangle(newPos, 5 + 3.5 * nib, 7 + 4.5 * nib, orientation, nib, i, 1);
}
string side = owner;
double head = Math.Round(hdg + random.Next(15));
if (ON_TESTSERVER) Console.WriteLine("Placing flak gun placed for {4} at ({0} {1} {2}) heading: {3}, formation: {5})", Math.Round(newPoint.x), Math.Round(newPoint.y), Math.Round(mo.Pos.z), head, mo.Name, formation);
f = Calcs.makeStatic(f, GamePlay, this, Math.Round(newPoint.x), Math.Round(newPoint.y), 0, type: flak[flakType], heading: head, side: side, radiusHide: Convert.ToInt32(radiusHide), chiefNum: autoFlakChiefNum, resetCount: resetCount, staticprefix: staticprefix);
resetCount = false;
if (tempFlak) tempFlakTotal++;
totalFlakPlaced++;
if (flakType >= flak.Count) flakType = 0;
}
}
if (!tempFlak) autoFlakTotal += nib * nfb;
return f;
} catch (Exception ex)
{
Console.WriteLine("autoflakPlacement ERROR: " + ex.Message);
return GamePlay.gpCreateSectionFile();
}
}
public Dictionary> AutoFlak_locations = new Dictionary>() { };
public object AutoFlak_locations_lock = new object();
//var MO_AutoFlak_locations = new List
{
try
{
bool dbug = false;
if (ON_TESTSERVER) Console.WriteLine("AutoFlak_selectLocation: Finding autoflak location for {0} pos=({1:n0},{2:n0})", mo.ID, mo.Pos.x, mo.Pos.y);
if (dbug) Console.WriteLine("MASL 1");
if (MO_ObjectiveIsNavalVessel(mo) || mo.MOObjectiveType == MO_ObjectiveType.Submarine || mo.isMoving())
{
if (ON_TESTSERVER) Console.WriteLine("AutoFlak_selectLocation: Exiting autoflak location for {0} pos=({1:n0},{2:n0}) because moving? {3} {4}", mo.ID, mo.Pos.x, mo.Pos.y, mo.isMoving(), mo.MOMobileObjectiveType);
return false;
}
double batteryRadius = mo.radius;
if (dbug) Console.WriteLine("MASL 2");
List MO_AutoFlak_locations = mo.get_AutoFlak_locations();
if (dbug) Console.WriteLine("MASL 2a");
double nmc_to_Obj_Dist_m = distanceToNearestMobileConvoy_m(mo.Pos);
if (dbug) Console.WriteLine("MASL 2b");
if (refresh && nmc_to_Obj_Dist_m > 6000 && MO_AutoFlak_locations != null && MO_AutoFlak_locations.Count > 5) return true;
int tries = 2000;
double distmult = 2.5;
if (dbug) Console.WriteLine("MASL 3");
if (refresh)
{
tries = 50;
distmult = 60;
}
int no_found = 0;
Point3d newPos = new Point3d();
bool noSuitablePointFound = false;
double min_nmc_dist_m = 5000;
if (dbug) Console.WriteLine("MASL 4");
for (int i = 0; i < tries; i++)
{
radius_hide = 6000;
if (i * distmult > 1000) min_nmc_dist_m = 4000;
if (i * distmult > 2000) min_nmc_dist_m = 3500;
if (i > 0.85 * tries) min_nmc_dist_m = 3000;
if (dbug) Console.WriteLine("MASL 5");
double angle = random.NextDouble() * 2.0 * Math.PI;
if (i > 0.9 * tries) radius = random.Next(10) + batteryRadius - (tries - i) * distmult;
newPos.x = Math.Round(mo.Pos.x + Math.Cos(angle) * radius);
newPos.y = Math.Round(mo.Pos.y + Math.Sin(angle) * radius);
maddox.game.LandTypes landType = GamePlay.gpLandType(newPos.x, newPos.y);
if (dbug) Console.WriteLine("MASL 6");
double nmcDist_m = distanceToNearestMobileConvoy_m(newPos);
double dist = 1000;
double apRadius = 1000;
try
{
AiAirport ap = Calcs.nearestAirport(GamePlay, newPos);
dist = Calcs.CalculatePointDistance(ap.Pos(), newPos);
apRadius = ap.FieldR();
}
catch (Exception ex) { Console.WriteLine("ERROR FLAKPLACE! " + ex.ToString()); }
if (dbug) Console.WriteLine("MASL 7");
if (landType != maddox.game.LandTypes.WATER && dist > 999 && dist > apRadius && nmcDist_m >= min_nmc_dist_m)
{
if (nmcDist_m < radius_hide - 1000) radius_hide = nmcDist_m - 1000;
newPos.z = radius_hide;
MO_AutoFlak_locations.Add(newPos);
no_found++;
if (no_found >= no_to_find) break;
}
}
if (dbug) Console.WriteLine("MASL 8");
if (no_found > 0)
{
lock (AutoFlak_locations_lock)
{
AutoFlak_locations[mo.ID] = MO_AutoFlak_locations;
}
if (ON_TESTSERVER) Console.WriteLine("AutoFlak_selectLocation: Found {0} autoflak locations for {1} ({2})", no_found, mo.ID, mo.Name);
return true;
}
if (dbug) Console.WriteLine("MASL 9");
return false;
}
catch (Exception ex)
{
Console.WriteLine("AutoFlak_selectLocation ERROR: " + ex.Message);
return false;
}
}
Point3d pos = mo.returnCurrentPosWithChief(); //use the "chief position calculator" where necessary //This is place ENEMY flake in the middle of a FRIENDLY objective, so that the enemyflak will destroy the objective //var flak = new List
{
{
List keys = new List(MissionObjectivesList.Keys);
Console.WriteLine("Handling TESTFLAK for {0} {1} {2} {3} {4}", mo.ID, mo.Pos.x, mo.Pos.y, NumFlakBatteries, NumInFlakBattery);
Point3d newPos = mo.Pos;
for (int j = 0; j < NumFlakBatteries; j++)
{
double rd = mo.radius;
if (rd < 250) rd = 20;
if (rd < 5000) rd = 5000;
newPos.x = pos.x + random.Next(Convert.ToInt32(mo.radius));
newPos.y = pos.y + random.Next(Convert.ToInt32(mo.radius));
string enemy = "de";
if (mo.AttackingArmy == 1) enemy = "gb";
ISectionFile f = GamePlay.gpCreateSectionFile();
double hdg = random.Next(360);
Calcs.Shuffle(flak);
for (int i = 0; i < NumInFlakBattery; i++)
{
double angle1 = i * 2.0 / NumInFlakBattery * Math.PI + random.NextDouble() / NumInFlakBattery;
double radius2 = random.Next(2) + 10 + NumInFlakBattery * 2;
double nex = newPos.x + Math.Cos(angle1) * radius2;
double ney = newPos.y + Math.Sin(angle1) * radius2;
string side = enemy;
f = Calcs.makeStatic(f, GamePlay, this, nex, ney, 0, type: flak[0], heading: hdg + random.Next(15), side: side);
}
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: TestObjectiveWithFlak");
GamePlay.gpPostMissionLoad(f);
Console.WriteLine("The TESTFLAK is at {0} {1})", new object[] { newPos.x, newPos.y });
}
}
}
static ManualResetEvent resetEvent = new ManualResetEvent(false);
string backupDir = CAMPAIGN_ID + @" campaign backups\"; //will be added at the end of STATSCS_FULL_PATH //WriteAllTextAsyncWithBackups(string fileDir_base, string fileName_base, string suffix, string ext, string backupDir, bool wait = false, ManualResetEvent resetEvent = null) * //System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(mo.GetType()); //List
{
Console.WriteLine("Writing " + name + " to file");
string ext = ".xml";
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_SESSIONSTATE_" + name + ext;
string suffix = "_SESSIONSTATE_" + name;
string fileName_base = CAMPAIGN_ID;
try
{
/*
BinaryFormatter writer = new BinaryFormatter();
using (FileStream fs = File.Create(filepath))
{
writer.Serialize(fs, mo);
}
*/
var serializer = new DataContractSerializer(mo.GetType());
string xmlString;
using (var sw = new StringWriter())
{
using (var writer = new XmlTextWriter(sw))
{
serializer.WriteObject(writer, mo);
writer.Flush();
xmlString = sw.ToString();
}
}
int count = 0;
if (wait)
{
/*Task task = Calcs.WriteAllTextAsync(filepath, xmlString);
bool res = await task; */
Calcs.WriteAllTextAsyncWithBackups(xmlString, STATSCS_FULL_PATH, fileName_base, suffix, ext, backupDir, wait: true, resetEvent: resetEvent);
Console.WriteLine("MO_WriteMissionObject: waiting . . . to write " + name);
Console.WriteLine("MO_WriteMissionObject: . . . . released.");
} else Calcs.WriteAllTextAsyncWithBackups(xmlString, STATSCS_FULL_PATH, fileName_base, suffix, ext, backupDir);
}
catch (Exception ex)
{
Console.WriteLine("WriteMissionObjectivesClass ERROR: " + ex.ToString());
return false;
}
return true;
}
* //System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(mo.GetType()); //XmlDictionaryReader reader = // XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas()); //System.Xml.Serialization.XmlSerializer reader = new System.Xml.Serialization.XmlSerializer(mo.GetType()); //jsonString = File.ReadAllText(filepath); //wait = true makes it wait for the async disk write & verify that it worked/no errors //usually we only do this right before final thread exit
{
Console.WriteLine("Reading " + name + " from file");
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_SESSIONSTATE_" + name + ".xml";
try
{
/*
BinaryFormatter writer = new BinaryFormatter();
using (FileStream fs = File.Create(filepath))
{
writer.Serialize(fs, mo);
}
*/
string xmlString = File.ReadAllText(filepath);
var serializer = new DataContractSerializer(mo.GetType());
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString))) {
DataContractSerializer formatter0 =
new DataContractSerializer(mo.GetType());
mo = formatter0.ReadObject(reader);
}
}
/*
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_" + name + ".json";
BinaryFormatter writer = new BinaryFormatter();
try
{
using (FileStream fs = File.OpenRead(filepath))
{
mo = writer.Deserialize(fs);
}
}
*/
catch (Exception ex)
{
Console.WriteLine("ReadMissionObjectivesClass ERROR: " + ex.ToString());
return null;
}
return mo;
}
//MO_WriteMissionObject(MO_BRBumrushInfo, "MO_BRBumrushInfo", wait); MO_initializeTurnMapPointsRequired_toLargeDict(); //put the values into the Dict that is saved //MO_WriteMissionObject(MissionObjectivesString, "MissionObjectivesString", wait); Dictionary
{
MO_WriteMissionObject(MissionObjectivesList, "MissionObjectivesList", wait);
MO_WriteMissionObject(MissionObjectivesTimes, "MissionObjectivesTimes", wait);
MO_WriteMissionObject(ScoutPhotoRecord, "ScoutPhotoRecord", wait);
MO_WriteMissionObject(DestroyedRadar, "DestroyedRadar", wait);
MO_WriteMissionObject(MissionObjectivesSuggested, "MissionObjectivesSuggested", wait);
MO_WriteMissionObject(MissionObjectiveScore, "MissionObjectiveScore", wait);
MO_WriteMissionObject(MissionObjectivesCompletedString, "MissionObjectivesCompletedString", wait);
MO_WriteMissionObject(GamePlay.gpTimeofDay(), "MissionCurrentTime", wait);
MO_WriteMissionObject(MO_TurnMapPointsRequired, "MO_TurnMapPointsRequired", wait);
}
public bool[] MO_ReadMissionObjects()
{
bool[] ret = new bool[] { true, true, true, true, true, true, true, true };
var mo = MO_ReadMissionObject(MissionObjectivesList, "MissionObjectivesList");
Console.WriteLine("Read " + mo.GetType().ToString());
if (mo != null) MissionObjectivesList = mo as Dictionary;
else ret[0] = false;
/*
if (mo != null) foreach ( string key in (mo_dic as Dictionary).Keys)
{
if (!MissionObjectivesList.ContainsKey(key)) continue;
MissionObjectivesList[key].Scouted = mo_dic[key].Scouted;
MissionObjectivesList[key].PlayersWhoScoutedNames = mo_dic[key].PlayersWhoScoutedNames;
}
*/
var mo1 = MO_ReadMissionObject(MissionObjectivesSuggested, "MissionObjectivesSuggested");
if (mo1 != null) Console.WriteLine("Read " + mo1.GetType().ToString());
if (mo1 != null) MissionObjectivesSuggested = mo1 as Dictionary>;
else ret[1] = false;
/*
*
* Dictionary> MissionObjectivesInfo = new Dictionary>() {
{ArmiesE.Red, Dictionary() },
{ArmiesE.Blue, Dictionary() }
};
*/
var mo2 = MO_ReadMissionObject(MissionObjectivesTimes, "MissionObjectivesTimes");
if (mo2 != null) Console.WriteLine("Read " + mo2.GetType().ToString());
if (mo2 != null)
{
MissionObjectivesTimes = mo2 as Dictionary>;
Console.WriteLine("MissionObjectivesTimes " + MissionObjectivesTimes.ToString());
}
else ret[2] = false;
/*
var mo2 = MO_ReadMissionObject(DestroyedRadar, "DestroyedRadar");
Console.WriteLine("Read " + mo1.GetType().ToString());
if (mo2 != null) DestroyedRadar = mo2 as Dictionary>;
else ret[2] = false;
*/
var mo3 = MO_ReadMissionObject(MissionObjectiveScore, "MissionObjectiveScore");
if (mo3 != null) Console.WriteLine("Read " + mo3.GetType().ToString());
if (mo3 != null) MissionObjectiveScore = mo3 as Dictionary;
else ret[3] = false;
var mo4 = MO_ReadMissionObject(MissionObjectivesCompletedString, "MissionObjectivesCompletedString");
if (mo4 != null) Console.WriteLine("Read " + mo4.GetType().ToString());
if (mo4 != null) MissionObjectivesCompletedString = mo4 as Dictionary;
else ret[4] = false;
/*
var mo5 = MO_ReadMissionObject(MissionObjectivesString, "MissionObjectivesString");
Console.WriteLine("Read " + mo5.GetType().ToString());
if (mo5 != null) MissionObjectivesString = mo5 as Dictionary;
else ret[5] = false;
*/
var mo5 = MO_ReadMissionObject(MO_BRBumrushInfo, "MO_BRBumrushInfo");
if (mo5 != null) Console.WriteLine("Read " + mo5.GetType().ToString());
if (mo5 != null) MO_BRBumrushInfoRestored = mo5 as Dictionary;
else ret[5] = false;
*/
var mo6 = MO_ReadMissionObject(ScoutPhotoRecord, "ScoutPhotoRecord");
if (mo6 != null) Console.WriteLine("Read " + mo6.GetType().ToString());
if (mo6 != null)
{
ScoutPhotoRecord = mo6 as Dictionary, List>;
try
{
/*foreach (KeyValuePair, List> entry in ScoutPhotoRecord)
{
Console.WriteLine(entry.Key);
Console.WriteLine(entry.Value);
Console.WriteLine(entry.Key.Item1.ToString());
Console.WriteLine(entry.Key.Item2.ToString());
Console.WriteLine(entry.Key.Item3.ToString());
Console.WriteLine(entry.Key.Item3.name);
Console.WriteLine(entry.Key.Item3.army.ToString());
}
*/
} catch (Exception ex) { Console.WriteLine("ScoutPhotoRecord read from disk ERROR: " + ex.ToString()); }
}
else ret[6] = false;
var mo7 = MO_ReadMissionObject(MO_TurnMapPointsRequired, "MO_TurnMapPointsRequired");
if (mo7 != null) Console.WriteLine("Read " + mo7.GetType().ToString());
if (mo7 != null)
{
MO_TurnMapPointsRequired = mo7 as Dictionary>;
Console.WriteLine("MO_TurnMapPointsRequired " + MO_TurnMapPointsRequired.ToString());
}
else ret[7] = false;
return ret;
/*
MO_WriteMissionObject(DestroyedRadar, "DestroyedRadar");
MO_WriteMissionObject(MissionObjectivesSuggested, "MissionObjectivesSuggested");
MO_WriteMissionObject(MissionObjectiveScore, "MissionObjectiveScore");
MO_WriteMissionObject(MissionObjectivesCompletedString, "MissionObjectivesCompletedString");
MO_WriteMissionObject(MissionObjectivesString, "MissionObjectivesString");
*/
}
//MO_SelectPrimaryObjectives(army); //first, remove any/all existing primary targets marked in the MissionObjectivesList //reason is, we want the .ini file primary objective list to be the operative list. //What it says, goes...
{
if (army < 1 || army > 2) return;
Console.WriteLine("Reading Mission Objectives from file for " + ArmiesL[army]);
List moKeys = new List(MissionObjectivesList.Keys);
foreach (var key in moKeys)
{
if (MissionObjectivesList[key].AttackingArmy == army) MissionObjectivesList[key].IsPrimaryTarget = false;
}
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapObjectives.ini";
Ini.IniFile ini = new Ini.IniFile(filepath);
List keys = ini.IniReadList(ArmiesL[army] + "_Objectives", "Objective");
double totalPoints = 0;
foreach (var key in keys)
{
var mo = new MissionObjective(this);
if (!MissionObjectivesList.TryGetValue(key, out mo)) continue;
int terr = GamePlay.gpFrontArmy(mo.Pos.x, mo.Pos.y);
if (mo.AttackingArmy == army && mo.PrimaryTargetWeight > 0 && mo.IsEnabled && !mo.IsPrimaryTarget && (mo.OwnerArmy == terr || mo.MOObjectiveType == MO_ObjectiveType.Submarine))
{
if (totalPoints < MO_PrimaryPointsRequired[(ArmiesE)army])
{
mo.IsPrimaryTarget = true;
totalPoints += mo.Points;
}
else
{
mo.IsPrimaryTarget = false;
}
}
}
if (totalPoints < MO_PrimaryPointsRequired[(ArmiesE)army])
{
MO_SelectPrimaryObjectives(army, totalPoints, fresh: false);
}
return;
}
if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MXX5 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //Save most recent copy of Campaign Map Score with suffix _old File.Copy(filepath, filepath_old); //We could use File.Move here if we want to eliminate the previous .ini file before writing new data to it, thus creating an entirely new .ini. But perhaps better to just delete specific sections as we do below...
{
Console.WriteLine("MO_Write #2");
string filepath = STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapObjectives.ini";
string filepath_old = STATSCS_FULL_PATH + CAMPAIGN_ID + "_MapObjectives_old.ini";
string currentContent = String.Empty;
try
{
if (File.Exists(filepath_old)) { File.Delete(filepath_old); }
Console.WriteLine("MO_Write #2a");
}
catch (Exception ex) { Console.WriteLine("MO_Write Inner: " + ex.ToString()); }
Console.WriteLine("MO_Write Save #3");
try
{
Ini.IniFile ini = new Ini.IniFile(filepath);
ini.IniDeleteSection("Red_Objectives");
ini.IniDeleteSection("Blue_Objectives");
ini.IniWriteList("Red_Objectives", "Objective", MO_ListAllPrimaryObjectives((int)ArmiesE.Red));
ini.IniWriteList("Blue_Objectives", "Objective", MO_ListAllPrimaryObjectives((int)ArmiesE.Blue));
Console.WriteLine("MO_Write #3a");
}
catch (Exception ex) { Console.WriteLine("MapState Write: " + ex.ToString()); }
MO_makeCampaignFilesBackup(filepath, @" campaign backups\", @"_MapObjectives-", ".ini");
Console.WriteLine("MO_Write #4");
/*
var backPath = STATSCS_FULL_PATH + CAMPAIGN_ID + @" campaign backups\";
string filepath_date = backPath + CAMPAIGN_ID + @"_MapObjectives-" + dt.ToString("yyyy-MM-dd-tt") + ".ini";
if (!System.IO.File.Exists(backPath))
{
try
{
System.IO.Directory.CreateDirectory(backPath);
}
catch (Exception ex) { Console.WriteLine("MO_Write Dir Create Date: " + ex.ToString()); }
}
try
{
if (File.Exists(filepath_date)) { File.Delete(filepath_date); }
File.Copy(filepath, filepath_date);
}
catch (Exception ex) { Console.WriteLine("MO_Write Date: " + ex.ToString()); }
*/
}
//Create the directory for the MapState.txt backup files, if it doesn't exist //System.IO.File.Create(backPath); //Save most recent copy of corresponding file with suffix like -2018-05-13.ini //Lists the current secondary/suggested targets to theplayer's screen, and/or just returns the keys of the objectives as a List
{
DateTime dt = DateTime.UtcNow;
string date = dt.ToString("u");
var backPath = STATSCS_FULL_PATH + CAMPAIGN_ID + dirName;
string filepath_date = backPath + CAMPAIGN_ID + fileSuffix + dt.ToString("yyyy-MM-dd-HH") + extension;
if (!System.IO.File.Exists(backPath))
{
try
{
System.IO.Directory.CreateDirectory(backPath);
}
catch (Exception ex) { Console.WriteLine("MO_Write Dir Create Date: " + ex.ToString()); }
}
try
{
if (File.Exists(filepath_date)) { File.Delete(filepath_date); }
File.Copy(fullFilename, filepath_date);
}
catch (Exception ex) { Console.WriteLine("MO_Write Date: " + ex.ToString()); }
}
//print out the radar contacts in reverse sort order, which puts closest distance/intercept @ end of the list // + " (" + mo.Pos.x + "," + mo.Pos.y + ")" });//timeout
{
int numDisplayed = 0;
double totDelay = 0;
List currentSecondaryObjectives = new List() { };
try
{
if (player != null && display) twcLogServer(new Player[] { player }, "SUGGESTED " + ArmiesL[army].ToUpper() + " SECONDARY OBJECTIVES:", new object[] { });
string msg1 = ">>> NOTE: If recon areas are listed, those sectors need to be scouted.";
if (player != null && display) twcLogServer(new Player[] { player }, msg1, new object[] { });
msg1 = ">>> Scout those sectors and take recon photos - Tab-4-9. HQ will then identify specific targets.";
if (player != null && display) twcLogServer(new Player[] { player }, msg1, new object[] { });
int count = 0;
foreach (var key in MissionObjectivesSuggested[(ArmiesE)army])
{
if (numDisplayed >= numToDisplay) break;
MissionObjective mo = null;
if (MissionObjectivesList.ContainsKey(key)) mo = MissionObjectivesList[key];
else continue;
if (!mo.Destroyed && !mo.ObjectiveAchievedForPoints && mo.IsEnabled)
{
currentSecondaryObjectives.Add(key);
if (display && player != null)
{
totDelay += delay;
count++;
if (count % 10 == 0) totDelay += 3.5;
Timeout(totDelay, () =>
{
string msg = "Recon sector: " + mo.Sector.Substring(0, 4).TrimEnd('.');
if (mo.Scouted) msg = mo.lastScoutedSector + " " + mo.Name + " (" + mo.Pos.x.ToString("F0") + ", " + mo.Pos.y.ToString("F0") + ")";
twcLogServer(new Player[] { player }, msg, new object[] { });
}
numDisplayed++;
}
}
}
catch (Exception ex) { Console.WriteLine("ListSuggestedObjectives ERROR!: " + ex.ToString()); }
return currentSecondaryObjectives;
}
//foreach (var key in MissionObjectives[(ArmiesE)army]) //mo.AttackingArmy == army //print out the radar contacts in reverse sort order, which puts closest distance/intercept @ end of the list // + " (" + mo.Pos.x + "," + mo.Pos.y + ")" if (!forEnemy) //the bad guys only know the scouted position of an asset (which might have MOVED etc in the meanwhile if (!Calcs.Point3dEqual(mo.lastScoutedPos, new Point3d(-1, -1, -1))) //set to (-1,-1,-1) means the objective was previously scouted by not is disabled/removed } else //each side knows the ACTUAL position of their assets, not just the scouted position { //set to (-1,-1,-1) means the objective was previously scouted by not is disabled/removed //if (mo.Destroyed) msg6 += " (destroyed)"; //else if (mo.IsPrimaryTarget) msg6 += " (primary objective)"; //This is cool but soooo long //msg6 += (mo.lastTimeScouted_hist_dt.Value).ToString("d'.'MM'.'yy' 'HH':'mm)"); });//timeout //if (timeLeft_min < END_MISSION_TICK / 2000 / 8) msg7 = ">>>" + gsl.staffGroupName + " may have been spotted in sector " + gsl.sectorDoublekeypad + " near " + mo.Name; });//timeout //Tobruk: 10Kft / 3km //twcLogServer(new Player[] { player }, ">>>>> The higher you fly the larger the area your photo will capture.", new object[] { });
{
int numDisplayed = 0;
double totDelay = 0;
string retmsg = "";
string msg = "Scouted " + ArmiesL[army] + " Targets with Coordinates:";
if (forEnemy) msg = "The enemy has been observed scouting these possible objectives within the " + ArmiesL[3-army] + " front lines:";
if (player != null) twcLogServer(new Player[] { player }, msg, new object[] { });
retmsg += msg + Environment.NewLine;
foreach (KeyValuePair entry in MissionObjectivesList)
{
if (numToDisplay > 0 && numDisplayed >= numToDisplay) break;
MissionObjective mo = entry.Value;
if (mo.AttackingArmy == army && mo.Scouted)
{
totDelay += delay;
string msg6 = "";
{
msg6 = mo.lastScoutedSector + " " + mo.Name;
string zpos_string = mo.lastScoutedPos.z.ToString("F0") + "m";
if (army == 1) zpos_string = Calcs.meters2feet(mo.lastScoutedPos.z).ToString("F0") + "ft";
msg6 += " [" + mo.lastScoutedPos.x.ToString("F0") + ", " + mo.lastScoutedPos.y.ToString("F0") + ", " + zpos_string + "]";
{
msg6 = mo.Sector + " " + mo.Name;
if (mo.IsEnabled)
Point3d point1 = mo.returnCurrentPosWithChief();
string zpos_string = point1.z.ToString("F0") + "m";
if (army == 2) zpos_string = Calcs.meters2feet(point1.z).ToString("F0") + "ft";
msg6 += " [" + point1.x.ToString("F0") + ", " + point1.y.ToString("F0") + ", " + zpos_string + "]";
}
}
if (!mo.IsEnabled) msg6 += "!!No longer there!!";
if (mo.lastTimeScouted_dt.HasValue) {
TimeSpan diff = DateTime.UtcNow - mo.lastTimeScouted_dt.Value;
msg6 += " ";
if (mo.numTimesScouted > 1) msg6 += mo.numTimesScouted.ToString("F0") + "X, ";
msg6 += (Math.Round(diff.TotalHours * 2.0) / 2.0).ToString("F1") + "hr";
}
string rd = " R" + mo.radius.ToString("F0") + "m";
if (army==1) rd = " R" + Calcs.meters2feet(mo.radius).ToString("F0") + "ft";
string dl = ", L" + mo.Points.ToString();
string pc = "";
if (mo.DestroyedPercent != 0) pc = ", " + (Math.Floor(mo.DestroyedPercent * 100.0)).ToString("F0") + "%";
int ndf = mo.numDefenseUnits();
string ndfmsg = "";
if (ndf > 0) ndfmsg = String.Format(" ({0} DUs, {1:f1}X)", ndf, mo.defenseUnitsHelpFactor());
msg6 += rd + dl + pc + ndfmsg;
retmsg += msg6 + Environment.NewLine;
numDisplayed++;
if (numDisplayed % 10 == 0) totDelay += 3.5;
Timeout(totDelay, () =>
{
if (player != null) twcLogServer(new Player[] { player }, msg6, new object[] { });
if (mo.hasGeneralStaff && !forEnemy)
{
var gsl = GeneralStaffLocations[(ArmiesE)army];
string af = "general";
if (mo.OwnerArmy == 1) af = "RAF";
else if (mo.OwnerArmy == 2) af = "Luftwaffe";
int timeLeft_min = calcTimeLeft_min();
string msg7 = ">>>Recon has identified a possible group of high-ranking " + af + " officers in sector " + gsl.sector + " near " + mo.Name;
if (timeLeft_min < MISSION_LENGTH_HRS * 60.0 / 2 || mo.numTimesScouted > 1) msg7 = ">>>Additional reconnaissance has determined that " + gsl.staffGroupName + " are in sector " + gsl.sectorKeypad + " near " + mo.Name;
if (timeLeft_min < MISSION_LENGTH_HRS * 60.0 / 4 || mo.numTimesScouted > 2) msg7 = ">>>Additional reconnaissance has determined that " + gsl.staffGroupName + " are in sector " + gsl.sectorDoublekeypad + " near " + mo.Name;
if (mo.numTimesScouted > 3) msg7 = ">>>Additional reconnaissance has determined that " + gsl.staffGroupName + " are in sector " + gsl.sectorDoublekeypad + " near (" + (gsl.pos.x + random.Next(1000) - 500).ToString("F0") + "," + (gsl.pos.y + random.Next(1000) - 500).ToString("F0") + ") in the area of " + mo.Name;
if (mo.numTimesScouted > 4) msg7 = ">>>Several additional reconnaissance flights have narrowed down the location of " + gsl.staffGroupName + " within less than 1 km, in sector " + gsl.sectorDoublekeypad + " near (" + (gsl.pos.x + random.Next(1000) - 500).ToString("F0") + "," + (gsl.pos.y + random.Next(1000) - 500).ToString("F0") + ") in the area of " + mo.Name;
if (mo.numTimesScouted > 5) msg7 = ">>>Several additional reconnaissance flights have narrowed down the location of " + gsl.staffGroupName + " to sector " + gsl.sectorDoublekeypad + " within a few hundred meters of (" + (gsl.pos.x + random.Next(1000) - 200).ToString("F0") + "," + (gsl.pos.y + random.Next(1000) - 200).ToString("F0") + ") in the area of " + mo.Name;
retmsg += msg7 + Environment.NewLine;
totDelay += delay;
Timeout(totDelay, () =>
{
if (player != null) twcLogServer(new Player[] { player }, msg7, new object[] { });
}
}
}
if (numDisplayed == 0)
{
msg = ">>>>> No objectives scouted yet <<<<<";
if (player != null) twcLogServer(new Player[] { player }, msg, new object[] { });
retmsg += msg + Environment.NewLine;
}
Timeout(totDelay + 2, () =>
{
if (player != null) twcLogServer(new Player[] { player }, ">>> To scout objectives, fly 20000ft/6000m or higher in an aircraft with no bombs on board and record a reconnaissance photo of the area via Tab-4-9.", new object[] { });
Timeout(2, () =>
{
if (player != null) twcLogServer(new Player[] { player }, ">>> Return the photos to base, land safely, and use chat command
{
if (player != null) twcLogServer(new Player[] { player }, ">>> The photos allow headquarters to determine precise coordinates of all potential objectives in that area.", new object[] { });
});
});
return retmsg;
}
/*
[CollectionDataContract
(Name = "ScoutPhotoRecord",
ItemName = "entry",
KeyName = "Playertuple",
ValueName = "ScoutedObjectiveList")]
public class ScoutPhotoRecord_class : Dictionary, List> { };
*/
No description available.
{
Console.WriteLine("Listing interesting scout targets for " + player.Name() + " at {0:N0}m", distance_m);
if (!ScoutInterestingTargets.ContainsKey(player)) return;
string sectorList = "";
if (player == null || player.Place() == null) return;
foreach (string s in ScoutInterestingTargets[player])
{
string moving = "";
Console.WriteLine("Listing all interesting scout targets " + s);
if (!MissionObjectivesList.ContainsKey(s)) continue;
MissionObjective mo = MissionObjectivesList[s];
if (Calcs.CalculatePointDistance(mo.returnCurrentPosWithChief(), player.Place().Pos()) > distance_m) continue;
if (MissionObjectivesList[s].isMoving()) moving = "(moving)";
string sect = Calcs.correctedSectorNameDoubleKeypad(this,(MissionObjectivesList[s].returnCurrentPosWithChief()));
sectorList += sect + moving + " ";
}
if (sectorList.Length == 0) return;
gpLogServerAndLog(new Player[] { player }, ">>> Interesting sectors from your recon flight for a closer look or high-res screenshot photos: " + sectorList, null);
}
No description available.
Timeout(10, () =>
{
gpLogServerAndLog(new Player[] { player }, ">>> Preliminary analysis indicates a high-res screenshot photo of sector " + MissionObjectivesList[moID].lastScoutedSector + " may help locate important targets in that area.", null);
});
Timeout(20, () =>
{
displayInterestingScoutTargets(player, distance_m);
});
}
//Don't show position if disabled, destroyed, other problematic situations... //if (newInterestingTarget) displayNewInterestingScoutTarget(player, moID); Dictionary
Console.WriteLine("Adding Interesting Scout Target: " + moID);
MissionObjective mo = MissionObjectivesList[moID];
if (!mo.IsEnabled || mo.Destroyed) return;
if (mo.hasChief() && !mo.chiefIsAlive()) return;
var nhs = new HashSet();
if (ScoutInterestingTargets.ContainsKey(player)) nhs = ScoutInterestingTargets[player];
bool newInterestingTarget = true;
if (nhs.Contains(moID)) newInterestingTarget = false;
nhs.Add(moID);
ScoutInterestingTargets[player] = nhs;
}
int ScoutPhotoID = 0;
// + currTime_sec.ToString() + " " + LastPhotoTime_sec[player].ToString() if (test.HasValue) pos = test.Value; //for testing if (MO_CheckForGeneralStaffReconPhoto(player, aircraft, army, pos)) return; //If they're taking a legit general staff recon photo we don't give an error message double radiusCovered_m = altitude / 0.342; //(Sin (20 degrees) = 0.342) Meaning that we can scout things 20 degrees below the horizon & lower. This might be alittle ambitious, but also maybe not? //foreach (var key in MissionObjectives[(ArmiesE)army]) //mo.AttackingArmy == army //if (!mo.Destroyed && mo.AttackingArmy == army && mo.IsEnabled && !mo.Scouted && Calcs.CalculatePointDistance (mo.Pos, pos) < radiusCovered_m) // no reason they can't scout destroyed objects - some might be undestroyed sometime soon...
{
Task.Run(() =>
{
if (player == null || player.Place() == null) return;
bool firstPhotoThisSession = true;
if (LastPhotoTime_sec.ContainsKey(player)) firstPhotoThisSession = false;
int currTime_sec = Time.tickCounter() / 33;
if (LastPhotoTime_sec.ContainsKey(player) && (currTime_sec - LastPhotoTime_sec[player]) < 15)
{
gpLogServerAndLog(new Player[] { player }, "Recon photo NOT recorded - photo once every 15 seconds at most! ", null);
return;
}
int numScouted = 0;
string minAlt = "20000 feet";
if (army == 2) minAlt = "6000m";
bool fail = false;
string reason = "";
if (player.Place() as AiAircraft == null && !test.HasValue)
{
fail = true;
reason += "Not in aircraft ";
}
AiAircraft aircraft = player.Place() as AiAircraft;
Point3d pos = aircraft.Pos();
double altitude = pos.z;
if (altitude < 6000)
{
fail = true;
reason += "Altitude too low ";
LastPhotoTime_sec[player] = currTime_sec;
}
string alt = (radiusCovered_m / 1000.0).ToString("F1") + " km";
if (army == 1) alt = (Calcs.meters2feet(radiusCovered_m) / 5280.0).ToString("F1") + " miles";
if (aircraft.AirGroup().hasBombs())
{
fail = true;
reason += "Aircraft indicates 'has bombs' ";
}
if (fail)
{
Console.WriteLine("Scout photo: fail alt:{0} ppasAC:{1} hasBombs:{2}", altitude, player.Place() as AiAircraft, aircraft.AirGroup().hasBombs());
twcLogServer(new Player[] { player }, "You must be in an aircraft, with no bombs on board, above " + minAlt + ", to successfully take a reconnaissance photo. (" + reason + ")", new object[] { });
return;
}
LastPhotoTime_sec[player] = currTime_sec;
ScoutPhotoID++;
List keys = new List();
twcLogServer(new Player[] { player }, ">>> Reconnaissance photo successfully taken, covering a radius of approx. " + alt + ".", new object[] { });
bool interestingScoutTarget = false;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (mo.AttackingArmy == army && (Calcs.CalculatePointDistance(mo.returnCurrentPosWithChief(), pos) < radiusCovered_m || Calcs.CalculatePointDistance(mo.lastScoutedPos, pos) < radiusCovered_m))
{
keys.Add(entry.Key);
numScouted++;
else if (mo.IsPrimaryTarget && mo.hasChief())
{
interestingScoutTarget = true;
}
{
interestingScoutTarget = true;
}
else if (mo.IsEnabled && mo.MOMobileObjectiveType != MO_MobileObjectiveType.None && random.NextDouble() < 0.15)
{
interestingScoutTarget = true;
}
else if (mo.IsPrimaryTarget && random.NextDouble() < 0.02)
{
interestingScoutTarget = true;
}
}
}
var recordKey = new Tuple(ScoutPhotoID, army, new aPlayer(player));
ScoutPhotoRecord.Add(recordKey, keys);
{
Timeout(12, () =>
{
Console.WriteLine("displaying interesting scout targets");
displayInterestingScoutTargets(player, radiusCovered_m * 1.75);
});
}
Timeout(60 * 60, () =>
{
{
int total = ScoutPhotoRecord[recordKey].Count();
ScoutPhotoRecord.Remove(recordKey);
if (total > 0) twcLogServer(new Player[] { player }, "I'm sorry to inform you that your reconnaissance photo taken over 1 hour ago identifying " + total.ToString() + " objectives was spoiled due to equipment malfunction during an overly extended flight.", new object[] { });
}
if (numScouted == 0)
{
Timeout(3, () =>
{
twcLogServer(new Player[] { player }, ">>> That area did not look very promising for locating valuable objectives.", new object[] { });
return;
});
}
if (numScouted < 0) numScouted = 0;
string msg1 = ">>> That area did not look very promising for locating valuable objectives.";
if (numScouted > 0) msg1 = ">>> It looks like that area may contain a few valuable military objectives.";
if (numScouted > 8) msg1 = ">>> It looks like that area may contain several valuable military objectives.";
Timeout(1.5, () =>
{
twcLogServer(new Player[] { player }, msg1, new object[] { });
});
{
Timeout(3, () =>
{
twcLogServer(new Player[] { player }, "Reconnaissance results will be available after you land safely and headquarters has a chance to analyze the photos fully.", new object[] { });
});
Timeout(4.5, () =>
{
twcLogServer(new Player[] { player }, "You have one hour to return and land safely or the photo will be spoiled.", new object[] { });
});
}
/*
else
{
Timeout(4.5, () =>
{
twcLogServer(new Player[] { player }, ">>> One hour to land/record photo.", new object[] { });
});
}
*/
});
}
//check = true means, the player is requesting to record the photos, ie, checking. //Otherwise it is some automated thing & no message is required unless there is success.
{
foreach (Player player in players)
{
MO_SpoilPlayerScoutPhotos(player);
}
}
HashSet> photosRecorded = new HashSet>();
No description available.
{
foreach (Player player in players)
{
MO_RecordPlayerScoutPhotos(player);
}
}
//note - only lists first 24 targets BY DEFAULT
{
int numRemainingObjectives = 0;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (!mo.ObjectiveAchievedForPoints && mo.AttackingArmy == army && mo.IsPrimaryTarget)
{
numRemainingObjectives++;
}
}
Console.WriteLine("Number remaining primary objectives for {0} is {1}", army, numRemainingObjectives);
return numRemainingObjectives;
}
if (leak) recipients = AllPlayersInArmyArray(3 - army); //Leak displays the enemy's current target list to the opposite army players //bhugh, XX2021-10, temp, for end of campaign special battle //+ " (" + mo.Pos.x + "," + mo.Pos.y + ")" //to display x,y coordinates });//timeout //+ " (" + mo.Pos.x + "," + mo.Pos.y + ")" //to display x,y coordinates });//timeout
{
string newline = Environment.NewLine;
if (html) newline = "
" + Environment.NewLine;
string retmsg = "";
string msg = "";
Player[] recipients = new Player[] { };
if (player != null) recipients = new Player[] { player };
int numDisplayed = 0;
double totDelay = 0;
msg = "REMAINING " + ArmiesL[army].ToUpper() + " PRIMARY OBJECTIVES:";
/*
if (army == 2)
{
msg = "SOLE REMAINING " + ArmiesL[army].ToUpper() + " PRIMARY OBJECTIVE";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg = msg + newline;
msg = ">>>>> Defend RESERVE COMMUNICATIONS HQ in sector BD04";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg += msg + newline;
msg = ">>>>> The ENTIRE CAMPAIGN hangs on defending this single objective now.";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg += msg + newline;
return retmsg;
}
*/
if (leak) msg = "REMAINING " + ArmiesL[army].ToUpper() + " PRIMARY OBJECTIVES (INTELLIGENCE LEAK from low-level General Staff recon photos):";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg = msg + newline;
if (!leak)
{
msg = ">>> NOTE: Last scouted position/time shown. If recon areas are listed, those sectors need to be scouted.";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg += msg + newline;
msg = ">>> Scout the areas and take recon photos - Tab-4-9. HQ will then identify specific targets & details.";
if (display) twcLogServer(recipients, msg, new object[] { });
retmsg += msg + newline;
}
int c = 0;
foreach (KeyValuePair entry in MissionObjectivesList)
{
if (numDisplayed >= numToDisplay) break;
MissionObjective mo = entry.Value;
if (!mo.ObjectiveAchievedForPoints && mo.AttackingArmy == army && mo.IsPrimaryTarget)
{
c++;
string msg1 = "Recon area: " + mo.bigSector;
if (mo.Scouted)
{
string pc = "";
if (mo.DestroyedPercent > 0) pc = ", " + (Math.Floor(mo.DestroyedPercent * 100.0)).ToString("F0") + "%";
string dl = " Level " + mo.Points.ToString();
string ls = "";
if (mo.lastTimeScouted_dt.HasValue)
{
TimeSpan diff = DateTime.UtcNow - mo.lastTimeScouted_dt.Value;
string excl = "";
if (diff.TotalHours > 15 && mo.isMobile()) excl = "!";
ls = " " + excl + (Math.Round(diff.TotalHours * 2.0) / 2.0).ToString("F0") + "hr" + excl;
}
string zpos_string = mo.lastScoutedPos.z.ToString("F0") + "m";
if (army == 1) zpos_string = Calcs.meters2feet(mo.lastScoutedPos.z).ToString("F0") + "ft";
msg1 = mo.lastScoutedSector + " " + mo.Name + " [" + mo.lastScoutedPos.x.ToString("F0") + ", " + mo.lastScoutedPos.y.ToString("F0") + ", " + zpos_string + "]" + ls + dl + pc;
}
retmsg += msg1 + newline;
totDelay += delay;
if (c % 10 == 0) delay += 18*delay;
if (display)
{
Timeout(totDelay, () =>
{
twcLogServer(recipients, msg1, new object[] { });
}
numDisplayed++;
}
}
double pts = MO_PointsRequired[(ArmiesE)army];
double pts_remain = MO_PointsRequired[(ArmiesE)army] - MissionObjectiveScore[(ArmiesE)army];
double pts_remain_noobjective = MO_PointsRequiredWithMissingPrimary[(ArmiesE)army] - MissionObjectiveScore[(ArmiesE)army];
if (pts_remain < 0) pts_remain = 0;
string msg2 = String.Format("****Remaining objective points to turn map: {0:n0}/{1:n0} (if all primary objectives destroyed)", pts_remain, pts);
double pts_remain_noobjective_display = pts_remain_noobjective;
if (pts_remain_noobjective_display < 0) pts_remain_noobjective_display = 0;
if (pts_remain <= 0 && c>0) msg2 = String.Format("****Remaining objective points to turn map: 0 with remaining primary objective{1} OR {0:n0} otherwise", pts_remain_noobjective_display, (c != 1)?"s":"");
retmsg += msg2 + newline;
totDelay += delay;
if (c % 10 == 0) delay += 18 * delay;
if (display)
{
Timeout(totDelay, () =>
{
twcLogServer(recipients, msg2, new object[] { });
}
return retmsg;
}
No description available.
{
var remainingMOs = new List();
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (!mo.ObjectiveAchievedForPoints && mo.AttackingArmy == army && mo.IsPrimaryTarget && mo.IsEnabled)
{
remainingMOs.Add(mo);
}
}
if (remainingMOs.Count <= 0) return "";
MissionObjective m = remainingMOs.OrderBy(x => Guid.NewGuid()).FirstOrDefault();
return Calcs.correctedSectorNameKeypad(this, m.Pos);
}
//keys.Sort(); //unfortunately sorting just actually scrambles them hopelessly //foreach (KeyValuePair
{
List keys = MissionObjectivesList.Keys.ToList();
string op = "";
DateTime utcDate = DateTime.UtcNow;
op += utcDate.ToString("u") + Environment.NewLine;
if (!misformat) op += "Can view with text editor or Excel (tab-delimited text file). If you open in Excel, save immediately with a new name so you don't block this file being re-written by a new mission." + Environment.NewLine;
if (!misformat) op += "ID\tName\tAttackingArmy\tOwnerArmy\tIsEnabled\tMOObjectiveType\tMOTriggerType\tIsPrimaryTarget\tPrimaryTargetWeight\tPoints\tDestroyed\tPos.x\tPos.y\tSector\tRadarEffectiveRadius\tTriggerName\tTriggerType\tTriggerPercent\tTriggerDestroyRadius\tStaticPercentageRequired\tStaticRemoveDelay_sec\tStaticRemoveSpread_sec\tComment\tHUDMessage\tLOGMessage\tStaticNames\tStaticRemoveNames" + Environment.NewLine;
foreach (string k in keys)
{
MissionObjective mo = MissionObjectivesList[k];
if (triggersonly && !mo.MOTriggerType.Equals(MO_TriggerType.Trigger)) continue;
if (misformat)
{
op += mo.ToString(misformat) + Environment.NewLine;
}
else
{
op += mo.ToString(misformat) + Environment.NewLine;
}
}
try
{
string filepath = CLOD_PATH + FILE_PATH + @"/" + filename;
Calcs.WriteAllTextAsync(filepath, op);
}
catch (Exception ex) { Console.WriteLine("MO_WriteOutAll: " + ex.ToString()); }
}
HashSet MO_flakMissionsLoaded = new HashSet();
//2022-12, removing the flak areas/*.mis files because we're replacing them with the //the tempflak system. This should gain us maybe 40-50 flak pieces or more, X2 (for each side)? //bhugh, temp, XX2021-10, cut the number of flak loaded in HALF due to doubling the # of primary //objectives temporarily, AND to make server more responsive etc //if (random.NextDouble() < 0.5) continue; //2022-12, removing the flak areas/*.mis files because we're replacing them with the //the tempflak system...
{
return true;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (mo.IsPrimaryTarget && mo.IsEnabled)
{
string flakID = mo.FlakID;
string flakMissionString = "";
if (flakMissions.Keys.Contains(flakID)) flakMissionString = flakMissions[flakID];
else Console.WriteLine("LoadFlak: No flak found for " + mo.Name + " " + flakID);
MO_flakMissionsLoaded.Add(flakID);
foreach (string flakMission in flakMissionsArray)
{
if (File.Exists(CLOD_PATH + FILE_PATH + "/" + flakMission))
{
Timeout(48, () =>
{
string s = CLOD_PATH + FILE_PATH + "/" + flakMission;
ISectionFile f = GamePlay.gpLoadSectionFile(s);
f = Calcs.changeArmy_Waypoints_SectionFile(f, GamePlay, this, changeToArmy: mo.OwnerArmy, maxWaypoints_remove: 0, maxPercentWaypoints_remove: 0);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Load objective flak file");
GamePlay.gpPostMissionLoad(f);
DebugAndLog(flakMission + " flak file loaded");
Console.WriteLine(flakMission + " flak file loaded");
});
}
else
{
Console.WriteLine("LoadFlak: No flak file found for " + mo.Name + " " + flakID + " " + flakMission);
}
}
}
}
return true;
}
//jcPos.z = 15000; //This makes it a place we can jump to & get an overview of the area //let's keep jerrycans -3 for now 2023-01 jcPos.z = -3; //This makes it a place we can jump to & get an overview of the area //place a jerrycan in the middle of the area, covering it. This allows stats to be counted for anything in this area, and also sets up smoke etc for any bombs hitting this area...
{
Point3d jcPos = mo.Pos;
if (MO_ObjectiveIsNavalVessel(mo)) jcPos.z = -50;
if (mo.TriggerDestroyRadius < 1410)
{
{
string jerry = "JerryCan_GER1_1";
if (mo.TriggerDestroyRadius > 71) jerry = "JerryCan_GER1_2";
if (mo.TriggerDestroyRadius > 141) jerry = "JerryCan_GER1_3";
if (mo.TriggerDestroyRadius > 282) jerry = "JerryCan_GER1_5";
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: PlaceAppropriateJerrycan");
Calcs.loadStatic(GamePlay, this, jcPos.x, jcPos.y, jcPos.z, "Stationary.Environment." + jerry, staticprefix: mo.ID.Substring(1));
});
}
else
{
double searchRadius_m = MO_CalcMobileObjRadius_m(mo);
double stretchA = 1;
{
ISectionFile f = GamePlay.gpCreateSectionFile();
f = PlaceObjectsInCircles(f, MO_Jerrycan1410, jcPos, searchRadius_m, 4.0 * searchRadius_m / 5.0, Convert.ToInt32(Math.Pow(Math.Ceiling(Math.Abs(searchRadius_m) / 1000), 2)), army: 0, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: stretchA, resetCount: false);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Placeappropriate jerrycan");
GamePlay.gpPostMissionLoad(f);
});
}
}
//place a jerrycan in the middle of the area, covering it. This allows stats to be counted for anything in this area, and also sets up smoke etc for any bombs hitting this area...
{
Point3d jcPos = mo.Pos;
jcPos.z = -2;
if (MO_ObjectiveIsNavalVessel(mo)) jcPos.z = -50;
string jerry = "JerryCan_GER1_1";
double searchRadius_m = mo.radius / 2.0;
double stretchA = 1;
{
ISectionFile f = GamePlay.gpCreateSectionFile();
int numi = Convert.ToInt32(searchRadius_m * 2 * Math.PI / 150.0);
if (numi < 20) numi = 20;
f = PlaceObjectsInCircles(f, MO_Jerrycan71, jcPos, searchRadius_m, 4.0 * searchRadius_m / 5.0, numi, army: 0, percentSide: 0, subHeading_deg: -1, stretcherType: 1, stretcherAmt: stretchA, resetCount: false);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Place some Jerrycans");
GamePlay.gpPostMissionLoad(f);
});
}
//load submission if requested // //This needs to be run whenever the objectives list is reinitialized, but also after each mission restart, after the missionobjectiveslist has been reloaded from disk //initializeobjectives initialize objectives
{
mo.loadInitSubmission();
/*
if (mo.InitSubmissionName != null && mo.InitSubmissionName.Length > 0 && !mo.Destroyed)
{
string s = CLOD_PATH + FILE_PATH + "/" + mo.InitSubmissionName;
try
{
Timeout(5, () =>
{
GamePlay.gpPostMissionLoad(s);
Console.WriteLine(s.Replace(CLOD_PATH + FILE_PATH, "") + " file loaded");
});
}
catch (Exception ex) { Console.WriteLine("MO_loadInitSubmission ERROR InitSubmission for Objective NOT loaded: {0} \n\n {1}", s, ex.ToString()); }
}
if (mo.Destroyed) Console.WriteLine(mo.Name + ": " + mo.InitSubmissionName + " initsubmission NOT loaded because this objective is destroyed.");
*/
}
MO_MakeCameras(mo); //note = this adds the info the file, must be finalized at the end //if (mo.MOObjectiveType == MO_ObjectiveType.KnickebeinHQ) mo.Destroyed = true; //testing (ON_TESTSERVER && random.Next(100) < 75 && MO_Naval_Ship_ObjectiveTypes.Contains(mo.MOObjectiveType)) ) //randomly turn off say 5% or 20% (or whatever amt set) of objectives each day. But, can't turn off radar or airports, etc (if marked as 'can't be disabled'...
{
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
mo.IsEnabled = true;
if ( (!mo.IsPrimaryTarget && mo.CanBeDisabled && random.Next(100) < MO_Objective_Percent_To_Disable ) ||
{
mo.IsEnabled = false;
Console.WriteLine("Mo_InitializeAllObjectives: Objective {0} {1} is disabled/removed from the objectives list for this session", mo.ID, mo.Name);
RemoveSuggestedObjective(mo);
}
bool shipObjective = MO_ObjectiveIsNavalVessel(mo);
bool submarineObjective = (mo.MOObjectiveType == MO_ObjectiveType.Submarine);
bool landingGroundObjective = (mo.MOTriggerType == MO_TriggerType.TemporaryLandingGround );
if (submarineObjective)
{
mo.OwnerArmy = mo.OriginalOwnerArmy;
mo.AttackingArmy = 3 - mo.OwnerArmy;
}
int terr = GamePlay.gpFrontArmy(mo.Pos.x, mo.Pos.y);
{
Console.WriteLine("MO_InitializeAllObjectives(): Objective " + mo.Name + " has changed sides to " + terr.ToString() + " at " + DateTime.UtcNow.ToString());
if (mo.CanBeDisabled) {
RemoveSuggestedObjective(mo);
}
mo.OwnerArmy = terr;
mo.AttackingArmy = 3 - terr;
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.ObjectiveAchievedForPoints = false;
mo.TimeToUndestroy_UTC = null;
mo.LastHitTime_UTC = null;
mo.AirfieldDamagePoints = 0;
mo.DefenseUnits = null;
mo.Scouted = false;
mo.PlayersWhoScoutedNames = new Dictionary();
mo.numTimesScouted = 0;
mo.PlayersWhoContributedNames = new HashSet();
mo.PlayersWhoRepairedNamesTimes = new Dictionary();
mo.ObjectsDestroyed_num = 0;
mo.OrdnanceOnTarget_kg = 0;
mo.ActorsDestroyed_num = 0;
mo.HUDMessage = mo.HUDMessage.Replace(ArmiesL[mo.OwnerArmy], ArmiesL[mo.AttackingArmy]);
mo.LOGMessage = mo.LOGMessage.Replace(ArmiesL[mo.OwnerArmy], ArmiesL[mo.AttackingArmy]);
mo.Comment += " Changed sides to " + terr.ToString() + " at " + DateTime.UtcNow.ToString();
}
Timeout(140, () =>
{
ISectionFile f2 = GamePlay.gpCreateSectionFile();
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: MO_HandleTriggerObjectiveRefresh");
GamePlay.gpPostMissionLoad(f2);
});
if (mo.IsEnabled)
{
MO_loadInitSubmission(mo);
maddox.game.LandTypes landType = GamePlay.gpLandType(mo.Pos.x, mo.Pos.y);
bool landTypeWater = false;
if (landType == maddox.game.LandTypes.WATER) landTypeWater = true;
if (mo.MOTriggerType == MO_TriggerType.PointArea && !landTypeWater)
{
MO_PlaceAppropriateJerrycan(mo);
}
if (!landTypeWater && mo.OwnerArmy != mo.OriginalOwnerArmy)
{
}
else if (mo.DestroyedPercent > 0) Timeout(125, () => { MO_RemoveObjective(mo, immediate: false, percent: mo.DestroyedPercent); });
bool isMobile = false;
if ((mo.MOMobileObjectiveType != null && mo.MOMobileObjectiveType != MO_MobileObjectiveType.None)) isMobile = true;
Console.WriteLine("Objective status: {0} ORTGG {1:N0} num required: {2:N0})", mo.Name, mo.OrdnanceRequiredToTrigger_kg, mo.ObjectsRequiredToTrigger_num);
if (mo.MOObjectiveType == MO_ObjectiveType.Radar && mo.OwnerArmy == 2 && !isMobile && mo.RadarEffectiveRadius > 9999 && !mo.ID.Contains("HQR") )
double angle = random.NextDouble() * 2 * Math.PI;
double y = Math.Sin(angle) * (5 * mo.TriggerDestroyRadius / 6) + mo.Pos.y;
ISectionFile f = GamePlay.gpCreateSectionFile();
f = Calcs.makeStatic(f, GamePlay, this, x, y, 0, "Stationary.Radar.Wotan_II", side: "de", resetCount: true);
/*
f = Calcs.makeStatic(f, GamePlay, this, x - 3.7, y + 4.5, mo.Pos.z, "Stationary.Environment.JerryCan_GER1_1", side: "de");
f = Calcs.makeStatic(f, GamePlay, this, x - 4.6, y - 4.6, mo.Pos.z, "Stationary. Environment.JerryCan_GER1_1", side: "de");
f = Calcs.makeStatic(f, GamePlay, this, x + 5.2, y - 5.6, mo.Pos.z, "Stationary.Environment.JerryCan_GER1_1", side: "de");
f = Calcs.makeStatic(f, GamePlay, this, x - 3.5, y + 3, mo.Pos.z, "Stationary.Weapons_.Bomb_B_SD-500_E", side: "de");
f = Calcs.makeStatic(f, GamePlay, this, x - 3.5, y - 4, mo.Pos.z, "Stationary.Weapons_.Bomb_B_SD-500_E", side: "de");
f = Calcs.makeStatic(f, GamePlay, this, x + 5, y - 4.5, mo.Pos.z, "Stationary.Weapons_.Bomb_B_SD-500_E", side: "de");
*/
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Initialize all objectives - update blue radars");
GamePlay.gpPostMissionLoad(f);
/*
ISectionFile f2 = GamePlay.gpCreateSectionFile();
f2 = Calcs.CreateBirthPlace(f2, mo.ID + "_airspawn", mo.Pos.x, mo.Pos.y, 666, mo.AttackingArmy);
GamePlay.gpPostMissionLoad(f2);
f2.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/" + mo.ID + "_airspawn.mis");
*/
Timeout(60, () =>
{
double numTargets = 0;
GroundStationary[] gs = GamePlay.gpGroundStationarys(mo.Pos.x, mo.Pos.y, mo.TriggerDestroyRadius);
if (gs != null) numTargets = gs.Length;
int targetsRequired = 2;
if (numTargets < targetsRequired) targetsRequired = Convert.ToInt32(numTargets);
mo.ObjectsRequiredToTrigger_num = targetsRequired;
Console.WriteLine("UPDATED BLUE RADAR {0} new radar angle {1} x,y: {2},{3} numTargets in radius {4}, num required: {5})", mo.Name, angle, x, y, numTargets, targetsRequired);
});
}
}
}
updateMobileConvoyPositionList();
Console.WriteLine("Starting Autoflak select location...");
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
MO_AutoFlak_selectLocations(mo);
}
ISectionFile autoFlakF = GamePlay.gpCreateSectionFile();
bool flResetCount = true;
Console.WriteLine("Starting to place Autoflak ...");
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (!mo.IsEnabled) continue;
if ((mo.AutoFlak || (mo.AutoFlakIfPrimary && mo.IsPrimaryTarget) || mo.numDefenseUnits()>4) && !mo.Destroyed) autoFlakF = MO_AutoFlakPlacement(mo, autoFlakF, flResetCount);
flResetCount = false;
}
Timeout(5, () => { GamePlay.gpPostMissionLoad(autoFlakF); if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Autoflak"); });
}
MissionObjectivesList = new Dictionary
{
Dictionary MissionObjectivesList_OLD = new Dictionary(MissionObjectivesList);
Console.WriteLine("#1" + (mission_objectives == null).ToString());
m_os.RadarPositionTriggersSetup();
Console.WriteLine("#2");
m_os.MissionObjectiveTriggersSetup();
m_os.LandingGroundTransferObjectives(MissionObjectivesList_OLD);
Console.WriteLine("#3");
Console.WriteLine("#4");
foreach (string ID in MissionObjectivesList.Keys)
{
if (!MissionObjectivesList_OLD.ContainsKey(ID)) continue;
MissionObjective mo = MissionObjectivesList[ID];
MissionObjective mo_old = MissionObjectivesList_OLD[ID];
mo_old.fixDestructionValues();
if (mo_old.Destroyed) Console.WriteLine("Destroyed: {0}", mo.Name);
mo.OwnerArmy = mo_old.OwnerArmy;
mo.Destroyed = mo_old.Destroyed;
mo.DestroyedPercent = mo_old.DestroyedPercent;
mo.ObjectiveAchievedForPoints = mo_old.ObjectiveAchievedForPoints;
mo.TimeToUndestroy_UTC = mo_old.TimeToUndestroy_UTC;
mo.LastHitTime_UTC = mo_old.LastHitTime_UTC;
mo.AirfieldDamagePoints = mo_old.AirfieldDamagePoints;
mo.DefenseUnits = mo_old.DefenseUnits;
if ((mo.DestroyedPercent > 0 || mo.Destroyed || mo.ObjectsDestroyed_num > 0 || mo.OrdnanceOnTarget_kg > 0 || mo.ActorsDestroyed_num > 0 || mo.AirfieldDamagePoints > 0)
&& !mo.LastHitTime_UTC.HasValue)
mo.LastHitTime_UTC = DateTime.UtcNow.AddHours(-random.Next(1, 5));
if (mo_old.PlayersWhoContributedNames != null) mo.PlayersWhoContributedNames = mo_old.PlayersWhoContributedNames;
if (mo_old.BirthplaceACTypes != null) mo.BirthplaceACTypes = mo_old.BirthplaceACTypes;
Console.WriteLine("updateMissionObjectivesListOnReload (mo.Pos, Mo.Scouted, mo_old.Scouted) pos | lastscoutedpos : {0:n0} {1:n0} {2:n0} | {3:n0} {4:n0} {5:n0} | {6:n0} {7:n0} {8:n0} {9} {10} {11}", mo.Pos.x, mo.Pos.y, mo.Pos.z, mo.lastScoutedPos.x, mo.lastScoutedPos.y, mo.lastScoutedPos.z, mo_old.lastScoutedPos.x, mo_old.lastScoutedPos.y, mo_old.lastScoutedPos.z, mo.lastScoutedSector, mo_old.lastScoutedSector, ID);
mo.Scouted = mo_old.Scouted;
if (mo.Scouted && !Calcs.Point3dEqual(mo_old.lastScoutedPos, new Point3d(0, 0, 0))) mo.lastScoutedPos = mo_old.lastScoutedPos;
if (mo.Scouted && mo_old.lastScoutedSector != null && mo_old.lastScoutedSector != "") mo.lastScoutedSector = mo_old.lastScoutedSector;
if (mo.Scouted && mo_old.PlayersWhoScoutedNames != null) mo.PlayersWhoScoutedNames = mo_old.PlayersWhoScoutedNames;
if (mo.Scouted && mo_old.numTimesScouted > 0) mo.numTimesScouted = mo_old.numTimesScouted;
if (mo.Scouted && mo_old.lastTimeScouted_dt.HasValue) mo.lastTimeScouted_dt = mo_old.lastTimeScouted_dt;
if (mo_old.PlayersWhoRepairedNamesTimes != null) mo.PlayersWhoRepairedNamesTimes = mo_old.PlayersWhoRepairedNamesTimes;
if (mo.MOMobileObjectiveType != null && mo.MOMobileObjectiveType != MO_MobileObjectiveType.None)
{
mo.Sector = mo_old.Sector;
mo.bigSector = mo_old.bigSector;
}
double zz = Calcs.LandElevation_m(mo.Pos);
mo.Pos = new Point3d(mo.Pos.x, mo.Pos.y, zz);
mo.OrdnanceOnTarget_kg = mo_old.OrdnanceOnTarget_kg;
mo.ObjectsDestroyed_num = mo_old.ObjectsDestroyed_num;
mo.ActorsDestroyed_num = mo_old.ActorsDestroyed_num;
mo.MobileNextMoveTime_dt = mo_old.MobileNextMoveTime_dt;
mo.fixDestructionValues();
}
Console.WriteLine("#5");
MO_CheckBirthPlacesRemoved();
Console.WriteLine("#6");
}
//Console.WriteLine("MLAPO " + mo.ID);
{
var list = new List() { };
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (mo.AttackingArmy == army && mo.IsPrimaryTarget && mo.IsEnabled)
{
list.Add(mo.ID);
}
}
return list;
}
No description available.
{
int numComplete = 0;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (mo.ObjectiveAchievedForPoints && mo.AttackingArmy == army && mo.IsPrimaryTarget && mo.IsEnabled)
{
numComplete++;
}
}
return numComplete;
}
int[] MO_numberprimaryobjectives = new int[3] { 0, 0, 0 };
if (MO_numberprimaryobjectives[army] > 0) return MO_numberprimaryobjectives[army]; //Once we have figured this out, >0, it won't change
{
int num = 0;
foreach (KeyValuePair entry in MissionObjectivesList)
{
MissionObjective mo = entry.Value;
if (mo.AttackingArmy == army && mo.IsPrimaryTarget && mo.IsEnabled)
{
num++;
}
}
MO_numberprimaryobjectives[army] = num;
return num;
}
No description available.
{
int npo = MO_NumberPrimaryObjectives(army);
if (npo == 0) return 0;
double x = MO_NumberPrimaryObjectivesComplete(army);
return (x / (double)npo * (double)100.0);
}
No description available.
{
int npo = MO_NumberPrimaryObjectives(army);
double x = MO_NumberPrimaryObjectivesComplete(army);
return (npo - x);
}
//Console.WriteLine("Checking scouts for " + winner); //Console.WriteLine("Checking scouts for " + mo.Name); sortedList.Sort((pair1, pair2) => pair1.Value.CompareTo(pair2.Value)); //This puts the Dict into a list & then sorts it by value, which is the order scouted. So we'll list first scouter first, second scouter 2nd, etc...
{
string output = "";
int army = 0;
if (winner == "Red") army = 1;
if (winner == "Blue") army = 2;
if (army == 0) return output;
var contribs = new HashSet();
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (mo.AttackingArmy != army) continue;
if (!mo.ObjectiveAchievedForPoints) continue;
if (mo.PlayersWhoScoutedNames == null || mo.PlayersWhoScoutedNames.Count < 1) continue;
var sortedList = mo.PlayersWhoScoutedNames.ToList();
output += " - " + mo.Name + ": ";
int count = 0;
foreach (KeyValuePair entry in sortedList)
{
string name = entry.Key;
if (count != 0) output += ", ";
output += name;
count++;
contribs.Add(name);
Console.WriteLine("Listing scouts, adding " + name);
}
output += "
" + Environment.NewLine;
}
if (contribs.Count > 0) output += "
" + Environment.NewLine + (contribs.Count).ToString("F0") + " players contributed to scouting objectives that contributed to this victory.
" + Environment.NewLine;
return output;
}
//Console.WriteLine("Checking repairers for " + winner); //Console.WriteLine("Checking scouts for " + mo.Name); //if (!mo.ObjectiveAchievedForPoints) continue; sortedList.Sort((pair1, pair2) => pair1.Value.CompareTo(pair2.Value)); //This puts the Dict into a list & then sorts it by value, which is the number of times repaired. So we'll list most repairs first, second most 2nd, etc...
{
string output = "";
int army = 0;
if (winner == "Red") army = 1;
if (winner == "Blue") army = 2;
if (army == 0) return output;
var contribs = new HashSet();
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (mo.OwnerArmy != army) continue;
if (mo.PlayersWhoRepairedNamesTimes == null || mo.PlayersWhoRepairedNamesTimes.Count < 1) continue;
var sortedList = mo.PlayersWhoRepairedNamesTimes.ToList();
output += " - " + mo.Name + ": ";
int count = 0;
foreach (KeyValuePair entry in sortedList)
{
string name = entry.Key;
if (count != 0) output += ", ";
output += name + string.Format(" ({0:N0} times)", entry.Value);
count++;
contribs.Add(name);
Console.WriteLine("Listing repairers, adding " + name);
}
output += "
" + Environment.NewLine;
}
if (contribs.Count > 0) output += "
" + Environment.NewLine + (contribs.Count).ToString("F0") + " players contributed to repairing objectives, contributing to this victory.
" + Environment.NewLine;
return output;
}
//testing //fuelReserveStrength = 0.39; //was 0.7 - 2022-07-31 //double newFuel = (double)minACfuel * 1.25; //GamePlay.gpHUDLogCenter(playersInPlane, "Low Fuel Reserves - Your Fuel Set by HQ!"); //Returns a # between 0 & 1 indicating the overall military strength/readiness for that army
{
try
{
int army = a.AirGroup().getArmy();
int minACfuel = a.GetMinimumFuelInPercent();
Player[] playersInPlane = this.playersInPlane(a as AiAircraft).ToArray();
double fuelReserveStrength = MO_CalculateMilitaryStrength((ArmiesE)army, MO_MilitaryStrengthType.Military_Fuel_Supply);
Console.WriteLine("MO_limitaircraftfuel working . . . army {0}, plane minFuel {1}, Army's Fuel Reserves {2:n0}, ac seats {3}, fuel requested {4}, is delivery: {5}", new object[] { army, minACfuel, fuelReserveStrength * 100, (a as AiCart).Places(), requestedFuel, isDelivery });
if (isDelivery)
{
double newFuel = (double)minACfuel * 1.15;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Pickup/delivery/ferry aircraft are allocated minimum fuel + 15%. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
twcLogServer(playersInPlane, ">>>Be sure to monitor your fuel consumption during the flight.", new object[] { newFuel });
return;
}
/*
if (fuelReserveStrength < 0.004)
{
a.RefuelPlane(minACfuel/5);
twcLogServer(playersInPlane, ">>>Due to critically low fuel reserves, HQ has limited fuel loads to below MINIMUM fuel. You're loaded at {0:n0}% fuel.", new object[] { minACfuel/5 });
GamePlay.gpHUDLogCenter(playersInPlane, "Critical Fuel Reserves - Your Fuel Limited Severely!");
}
else if (fuelReserveStrength < 0.05)
{
a.RefuelPlane(minACfuel/4);
twcLogServer(playersInPlane, ">>>Due to critically low fuel reserves, HQ has limited fuel loads to well below MINIMUM fuel. You're loaded at {0:n0}% fuel.", new object[] { minACfuel/4 });
GamePlay.gpHUDLogCenter(playersInPlane, "Critical Fuel Reserves - Your Fuel Limited to Severely!");
}
else if (fuelReserveStrength < 0.1)
{
a.RefuelPlane(minACfuel/3);
twcLogServer(playersInPlane, ">>>Due to critically low fuel reserves, HQ has limited fuel loads to well below the usual MINIMUM fuel. You're loaded at {0:n0}% fuel.", new object[] { minACfuel/3 });
GamePlay.gpHUDLogCenter(playersInPlane, "Critical Fuel Reserves - Your Fuel Limited Below Minimum!");
}
else if (fuelReserveStrength < 0.2)
{
a.RefuelPlane(2*minACfuel/3);
twcLogServer(playersInPlane, ">>>Due to critically low fuel reserves, HQ has limited fuel loads SEVERELY, below the usual minimum. You're loaded at {0:n0}% fuel.", new object[] { 2*minACfuel/3 });
GamePlay.gpHUDLogCenter(playersInPlane, "Critical Fuel Reserves - Your Fuel Limited Severely!");
}
else if (fuelReserveStrength < 0.4)
{
a.RefuelPlane(minACfuel);
twcLogServer(playersInPlane, ">>>Due to critically low fuel reserves, HQ has limited fuel loads to MINIMUM fuel. You're loaded at {0:n0}% fuel.", new object[] { minACfuel });
GamePlay.gpHUDLogCenter(playersInPlane, "Critical Fuel Reserves - Your Fuel Limited to Minimum!");
}
else if (fuelReserveStrength <= 0.5)
{
double newFuel = (double)minACfuel * 1.15;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Due to very low fuel reserves, HQ has set all aircraft fuel loads to MINIMUM fuel + 15%. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
GamePlay.gpHUDLogCenter(playersInPlane, "Very Low Fuel Reserves - Your Fuel Set by HQ!");
}
else if (fuelReserveStrength <= 0.6)
{
double newFuel = (double)minACfuel * 1.25;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Due to low fuel reserves, HQ has set all aircraft fuel loads to MINIMUM fuel + 25%. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
GamePlay.gpHUDLogCenter(playersInPlane, "Low Fuel Reserves - Your Fuel Set by HQ!");
}
else */
if (fuelReserveStrength <= 0.05)
{
double newFuel = (double)minACfuel * 0.6;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Due to low fuel reserves, HQ has set all aircraft fuel loads to just 60% of the previously enforced minimum level. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
twcLogServer(playersInPlane, ">>>Fly carefully and with fuel efficiency as you uppermost priority!", new object[] { });
GamePlay.gpHUDLogCenter(playersInPlane, "Very, VERY Low Fuel Reserves - Your Fuel Set by HQ!");
}
else if (fuelReserveStrength <= 0.125)
{
double newFuel = (double)minACfuel * 0.8;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Due to low fuel reserves, HQ has set all aircraft fuel loads to just 80% of the previously enforced minimum level. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
twcLogServer(playersInPlane, ">>>Fly carefully and with fuel efficiency as you uppermost priority!", new object[] { });
GamePlay.gpHUDLogCenter(playersInPlane, "Very Low Fuel Reserves - Your Fuel Set by HQ!");
}
else if (fuelReserveStrength <= 0.25 && (a as AiCart).Places() == 1)
{
double newFuel = (double)minACfuel * 1.25;
a.RefuelPlane((int)Math.Round(newFuel));
twcLogServer(playersInPlane, ">>>Due to low fuel reserves, HQ has set all single-seat aircraft fuel loads to MINIMUM fuel + 25%. You're loaded at {0:n0}% fuel.", new object[] { newFuel });
GamePlay.gpHUDLogCenter(playersInPlane, "Low Fuel Reserves - Your Fuel Set by HQ!");
}
else if (fuelReserveStrength <= 0.5 && (a as AiCart).Places() == 1)
{
a.RefuelPlane(80);
twcLogServer(playersInPlane, ">>Due to low fuel reserves, HQ has set all single-seat aircraft fuel loads to 80% capacity. You're loaded at 80% fuel.", new object[] {});
GamePlay.gpHUDLogCenter(playersInPlane, "Low Fuel Reserves - Your Fuel Set by HQ!");
} else if (requestedFuel != -1 & requestedFuel >= 0)
{
if (requestedFuel > 100) requestedFuel = 100;
a.RefuelPlane(requestedFuel);
twcLogServer(playersInPlane, ">>Fuel loaded at {0}%", new object[] {requestedFuel });
}
}
catch (Exception ex) { Console.WriteLine("MO_SetaircraftFuel ERROR: " + ex.ToString()); }
}
if (army == ArmiesE.None) return 1; //should never happen.... //var armies = new List
{
double total = 0;
double total_possible = 0;
foreach (MO_MilitaryStrengthType type in MO_objectivetype_by_strengthtype.Keys)
{
double res = MO_CalculateMilitaryStrength(army, type);
total += res;
total_possible += 1;
}
if (total_possible == 0) total_possible = 1;
return total/total_possible;
}
//MO_MilitaryStreng //MO_military
{
string ret = "";
var armies = new List { ArmiesE.Red, ArmiesE.Blue };
foreach (ArmiesE army in armies)
{
foreach (MO_MilitaryStrengthType type in MO_objectivetype_by_strengthtype.Keys)
{
double res = MO_CalculateMilitaryStrength(army, type);
MO_MilitaryStrengths[new Tuple(army, type)] = res;
ret += army.ToString() + " " + type.ToString().Replace('_',' ') + " is at " + (res * 100.0).ToString("n0") + "%";
ret += Environment.NewLine;
}
ret += Environment.NewLine;
}
return ret;
}
//MO_MilitaryStreng //MO_military //Returns the percent operational of the given army's objective types, for whichever type you request //Should be 0-100% (ie, values range 0-1); //return -1 indicates error some kind/ shouldn't ever happen
{
var armies = new List { ArmiesE.Red, ArmiesE.Blue };
foreach (ArmiesE army in armies)
{
foreach (MO_MilitaryStrengthType type in MO_objectivetype_by_strengthtype.Keys)
{
double res = MO_CalculateMilitaryStrength(army, type);
MO_MilitaryStrengths[new Tuple(army, type)] = res;
Console.WriteLine(army.ToString() + " strength for " + type.ToString() + " is " + (res*100.0).ToString("n0") + "%");
}
}
}
add_amt = 1; //We're saying each thing destroyed reduces the capability by 1%; but see adjustments below. if (mo.DestroyedPercent > 1) add_amt += (mo.DestroyedPercent - 1) / 5; //little bonus for extra destruction of targets else if (mo.DestroyedPercent > 0) add_amt = mo.DestroyedPercent/3; //Doesn't count as much if only partially destroyed //Whenever team stats is updated, we include a list of all objectives destroyed & which players contributed...
{
double output = 1;
double total = 0;
double good = 0;
double bad = 0;
if (!MO_objectivetype_by_strengthtype.ContainsKey(type)) return -1;
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if ((ArmiesE)mo.OwnerArmy != army) continue;
if (!MO_objectivetype_by_strengthtype[type].Contains(mo.MOObjectiveType)) continue;
double level = mo.Points;
total += level;
double add_amt = 0;
if (mo.Destroyed) {
}
bad += add_amt * level;
}
good = total - bad;
if (good < 0) good = 0;
if (total == 0) total = 1;
return good / total;
}
//ms += nl;
{
try
{
string nl = "
" + Environment.NewLine;
if (!html) nl = Environment.NewLine;
Tuple stl = showTimeLeft(player: null, showMessage: false, inGameTimeOnly: true);
string inGameTime = stl.Item1;
string ms = "On " + inGameTime + " " + ((ArmiesE)mo.AttackingArmy).ToString() + " destroyed " + mo.Name + nl;
int count = 0;
string output = "";
foreach (string name in mo.PlayersWhoContributedNames)
{
if (count != 0) output += ", ";
output += name;
count++;
}
if (count > 0)
{
ms += "Pilots who contributed: " + output + nl;
}
count = 0;
output = "";
foreach (string name in mo.PlayersWhoScoutedNames.Keys)
{
if (count != 0) output += ", ";
output += name;
if (mo.PlayersWhoScoutedNames[name] > 1) output += string.Format(" ({0:n0}X)", mo.PlayersWhoScoutedNames[name]);
count++;
}
if (count > 0)
{
ms += "Pilots who scouted this objective: " + output + nl;
}
count = 0;
output = "";
foreach (string name in mo.PlayersWhoRepairedNamesTimes.Keys)
{
if (count != 0) output += ", ";
output += name;
if (mo.PlayersWhoRepairedNamesTimes[name] >= 1) output += string.Format(" ({0:n0} loads)", mo.PlayersWhoRepairedNamesTimes[name]);
count++;
}
if (count > 0)
{
ms += ArmiesL[mo.OwnerArmy] + " pilots who repaired this objective: " + output + nl;
}
MissionObjectivesCompleteContributors_thisStatsPeriod[(ArmiesE)mo.AttackingArmy] += ms;
return ms;
}
catch (Exception ex) { Console.WriteLine("main MO_addPlayersWhoContributedforTeamStatsList_onObjectiveDestroyed ERROR: " + ex.ToString()); return ""; }
}
No description available.
{
if (!MissionObjectivesCompleteContributors_thisStatsPeriod.ContainsKey(army)) return "";
string ret = MissionObjectivesCompleteContributors_thisStatsPeriod[army];
if (clear) MissionObjectivesCompleteContributors_thisStatsPeriod[army] = "";
return ret;
}
//Autosends generic scores needed by all objective types. //Send the score as 1/kill - this figures if they need to be multiplied by 100 or not
{
string output = "";
int army = 0;
if (winner == "Red") army = 1;
if (winner == "Blue") army = 2;
if (army == 0) return output;
var contribs = new HashSet();
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (mo.AttackingArmy != army) continue;
if (!mo.Destroyed) continue;
if (mo.PlayersWhoContributedNames == null || mo.PlayersWhoContributedNames.Count == 0) continue;
output += " - " + mo.Name + ": ";
int count = 0;
foreach (string name in mo.PlayersWhoContributedNames)
{
if (count != 0) output += ", ";
output += name;
count++;
contribs.Add(name);
}
output += "
" + Environment.NewLine;
}
if (contribs.Count > 0) output += "
" + Environment.NewLine + (contribs.Count).ToString("F0") + " players contributed to destroying objectives that contributed to this victory.
" + Environment.NewLine;
return output;
}
/******************************************
* RELEVANT STATS CODES
*
COUNTS (ie, integer, 1=one victory):
647 Aircraft Kill Participation Count
648 Ground Objects(AAGuns, Artilleries and Tanks only) Kill Participation Count
649 Naval(All kinds of Ships, amphibians not included) Kill Participation Count
794 Ground Objects(All EXCEPT AAGuns, Artilleries and Tanks) Kill Participation Count
Below, the first of each set of 4 values if PERCENTAGE (ie, requires kills X 100, 100 = one victory)
and the 2nd, 3rd, 4th are COUNTS (ie, integer, 1=one victory)
ALL FOUR TYPES COMBINED/TOTALLED (Aerial, AA, Naval, Other Surface)
798 Total kill percentage (adds up percentage credit towards each completed kill for a grand total)
799 Number of Full Victories (>=75% of kill)
800 Number of Shared Victories (40-75% of kill)
801 Number of Assists (1-40% of kill)
AERIAL ONLY
802 Total kill percentage (adds up percentage credit towards each completed kill for a grand total)
803 Number of Full Victories (>=75% of kill)
804 Number of Shared Victories (40-75% of kill)
805 Number of Assists (1-40% of kill)
AA/Artillery/Tank ONLY
806 Total kill percentage (adds up percentage credit towards each completed kill for a grand total)
807 Number of Full Victories (>=75% of kill)
808 Number of Shared Victories (40-75% of kill)
809 Number of Assists (1-40% of kill)
NAVAL/SHIP ONLY
810 Total kill percentage (adds up percentage credit towards each completed kill for a grand total)
811 Number of Full Victories (>=75% of kill)
812 Number of Shared Victories (40-75% of kill)
813 Number of Assists (1-40% of kill)
OTHER GROUND ONLY
814 Total kill percentage (adds up percentage credit towards each completed kill for a grand total)
815 Number of Full Victories (>=75% of kill)
816 Number of Shared Victories (40-75% of kill)
817 Number of Assists (1-40% of kill)
*/
//798, 802, 806, 810, 814 are all PERCENTAGES meaning they must be the total saved = KILLS X 100 //799, 800, 801, 803, 804,805, 807, 808, 809, 811, 812, 813 are integers with each integer representing ONE KILL //647, 648, 649, 794 are ALSO integers List
try
{
int scoreX100_int = 0;
int score_int = 0;
try
{
scoreX100_int = Convert.ToInt32(Math.Round(score * 100.0));
}
catch { scoreX100_int = 0; Console.WriteLine(" Score was {0:n4} - conversion to scoreX100 INT failed, setting to 0", score); }
try
{
score_int = Convert.ToInt32(Math.Round(score));
}
catch { score_int = 0; Console.WriteLine(" Score was {0:n4} - conversion to score_int INT failed, setting to 0", score);
GamePlay.gpLogServer(new Player[] { player }, ">>>ERROR in RECORDING STATS POINTS (main mission - AddStatPoints - convert to int)!!!!! Please inform Flug.", null);
}
foreach (int id in ids)
{
if (percentageStatsCodesX100.Contains(id))
{
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddSessStat(player, id, scoreX100_int);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddToMissionStat(player, id, scoreX100_int);
}
else if (countStatsCodesX1.Contains(id))
{
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddSessStat(player, id, score_int);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddToMissionStat(player, id, score_int);
}
else
{
Console.WriteLine("ERROR in MO_AddStatPoints: One of the stats codes was not in X1 or X100, it is lost! Trying it as COUNTX1 type. Code: " + id.ToString("n0"));
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddSessStat(player, id, score_int);
if (TWCSaveIPlayerStat != null) TWCSaveIPlayerStat.StbSis_AddToMissionStat(player, id, score_int);
}
}
}
catch (Exception ex) { Console.WriteLine("MO_AddStatPoints ERROR: " + ex.ToString());
GamePlay.gpLogServer(new Player[] { player }, ">>>MAJOR ERROR in RECORDING STATS POINTS (main mission - AddStatPoints)!!!!! Please inform Flug.", null);
}
}
//798-799 all types combined (total) -806/807 AA/Artillery/Tanks, 810/811 Naval/ship, 814/815 Other //ground recon photos taken, 849 # of objectives photographed //Here we include the code #s for the specific type of kill (AA, naval, ground). The generic kill counting codes are included by MO_AddStatsPoints() //If the player isn't online we substitute in its place the 'stub' Player p1...
{
try
{
if (player == null) player = Calcs.PlayerFromName(this, name);
int army = 1;
if (mo != null)
{
if (isRepair) army = mo.OwnerArmy;
else army = mo.AttackingArmy;
}
if (player == null)
{
aPlayer p1 = new aPlayer(name, army);
player = p1 as Player;
}
if (objectiveType == MO_ObjectiveType.none && mo != null && mo.MOObjectiveType != null) objectiveType = mo.MOObjectiveType;
if (objectiveType == MO_ObjectiveType.Inflight_Aircraft)
{
HashSet scoreIDs = new HashSet { 802, 803, 647 };
MO_AddStatPoints(player, score, scoreIDs);
}
else if (objectiveType == MO_ObjectiveType.Artillery_and_AA
)
{
HashSet scoreIDs = new HashSet { 806, 807, 648 };
MO_AddStatPoints(player, score, scoreIDs);
}
else if (MO_Naval_Ship_ObjectiveTypes.Contains(objectiveType) || MO_Naval_Ship_ObjectiveTypes.Contains(objectiveType)
)
{
HashSet scoreIDs = new HashSet { 810, 811, 649 };
MO_AddStatPoints(player, score, scoreIDs);
}
else
/* covers these & a bunch more - all just classed as ground targets:
* (mo.MOObjectiveType == MO_ObjectiveType.GroundAircraft ||
mo.MOObjectiveType == MO_ObjectiveType.ArmyBase ||
mo.MOObjectiveType == MO_ObjectiveType.Dam ||
mo.MOObjectiveType == MO_ObjectiveType.Dock
)
*/
{
HashSet scoreIDs = new HashSet { 814, 815, 794 };
MO_AddStatPoints(player, score, scoreIDs);
}
}
catch (Exception ex) { Console.WriteLine("MO_AddPlayerStatsScoresForObjectiveDestructionOrRepair ERROR: " + ex.Message);
GamePlay.gpLogServer(new Player[] { player }, ">>>MAJOR ERROR in COVER REPAIR - STATS RECORDING (mainmission)!!!!! Please inform Flug.", null);
};
}
//Task.Run(() => //**add player stat points for any players who scouted/recon photo for this objective //It is max for first player to recon, then reduced by 50% for each succeeding player who also reconned it //mo.PlayersWhoScoutedNames[name] is the ORDER in which people scouted, ie 0 = t he first, 1 = the second, 2 = the third, etc. So that we can award points based on that...
{
{
try
{
if (GamePlay.gpRemotePlayers() != null) foreach (Player player in GamePlay.gpRemotePlayers())
{
if (player == null || player.Place() == null) continue;
if (OldObj.AttackingArmy == player.Army() &&
player.Place() != null &&
Calcs.CalculatePointDistance(player.Place().Pos(), OldObj.Pos) < 10000)
{
MO_AddPlayerStatsScoresForObjectiveDestructionOrRepair(player, player.Name(), OldObj, score);
OldObj.PlayersWhoContributedNames.Add(player.Name());
}
}
}
catch (Exception ex) { Console.WriteLine("MO_AddAllPlayersCredit ERROR: " + ex.Message); };
try
{
if (OldObj.PlayersWhoScoutedNames != null) foreach (string playerName in OldObj.PlayersWhoScoutedNames.Keys)
{
Console.WriteLine("stat points for players who scouted: {0:n3}, {1:n0}", score / Math.Pow(2.0, OldObj.PlayersWhoScoutedNames[playerName]), OldObj.PlayersWhoScoutedNames[playerName]);
MO_AddPlayerStatsScoresForObjectiveDestructionOrRepair(null, playerName, OldObj, score / Math.Pow(2.0, OldObj.PlayersWhoScoutedNames[playerName]));
}
}
catch (Exception ex) { Console.WriteLine("MO_AddAllPlayersCredit ERROR2: " + ex.Message); };
try
{
if (OldObj.PlayersWhoRepairedNamesTimes != null) foreach (string playerName in OldObj.PlayersWhoRepairedNamesTimes.Keys)
{
Console.WriteLine("stat points for players who repaired: {0:n0}, {1:n0}, {2:n5}", score, OldObj.PlayersWhoRepairedNamesTimes[playerName], OldObj.PlayersWhoRepairedNamesTimes[playerName] / (11.0 * 2.0));
}
}
catch (Exception ex) { Console.WriteLine("MO_AddAllPlayersCredit ERROR2: " + ex.Message); };
}
}
//temp bhugh XX2021-10: time to fix for everything is X5 to raise the stakes //temp bhugh XX2021-10: slowDownRepairFactor is also 5 & applies to other things that don't have timetofixfromnow set //2021-11 made it 7 instead of 5, slower yet //2021-11 made it 3 instead of 7, 7 seems to put everything more than a month to repair etc //2023-01 - putting it to 2 instead //2023-01-25 - putting it to 1.1. Still long but not TOO long...
{
try
{
double slowDownRepairFactor = 1.1;
timetofixFromNow_sec *= 1.1;
var OldObj = new MissionObjective(this);
if (!MissionObjectivesList.TryGetValue(ID, out OldObj))
{
return false;
}
if (fromTrigger && OldObj.MOTriggerType != MO_TriggerType.Trigger) return false;
OldObj.fixDestructionValues();
DateTime currTime_dt = DateTime.UtcNow;
double repairSpeedupFactor = 1;
if (MissionObjectivesTimes[(ArmiesE)OldObj.OwnerArmy].ContainsKey("RepairCrewEndTime_dt") && MissionObjectivesTimes[(ArmiesE)OldObj.OwnerArmy]["RepairCrewEndTime_dt"] > currTime_dt) repairSpeedupFactor = 4;
double defenseUnits_speedup = OldObj.defenseUnitsHelpFactor() - 1;
repairSpeedupFactor += defenseUnits_speedup;
if (OldObj.MOTriggerType == MO_TriggerType.Trigger && GamePlay.gpGetTrigger(ID) != null)
{
Console.WriteLine("MO_DestroyObjective: Disabling trigger " + ID);
GamePlay.gpGetTrigger(ID).Enable = false;
}
removeEnemyGroundActorsStationariesNearAnObjectiveInNeutralTerritory(OldObj);
if (OldObj.IsEnabled) {
if (percentdestroyed > 0) OldObj.DestroyedPercent = percentdestroyed;
if (AirfieldDamagePoints > 0) OldObj.AirfieldDamagePoints = AirfieldDamagePoints;
if (timetofixFromNow_sec > 0)
{
double mProductionStrength = MO_CalculateMilitaryStrength((ArmiesE)OldObj.OwnerArmy, MO_MilitaryStrengthType.General_Production_And_Supply);
double productionFactor = 1/Math.Sqrt( mProductionStrength/0.75);
if (productionFactor > 1.15) productionFactor = 1.15;
if (!OldObj.TimeToUndestroy_UTC.HasValue || OldObj.TimeToUndestroy_UTC.Value.CompareTo(DateTime.UtcNow) < 0) {
OldObj.TimeToUndestroy_UTC = DateTime.UtcNow.AddSeconds(timetofixFromNow_sec*productionFactor);
} else
{
OldObj.TimeToUndestroy_UTC = OldObj.TimeToUndestroy_UTC.Value.AddSeconds(timetofixFromNow_sec * productionFactor / 2 );
}
}
OldObj.LastHitTime_UTC = DateTime.UtcNow;
}
bool alreadyCounted = false;
bool alreadyDestroyed = false;
Console.WriteLine(" MO_DestroyObjective1: {0} {1} {2} {3}", ID, alreadyCounted, alreadyDestroyed, percentSpecified);
OldObj.Destroyed = true;
OldObj.ObjectiveAchievedForPoints = true;
if (OldObj.MOObjectiveType == MO_ObjectiveType.Radar || OldObj.MOObjectiveType == MO_ObjectiveType.KnickebeinHQ)
{
if (OldObj.OwnerArmy == 1) DestroyedRadar[(ArmiesE.Red)].Add(OldObj);
if (OldObj.OwnerArmy == 2) DestroyedRadar[(ArmiesE.Blue)].Add(OldObj);
if (!alreadyDestroyed)
{
OldObj.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(OldObj.TimetoRepairIfDestroyed_hr * slowDownRepairFactor / repairSpeedupFactor);
else OldObj.DestroyedPercent = 1;
}
else
{
double reduction_factor = (1.5 + OldObj.DestroyedPercent * OldObj.DestroyedPercent);
}
} else
{
if (!alreadyDestroyed)
{
OldObj.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(OldObj.TimetoRepairIfDestroyed_hr * slowDownRepairFactor / repairSpeedupFactor );
else OldObj.DestroyedPercent = 1;
Console.WriteLine(" MO_DestroyObjective1: not already destroyed");
}
else
{
Console.WriteLine(" MO_DestroyObjective1: already destroyed");
}
}
if (!alreadyCounted)
{
double add_points = OldObj.Points;
if (alreadyDestroyed)
{
double reduct_factor = OldObj.DestroyedPercent;
if (reduct_factor < 1.5) reduct_factor = 1.5;
add_points = OldObj.Points / (reduct_factor * reduct_factor);
}
Console.WriteLine(" MO_DestroyObjective1: not already counted");
if (OldObj.AttackingArmy == 1)
{
MissionObjectivesCompletedString[ArmiesE.Red] += " - " + OldObj.Name;
Console.WriteLine("MO_DestroyObjective: Name " + OldObj.Name);
Console.WriteLine("MO_DestroyObjective: String " + MissionObjectivesCompletedString[ArmiesE.Red]);
MissionObjectiveScore[ArmiesE.Red] += add_points;
}
if (OldObj.AttackingArmy == 2)
{
MissionObjectivesCompletedString[ArmiesE.Blue] += " - " + OldObj.Name;
Console.WriteLine("MO_DestroyObjective: Name " + OldObj.Name);
Console.WriteLine("MO_DestroyObjective: String " + MissionObjectivesCompletedString[ArmiesE.Blue]);
MissionObjectiveScore[ArmiesE.Blue] += add_points;
}
}
{
Console.WriteLine(" MO_DestroyObjective1: already counted");
if (OldObj.AttackingArmy == 1)
{
if (!MissionObjectivesCompletedString[ArmiesE.Red].Contains(OldObj.Name))
{
MissionObjectivesCompletedString[ArmiesE.Red] += " - " + OldObj.Name;
}
}
if (OldObj.AttackingArmy == 2)
{
if (!MissionObjectivesCompletedString[ArmiesE.Blue].Contains(OldObj.Name))
{
MissionObjectivesCompletedString[ArmiesE.Blue] += " - " + OldObj.Name;
}
}
if (!alreadyDestroyed)
{
Console.WriteLine(" MO_DestroyObjective1: already counted, not already destroyed (ie, probably destroyed earlier but now repaired");
double percCount = OldObj.DestroyedPercent;
if (percentSpecified)
else
MissionObjectiveScore[(ArmiesE)OldObj.AttackingArmy] += OldObj.Points / 4;
}
else
{
Console.WriteLine(" MO_DestroyObjective1: already counted, already destroyed");
double pointsToAdd = 0;
double percCount = percentdestroyed;
double scale_fact = Math.Pow(Math.Abs(OldObj.DestroyedPercent), 0.6);
if (scale_fact < 1.5) scale_fact = 1.5;
if (scale_fact > 5) scale_fact = 5;
else pointsToAdd = OldObj.Points / scale_fact;
MissionObjectiveScore[(ArmiesE)OldObj.AttackingArmy] += pointsToAdd;
}
}
string pom = "";
if (OldObj.IsPrimaryTarget && !alreadyCounted) pom = "Primary objective! ";
string mes = ArmiesL[OldObj.AttackingArmy] + " destroyed " + OldObj.Name;
if (OldObj.HUDMessage != null && OldObj.HUDMessage.Length > 0) mes = OldObj.HUDMessage;
if (( alreadyCounted || alreadyDestroyed) && OldObj.MOTriggerType != MO_TriggerType.TemporaryLandingGround) mes = ArmiesL[OldObj.AttackingArmy] + " damaged " + OldObj.Name;
Timeout(messageDelay_sec, () =>
{
GamePlay.gpHUDLogCenter(mes);
});
string mes1 = "";
if (OldObj.LOGMessage != null && OldObj.LOGMessage.Length > 0) mes1 = OldObj.LOGMessage;
if ((alreadyCounted || alreadyDestroyed) && OldObj.MOTriggerType != MO_TriggerType.TemporaryLandingGround) mes1 = ArmiesL[OldObj.AttackingArmy] + " has further damaged " + OldObj.Name;
Timeout(messageDelay_sec, () =>
{
twcLogServer(null, mes1, new object[] { });
twcLogServer(null, pom + "All involved have received commendations and promotions.", new object[] { });
});
List mos = new List();
try
{
}
catch (Exception ex) { Console.WriteLine("MO_Destroy error 3.5 - listsuggestedobjectives: " + ex.Message); };
if (alreadyDestroyed) score = score / 2;
if (OldObj.IsPrimaryTarget && !alreadyCounted) score *= 3;
MO_AddAllPlayersStatAndContributedScoredForObjectiveDamageDestruction(OldObj, score);
MO_addPlayersWhoContributedforTeamStatsList_onObjectiveDestroyed(OldObj, html: true, display: false);
MO_CheckObjectivesComplete();
MO_RemoveObjective(OldObj);
string smoke = "BuildingFireSmall";
Calcs.loadSmokeOrFire(GamePlay, this, OldObj.Pos.x, OldObj.Pos.y, 0, smoke, duration_s: 6 * 3600);
return true;
}
catch (Exception ex) { Console.WriteLine("MO_Destroy error4: " + ex.Message); return true; };
}
//OldObj = new MissionObjective(msn); //Add the extra time/destruction percent and/or update the time when the object will be undestroyed //If we hit 200% destroyed it can count as a mission objective destroyed, again, for points. if (!OldObj.ObjectiveAchievedForPoints && AirfieldDamagePointsAdded > 0) //if it is an airfield & we have passed another 100% - 200% - 300%-etc type threshold & it is not counted as an objective for scoring, we can count it
DateTime? TimeLastHit_UTC = null, double AirfieldDamagePoints = 0, double AirfieldDamagePointsAdded = 0, double messageDelay_sec = 0)
{
try
{
var OldObj = new MissionObjective(this);
if (!MissionObjectivesList.TryGetValue(ID, out OldObj))
{
return false;
}
OldObj.fixDestructionValues();
if (OldObj.IsEnabled)
{
if (!OldObj.ObjectiveAchievedForPoints && percentdestroyed >= 2.0)
{
MO_DestroyObjective(ID, true, percentdestroyed, timetofixFromNow_sec, TimetoUndestroy_UTC);
return true;
}
{
int roundnd = Convert.ToInt32(Math.Floor(AirfieldDamagePoints));
int roundod = Convert.ToInt32(Math.Floor(AirfieldDamagePoints - AirfieldDamagePointsAdded));
if (roundnd > roundod) MO_DestroyObjective(ID, true, percentdestroyed, timetofixFromNow_sec, TimetoUndestroy_UTC, AirfieldDamagePoints: AirfieldDamagePoints, messageDelay_sec: messageDelay_sec);
return true;
}
if (percentdestroyed > 0) OldObj.DestroyedPercent = percentdestroyed;
if (timetofixFromNow_sec > 0) OldObj.TimeToUndestroy_UTC = DateTime.UtcNow.AddSeconds(timetofixFromNow_sec);
if (TimetoUndestroy_UTC.HasValue) OldObj.TimeToUndestroy_UTC = TimetoUndestroy_UTC.Value;
if (TimeLastHit_UTC.HasValue) OldObj.LastHitTime_UTC = TimeLastHit_UTC.Value;
else OldObj.LastHitTime_UTC = DateTime.UtcNow;
if (AirfieldDamagePoints > 0) OldObj.AirfieldDamagePoints = AirfieldDamagePoints;
}
OldObj.fixDestructionValues();
return true;
}
catch (Exception ex) { Console.WriteLine("MO_Destroy_addTime ERROR: " + ex.Message); return true; }
}
//Task.Run(() => //If it doesn't have a spawnpoint, we give it one. Even if it didn't have one before...
{
{
if (percentToRestore >= 100)
{
double dist_m = Calcs.distanceToNearestBirthplace(GamePlay, mo.Pos, mo.OwnerArmy);
Console.WriteLine("RestoreAirfield: Checking distance from {0}: {1} ({2:F0},{3:F0})", mo.Name, dist_m, mo.Pos.x, mo.Pos.y);
if (dist_m > 2300)
{
Timeout(30, () =>
{
ISectionFile f2 = GamePlay.gpCreateSectionFile();
int maxLen = 20;
if (ID.Length < 20) maxLen = ID.Length;
string bname = (ID.Substring(0, maxLen) + " " + random.Next(10, 99).ToString("F0")).Replace(" ", "_");
f2 = Calcs.CreateBirthPlace(f2, bname, Pos.x, Pos.y, 0, OwnerArmy);
if (ON_TESTSERVER) Console.WriteLine("PostmissionLoad: Restore airfield");
GamePlay.gpPostMissionLoad(f2);
f2.save(CLOD_PATH + FILE_PATH + "/sectionfiles" + "/" + bname + ".mis");
});
}
MO_MissionObjectiveAirfieldsArmyReset(this, GamePlay, OwnerArmy, apID: ID);
}
removeSmokeFireCraters(Pos, radius, percentToRestore);
Console.WriteLine("Removing craters from: " + Name);
}
}
//if (OwnerArmy < 1 || OwnerArmy > 2) return;//can't do anything . ...
{
}
*/
private bool MO_ObjectiveUndestroy_recurs_firstrun = true;
public System.Threading.Timer MO_ObjectiveUndestroyTimer;
dueTime: 80000, //wait time @ startup, milliseconds period: 506353); //periodically call the callback at this interval, every 506 seconds //Undestroys & also checks up on any mobile objective moves needed.
{
Console.WriteLine("MO_ObjectiveUndestroyTimer_recurs() start at " + DateTime.UtcNow.ToString("T"));
MO_ObjectiveUndestroyTimer = new System.Threading.Timer(
new TimerCallback(MO_ObjectiveUndestroy),
null,
}
//Timeout(316.3, () => { MO_ObjectiveUndestroy_recurs(); }); //Task.Run( ()=> if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MMOXX1 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //For objectives with 'chiefs'/groundactors, check whether any of them need to be refreshed if (restartChief_log.ContainsKey(mo) && currTime_dt.Subtract(restartChief_log[mo]).TotalSeconds >= 600) //only run this once every 10 minutes at most //This also coordinates with restartChiefIfAllDead, so neither will run too often on a single objective if ((mo.Destroyed && mo.TimeToUndestroy_UTC.HasValue && mo.TimeToUndestroy_UTC.Value.CompareTo(currTime_UTC) < 0) //it's time to undestroy || (mo.Destroyed && !mo.TimeToUndestroy_UTC.HasValue && MO_ObjectiveUndestroy_recurs_firstrun)) //it's destroyed but no time to undestroy has been set. Undestroy it on first run of the session; not sure what else to do...
{
{
Console.WriteLine("MO_ObjectiveUndestroy running to check for any objectives that should be returned to service");
Timeout(94.2341, () => { MO_DisplayGeneralStaffIntelligenceLeaks(); });
DateTime currTime_UTC = DateTime.UtcNow;
List molk = new List(MissionObjectivesList.Keys.ToList());
int numUndestroyed = 0;
foreach (string ID in molk)
{
MissionObjective mo = MissionObjectivesList[ID];
MO_HandleMobileObjectivePlacement(mo, startup: false);
Timeout(84 + random.Next(360), () => {
DateTime currTime_dt = DateTime.UtcNow;
{
restartChief_log[mo] = currTime_dt;
if (mo.hasChief() && mo.hasChiefGroundactorsButTheyAreDeadOrDestroyed()) mo.loadInitSubmission();
mo.reloadMobileObjectiveChiefs();
}
});
{
numUndestroyed++;
string time = "No value";
if (mo.TimeToUndestroy_UTC.HasValue) time = mo.TimeToUndestroy_UTC.ToString();
Console.WriteLine("Undestroying: {0} {1} {2:F0} {3} ", mo.Name, mo.Destroyed, mo.DestroyedPercent * 100.0, time);
mo.Destroyed = false;
mo.DestroyedPercent = 0;
mo.TimeToUndestroy_UTC = null;
mo.LastHitTime_UTC = null;
mo.ObjectsDestroyed_num = 0;
mo.OrdnanceOnTarget_kg = 0;
mo.ActorsDestroyed_num = 0;
mo.AirfieldDamagePoints = 0;
double addTime_s = 0;
if (!MO_ObjectiveUndestroy_recurs_firstrun) addTime_s = 11.2341 + numUndestroyed * 40 + random.Next(20);
Timeout(addTime_s, () =>
{
if (mo.MOObjectiveType == MO_ObjectiveType.Military_Airfield) restoreAirfield(mo);
if (mo.MOObjectiveType == MO_ObjectiveType.Radar || mo.MOObjectiveType == MO_ObjectiveType.KnickebeinHQ) restoreRadar(mo);
});
twcLogServer(null, mo.Name + " has been repaired and returned to service.");
time = "No value";
if (mo.TimeToUndestroy_UTC.HasValue) time = mo.TimeToUndestroy_UTC.ToString();
Console.WriteLine("Undestroying after: {0} {1} {2:F0} {3} ", mo.Name, mo.Destroyed, mo.DestroyedPercent * 100.0, time);
}
if (mo.Destroyed && mo.MOObjectiveType == MO_ObjectiveType.Military_Airfield &&
mo.TimeToUndestroy_UTC.HasValue && mo.TimeToUndestroy_UTC.Value.CompareTo(currTime_UTC.AddHours(2)) < 0) {
}
}
MO_ObjectiveUndestroy_recurs_firstrun = false;
}
}
//Turn the map by completing ALL primary objectives //OR most primary objectives (greater than specified percentage) plus reaching the higher point level required in that situation || TestingOverrideArmy == 2)// Blue battle Success //WriteResults_Out_File("2"); //EndMission(70, "Blue"); || TestingOverrideArmy == 1)// Red battle Success //WriteResults_Out_File("1"); //EndMission(70, "Red"); //Console.WriteLine("Figuring leaks: {0} {1} {2} {3}", MissionObjectiveScore[ArmiesE.Red], MO_PointsRequired[ArmiesE.Red], bp, MO_PrimaryObjectivesRemaining( (int)ArmiesE.Red)); //Console.WriteLine("Figuring Leaks: " + MO_IntelligenceLeakNearMissionEnd[ArmiesE.Blue] + " " + MO_IntelligenceLeakNearMissionEnd[ArmiesE.Red]); //This is where all the bumrush code goes in the Tobruk campaign. //So inland, on home soil, both sides used observation networks to locate enemy aircraft & activity
{
double bp = MO_PercentPrimaryObjectives((int)ArmiesE.Blue);
if ((MissionObjectiveScore[ArmiesE.Blue] >= MO_PointsRequired[ArmiesE.Blue] && bp > 99)
|| bp >= MO_PercentPrimaryTargetsRequired[ArmiesE.Blue] && MissionObjectiveScore[ArmiesE.Blue] >= MO_PointsRequiredWithMissingPrimary[ArmiesE.Blue]
|| MissionObjectiveScore[ArmiesE.Blue] >= MO_PointsRequiredWithNoPrimary[ArmiesE.Blue]
{
Task.Run(() => WriteResults_Out_File("2"));
Timeout(10, () =>
{
twcLogServer(null, "Blue has Successfully Turned the Map!!!", new object[] { });
GamePlay.gpHUDLogCenter("Blue has Successfully Turned the Map!!!");
});
MO_MissionObjectiveRollingWinnerHandler(ArmiesE.Blue);
}
double rp = MO_PercentPrimaryObjectives((int)ArmiesE.Red);
if ((MissionObjectiveScore[ArmiesE.Red] >= MO_PointsRequired[ArmiesE.Red] && rp > 99)
|| rp >= MO_PercentPrimaryTargetsRequired[ArmiesE.Red] && MissionObjectiveScore[ArmiesE.Red] >= MO_PointsRequiredWithMissingPrimary[ArmiesE.Red]
|| MissionObjectiveScore[ArmiesE.Red] >= MO_PointsRequiredWithNoPrimary[ArmiesE.Red]
{
Task.Run(() => WriteResults_Out_File("1"));
Timeout(10, () =>
{
twcLogServer(null, "Red has completed all objectives and won the battle!!!", new object[] { });
GamePlay.gpHUDLogCenter("Red has Won the Battle!!!");
});
MO_MissionObjectiveRollingWinnerHandler(ArmiesE.Red);
}
if (MO_PrimaryObjectivesRemaining((int)ArmiesE.Red) <= 3)
{
MO_IntelligenceLeakNearMissionEnd[ArmiesE.Blue] = "Intelligence sources indicate the enemy may be attacking sector " + MO_SectorOfRandomRemainingPrimaryObjective((int)ArmiesE.Red) + " soon";
}
else if (MO_PrimaryObjectivesRemaining((int)ArmiesE.Red) <= 3)
{
MO_IntelligenceLeakNearMissionEnd[ArmiesE.Red] = "Intelligence sources indicate the enemy may be attacking sector " + MO_SectorOfRandomRemainingPrimaryObjective((int)ArmiesE.Blue) + " soon"; ;
}
}
/* START BUMRUSH STUFF*/
/* END BUMRUSH STUFF */
if (terr != attackingArmy) return false; //On enemy territory you never have an observer network if (landType == maddox.game.LandTypes.WATER) return false; // no observation network on water if (pos.z > 4000) chanceOfMissing += 66 * (pos.z - 4000) / 8000; //so chance of seeing becomes less starting at 4000m & down to zero at 8000m = 27000-ish ft. if (pos.z < 500) chanceOfMissing += 66* (500-pos.z)/400; //so chance of seeing becomes less if under 500m...
{
if (GamePlay == null) return false;
if (attackingArmy != 1 && attackingArmy != 2) return false;
int terr = GamePlay.gpFrontArmy(pos.x, pos.y);
maddox.game.LandTypes landType = GamePlay.gpLandType(pos.x, pos.y);
double chanceOfMissing = 33;
return true;
}
//So we take 2 circles starting at the radar location and moving towards heading 315 for Blue radars & 135 for Red radars //this works pretty well for the Channel map. //Console.WriteLine(value.Name + " " + army.ToString() + " " + dist.ToString("F0") + " " + value.RadarEffectiveRadius.ToString("F0") + " " + p.x.ToString("F0") + " " + p.y.ToString("F0") + " " + value.Pos.x.ToString("F0") + " " + value.Pos.y.ToString("F0"));
{
var DR = new List();
if (army == 1 || army == 2) DR = DestroyedRadar[(ArmiesE)army];
else return false;
foreach (MissionObjective value in DR)
{
for (int i = 0; i < 2; i++) {
double xadd = (double)i * value.RadarEffectiveRadius;
double yadd = -(double)i * value.RadarEffectiveRadius;
if (army == 2) {
xadd = -(double)i * value.RadarEffectiveRadius;
yadd = (double)i * value.RadarEffectiveRadius;
}
Point3d calcPos = new Point3d(value.Pos.x + xadd, value.Pos.y + yadd, p.z);
double dist = Calcs.CalculatePointDistance(p, calcPos);
if (dist < value.RadarEffectiveRadius) return true;
}
}
return false;
}
//Console.WriteLine(value.Name + " " + army.ToString() + " " + dist.ToString("F0") + " " + value.RadarEffectiveRadius.ToString("F0") + " " + p.x.ToString("F0") + " " + p.y.ToString("F0") + " " + value.Pos.x.ToString("F0") + " " + value.Pos.y.ToString("F0")); //TOBRUK - radar coverage is based on distance from nearest objective //This provides the distance to the nearest objective of the army given
{
var DR = new List();
if (army == 1 || army == 2) DR = DestroyedRadar[(ArmiesE)army];
else return false;
foreach (MissionObjective value in DR)
{
Point3d calcPos = new Point3d(value.Pos.x, value.Pos.y, p.z);
double dist = Calcs.CalculatePointDistance(p, calcPos);
if (dist < value.RadarEffectiveRadius) return true;
}
return false;
}
No description available.
{
double closestDist_m = 1000000;
bool first = true;
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (!mo.IsEnabled || mo.OwnerArmy != army || mo.Destroyed) continue;
double dist_m = Calcs.CalculatePointDistance(p, mo.returnCurrentPosWithChief());
if (first || dist_m< closestDist_m) { first = false; closestDist_m = dist_m; }
}
return closestDist_m;
}
//things that are just out of range of our mobile radar units if (dist_m > 145000) return false; //Basing this in Freya, service range 130km https://en.wikipedia.org/wiki/Radar_in_World_War_II#Transportable_Radio_Unit if (dist_m > 120000 && random.Next(25000) < (dist_m - 120000)) return false; //Phases in gradually 120000-145000 //OK< we don't have to worry about the "close to the ground/radar clutter" aspect because that is all covered by the belowRadar routine. //This routine just answers the question, is this objective in an area where radar coverage is possible...
{
try
{
if (admin || radarArmy == 0 || radarArmy > 2) return true;
if (mission_objectives == null) { Console.WriteLine("#1.51 Mission Objectives really doesn't exist!"); return true; }
if (MO_IsPointInDestroyedRadarArea_TOBRUK(pos, radarArmy)) return false;
double dist_m = MO_DistanceFromNearestRadarUnit(pos, radarArmy);
/*
double elev_m = Calcs.LandElevation_m(pos);
*/
double minHeight_m = MO_minHeightForRadarDetection(dist_m);
return true;
}
catch (Exception ex) { Console.WriteLine("MO_isRadarEnabledByArea_TOBRUK ERROR: "+ex.ToString()); return true; }
}
//Console.WriteLine("#1 " + pos.x.ToString() + " " + pos.y.ToString() + " " + radarArmy.ToString()); //WITHIN AN AREA WHERE THE RADAR HAS BEEN DESTROYED? //Finds if the point/ac is in an area with destroyed radar for either/both sides //if (mission_objectives != null) { if (MO_IsPointInDestroyedRadarArea(pos, radarArmy)) return false; } //else Console.WriteLine("#1.5111 Mission Objectives doesn't exist!!!!!"); if (MO_IsPointInHomeSoilObservationArea(pos, radarArmy)) return true; //So if it is on home ground & detected by the observer network, then it is on the charts //if (mission_objectives == null) Console.WriteLine("#1.52 Mission Objectives really doesn't exist!"); //Console.WriteLine("#2.123 " + pos.x.ToString() + " " + radarArmy.ToString()); //RED army areas where radar horizon is in effect //We just draw some simple lines to determine areas inside the radar horizon (generally, close enough to radar towers or on friendly territory where observer networks apply) //On the far side of those lines we apply the formula for lowest altitude a radar station can see, beyond it's radar horizon, depending on distance from the tower if (pos.x <= 170000) //for the portion of the map where x< 170000 (the westernmost part) we just draw a straight line across at y=130000 and count the distance from there if (pos.y >= 145000) return true; //This is within the radar horizon, so we're just ignoring it here. double dist_m = 145000 - pos.y; //we count the line y=145 000 as the radar horizon; the radar horizon is ~ 45km from the radar device...
{
if (admin || radarArmy == 0 || radarArmy > 2) return true;
if (mission_objectives == null) Console.WriteLine("Radar Out by Area #1.51: Mission Objectives really doesn't exist!");
else {
if (MO_IsPointInDestroyedRadarArea(pos, radarArmy)) return false;
}
if (radarArmy == 1)
{
{
double minHeight_m = MO_minHeightForRadarDetection(dist_m + 45000);
if (pos.z < minHeight_m) return false;
else return true;
}
{
Point2d p2 = new Point2d(295347, 220011);
double dist_m = Calcs.PointToLineDistance(p1, p2, pos);
double minHeight_m = MO_minHeightForRadarDetection(dist_m + 45000);
}
}
else if (radarArmy == 2)
{
{
double minHeight_m = MO_minHeightForRadarDetection(dist_m + 45000);
if (pos.z < minHeight_m) return false;
else return true;
{
Point2d p1 = new Point2d(227132, 243249);
Point2d p2 = new Point2d(170000, 130000);
double dist_m = Calcs.PointToLineDistance(p1, p2, pos);
double minHeight_m = MO_minHeightForRadarDetection(dist_m + 45000);
}
/*
if (pos.x > 170000 && pos.x <= 190000)
{
if ((pos.x - 170000) / 80000 * 42000 + 250000 < pos.y) return false;
}
if (pos.x > 8000 && pos.x <= 170000)
{
if ((pos.x - 8000) / 162000 * 14000 + 236000 < pos.y) return false;
}
return true;
*/
}
return true;
}
public static double RADAR_RADIUS_OF_EARTH_m = 8494666.667;
No description available.
{
return Math.Pow((distance_m - Math.Sqrt(2 * radarHeight_m * RADAR_RADIUS_OF_EARTH_m)), 2) / 2 / RADAR_RADIUS_OF_EARTH_m;
}
double days = Math.Ceiling((mo.TimeToUndestroy_UTC.Value.Subtract(DateTime.UtcNow)).TotalDays * 2.0) / 2.0; //round to the half day returnmsg = ""; //In case of display == false we just don't return any message at all, allowing this bit to simply be omitted
{
try
{
int count = 0;
string returnmsg = "";
double delay = 0.1;
var DR = new List();
List armies;
if (army == 1) armies = new List() { 1 };
else if (army == 2) armies = new List() { 2 };
else armies = new List() { 1, 2 };
foreach (int a in armies)
{
DR = DestroyedRadar[(ArmiesE)a];
foreach (MissionObjective mo in DR)
{
string msg2 = " (unknown)";
int ndf = mo.numDefenseUnits();
string ndfmsg = null;
if (ndf > 0) ndfmsg = String.Format("{0} DUs, {1:f1}X", ndf, mo.defenseUnitsHelpFactor());
if (mo.TimeToUndestroy_UTC.HasValue)
{
string strnmsg = String.Format("({0:f0}K, ", mo.RadarEffectiveRadius / 1000);
msg2 = strnmsg + days.ToString("F1") + " days";
if (ndfmsg == null) msg2 += ")";
else msg2 += "; " + ndfmsg + ")";
}
else if (ndfmsg != null) msg2 = "(" + ndfmsg + ")";
string sect = " (" + mo.Sector + ") ";
if (forEnemy) sect = " ";
string msg = mo.Name + sect + "destroyed " + msg2;
if (!mo.IsEnabled) msg += " (HQ has currently withdrawn this radar from use)";
returnmsg += msg + "\n";
if (display)
{
delay += 0.02;
if (count % 10 == 0) delay += 3.5;
Timeout(delay, () => { twcLogServer(new Player[] { player }, msg, new object[] { }); });
}
count++;
}
}
if (count == 0)
{
string msg = "No radar currently damaged or destroyed";
if (display) twcLogServer(new Player[] { player }, msg, new object[] { });
}
return returnmsg;
}
catch (Exception ex) { Console.WriteLine("MO_RadarList Error: " + ex.ToString()); return ""; };
}
if (mo.TimeToUndestroy_UTC.HasValue && mo.Destroyed) //time to undestroy is MEANINGLESS unless it is actually .Destroyed == true double days = Math.Ceiling((mo.TimeToUndestroy_UTC.Value.Subtract(DateTime.UtcNow)).TotalDays * 2.0) / 2.0; //round to the half day returnmsg = ""; //In case of display == false we just don't return any message at all, allowing this bit to simply be omitted
{
try
{
int count = 0;
string returnmsg = "";
double delay = 0.05;
List armies;
if (army == 1) armies = new List() { 1 };
else if (army == 2) armies = new List() { 2 };
else armies = new List() { 1, 2 };
foreach (int a in armies)
{
foreach (MissionObjective mo in MissionObjectivesList.Values)
{
if (mo.OwnerArmy != a) continue;
if (!all && mo.DestroyedPercent == 0 && !mo.Destroyed) continue;
if (!includeAirports && mo.MOObjectiveType == MO_ObjectiveType.Military_Airfield) continue;
if (!includeRadar && (mo.MOObjectiveType == MO_ObjectiveType.Radar || mo.MOObjectiveType == MO_ObjectiveType.KnickebeinHQ)) continue;
int ndf = mo.numDefenseUnits();
string ndfmsg = null;
if (ndf > 0) ndfmsg = String.Format("{0} DUs, {1:f1}X", ndf, mo.defenseUnitsHelpFactor());
string msg2 = "";
{
msg2 = "(" + days.ToString("F1") + " days";
if (ndfmsg == null) msg2 += ")";
else msg2 += "; " + ndfmsg + ")";
}
else if (ndfmsg!= null) msg2 = "(" + ndfmsg + ")";
string msg = mo.Name;
string sect = " (" + mo.Sector + ") ";
if (forEnemy) sect = " ";
if (mo.Destroyed || mo.DestroyedPercent >= 1) msg += sect + "destroyed " + msg2;
else msg += sect + string.Format("{0:n0}% " + msg2, Math.Floor(mo.DestroyedPercent * 100.0));
if (!mo.IsEnabled) msg += " (HQ has currently withdrawn this facility from use)";
returnmsg += msg + "\n";
if (display)
{
delay += 0.02;
if (count % 10 == 0) delay += 3.5;
Timeout(delay, () => { twcLogServer(new Player[] { player }, msg, new object[] { }); });
}
count++;
}
}
if (count == 0)
{
string msg = "None of these objectives currently damaged or destroyed";
if (display) twcLogServer(new Player[] { player }, msg, new object[] { });
}
return returnmsg;
}
catch (Exception ex) { Console.WriteLine("MO_ObjectiveList Error: " + ex.ToString()); return ""; };
}
//if (ds != null && ds.initiator !=null && ds.initiator.Player != null || ds.initiator.Player.Name() != null) // mo.PlayersWhoContributedNames.Add(ds.initiator.Player.Name()); ); //task.run()
{
Task.Run(() =>
{
try
{
foreach (DamagerScore ds in damages)
{
if (ds == null) continue;
if (ds != null && ds.initiator != null) MO_addInitiatorToListOfPlayersWhoContributed(ds.initiator, mo);
}
}
catch (Exception ex) { Console.WriteLine("MO_addDamagersToListOfPlayersWhoContributed ERROR : {0} ", ex.ToString()); }
}
}
//Ships often kill themselves or nearby ships, so this is trying to identify those & not count them
{
try
{
if (initiator == null) return;
if (initiator.Player == null) return;
if (initiator.Player.Name() == null) return;
if (initiator != null && initiator.Player != null && initiator.Player.Name() != null)
{
mo.makeScoutedFromBombRun(initiator.Player);
mo.PlayersWhoContributedNames.Add(initiator.Player.Name());
}
}
catch (Exception ex) { Console.WriteLine("MO_addInitiatorToListOfPlayersWhoContributed ERROR: {0}", ex.ToString()); }
}
//Console.WriteLine("main_PointArea_actor"); if (adi.Player != null) return false; //at least 1 player contributed to the death, so it's good if (damageAct == damagedAct) continue; //damager & damaged are same, this doesn't count as actual death, just suicide if (damageAct.Army() > 0 && damageAct.Army() != damagedAct.Army()) return false; //damager actxor is not neutral, and the damaged thing is neutral or opposite army) if (damageAct.Name() == damagedAct.Name()) continue; //its very common for one BritishBarge to ram the next BritishBarge etc & kill it if (adig == dAg) continue; //same ground actor or if (adig.Type() == dAg.Type() ) continue; //same type of ground actor return false; //This one passed the test - the damager is some different actor, not the same army, not the same type etc
{
try
{
foreach (DamagerScore d in damages)
{
if (d == null) continue;
AiDamageInitiator adi = d.initiator;
if (adi == null) continue;
if (adi.Person != null) return false;
if (adi.Actor == null) continue;
AiActor damageAct = adi.Actor;
if (adi as AiGroundActor != null && damagedAct as AiGroundActor != null)
{
AiGroundActor adig = adi as AiGroundActor;
AiGroundActor dAg = damagedAct as AiGroundActor;
}
}
return true;
}
catch (Exception ex) { Console.WriteLine("MO_isDeathOnlyDuetoSelf ERROR: {0}", ex.ToString()); return false; }
}
if (addedPercent < 0) addedPercent = 0; //We might for some reason REDUCE the percent destroyed, which if negative will cause problems below if (mo.TimeToUndestroy_UTC.HasValue) mo.TimeToUndestroy_UTC.Value.AddHours(additionalTimeToFix_hr); //just add time proportional to how many objects required to kill it 100%. But divided by 4 since we are discounting the destruction MO_DestroyObjective_addTimeOrPoints(mo.ID, percentdestroyed: mo.DestroyedPercent); //adds possible Campaign points, mostly, in this case else if (Math.Floor(oldDestroyedPercent * 100.0 / 10.0) % 2 != Math.Floor(mo.DestroyedPercent * 100.0 / 10.0) % 2) //if crossing threshold @ 10, 20, 30, etc, 50, 100% give a message with status update of objective //calculates & returns the destroyed percentage based on # of objects killed w/in the radius //kg of ordnance dropped in radius, & number of "Chief" actors killed belonging to this objective //So it is a complex thing where requirements for any of those can be zero and if so that factor just drops out //But any factors remaining get a percentage of the total damage points (1/3 or 1/2, if 3 or 3) //BUT if say objects is 2/30 requires and KG bombs is 20000/5000 required then the ordnance points //start counting towards the total, just at a lower rate...
{
try {
if (mo.ObjectsRequiredToTrigger_num == 0) mo.ObjectsRequiredToTrigger_num = 10;
if (triggerCalled && mo.ObjectsDestroyed_num < mo.ObjectsRequiredToTrigger_num) mo.ObjectsDestroyed_num = mo.ObjectsRequiredToTrigger_num;
DateTime currTime_dt = DateTime.UtcNow;
double repairSpeedupFactor = 1;
if (MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy].ContainsKey("RepairCrewEndTime_dt") && MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy]["RepairCrewEndTime_dt"] > currTime_dt) repairSpeedupFactor = 4;
double tempDestroyedPercent = mo.ObjectsDestroyed_num / mo.ObjectsRequiredToTrigger_num;
if (tempDestroyedPercent > 1) tempDestroyedPercent = 1 + 0.4 * Math.Pow(tempDestroyedPercent - 1.0, 0.7);
double oldDestroyedPercent = mo.DestroyedPercent;
mo.DestroyedPercent = tempDestroyedPercent;
double addedPercent = tempDestroyedPercent - oldDestroyedPercent;
if (mo.ObjectsDestroyed_num >= mo.ObjectsRequiredToTrigger_num)
{
if (!mo.Destroyed || !mo.ObjectiveAchievedForPoints)
MO_DestroyObjective(mo.ID, percentdestroyed: mo.ObjectsDestroyed_num / mo.ObjectsRequiredToTrigger_num, timetofixFromNow_sec: mo.TimetoRepairIfDestroyed_hr * 3600 / repairSpeedupFactor);
}
else if (mo.DestroyedPercent > 1)
{
double additionalTimeToFix_hr = (mo.TimetoRepairIfDestroyed_hr * addedPercent / repairSpeedupFactor);
else mo.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(additionalTimeToFix_hr);
}
{
twcLogServer(null, "{0} damaged: {1}% destroyed, {2} items damaged of {3} required to destroy objective", new object[] { mo.Name, (Math.Floor(mo.DestroyedPercent * 100.0)).ToString("F0"), mo.ObjectsDestroyed_num.ToString("F0"), mo.ObjectsRequiredToTrigger_num.ToString("F0") });
}
}
catch (Exception ex) { Console.WriteLine("MO_CalculateAndRecordTriggerObjectivesDamagePercent ERROR: " + ex.ToString()); }
}
//Special case where you are supposed to destroy actors but the area has been pounded //over & over and still actors not destroyed. With this the obj will still trigger...
{
try
{
if (mo == null) return;
mo.fixDestructionValues();
DateTime currTime_dt = DateTime.UtcNow;
double repairSpeedupFactor = 1;
if (MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy].ContainsKey("RepairCrewEndTime_dt") && MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy]["RepairCrewEndTime_dt"] > currTime_dt) repairSpeedupFactor = 4;
double divisor = 0;
if (mo.OrdnanceRequiredToTrigger_kg > 0) divisor++;
if (mo.ObjectsRequiredToTrigger_num > 0) divisor++;
if (mo.ActorsRequiredToTrigger_num > 0) divisor++;
if (mo.ActorsDestroyed_num == 0 && mo.OrdnanceRequiredToTrigger_kg == 0 && mo.ActorsRequiredToTrigger_num > 0 && mo.OrdnanceOnTarget_kg > 8000) mo.ActorsDestroyed_num = 1;
if (mo.ActorsDestroyed_num == 0 && mo.OrdnanceRequiredToTrigger_kg == 0 && mo.ActorsRequiredToTrigger_num > 0 && mo.OrdnanceOnTarget_kg > 12000) mo.ActorsDestroyed_num = mo.ActorsRequiredToTrigger_num;
double dst_pc_ord = 0;
if (mo.OrdnanceRequiredToTrigger_kg > 0) dst_pc_ord = mo.OrdnanceOnTarget_kg / mo.OrdnanceRequiredToTrigger_kg / divisor;
double dst_pc_obj = 0;
if (mo.ObjectsRequiredToTrigger_num > 0) dst_pc_obj = mo.ObjectsDestroyed_num / mo.ObjectsRequiredToTrigger_num / divisor;
double dst_pc_act = 0;
if (mo.ActorsRequiredToTrigger_num > 0) dst_pc_act = mo.ActorsDestroyed_num / mo.ActorsRequiredToTrigger_num / divisor;
double dst_pc_obj_orig = dst_pc_obj;
if (dst_pc_obj > divisor && mo.OrdnanceRequiredToTrigger_kg > mo.OrdnanceOnTarget_kg) dst_pc_obj = divisor;
if (dst_pc_ord > divisor && (mo.ObjectsDestroyed_num < mo.ObjectsRequiredToTrigger_num || mo.ActorsDestroyed_num < mo.ActorsRequiredToTrigger_num))
{
double orig_dst_pc_ord = dst_pc_ord;
dst_pc_ord = divisor;
double add_dst_pc_ord = 0;
if (mo.OrdnanceRequiredToTrigger_kg > 1000 && orig_dst_pc_ord > 1) add_dst_pc_ord = (orig_dst_pc_ord - divisor) / 3;
dst_pc_ord += add_dst_pc_ord;
}
if (dst_pc_obj_orig > divisor && (mo.OrdnanceRequiredToTrigger_kg > mo.OrdnanceOnTarget_kg || mo.ActorsRequiredToTrigger_num > mo.ActorsDestroyed_num))
{
double add_dst_pc_obj = 0;
if (mo.ObjectsRequiredToTrigger_num >= 12 && dst_pc_obj_orig > 1) add_dst_pc_obj = (dst_pc_obj_orig - divisor) / 3;
if (mo.ObjectsRequiredToTrigger_num < 16) add_dst_pc_obj *= mo.ObjectsRequiredToTrigger_num / 16;
dst_pc_obj += add_dst_pc_obj;
}
if (dst_pc_act > divisor && (mo.OrdnanceRequiredToTrigger_kg > mo.OrdnanceOnTarget_kg || mo.ObjectsRequiredToTrigger_num > mo.ObjectsDestroyed_num))
{
double dst_pc_act_orig = dst_pc_act;
double add_dst_pc_act = 0;
if (dst_pc_act_orig > 1) add_dst_pc_act = (dst_pc_act_orig - divisor) / 3;
dst_pc_act += add_dst_pc_act;
}
double tempDestroyedPercent = dst_pc_obj + dst_pc_ord + dst_pc_act;
if (tempDestroyedPercent > 1) tempDestroyedPercent = 1 + 0.4 * Math.Pow(tempDestroyedPercent - 1.0, 0.7);
double oldDestroyedPercent = mo.DestroyedPercent;
mo.DestroyedPercent = tempDestroyedPercent;
double addedPercent = tempDestroyedPercent - oldDestroyedPercent;
Console.WriteLine("MO_CalculateAndRecordPointareaObjectivesDamagePercent: {0:F0}% objects, {1:F0}% KG, {9:F0}% actors => {2:F0}% Tot, {3:F0} KG KGreq: {4:F0} Numreq: {5:F0} ActReq: {7:F0} ActDest: {8:F0} Name: {6} ", dst_pc_obj * 100, dst_pc_ord * 100, mo.DestroyedPercent * 100, mo.OrdnanceOnTarget_kg, mo.OrdnanceRequiredToTrigger_kg, mo.ObjectsRequiredToTrigger_num, mo.Name, mo.ActorsRequiredToTrigger_num, mo.ActorsDestroyed_num, dst_pc_act * 100);
if ((!mo.Destroyed || !mo.ObjectiveAchievedForPoints) && mo.DestroyedPercent >= 1)
else if (mo.DestroyedPercent > 1)
{
double additionalTimeToFix_hr = (mo.TimetoRepairIfDestroyed_hr * addedPercent / repairSpeedupFactor);
else mo.TimeToUndestroy_UTC = DateTime.UtcNow.AddHours(additionalTimeToFix_hr);
}
{
twcLogServer(null, "{0} damaged: {1}% destroyed, {2} items damaged, {4} enemies killed, {3} kg on target", new object[] { mo.Name, (Math.Floor(mo.DestroyedPercent * 100.0)).ToString("F0"), mo.ObjectsDestroyed_num.ToString("F0"), mo.OrdnanceOnTarget_kg.ToString("F0"), mo.ActorsDestroyed_num.ToString("F0") });
}
}
catch (Exception ex) { Console.WriteLine("PointArea Calculation ERROR: " + ex.ToString()); }
}
Dictionary restartChief_log = new Dictionary() { };
//Timeout(random.NextDouble * 600 + 600, () => { { //speed things up for testing purposes if (restartChief_log.ContainsKey(mo) && currTime_dt.Subtract(restartChief_log[mo]).TotalSeconds < 600) continue; //only run this once every 10 minutes at most //FOR AIACTOR TARGETS DESTROYED
{
Console.WriteLine("restartChiefIfAllDead running... will restart {0} in 10-20 minutes if its the last actor of an objective...", shortName);
Timeout(random.NextDouble() * 30 + 300, () =>
var molk = new List(MissionObjectivesList.Keys);
foreach (string ID in molk)
{
try
{
MissionObjective mo = MissionObjectivesList[ID];
if (actor.Army() != mo.OwnerArmy) continue;
if (mo.MOTriggerType != MO_TriggerType.PointArea || !mo.IsEnabled || mo.Destroyed || !mo.hasChief()) continue;
if (!(shortName.ToLower()).Contains(mo.ChiefName.ToLower())) continue;
if (mo.chiefIsAlive()) continue;
DateTime currTime_dt = DateTime.UtcNow;
restartChief_log[mo] = currTime_dt;
Console.WriteLine("restartChiefIfAllDead: {0} was the last actor in objective {1} that is still alive, so the initsubmission {2} is being run now to restart it AND/OR the mobileobjective is being re-established", shortName, mo.ID, mo.InitSubmissionName);
mo.loadInitSubmission();
mo.reloadMobileObjectiveChiefs();
}
catch (Exception ex) { Console.WriteLine("restartChiefIfAllDead ERROR: " + ex.ToString()); }
}
});
}
//maddox.game.LandTypes landType = GamePlay.gpLandType(pos.x, pos.y); //For now, all things we handle below are on land, so if the land type is water we just //get out of here immediately //if (landType == maddox.game.LandTypes.WATER) return; //Ok, doing ships & water type targets this doesn't really work. So just X it out...
{
try
{
if (GamePlay == null) return;
int terr = GamePlay.gpFrontArmy(pos.x, pos.y);
if (initiator != null)
string acType = "";
if (initiator != null)
{
AiAircraft aircraft = initiator.Actor as AiAircraft;
acType = Calcs.GetAircraftType(aircraft);
}
double aircraftCorrection = bomberCorrectionFactor(acType);
mass_kg = mass_kg * aircraftCorrection;
DateTime currTime_dt = DateTime.UtcNow;
double repairSpeedupFactor = 1;
{
MissionObjective mo = MissionObjectivesList[ID];
if (mo.MOTriggerType != MO_TriggerType.PointArea || !mo.IsEnabled) continue;
if (Calcs.IsNaN(pos)) continue;
double dist = Calcs.CalculatePointDistance(pos, mo.Pos);
if (dist <= mo.radius || dist <= mo.TriggerDestroyRadius)
{
mo.fixDestructionValues();
double oldOONTkg = mo.OrdnanceOnTarget_kg;
MO_addInitiatorToListOfPlayersWhoContributed(initiator, mo);
mo.OrdnanceOnTarget_kg += mass_kg;
mo.LastHitTime_UTC = DateTime.UtcNow;
if (MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy].ContainsKey("RepairCrewEndTime_dt") && MissionObjectivesTimes[(ArmiesE)mo.OwnerArmy]["RepairCrewEndTime_dt"] > currTime_dt) repairSpeedupFactor = 4;
MO_CalculateAndRecordPointareaObjectivesDamagePercent(mo);
}
}
}
catch (Exception ex)
{
Console.WriteLine("handle PointArea bomb hit ERROR: " + ex.ToString());
}
}
if (dist_m < mo.radius + mo_check.radius) return true; //too close, the radii will overlap
{
try
{
foreach (string ID in MissionObjectivesList.Keys)
{
MissionObjective mo = MissionObjectivesList[ID];
if (mo_check == mo) continue;
if (!mo.IsEnabled) continue;
if (check_army != 0 && check_army != mo.OwnerArmy) continue;
double dist_m = Calcs.CalculatePointDistance(check_pos, mo.returnCurrentPosWithChief());
}
return false;
}
catch (Exception ex) { Console.WriteLine("ERROR MO_oneObjectiveTooNearAnother! " + ex.ToString()); return false; }
}
/********************************************************************************************************************
* ****END****MISSION OBJECTIVES CLASSES & METHODS
* **********************************************************************************************************************/
mo.makeScoutedandLaunchDefenseFromHit(pos, player); //makes the mo scouted if this hit is near the mo, less than 2k. So will work for any hit like a bomb drop or killing a stationary or actor
{
foreach (string ID in MissionObjectivesList.Keys)
{
MissionObjective mo = MissionObjectivesList[ID];
}
}
Dictionary recentlyCalledActions_dict = new Dictionary();
//return TRUE if AI spawns should be stopped bec of too many players //FALSE if AI/trigger missions can continue //BALANCEAILOAD and STOPAI are the two main ways we control how many //AI groups come into the game. BALANCEAILOAD will load bomber groups periodically //if the action gets too low/boring...
{
if (!recentlyCalledActions_dict.ContainsKey(shortName))
{
recentlyCalledActions_dict[shortName] = DateTime.UtcNow;
return false;
}
TimeSpan sinceCalled = DateTime.UtcNow - recentlyCalledActions_dict[shortName];
recentlyCalledActions_dict[shortName] = DateTime.UtcNow;
if (sinceCalled.TotalMinutes < time_min) return true;
return false;
}
//Console.WriteLine("stopAI 1"); //bhugh, temp, XX2021-10, cutting ai by 20% to heat up action a little //2021-11 leaving it be for now //2022-12 - removing the 20% cut now, increasing # of AI //if (random.NextDouble() < 0.2) return true; //this puts a minimum on the # of aircraft on one side or the other //Even if we "want" to stop this sortie, if there are a pathetically //low # of a/c on one side or the other we still let it go regardless //(depending on number of players are outlined below //Console.WriteLine("stopAI 4"); //if (nump > 80 || (nump > 60 && random.NextDouble() > 0.65) || (nump > 40 && random.NextDouble() > 0.2)) //2021/07/16 - this was 30/50, trying 20/40 to see if //double maxPlayers = 40; //This number of players or more, and no AI will spawn //double minPlayers = 20; //At this number of players, the number of AI starts to decrease a bit, until fully phased out at maxPlayers //bhugh, temp, XX2021-10: cutting down the number of AI to raise the stakes, so that it will be more duke it out //breather to breather //leaving it be for now 2021-11 //2022-12 - was 5 & 15, now raising to 10 & 20 //2023-1 - now 8 & 12 //2023-01 - now 9 & 15; double maxPlayers = 15; //This number of players or more, and no AI will spawn double minPlayers = 9; //At this number of players, the number of AI starts to decrease a bit, until fully phased out at maxPlayers //Console.WriteLine("stopAI 5"); //Console.WriteLine("stopAI: " + nump.ToString() + " players currently online"); //Console.WriteLine("stopAI 6"); //So regardless of phase-out of AI groups, if one side has just a few players //we continue to send AI bomber raids from their side, just to keep things active/interesting //Console.WriteLine("stopAI 7"); //hard limit of a/c to 60 each side. //bhugh, temp, XX2021-10, making it just 30 for this endgame //2021-11 this doesnt really seem to work but leaving it be for now...
{
try
{
if (panic()) return true;
if (actionName.Length == 0) return false;
double nump = (double)Calcs.gpNumberOfPlayers(GamePlay);
int numRedPlayers = Calcs.gpNumberOfPlayers(GamePlay, 1);
int numBluePlayers = Calcs.gpNumberOfPlayers(GamePlay, 2);
bool letFighterPatrolGo = (doesNestedListContain(redFighterActions, actionName) || doesNestedListContain(blueFighterActions, actionName)) && (numBlueAircraft + numRedAircraft < 140) && nump < 16;
if (doesNestedListContain(redFighterActions, actionName) && numRedPlayers > 8) letFighterPatrolGo = false;
if (doesNestedListContain(blueFighterActions, actionName) && numBluePlayers > 8) letFighterPatrolGo = false;
Console.WriteLine("stopAI 2");
bool letBlueBomberGo = false;
if ((numBlueAircraft <= 60) && doesNestedListContain(blueBomberActions, actionName)) letBlueBomberGo = true;
bool letRedBomberGo = false;
if ((numRedAircraft <= 60) && doesNestedListContain(redBomberActions, actionName)) letRedBomberGo = true;
if (!letFighterPatrolGo && !letRedBomberGo && !letBlueBomberGo)
{
Console.WriteLine("stopAI 3");
if ((numBlueAircraft + numRedAircraft > 90)) return true;
if (numBlueAircraft > 45 && blueAllActions.Contains(actionName)) return true;
if (numRedAircraft > 45 && redAllActions.Contains(actionName)) return true;
}
double diffPlayers = maxPlayers - minPlayers;
if (diffPlayers == 0) diffPlayers = 1;
Console.WriteLine("stopAI: Blue ac/players {0} {1}; Red ac/players {2} {3}; Stop AI group " + actionName + "? " + DateTime.UtcNow.ToString("T"), numBlueAircraft, numBluePlayers, numRedAircraft, numRedPlayers);
if (nump == 0 && !ON_TESTSERVER)
{
Console.WriteLine("stopAI: Stopping AI Trigger NO players online");
return true;
}
if (actionName.Length > 0 && (
doesNestedListContain(redBomberActions, actionName) || doesNestedListContain(blueBomberActions, actionName)))
{
if ((numBlueAircraft > 60) && doesNestedListContain(blueBomberActions, actionName)) return true;
if ((numRedAircraft > 60) && doesNestedListContain(redBomberActions, actionName)) return true;
if (numBluePlayers < 5 && doesNestedListContain(blueBomberActions, actionName)) return false;
if (numRedPlayers < 5 && doesNestedListContain(redBomberActions, actionName)) return false;
if (nump < (minPlayers + maxPlayers) / 2 && nump > 0)
{
if (numRedPlayers / nump < 0.33 && doesNestedListContain(redBomberActions, actionName)) return false;
if (numBluePlayers / nump < 0.33 && doesNestedListContain(blueBomberActions, actionName)) return false;
}
}
/******************************
* RAMP AI DOWN AS # OF LIVE PLAYERS INCREASES
* ****************************/
if (nump > maxPlayers || (nump <= maxPlayers && minPlayers >= minPlayers && random.NextDouble() < (nump - minPlayers) / diffPlayers))
{
Console.WriteLine("stopAI: Stopping AI Trigger/too many players online");
return true;
}
else
{
Console.WriteLine("stopAI: No, NOT stopping AI Trigger/too few players online");
return false;
}
}
catch (Exception ex) { Console.WriteLine("ERROR stopAI: " + ex.ToString()); return false; }
}
/*
public override void OnTrigger(int missionNumber, string shortName, bool active)
{
base.OnTrigger(missionNumber, shortName, active);
Console.WriteLine("OnTrigger: Received trigger " + shortName + " mission#: " + missionNumber + " active: "+active.ToString());
AiAction action = GamePlay.gpGetAction(shortName);
if (action != null && active)
{
Console.WriteLine("OnTrigger: Activating action " + shortName + " from trigger " + shortName + " mission#: " + missionNumber);
action.Do();
}
}
*/
/*********************************************************************************************************************
* *******************************************************************************************************************
* ONTRIGGER
*
* Handle bombing/objective destruction triggers as well as
* triggers that launch various air raids and other events
*
* In an action entry, the "1" indicates the action is enabled - 0 means disabled. If set to disabled, then (it appears?)
* the action wont activate if you call it.
*
* [Action]
* action1 ASpawnGroup 1 BoB_LW_KuFlGr_706.03 <--- WILL RUN
* action2 ASpawnGroup 0 BoB_LW_KuFlGr_706.04 <--- WILL ***NOT*** RUN!!!!
*
* In OnTrigger, we can trigger any action if we know its name via action.Do() - it doesn't need to be the associated action in the .mis file
*
* If there is no .cs file, CloD will automatically .Do() the action with the exact same name as the trigger when the trigger is called and the action is enabled.
* However, if you have .cs file then you must include OnTrigger include a bit of code to manually call the action with the same name as the trigger. That is
* included below in the 'else' portion of the method.
*
* You can call actions at any time; you don't need to rely on the trigger to set it off. You only need to know the exact name of the
* trigger from the .mis file Sample:
*
* AiAction action = GamePlay.gpGetAction(tr);
* if (action != null) action.Do();
*
* You can also call a Trigger at any time using this sample code:
*
* if (GamePlay.gpGetTrigger(tr) != null ) {
* Battle.OnEventGame(GameEventId.Trigger, tr, true, 1);
* }
*
* You can call both triggers and actions from any mission--either the main mission file or any sub-mission loaded via gpPostMissionLoad.
* You only need the EXACT name from the .mis file.
*
* Also Timers should be named as timers with the time to launch in the title to avoid confusion
*
* TGroundDestroyed type triggers ONLY DETECT OBJECTS KILLED if they are labelled as de or gb. The nn objects are simply not counted.
*
*
* ****************************************************************************************************************/
string lastTrigger = "";
public override void OnTrigger(int missionNumber, string shortName, bool active)
{
base.OnTrigger(missionNumber, shortName, active);
Console.WriteLine("OnTrigger: " + shortName + " " + missionNumber.ToString() + " Active: " + active.ToString());
string newTrigger = missionNumber.ToString() + ":" + shortName;
bool res;
if (lastTrigger != newTrigger) MO_CalculateAndRecordTriggerObjectivesDamagePercent(shortName, active);
lastTrigger = newTrigger;
/*
"Rouen_2_Lehavre", "Panzer_2_Calais",
"Rouen_2_Brombos", "Opel_BlitzFuel1",
"Dieppe_2_Lehavre",
"Bernay_2_Hornfleur", "Dunkirk_2_GrandFort",
"Beaumont_2_Forges", "Onkel_Albert_Staff_Car",
"Lehavre_2_Forges", "LeTreport_fuel_Convoy",
"FuelBeauvis_2_Nuefchatel", "Abbeville_2_PoixDePicard",
"Huate_from_Dieppe", "Amiens_2_MontDidiear",
"Clermont_2_Dieppe", "Arras_2_WallyBeaucamp",
"Opel_Blitz_fuel_1", "GER_Fuel_Column_1",
"Rouen_2_Dieppe2", "GER_Fuel_Column_2",
"Stelling_to_Dunkirk "GER_Fuel_Column_3",
"General_Tiny_Barber",
"Rouen_Fuel_Convoy_2Dieppe",
"Les_Andeleys_2_Brombos",
"Axis_War_Plans",
*/
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, " Rouen_2_Lehavre Convoy Launched", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(15, () => sendScreenMessageTo(1, " Panzer_2_Calais Convoy Launched", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Rouen_2_Brombos convoy launched", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
else if ("Timer4_31min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Abbeville .Ligescourt Cramont area refueling", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Dieppe to Le Havre Convoy launched", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
Timeout(10, () => sendScreenMessageTo(2, "Beckton Sewage Treatment facility Destroyed", null));
Timeout(20, () => sendScreenMessageTo(2, "Crap everywhere", null));
Timeout(10, () => sendScreenMessageTo(1, "Beckton Sewage Treatment facility Destroyed,", null));
Timeout(20, () => sendScreenMessageTo(1, "Crap everywhere 3 sheets in the wind", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
Timeout(10, () => sendScreenMessageTo(2, "Sewage Treatment facility Destroyed in Dunkirk", null));
Timeout(20, () => sendScreenMessageTo(2, "Crap everywhere ", null));
Timeout(10, () => sendScreenMessageTo(1, "Allied Effort results in destruction of a sewage plant in Dunkirk,", null));
Timeout(20, () => sendScreenMessageTo(1, "Crap everywhere", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Dunkirk_2_GrandFort Convoy launched", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Bernay_2_Hornfleur Convoy launched", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(40, () => sendScreenMessageTo(1, "German General on Inspection", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Beaumont_2_Forges Convoy launched", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "LeTreport_fuel_Convoy launched", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Critical Fuel Supplies Lehavre_2_Forges", null));
Timeout(10, () => sendScreenMessageTo(1, "Friendly Fuel Supplies Flowing Lehavre_2_Forges ", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Enemy Tanks Spotted Abbeville to Poix Nord", null));
}
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Fuel Supplies Beauvis to Nuefchatel", null));
}
else if ("Timer14_121min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Supplies from Amiens to Mt. Didiear.", null));
}
else if ("Timer15_125min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Supplies from Huate_from_Dieppe.", null));
}
else if ("Timer16_126min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(60, () => sendScreenMessageTo(1, "Arras_2_WallyBeaucamp Supplies moving now!", null));
}
else if ("Timer17_180min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(60, () => sendScreenMessageTo(2, "Clermont_2_Dieppe fuel supplies Spotted!!!.", null));
}
else if ("Timer18_181min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(60, () => sendScreenMessageTo(2, "Liegescourt area fuel supplies Spotted!!!.", null));
}
else if ("Timer19_210min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(60, () => sendScreenMessageTo(2, "Stelling_to_Canterbury Dunkirk area in Britain moving now ", null));
}
else if ("Timer20_211min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(60, () => sendScreenMessageTo(1, " St omar to Colembert", null));
}
else if ("Timer21_240min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Scotish General touring front lines Le Havre to Dieppe.", null));
}
else if ("Timer22_241min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Fuel Supplies movingAbbeville to Arras!", null));
}
else if ("Timer23_270min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Rouen_Fuel_Convoy_2Dieppe", null));
}
else if ("Timer24_271min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Les_Andeleys_2_Brombos fuel trucks heading out.", null));
}
else if ("Timer25_300min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Enemy has our battle plans single vehicle BD5 to AY8", null));
Timeout(30, () => sendScreenMessageTo(2, "Destroy the Vehicle with the plans!!", null));
}
else if ("Timer24_271min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Rouen_2_Dieppe2 fuel trucks heading out.", null));
}
{
AiAction action = GamePlay.gpGetAction("110_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
AiAction action = GamePlay.gpGetAction("110_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
AiAction action = GamePlay.gpGetAction("109_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
AiAction action = GamePlay.gpGetAction("Heavy_Bomber_Raid_2");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "#2 Heavy enemy raid with escorts moving North!", null));
}
{
AiAction action = GamePlay.gpGetAction("110_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
AiAction action = GamePlay.gpGetAction("109_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(40, () => sendScreenMessageTo(1, "Heavy raid with escorts moving North!", null));
}
{
AiAction action = GamePlay.gpGetAction("109_late_raid_Jabo");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "109s heading north from moving Northwest from Merville!", null));
GamePlay.gpGetTrigger(shortName).Enable = false;
}
{
AiAction action = GamePlay.gpGetAction("TimedPanzerConvoy");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Enemy Tanks Spotted AS 1 heading West", null));
}
{
AiAction action = GamePlay.gpGetAction("StukaRaid");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_120min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("StukaRaid");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "test of timed operation.", null));
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("StukaRaid2");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_270min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("StukaRaid3");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer2_31min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_B_Interior_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer2_90min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_B_Interior_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_240min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_B_Somme_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(600, () => sendScreenMessageTo(1, "Activity reported along Somme.", null));
}
else if ("ATimer1_60min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_120min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_240min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Enemy aircraft reported along Somme.", null));
}
else if ("ATimer1_300min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_60min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Fighters near front lines", null));
}
else if ("ATimer1_90min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Fighters near front lines", null));
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Beware of front line fighters!", null));
Timeout(600, () => sendScreenMessageTo(2, "Again our fighters cover he front lines", null));
}
else if ("ATimer1_270min".Equals(shortName) && active && !stopAI())
{
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Air trafic increase near front lines!", null));
Timeout(600, () => sendScreenMessageTo(2, "Last flight of our fighters headed to front lines!", null));
}
else if ("ATimer1_92min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("StukaRaid2");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Heavy Stuka raid on front lines Escorts needed Launching Freecamp Now!!!.", null));
Timeout(600, () => sendScreenMessageTo(1, "Activity in Le Havre Area!!", null));
}
else if ("ATimer1_95min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Blenhiem_Raid2");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(1, "Blenheims requesting escort. Heading to Rouen Fuel targets low and fast", null));
}
else if ("ATimer3_120min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Blenhiem_Raid3");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(10, () => sendScreenMessageTo(2, "Spies report Blenheim aircraft heading East toward Rouen.", null));
}
else if ("ATimer1_300min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Blenhiem_Raid");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("Timer3_90min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_Rouen_Diep_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_Rouen_Diep_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_Rouen_Diep_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_30min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Cher_Cover_Hi");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_180min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("Timed_Rouen_Diep_Patrol");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
}
else if ("ATimer1_270min".Equals(shortName) && active && !stopAI())
{
AiAction action = GamePlay.gpGetAction("109_Escort_2_London");
if (action != null)
{
action.Do();
Console.WriteLine("Triggered action " + action.Name);
}
Timeout(600, () => sendScreenMessageTo(1, "Heavy Bomber Raid heading West w/escorts", null));
}
/*************
Place a bunch of old triggers were previously housed, before
2021/07/18
************************/
else
{
Console.WriteLine("OnTrigger: Received trigger " + shortName + " mission#: " + missionNumber);
if (active) execAction(shortName, "OnTrigger");
}
bool tcull = false; //tobrukCullAI(shortName); bool rcall = false; //recentlyCalled(shortName, 60); Save results to file that will be read by the WatchDog program. 1= red win, 2 = blue win, 3= tie
Console.WriteLine("execAction 1");
AiAction action = GamePlay.gpGetAction(shortName);
Console.WriteLine("execAction 2");
bool stopai = stopAI(shortName);
if (action != null && !stopai && !tcull && !rcall)
{
Console.WriteLine(origin +": Activating action " + action.Name + " from trigger " + shortName);
action.Do();
} else
{
Console.WriteLine(origin + ": Skipping action " + action.Name + " " + shortName + " because null: {0} many players: {1} tobrukCull: {2} toorecentlycalled: {3} ", action==null, stopai, tcull, rcall);
}
}
if (TWCComms.Communicator.Instance.WARP_CHECK) Console.WriteLine("MXX4 " + DateTime.UtcNow.ToString("T")); //Testing for potential causes of warping //Console.WriteLine("WriteResults_Out_File - file & contents: " + RESULTS_OUT_FILE + " " + result); } //class mission : amission Various helpful calculations & formulas //This is a puzzling one but usually we are using distance to check if //two things are CLOSE to one another. If one doesn't have a defined position //then it is definitely not CLOSE to anything...
{
try
{
using (StreamWriter file = new StreamWriter(RESULTS_OUT_FILE, false))
{
file.WriteLine(result);
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("WriteResults_Out_File( - Error writing Mission RESULTS_OUT_FILE: " + RESULTS_OUT_FILE + " " + ex.Message);
return false;
}
}
public static class Calcs
{
private static Random clc_random = new Random();
public static double distance(double a, double b)
{
if (Double.IsNaN(a) || Double.IsNaN(b)) return Double.PositiveInfinity;
return (double)Math.Sqrt(a * a + b * b);
}
public static bool IsNaN (Point3d p)
{
if (Double.IsNaN(p.x) || Double.IsNaN(p.y) || Double.IsNaN(p.z)) return true;
else return false;
}
public static bool IsNaN(Vector3d p)
{
if (Double.IsNaN(p.x) || Double.IsNaN(p.y) || Double.IsNaN(p.z)) return true;
else return false;
}
public static double meters2miles(double a)
{
return (a / 1609.344);
}
public static double meterspsec2milesphour(double a)
{
return (a * 2.23694);
}
public static double milesphour2meterspsec(double a)
{
return (a / 2.23694);
}
public static double meterspsec2kmphour(double a)
{
return (a * 3600/1000);
}
public static double knots2meterspsec(double a)
{
return (a * 0.514444);
}
public static double meterspsec2knots(double a)
{
return (a / 0.514444);
}
public static double meterspsec2ftpermin(double a)
{
return (a * 196.85);
}
public static double ftpermin2meterspsec(double a)
{
return (a / 196.85);
}
public static double meters2feet(double a)
{
return (a / 1609.344 * 5280);
}
public static double feet2meters(double a)
{
return (a * 1609.344 / 5280);
}
public static double Celsius2Fahrenheit(double a)
{
return (a * 1.8 + 32);
}
public static double Fahrenheit2Celsius(double a)
{
return (a - 32) * 5 / 9;
}
public static double lb2kg(double a)
{
return a / 2.20462;
}
public static double kg2lb(double a)
{
return a * 2.20462;
}
public static double DegreesToRadians(double degrees)
{
return degrees * (Math.PI / 180.0);
}
public static double RadiansToDegrees(double radians)
{
return radians * (180.0 / Math.PI);
}
public static double CalculateGradientAngle(Vector3d startPoint, Vector3d endPoint)
{
return CalculateGradientAngle(new Point3d(startPoint.x, startPoint.y, startPoint.z),
new Point3d(endPoint.x, endPoint.y, endPoint.z));
}
public static double CalculateGradientAngle(Vector3d endPoint)
{
return CalculateGradientAngle(
new Point3d(endPoint.x, endPoint.y, endPoint.z));
}
public static double CalculateGradientAngle(Point3d endPoint)
{
return CalculateGradientAngle(
new Point3d(0, 0, 0),
endPoint);
}
public static double CalculateGradientAngle(Point3d startPoint, Point3d endPoint)
{
double diffX = endPoint.x - startPoint.x;
double diffY = endPoint.y - startPoint.y;
double radAngle = Math.PI / 2 - Math.Atan2(diffY, diffX);
double degAngle = RadiansToDegrees(radAngle);
if (degAngle < 0)
{
degAngle = degAngle + 360;
}
return degAngle;
}
public static bool Point3dEqualXY(
Point3d p1,
Point3d p2)
{
if (p1.x != p2.x || p1.y != p2.y) return false;
else return true;
}
public static bool Point3dEqual(
Point3d p1,
Point3d p2)
{
if (p1.x != p2.x || p1.y != p2.y || p1.z != p2.z) return false;
else return true;
}
public static bool Point3dEqual(
Vector3d p1,
Point3d p2)
{
if (p1.x != p2.x || p1.y != p2.y || p1.z != p2.z) return false;
else return true;
}
public static bool Point3dEqual(
Point3d p1,
Vector3d p2)
{
if (p1.x != p2.x || p1.y != p2.y || p1.z != p2.z) return false;
else return true;
}
public static bool Point3dEqual(
Vector3d p1,
Vector3d p2)
{
if (p1.x != p2.x || p1.y != p2.y || p1.z != p2.z) return false;
else return true;
}
public static double CalculatePointDistance(
Point2d startPoint,
Point3d endPoint)
{
double diffX = Math.Abs(endPoint.x - startPoint.x);
double diffY = Math.Abs(endPoint.y - startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Point2d startPoint,
Point2d endPoint)
{
double diffX = Math.Abs(endPoint.x - startPoint.x);
double diffY = Math.Abs(endPoint.y - startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Point3d startPoint,
Point3d endPoint)
{
double diffX = Math.Abs(endPoint.x - startPoint.x);
double diffY = Math.Abs(endPoint.y - startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Vector3d startPoint,
Vector3d endPoint)
{
double diffX = Math.Abs(endPoint.x - startPoint.x);
double diffY = Math.Abs(endPoint.y - startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Point2d startPoint)
{
double diffX = Math.Abs(startPoint.x);
double diffY = Math.Abs(startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Point3d startPoint)
{
double diffX = Math.Abs(startPoint.x);
double diffY = Math.Abs(startPoint.y);
return distance(diffX, diffY);
}
public static double CalculatePointDistance(
Vector3d startPoint)
{
double diffX = Math.Abs(startPoint.x);
double diffY = Math.Abs(startPoint.y);
return distance(diffX, diffY);
}
public static double PointToLineDistance(Point2d linePoint1, Point2d linePoint2, Point3d singlePoint)
{
return PointToLineDistance(linePoint1, linePoint2, new Point2d(singlePoint.x, singlePoint.y));
}
public static double PointToLineDistance(Point2d linePoint1, Point2d linePoint2, Point2d singlePoint)
{
double a = linePoint2.y - linePoint1.y;
double b = -(linePoint2.x - linePoint1.x);
double c = (-b * linePoint1.y) - a * linePoint1.x;
}
public static Point3d addVectorwithScalarMultXY(Point3d vec1, Point3d vec2, double scalar )
{
return new Point3d(vec1.x + vec2.x * scalar, vec1.y + vec2.y * scalar, 0);
}
public static Point3d unitVectorXY(Point3d posA)
{
double dist = CoverCalcs.CalculatePointDistance(posA);
return new Point3d(posA.x / dist, posA.y / dist, 0);
}
public static Point3d unitVectorXY(Point3d posA, Point3d posB)
{
double dist = CoverCalcs.CalculatePointDistance(posA, posB);
Point3d unit_vec_PosAtoPosB = new Point3d((posB.x - posA.x) / dist, (posB.y - posA.y) / dist, 0);
return unit_vec_PosAtoPosB ;
}
public static Point3d unitNormalVectorCCWXY(Point3d posA, Point3d posB) {
Point3d unit_vec_PosAtoPosB = unitVectorXY(posA, posB);
Point3d unit_vec_perpPosAtoPosB = new Point3d(-unit_vec_PosAtoPosB.y, unit_vec_PosAtoPosB.x, 0);
return unit_vec_perpPosAtoPosB;
}
public static Point3d unitNormalVectorCWXY(Point3d posA, Point3d posB)
{
Point3d unit_vec_PosAtoPosB = unitVectorXY(posA, posB);
Point3d unit_vec_perpPosAtoPosB = new Point3d(unit_vec_PosAtoPosB.y, -unit_vec_PosAtoPosB.x, 0);
return unit_vec_perpPosAtoPosB;
}
public static Point3d reverseVectorXY(Point3d pos)
{
return new Point3d(-pos.x, -pos.y,0);
}
public static double angleBetweenVectorsXY_rad(Point3d pos1, Point3d pos2)
{
double dist1 = CalculatePointDistance(pos1);
double dist2 = CalculatePointDistance(pos2);
double intmd = (pos1.x * pos2.x + pos1.y * pos2.y) / (dist1 * dist2);
return Math.Acos(intmd);
}
public static Point3d bisectAngleUnitVectorXY(Point3d posA, Point3d posB, Point3d posC, Point3d posD)
{
Point3d vec1 = unitVectorXY(posA, posB);
Point3d vec2 = unitVectorXY(posC, posD);
Point3d bisectVec = unitVectorXY(new Point3d(vec1.x + vec2.x, vec1.y + vec2.y, 0));
Point3d unvCCW = unitNormalVectorCCWXY(vec1, vec2);
if (Point3dEqualXY(bisectVec, new Point3d(0, 0, 0))){
bisectVec = unvCCW;
}
double theta = Calcs.angleBetweenVectorsXY_rad(bisectVec, unvCCW);
if (theta > Math.PI / 2) bisectVec = reverseVectorXY(bisectVec);
return bisectVec;
}
/**
* Calculates the point of interception for one object starting at point
* a with speed vector v and another object
* starting at point b with a speed of s.
*
* @see
*
* @param a
* start vector of the object to be intercepted
* @param v
* speed vector of the object to be intercepted
* @param b
* start vector of the intercepting object
* @param s
* speed of the intercepting object
* @return Point3d where x,y is vvector of interception & z is time; or null if object cannot be
* intercepted or calculation fails
*
* @author Jens Seiler
*/
public static Point3d calculateInterceptionPoint(Point3d a, Point3d v, Point3d b, double s)
{
double ox = a.x - b.x;
double oy = a.y - b.y;
double h1 = v.x * v.x + v.y * v.y - s * s;
double h2 = ox * v.x + oy * v.y;
double t;
if (h1 == 0)
t = -(ox * ox + oy * oy) / (2 * h2);
}
else
double minusPHalf = -h2 / h1;
if (discriminant < 0)
return new Point3d(0, 0, 0); ; ;
}
double root = Math.Sqrt(discriminant);
double t1 = minusPHalf + root;
double t2 = minusPHalf - root;
double tMin = Math.Min(t1, t2);
double tMax = Math.Max(t1, t2);
if (t < 0)
return new Point3d(0, 0, 0); ;
}
}
return new Point3d(a.x + t * v.x, a.y + t * v.y, t);
}
#region Calculations
public static int Meters2Angels(double altitude)
{
double altAngels = (altitude / 0.3048) / 1000;
if (altAngels > 1)
altAngels = Math.Round(altAngels, MidpointRounding.AwayFromZero);
else
altAngels = 1;
return (int)altAngels;
}
public static int Feet2Angels(double altitude)
{
double altAngels = (altitude) / 1000;
if (altAngels > 1)
altAngels = Math.Round(altAngels, MidpointRounding.AwayFromZero);
else
altAngels = 1;
return (int)altAngels;
}
public static int ToMiles(double distance)
{
double distanceMiles = 0;
return (int)distanceMiles;
}
/*
* angle1 = i * 2.0 / howmany * Math.PI + random.NextDouble() / howmany * Math.PI * 2.0 / 3.0;
double radius1 = radius_m + (circleStretcher(angle1, stretcherAmt, stretcherType));
thingPos.x = newPos.x + Math.Cos(angle1) * radius2;
thingPos.y = newPos.y + Math.Sin(angle1) * radius2;
*/
public static double circleStretcher(double ang, double stretcherAmt, int type)
{
double ret = 0;
double PI = Math.PI;
double PI2 = 2.0 * PI;
if (type == 0)
{
ret = ang / PI2;
ret = ang % 1;
ret = ret * ret;
if (ret > 0.5) ret = 1 - ret;
}
else if (type == 1)
{
ret = ang / PI2;
ret = ang % 1;
if (ret > 0.5) ret = 1 - ret;
}
ret *= stretcherAmt;
return ret;
}
public static Point3d pointsOnAStretchedCircle(Point3d center, double radius, int numPoints, int pointNum, double randomness_rad = 0, double randomness_radius = 0, double stretcherAmt =0, int stretcherType = 1 )
{
double angle1 = pointNum * 2.0 / (double)numPoints * Math.PI + clc_random.NextDouble() *randomness_rad;
double radius1 = radius + (circleStretcher(angle1, stretcherAmt, stretcherType));
double nex = center.x + Math.Cos(angle1) * radius2;
double ney = center.y + Math.Sin(angle1) * radius2;
return new Point3d(nex, ney, center.z);
}
public static Point3d pointsOnACircle(Point3d center, double radius, int numPoints, int pointNum, double randomness_rad=0, double randomness_radius=0)
{
double angle1 = pointNum * 2.0 / (double)numPoints * Math.PI + clc_random.NextDouble() * randomness_rad ;
double radius2 = clc_random.NextDouble()*randomness_radius + radius;
double nex = center.x + Math.Cos(angle1) * radius2;
double ney = center.y + Math.Sin(angle1) * radius2;
return new Point3d(nex, ney, center.z);
}
public static Point3d pointsOnALine(Point3d center, double length, double angle_deg, int numPoints, int pointNum, double randomness=0)
{
if (numPoints == 0) numPoints = 1;
double angle_rad = DegreesToRadians(angle_deg);
double x = length * ((double)pointNum / (double)numPoints - 0.5) + clc_random.NextDouble()*randomness;
double nex = center.x + Math.Cos(angle_rad) * x;
double ney = center.y + Math.Sin(angle_rad) * x;
return new Point3d(nex, ney, center.z);
}
public static Point3d pointsOnADoubleLine(Point3d center, double length, double line_dist, double angle_deg, int numPoints, int pointNum, double randomness)
{
bool even = (pointNum % 2 == 0);
int numPoints_onsingleline = (numPoints + 1) / 2;
if (numPoints_onsingleline == 0) numPoints_onsingleline = 1;
double angle_rad = DegreesToRadians(angle_deg);
double x = length * ((pointNum/2) / (double)numPoints_onsingleline - 0.5) + randomness*clc_random.NextDouble();
double y = line_dist / 2 + randomness * clc_random.NextDouble();
if (!even) y = -y;
double nex = center.x + Math.Cos(angle_rad) * x - Math.Sin(angle_rad)*y;
double ney = center.y + Math.Sin(angle_rad) * x + Math.Cos(angle_rad) * y;
return new Point3d(nex, ney, center.z);
}
public static Point3d pointsOnARectangle(Point3d center, double length1, double length2, double angle_deg, int numPoints, int pointNum, double randomness)
{
bool even = (pointNum % 2 == 0);
double denom = Math.Abs(length1) + Math.Abs(length2);
if (denom == 0) denom = 0.00001;
int dblLine1PointNum = Convert.ToInt32(Math.Round (numPoints * length1 / denom));
int dblLine2PointNum = Convert.ToInt32(Math.Round (numPoints * length2 / denom));
if (even) return pointsOnADoubleLine(center, length1, length2, angle_deg, dblLine1PointNum, pointNum /2, randomness);
else return pointsOnADoubleLine(center, length2, length1, angle_deg + 90, dblLine2PointNum, pointNum /2, randomness);
}
public static double AltitudeAGL_m (AiActor actor)
{
return AltitudeAGL_m(actor.Pos());
}
public static double AltitudeAGL_m(Point3d p)
{
double T = maddox.core.WLandscape.getWorldMapT(p.x, p.y);
double height_m = LandElevation_m(p);
return (p.z - height_m);
}
public static double LandElevation_m(Point3d p)
{
double height_m = twcLandscape.HQ(p.x, p.y);
return height_m;
}
public static Point3d Il2Point3dToLongLat(Point3d pos)
{
/*pos.x = (int)pos.x - 146643;
pos.x = pos.x / 63763.30751;
pos.x = pos.x - 0.095287;
*/
/* pos.y = (int)pos.y - 250937;
pos.y = pos.y / 112533.651;
pos.y = pos.y + 51.303649;
*/
pos.x = -2.017013 + 0.00001256447 * pos.x + 5.532674e-12 * pos.x * pos.x - 6.478475e-18 * pos.x * pos.x * pos.x;
pos.y = 49.01039 + 0.00000923699 * pos.y - 2.674155e-12 * pos.y * pos.y + 7.598837e-18 * pos.y * pos.y * pos.y;
return pos;
}
public static string DegreesToWindRose(double degrees)
{
String[] directions = { "North", "North East", "East", "South East", "South", "South West", "West", "North West", "North" };
return directions[(int)Math.Round((((double)degrees % 360) / 45))];
}
public static double CalculateBearingDegree(Vector3d vector)
{
Vector2d matVector = new Vector2d(vector.y, vector.x);
double bearing = (matVector.direction()) * 180.0 / Math.PI;
return (bearing > 0.0 ? bearing : (360.0 + bearing));
}
public static double CalculateBearingDegree(Vector2d vector)
{
Vector2d newVector = new Vector2d(vector.y, vector.x);
double bearing = (newVector.direction()) * 180.0 / Math.PI;
return (bearing > 0.0 ? bearing : (360.0 + bearing));
}
public static double CalculateBearingFromOrigin(Point2d targetLocation, Point2d originLocation)
{
double deltaX = targetLocation.x - originLocation.x;
double deltaY = targetLocation.y - originLocation.y;
double bearing = Math.Atan2(deltaX, deltaY);
bearing = bearing * (180.0 / Math.PI);
return (bearing > 0.0 ? bearing : (360.0 + bearing));
}
public static double CalculateBearingFromOrigin(Point3d targetLocation, Point3d originLocation)
{
double deltaX = targetLocation.x - originLocation.x;
double deltaY = targetLocation.y - originLocation.y;
double bearing = Math.Atan2(deltaX, deltaY);
bearing = bearing * (180.0 / Math.PI);
return (bearing > 0.0 ? bearing : (360.0 + bearing));
}
public static int GetDegreesIn10Step(double degrees)
{
degrees = Math.Round((degrees / 10), MidpointRounding.AwayFromZero) * 10;
if ((int)degrees == 360)
degrees = 0.0;
return (int)degrees;
}
public static int RoundInterval(double number, int interval = 10)
{
number = Math.Round((number / interval), MidpointRounding.AwayFromZero) * interval;
return (int)number;
}
public static string correctedSectorNameDoubleKeypad(AMission msn, Point3d p)
{
string s = correctedSectorName(msn, p) + "." + doubleKeypad(p);
return s;
}
public static string correctedSectorNameKeypad(AMission msn, Point3d p)
{
string s = correctedSectorName(msn, p) + "." + singleKeypad(p);
return s;
}
public static string makeBigSector(AMission msn, Point3d p, double points = 5, int maxSectorWidth = 4)
{
if (points > 200) maxSectorWidth *= 12;
else if (points > 100) maxSectorWidth *= 16;
else if (points > 20) maxSectorWidth *= 3;
else if (points > 12) maxSectorWidth *= 2;
else if (points > 8) maxSectorWidth += 2;
else if (points >= 5) maxSectorWidth += 1;
Console.WriteLine("Making Big Sector: " + points.ToString("N0") + " " + maxSectorWidth.ToString());
Point3d p1 = new Point3d(p.x - clc_random.Next((maxSectorWidth - 1) * 10000), p.y - clc_random.Next((maxSectorWidth - 1) * 10000), p.z);
if (p1.x < 10000) p1.x = 10000;
if (p1.y < 10000) p1.y = 10000;
Point3d p2 = new Point3d(p.x + clc_random.Next((maxSectorWidth - 1) * 10000), p.y + clc_random.Next((maxSectorWidth - 1) * 10000), p.z);
if (p1.x < 10000) p1.x = 10000;
if (p1.y < 10000) p1.y = 10000;
if (p2.y > 309000) p2.y = 309000;
return correctedSectorName(msn, p1) + "-" + correctedSectorName(msn, p2);
}
public static string correctedSectorName(AMission msn, Point3d p)
{
string sector = msn.GamePlay.gpSectorName(p.x, p.y);
return sector;
}
public static string doubleKeypad(Point3d p)
{
int keyp = keypad(p, 10000);
int keyp2 = keypad(p, 10000 / 3);
return keyp.ToString() + "." + keyp2.ToString();
}
public static string singleKeypad(Point3d p)
{
int keyp = keypad(p, 10000);
return keyp.ToString();
}
public static int keypad(Point3d p, double size)
{
int lat_rem = (int)Math.Floor(3 * (p.y % size) / size);
int lng_rem = (int)Math.Floor(3 * (p.x % size) / size);
return lat_rem * 3 + lng_rem + 1;
}
public static int giantkeypad(Point3d p)
{
double sizex = 360000;
double sizey = 310000;
int lat_rem = (int)Math.Floor(3 * (p.y % sizey) / sizey);
int lng_rem = (int)Math.Floor(3 * (p.x % sizex) / sizex);
int ret = lat_rem * 3 + lng_rem + 1;
if (ret > 10) ret = 10;
if (ret < 0) ret = 0;
return ret;
}
public static int NoOfAircraft(int number, AiAirGroup airGroup = null)
{
var random_seeded = clc_random;
if (airGroup != null)
random_seeded = new Random(airGroup.GetHashCode());
if (number > 0 && number <= 3)
{
return 2;
}
if (number <= 6)
{
return 5;
}
int ranadd = random_seeded.Next(3) - 1;
if (random_seeded.NextDouble() > 0.5) return number;
return number + ranadd;
}
public static int NoOfAircraftBy5(int number)
{
int firstDecimal = 0;
int higherDecimal = 0;
higherDecimal = Math.DivRem(number, 10, out firstDecimal);
if (firstDecimal > 3 && firstDecimal <= 8)
firstDecimal = 5;
else if (firstDecimal > 8)
higherDecimal += 1;
if (higherDecimal > 0)
return (int)higherDecimal * 10;
else
{
{
firstDecimal = 2;
}
return (int)firstDecimal;
}
}
#endregion
public static IEnumerable SplitToLines(string stringToSplit, int maxLineLength)
{
if (stringToSplit.Length <= maxLineLength) { yield return stringToSplit; yield break; }
string[] words = stringToSplit.Split(' ');
StringBuilder line = new StringBuilder();
foreach (string word in words)
{
if (word.Length + line.Length <= maxLineLength)
{
line.Append(word + " ");
}
else
{
if (line.Length > 0)
{
yield return line.ToString().Trim();
line.Clear();
}
string overflow = word;
while (overflow.Length > maxLineLength)
{
yield return overflow.Substring(0, maxLineLength);
overflow = overflow.Substring(maxLineLength);
}
line.Append(overflow + " ");
}
}
yield return line.ToString().Trim();
}
public static string GetAircraftType(AiActor actor)
{
if (actor as AiAircraft == null) return "";
else return GetAircraftType(actor as AiAircraft);
}
public static string GetAircraftType(AiAirGroup airGroup)
string result = "";
if (airGroup != null && airGroup.GetItems() != null && airGroup.GetItems().Length > 0)
{
AiAircraft aircraft = airGroup.GetItems()[0] as AiAircraft;
result = GetAircraftType(aircraft);
}
return result;
}
public static string GetAircraftType(AiAircraft aircraft)
string result = "";
if (aircraft != null)
{
string[] part = type.Trim().Split('.');
else return type;
}
return result;
}
public static string GetActorType(AiActor actor)
string result = "";
if (actor != null)
{
string[] part = type.Trim().Split('.');
else return type;
}
return result;
}
public static bool isHeavyBomber(AiAircraft aircraft)
{
if (aircraft == null) return false;
string acType = GetAircraftType(aircraft);
return isHeavyBomber(acType);
}
public static bool isHeavyBomber(AiAirGroup airGroup)
{
AiAircraft aircraft = null;
if (airGroup != null && airGroup.GetItems().Length > 0 && (airGroup.GetItems()[0] as AiAircraft) != null) aircraft = airGroup.GetItems()[0] as AiAircraft;
return isHeavyBomber(aircraft);
}
public static bool isHeavyBomber(string acType)
{
if (acType == "") return false;
bool ret = false;
if (acType.Contains("Ju-88A") || acType.Contains("He-111") || acType.Contains("BR-20") || acType.Contains("BlenheimMkI") || acType.Contains("Do-17") || acType.Contains("Wellington")
|| acType.Contains("Do-215B")
if (acType.Contains("BlenheimMkIVF") || acType.Contains("BlenheimMkIVNF") || acType.Contains("BlenheimMkIF") || acType.Contains("BlenheimMkINF")) ret = false;
return ret;
}
public static bool isDiveBomber(AiAircraft aircraft)
{
if (aircraft == null) return false;
string acType = GetAircraftType(aircraft);
return isDiveBomber(acType);
}
public static bool isDiveBomber(AiAirGroup airGroup)
{
AiAircraft aircraft = null;
if (airGroup != null && airGroup.GetItems().Length > 0 && (airGroup.GetItems()[0] as AiAircraft) != null) aircraft = airGroup.GetItems()[0] as AiAircraft;
return isDiveBomber(aircraft);
}
public static bool isDiveBomber(string acType)
{
if (acType == "") return false;
bool ret = false;
return ret;
}
public static bool isStrikeAC(Player player)
{
if (player == null) return false;
return isStrikeAC(player.Place() as AiAircraft);
}
public static bool isStrikeAC(AiAircraft aircraft)
{
if (aircraft == null) return false;
string acType = GetAircraftType(aircraft);
return isStrikeAC(acType);
}
public static bool isStrikeAC(AiAirGroup airGroup)
{
if (airGroup == null) return false;
AiAircraft aircraft = null;
if (airGroup.GetItems().Length > 0 && (airGroup.GetItems()[0] as AiAircraft) != null) aircraft = airGroup.GetItems()[0] as AiAircraft;
return isStrikeAC(aircraft);
}
public static bool isStrikeAC(string acType)
{
if (acType == "") return false;
bool ret = false;
if (acType.Contains("Ju-87") || acType.Contains("Bf-110") || acType.Contains("Beaufighter") || acType.Contains("Ju-88C") || acType.Contains("BlenheimMkIVF") || acType.Contains("BlenheimMkIVNF") || acType.Contains("BlenheimMkIF") || acType.Contains("BlenheimMkINF")
|| acType.Contains("HurricaneMkI_FB") || acType.Contains("HurricaneMkIIc") || acType.Contains("HurricaneMkIId")
return ret;
}
public static bool isStrikeACwithNoBombs(string acType)
{
if (acType == "") return false;
bool ret = false;
if (acType.Contains("Bf-110C-2") || acType.Contains("Bf-110C-6") ||
(acType.Contains("Bf-110C-4") && !acType.Contains("Bf-110C-4B") ) ||
acType.Contains("BeaufighterMkIF") || acType.Contains("BeaufighterMkINF")
return ret;
}
public static string GetMD5Hash(string input)
{
MD5 md5Hash = new MD5CryptoServiceProvider();
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
public static Player PlayerFromName(AMission msn, string name)
if (msn.GamePlay.gpRemotePlayers() != null) foreach (Player player in msn.GamePlay.gpRemotePlayers())
{
if (player.Name() == name) return player;
}
else if (msn.GamePlay.gpPlayer() != null)
{
if (msn.GamePlay.gpPlayer().Name() == name) return msn.GamePlay.gpPlayer();
}
return null;
}
public static int gpNumberOfPlayers(this IGamePlay GamePlay)
int result = 0;
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
return GamePlay.gpRemotePlayers().ToList().Count;
}
else if (GamePlay.gpPlayer() != null)
{
result = 1;
}
return result;
}
public static int gpNumberOfPlayers(this IGamePlay GamePlay, int army)
int result = 0;
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
List players = new List(GamePlay.gpRemotePlayers());
for (int i = 0; i < players.Count; i++)
{
if (players[i].Army() == army) result += 1;
}
}
else if (GamePlay.gpPlayer() != null)
{
if (GamePlay.gpPlayer().Army() == army) return 1;
result = 0;
}
return result;
}
public static int gpNumberOfPlayersActive(this IGamePlay GamePlay, int army)
int result = 0;
if (GamePlay.gpRemotePlayers() != null || GamePlay.gpRemotePlayers().Length > 0)
{
List players = new List(GamePlay.gpRemotePlayers());
for (int i = 0; i < players.Count; i++)
{
if (players[i].Army() == army)
{
if (players[i].Place() == null) continue;
if (players[i].Place() as AiAircraft == null) continue;
AiAircraft aircraft = players[i].Place() as AiAircraft;
double altAGL_m = aircraft.getParameter(part.ParameterTypes.Z_AltitudeAGL, 0);
}
}
}
else if (GamePlay.gpPlayer() != null)
{
if (GamePlay.gpPlayer().Army() == army) return 1;
result = 0;
}
return result;
}
public static int KillActorsByNameMatch(ABattle battle, IGamePlay GamePlay, AMission mission, Dictionary actors, string name = "", int matcharmy = 0, string type = "")
{
List l = GetActorsByNameMatch(GamePlay, mission, actors, name, matcharmy, type, onlyArtilleryAndVehicles: true);
return KillActorsOnList(battle, mission, l);
}
public static int KillGroundActorsNear(ABattle battle, IGamePlay GamePlay, AMission mission, Dictionary groundActors, Point3d location, double radius_m, int matcharmy = 0, string type = "")
{
List l = GetGroundActorsNear(GamePlay, mission, groundActors, location, radius_m, matcharmy, type, onlyArtilleryAndVehicles: true);
return KillActorsOnList(battle, mission, l);
}
public static int KillActorsOnList(ABattle battle, AMission mission, List l)
{
int count = 0;
foreach (AiActor a in l)
{
try
{
if (a == null) continue;
count++;
}
catch (Exception ex)
{
Console.WriteLine("Calcs.KillActorsOnList ERROR: " + ex.ToString());
}
}
return count;
}
public static AiActor GetGroundActorNear(this IGamePlay GamePlay, AMission mission, Dictionary groundActors, Point3d location, double radius_m, int matcharmy = 0, string type = "", bool onlyArtilleryAndVehicles = false)
{
List l = GetGroundActorsNear(GamePlay, mission, groundActors, location, radius_m, matcharmy, type, onlyArtilleryAndVehicles: onlyArtilleryAndVehicles);
if (l.Count == 0) return null;
int index = clc_random.Next(l.Count);
return l[index];
}
public static List GetGroundActorsNear(this IGamePlay GamePlay, AMission mission, Dictionary groundActors, Point3d location, double radius_m, int matcharmy = 0, string type = "", bool onlyArtilleryAndVehicles = false)
{
List l = new List();
foreach (AiActor actor in groundActors.Values)
{
if ((actor as AiGroundActor) == null) continue;
if (matcharmy > 0 && (actor as AiGroundActor).Army() != matcharmy) continue;
bool art = isActorArtillery(actor);
bool veh = isActorVehicle(actor);
if (onlyArtilleryAndVehicles && !art && !veh) continue;
if (type.ToLower() == "vehicle" && !veh) continue;
if (type.ToLower() == "artillery" && !art) continue;
if (CalculatePointDistance(location, actor.Pos()) > radius_m) continue;
l.Add(actor);
}
return l;
}
public static List GetActorsNear(this IGamePlay GamePlay, AMission mission, Dictionary aircraftDict, Point3d location, double radius_m, int matcharmy = 0, string type = "")
{
List l = new List();
type = type.ToLower();
foreach (AiActor actor in aircraftDict.Values)
{
if (type == "groundactor" && (actor as AiGroundActor) == null) continue;
if (type == "aircraft" && (actor as AiAircraft) == null) continue;
if (!actor.IsValid() || !actor.IsAlive()) continue;
if (type == "aircraft" && (actor as AiAircraft).IsKilled()) continue;
if (matcharmy > 0 && actor.Army() != matcharmy) continue;
bool art = isActorArtillery(actor);
bool veh = isActorVehicle(actor);
if (type.ToLower() == "vehicle" && !veh) continue;
if (type.ToLower() == "artillery" && !art) continue;
if (CalculatePointDistance(location, actor.Pos()) > radius_m) continue;
l.Add(actor);
}
return l;
}
public static int CountGroundActors(this IGamePlay GamePlay, AMission mission, Dictionary groundActors, Point3d location, double radius_m, int matcharmy = 0, string type = "", bool onlyArtilleryAndVehicles = false)
{
int count = 0;
/*
if (GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
if (matcharmy != 0 && matcharmy != army) continue;
if (GamePlay.gpGroundGroups(army) != null && GamePlay.gpGroundGroups(army).Length > 0)
{
foreach (AiGroundGroup groundGroup in GamePlay.gpGroundGroups(army))
{
if (type != null && groundGroup.GroupType() != type) continue;
Point3d grouppos = new Point3d(-100000, -100000, -100000);
groundGroup.GetPos(out grouppos);
if (Calcs.CalculatePointDistance(location, grouppos) > 5 * radius_m) continue;
if (groundGroup.GetItems() != null && groundGroup.GetItems().Length > 0)
{
foreach (AiActor actor in groundGroup.GetItems())
{
if ((AiGroundActor)actor == null) continue;
if (CalculatePointDistance(location, actor.Pos()) > radius_m) continue;
count++;
}
}
}
}
}
} */
foreach (AiActor actor in groundActors.Values)
{
try
{
if (actor == null || actor as AiGroundActor == null) continue;
if (matcharmy > 0 && (actor as AiGroundActor).Army() != matcharmy) continue;
bool art = isActorArtillery(actor);
bool veh = isActorVehicle(actor);
if (onlyArtilleryAndVehicles && !art && !veh) continue;
if (type.ToLower() == "vehicle" && !veh) continue;
if (type.ToLower() == "artillery" && !art) continue;
if (CalculatePointDistance(location, actor.Pos()) > radius_m) continue;
count++;
}
catch (Exception ex) { Console.WriteLine("CountGroundActors inner loop ERROR: " + ex.ToString()); }
}
return count;
}
public static AiGroundActorType[] agatArtillery = { AiGroundActorType.AAGun, AiGroundActorType.Artillery };
public static bool isActorArtillery(AiActor actor)
{
AiGroup aig = actor.Group();
if ((aig as AiGroundGroup) != null && (aig as AiGroundGroup).GroupType() == AiGroundGroupType.Artillery) return true;
AiGroundActor gactor = actor as AiGroundActor;
if (gactor == null) return false;
if (agatArtillery.Contains(gactor.Type())) return true;
return false;
}
public static AiGroundActorType[] agatVehicle = { AiGroundActorType.Amphibian, AiGroundActorType.Bus, AiGroundActorType.Car, AiGroundActorType.LightTruck, AiGroundActorType.Motorcycle, AiGroundActorType.SPG, AiGroundActorType.Tank, AiGroundActorType.Tractor, AiGroundActorType.Trailer, AiGroundActorType.Truck };
public static bool isActorVehicle(AiActor actor)
{
AiGroup aig = actor.Group();
if ((aig as AiGroundGroup) != null && (aig as AiGroundGroup).GroupType() == AiGroundGroupType.Vehicle) return true;
AiGroundActor gactor = actor as AiGroundActor;
if (gactor == null) return false;
if (agatVehicle.Contains(gactor.Type())) return true;
return false;
}
public static int CountGroundArtillery(this IGamePlay GamePlay, Point3d location, double radius_m, int matcharmy = 0)
{
int count = 0;
string matchstring = "gb";
if (matcharmy == 2) matchstring = "de";
List gs = GamePlay.gpGroundStationarys(location.x, location.y, radius_m).ToList();
foreach (GroundStationary g in gs)
{
if (matcharmy > 0 && g.country != matchstring) continue;
if (g.Type == AiGroundActorType.AAGun || g.Type == AiGroundActorType.Artillery) count++;
}
return count;
}
public static int CountMatchingGroundObjects(this IGamePlay GamePlay, Point3d location, double radius_m, string matchTitle = null, AiGroundActorType matchType = AiGroundActorType.Unknown, string matchName = null, int matcharmy = 0, bool? matchAlive = true, bool antiMatch = false)
{
try
{
int count = 0;
string matchstring = "gb";
if (matcharmy == 2) matchstring = "de";
List gs = GamePlay.gpGroundStationarys(location.x, location.y, radius_m).ToList();
foreach (GroundStationary g in gs)
{
if (matcharmy > 0 && g.country != matchstring) continue;
if (matchAlive.HasValue && matchAlive.Value != g.IsAlive) continue;
if (antiMatch)
{
if (matchTitle != null && g.Title.ToLower().Contains(matchTitle.ToLower())) continue;
if (g.Type != AiGroundActorType.Unknown && g.Type == matchType) continue;
if (matchName != null && g.Name.ToLower().Contains(matchName.ToLower())) continue;
}
else
{
if (matchTitle != null && !g.Title.ToLower().Contains(matchTitle.ToLower())) continue;
if (g.Type != AiGroundActorType.Unknown && g.Type != matchType) continue;
if (matchName != null && !g.Name.ToLower().Contains(matchName.ToLower())) continue;
}
count++;
}
return count;
} catch (Exception ex) { Console.WriteLine("ERROR CountMatchingGroundObjects: " + ex.ToString()); return 0; }
}
public static AiGroundGroup nearestGroundGroup(this IGamePlay GamePlay, Point3d location, double radius_m, int matcharmy = 0, AiGroundGroupType type = AiGroundGroupType.Vehicle, int randomness = 0)
{
int count = 0;
double distance = radius_m;
int numInGroup = 0;
AiGroundGroup foundgg = null;
if (GamePlay != null && GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
try
{
foreach (int army in GamePlay.gpArmies())
{
if (matcharmy != 0 && matcharmy != army) continue;
if (GamePlay.gpGroundGroups(army) != null && GamePlay.gpGroundGroups(army).Length > 0)
{
AiGroundGroup[] aggs = GamePlay.gpGroundGroups(army);
Calcs.Randomize(aggs);
foreach (AiGroundGroup groundGroup in aggs)
{
if (groundGroup == null) continue;
if (!GamePlay.gpActorIsValid(groundGroup)) continue;
if (type != null && groundGroup.GroupType() != type) continue;
Point3d grouppos = new Point3d(-100000, -100000, -100000);
groundGroup.GetPos(out grouppos);
double temp_distance = Calcs.CalculatePointDistance(location, grouppos);
int temp_numInGroup = groundGroup.GetItems().Length;
if (temp_distance > radius_m) continue;
if (count == 0 && temp_numInGroup > 0) { foundgg = groundGroup; distance = temp_distance; numInGroup = temp_numInGroup; count++; continue; }
if ((temp_distance < distance && temp_numInGroup > 2) || clc_random.Next(0, 100) < randomness) { foundgg = groundGroup; distance = temp_distance; numInGroup = temp_numInGroup; count++; }
}
}
}
}
catch (Exception ex) { Console.WriteLine("nearestGroundGroup ERROR: " + ex.ToString()); }
}
return foundgg;
}
public static double distanceToNearestAirport(this IGamePlay GamePlay, AiActor actor)
{
if (actor == null) return 10000000000000000.0;
Point3d pd = actor.Pos();
return distanceToNearestAirport(GamePlay, actor.Pos(), actor.Army());
}
public static double distanceToNearestAirport(this IGamePlay GamePlay, Point3d pd, int army)
{
if (GamePlay == null) return d2;
double d2Min = d2;
int n = GamePlay.gpAirports().Length;
for (int i = 0; i < n; i++)
{
AiActor a = (AiActor)GamePlay.gpAirports()[i];
if (a == null) continue;
if (GamePlay.gpFrontArmy(a.Pos().x, a.Pos().y) != army) continue;
Point3d pp;
pp = a.Pos();
pd.z = pp.z;
d2 = pd.distanceSquared(ref pp);
if (d2 < d2Min)
{
d2Min = d2;
}
}
return Math.Sqrt(d2Min);
}
public static AiAirport nearestAirport(this IGamePlay GamePlay, Point3d location, int army = 0)
{
AiAirport NearestAirfield = null;
if (GamePlay == null) return null;
AiAirport[] airports = GamePlay.gpAirports();
Point3d StartPos = location;
if (airports != null)
{
foreach (AiAirport airport in airports)
{
AiActor a = airport as AiActor;
if (a == null || !a.IsValid()) continue;
if (army != 0 && GamePlay.gpFrontArmy(a.Pos().x, a.Pos().y) != army) continue;
if (NearestAirfield != null)
{
if (NearestAirfield.Pos().distanceSquared(ref StartPos) > airport.Pos().distanceSquared(ref StartPos))
NearestAirfield = airport;
}
else NearestAirfield = airport;
}
}
return NearestAirfield;
}
public static AiAirport AirportByName(this IGamePlay GamePlay, string name)
{
if (GamePlay == null) return null;
AiAirport[] airports = GamePlay.gpAirports();
if (airports != null)
{
foreach (AiAirport airport in airports)
{
AiActor a = airport as AiActor;
if (a is object && a.Name() == name) return airport;
}
}
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces().ToList())
{
if (bp == null) continue;
if (bp.Name() == name)
{
Point3d bp_pos = bp.Pos();
if (airports != null)
{
foreach (AiAirport airport in airports)
{
AiActor a = airport as AiActor;
if (a == null) continue;
if (Calcs.CalculatePointDistance( bp_pos,a.Pos()) <= airport.FieldR()) return airport;
}
}
}
}
return null;
}
public static bool KillStationary(ABattle battle, AMission mission, GroundStationary gs, int waitTime = 0)
{
if (gs != null)
{
mission.Timeout(waitTime, () =>
{
battle.OnEventGame(GameEventId.StationaryKilled, gs, null, 0);
});
return true;
}
return false;
}
public static bool KillActor(ABattle battle, AMission mission, AiActor actor, int waitTime = 0)
{
if (actor != null)
{
mission.Timeout(waitTime, () =>
{
battle.OnEventGame(GameEventId.ActorDead, actor, battle.GetDamageInitiators(actor), 0);
});
return true;
}
return false;
}
public static List GetActorsByNameMatch(this IGamePlay GamePlay, AMission mission, Dictionary actors, string name = "", int matcharmy = 0, string type = "", bool onlyArtilleryAndVehicles= false, bool completeList=false)
{
try
{
List l = new List();
foreach (AiActor actor in actors.Values.ToList())
{
if (actor == null) continue;
if (!actor.Name().ToLower().Contains(name.ToLower())) continue;
if (matcharmy > 0 && actor.Army() != matcharmy) continue;
bool art = isActorArtillery(actor);
bool veh = isActorVehicle(actor);
if (!completeList && type.ToLower() == "vehicle" && !veh) continue;
if (!completeList && type.ToLower() == "artillery" && !art) continue;
l.Add(actor);
}
return l;
}
catch (Exception ex)
{
Console.WriteLine("Calcs.GetActorsByNameMatch ERROR: " + ex.ToString());
return new List();
}
}
public static AiAirport nearestAirport(this IGamePlay GamePlay, AiActor actor, int army = 0)
{
if (actor == null) return null;
Point3d pd = actor.Pos();
return nearestAirport(GamePlay, pd, army);
}
public static double distanceToNearestBirthplace(IGamePlay GamePlay, Point3d location, int army = 0)
{
Point3d StartPos = location;
double bestDist_m = 1000000000000;
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (army > 0 && bp.Army() != army) continue;
Point3d bp_pos = bp.Pos();
double dist = CalculatePointDistance(bp_pos, location);
}
return bestDist_m;
}
public static AiBirthPlace nearestBirthplace(IGamePlay GamePlay, Point3d location, out double distance_m, int army = 0)
{
Point3d StartPos = location;
double bestDist_m = 1000000000000;
AiBirthPlace return_bp = null;
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
{
if (army > 0 && bp.Army() != army) continue;
Point3d bp_pos = bp.Pos();
double dist = CalculatePointDistance(bp_pos, location);
if (dist < bestDist_m)
{
return_bp = bp;
}
}
distance_m = bestDist_m;
return return_bp;
}
public static AiBirthPlace nearestBirthplace(IGamePlay GamePlay, AiActor actor, out double distance_m, int army = 0)
{
distance_m = 0;
if (actor == null) return null;
if (army == null) return null;
Point3d pd = actor.Pos();
var bp = nearestBirthplace(GamePlay, pd, out distance_m, army);
return bp;
}
public static T chooseRandomElement(this IList list)
{
if (list == null || list.Count == 0) return default(T);
return list[clc_random.Next(list.Count)];
}
public static void Shuffle(this IList list)
{
if (list == null || list.Count == 0) return;
for (var i = 0; i < list.Count; i++)
list.Swap(i, clc_random.Next(i, list.Count));
}
public static void Swap(this IList list, int i, int j)
{
var temp = list[i];
list[i] = list[j];
list[j] = temp;
}
public static async Task WriteAllTextAsyncWithBackups(string data, string fileDir_base, string fileName_base, string suffix, string ext, string backupDirStub, bool wait = false, ManualResetEvent resetEvent = null)
{
DateTime dt = DateTime.UtcNow;
string date = dt.ToString("u");
TimeSpan now = DateTime.UtcNow.TimeOfDay;
string backupDirFile = fileDir_base + backupDirStub + fileName_base + suffix + "-" + dt.ToString("yyyy-MM-dd-HH");
if (wait) backupDirFile = fileDir_base + backupDirStub + fileName_base + suffix + "-" + dt.ToString("yyyy-MM-dd-HH-mm-ss");
string filename_main = fileDir_base + fileName_base + suffix + ext;
string backupTxtFile2 = fileDir_base + fileName_base + suffix + "_old2" + ext;
string backupTxtFile1 = fileDir_base + fileName_base + suffix + "_old" + ext;
string tempNewTxtFile = fileDir_base + fileName_base + suffix + "_tmp" + ext;
try
{
try
{
System.IO.File.Delete(tempNewTxtFile);
}
catch (Exception ex) { }
try
{
await WriteAllTextAsync(tempNewTxtFile, data);
}
catch (Exception ex) {
Console.WriteLine("WriteAllTextAsyncWithBackups ERROR writing-ABORTING SAVE!! " + fileName_base + suffix + "_tmp" + ext + ": " + ex.Message);
if (resetEvent != null) resetEvent.Set();
return false;
}
if (System.IO.File.Exists(tempNewTxtFile)) {
try
{
System.IO.File.Delete(backupDirFile);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR deleting " + backupDirFile + ": " + ex.Message); }
try
{
System.IO.File.Copy(tempNewTxtFile, backupDirFile);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR moving to backup " + fileName_base + suffix + "_tmp" + ext + ": " + ex.Message); }
try
{
System.IO.File.Delete(backupTxtFile2);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR deleting " + fileName_base + suffix + "_old2" + ext + ": " + ex.Message); }
try
{
System.IO.File.Move(backupTxtFile1, backupTxtFile2);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR moving to " + fileName_base + suffix + "_old2" + ext + ": " + ex.Message); }
try
{
System.IO.File.Delete(backupTxtFile1);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR deleting " + fileName_base + suffix + "_old" + ext + ": " + ex.Message); }
try
{
System.IO.File.Copy(filename_main, backupTxtFile1);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR copying to " + fileName_base + suffix + "_old" + ext + ": " + ex.Message); }
try
{
System.IO.File.Delete(filename_main);
}
catch (Exception ex) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR deleting " + fileName_base + suffix + ext + ": " + ex.Message); }
try
{
System.IO.File.Move(tempNewTxtFile, filename_main);
} catch (Exception ex)
{
string r = dt.ToString("yyyy-MM-dd-HHmmss");
try
{
System.IO.File.Move(tempNewTxtFile, filename_main + "EMERGENCY_SAVE" + "-" + r);
}
catch (Exception ex1) { Console.WriteLine("WriteAllTextAsyncWithBackups ERROR on emergency save " + fileName_base + suffix + ext + ": " + ex1.ToString()); }
}
} else
{
Console.WriteLine("WriteAllTextAsync ERROR - file write FAILED: " + fileName_base + suffix + "_tmp" + ext);
}
if (resetEvent != null) resetEvent.Set();
return false;
}
catch (Exception ex)
{
Console.WriteLine("WriteAllTextAsync ERROR writing " + fileName_base + suffix + "_tmp" + ext + ": " + ex.Message);
if (resetEvent != null) resetEvent.Set();
return false;
}
}
public static async Task WriteAllTextAsync(string filelocation, string data, bool wait = false, ManualResetEvent resetEvent = null)
{
try
{
using (var sw = new StreamWriter(filelocation))
{
/*
int count = 0;
if (wait)
{
*
while (count < 10)
{
Task task = Calcs.WriteAllTextAsync(filepath, xmlString);
bool res = await task;
if (res) break;
Console.WriteLine("MO_WriteMissionObject: Attempt #" + count.ToString() + " to write " + name + " not successful");
Thread.Sleep(1);
count++;
}*
Task task = sw.WriteAsync(data);
await task;
}
else */
await sw.WriteAsync(data);
}
return true;
}
catch (Exception ex)
{
Console.WriteLine("WriteAllTextAsync ERROR writing " + filelocation + ": " + ex.ToString());
if (resetEvent != null) resetEvent.Set();
return false;
}
}
public static void removeArtilleryAAGroundVehicles(IGamePlay GamePlay, AMission mission, Dictionary groundActors, double x_m, double y_m, double radius_m, int matcharmy = 0)
{
{
try
{
Console.WriteLine("Removing artillery, AA, and ground vehicles at " + x_m.ToString() + ", " + y_m.ToString() + " radius: " + radius_m.ToString());
string matchstring = "";
if (matcharmy == 1) matchstring = "gb";
if (matcharmy == 2) matchstring = "de";
int countStat = 0;
int countAct = 0;
try
{
List gs = GamePlay.gpGroundStationarys(x_m, y_m, radius_m).ToList();
if (gs != null) foreach (GroundStationary g in gs)
{
try
{
if (g == null || (g as GroundStationary) == null) continue;
Console.WriteLine("Groundstat within radius: " + g.Name + " " + g.country + " " + g.Title + " " + g.Type.ToString());
if (matcharmy > 0 && g.country != matchstring) continue;
if (g.Type == AiGroundActorType.AAGun || g.Type == AiGroundActorType.Artillery)
{
mission.Timeout(clc_random.Next(0, 76), () =>
{
if (g != null)
{
Console.WriteLine("Groundstat DESTROYING " + g.Name + " " + g.country + " " + g.Title + " " + g.Type.ToString());
g.Destroy();
}
countStat++;
}
}
catch (Exception ex) { Console.WriteLine("RemoveAllGroundStationariesActors: STATIONARIES INNER LOOP ERROR! " + ex.ToString()); }
}
/*
if (GamePlay.gpArmies() != null && GamePlay.gpArmies().Length > 0)
{
foreach (int army in GamePlay.gpArmies())
{
if (matcharmy != 0 && matcharmy != army) continue;
if (GamePlay.gpGroundGroups(army) != null && GamePlay.gpGroundGroups(army).Length > 0)
{
foreach (AiGroundGroup groundGroup in GamePlay.gpGroundGroups(army))
{
Point3d grouppos = new Point3d(-100000, -100000, -100000);
groundGroup.GetPos(out grouppos);
Console.WriteLine("Groundgroup " + groundGroup.ID() + " " + groundGroup.GroupType().ToString() + " at " + grouppos.ToString() + " | " + Calcs.CalculatePointDistance(new Point2d(x_m, y_m), grouppos).ToString() + " R " + radius_m.ToString());
if (groundGroup.GetItems() != null && groundGroup.GetItems().Length > 0)
{
foreach (AiActor actor in groundGroup.GetItems())
{
Console.WriteLine("Groundact " + actor.Name() + " at " + actor.Pos().ToString() + " health " + (actor as AiGroundActor).Health().ToString());
if ((AiGroundActor)actor == null) continue;
if (CalculatePointDistance(new Point2d(x_m, y_m), actor.Pos()) > radius_m) continue;
mission.Timeout(clc_random.Next(5, 10), () => {
string firetype = "BuildingFireSmall";
if (clc_random.NextDouble() < 0.6333) firetype = "Smoke1";
if (clc_random.NextDouble() < 0.3333) Calcs.loadSmokeOrFire(GamePlay, mission, actor.Pos().x, actor.Pos().y, 0, firetype);
(actor as AiCart).Destroy();
});
countAct++;
}
}
}
} */
}
catch (Exception ex) { Console.WriteLine("RemoveAllGroundStationariesActors: STATIONARIES 1 ERROR! " + ex.ToString()); }
try
{
foreach (AiActor actor in groundActors.Values)
{
if (actor == null || (AiGroundActor)actor == null) continue;
if (matcharmy > 0 && (actor as AiGroundActor).Army() != matcharmy) continue;
if (CalculatePointDistance(new Point2d(x_m, y_m), actor.Pos()) > radius_m) continue;
Console.WriteLine("Groundact " + actor.Name() + " at " + actor.Pos().ToString() + " health " + (actor as AiGroundActor).Health().ToString());
mission.Timeout(clc_random.Next(1, 30), () =>
{
string firetype = "BuildingFireSmall";
if (actor != null)
{
Console.WriteLine("Groundact DESTROYING " + actor.Name() + " at " + actor.Pos().ToString() + " health " + (actor as AiGroundActor).Health().ToString());
(actor as AiCart).Destroy();
}
});
countAct++;
}
}
catch (Exception ex) { Console.WriteLine("RemoveAllGroundStationariesActors: ACTORS ERROR! " + ex.ToString()); }
Console.WriteLine("removeArtilleryAAGroundVehicles at {0:n0}, {1:n} radius {2:n}. Removed {3} stationaries, {4} groundactors", new object[] { x_m, y_m, radius_m, countStat, countAct });
}
catch (Exception ex) { Console.WriteLine("RemoveAllGroundStationariesActors: ERROR! " + ex.ToString()); }
}
public static bool anyEnemyOrNeutralStationaries(IGamePlay GamePlay, double x, double y, double radius, int myArmy)
{
bool ret = false;
string myCountry = "gb";
if (myArmy == 2) myCountry = "de";
foreach (GroundStationary sta in GamePlay.gpGroundStationarys(x, y, radius))
{
if (sta == null) continue;
if (sta.country != myCountry) return true;
}
return ret;
}
public static bool anyEnemyStationaries(IGamePlay GamePlay, double x, double y, double radius, int myArmy)
{
bool ret = false;
string enemyCountry = "de";
if (myArmy == 2) enemyCountry = "gb";
foreach (GroundStationary sta in GamePlay.gpGroundStationarys(x, y, radius))
{
if (sta == null) continue;
if (sta.country == enemyCountry) return true;
}
return ret;
}
public static ISectionFile changeArmyToTerritory_SectionFile(ISectionFile f, maddox.game.IGamePlay GamePlay, AMission mission)
{
try
{
string key = "";
string value = "";
var armyLists = new List>()
{
new List() { "nn" },
new List() { "gb", "us", "fr", "gb", "ru", "rz" },
new List() { "de", "it", "hu", "fi", "ja", "ro", "sa" },
};
string[] mainArmy = { "nn", "gb", "de" };
/*
List neutralarmies = new List() { "nn" };
string newarmy = "nn";
var blueArmies = new List() { "de", "it", "hu", "fi", "ja", "ro", "sa" };
string mainBlueArmy = "de";
var redArmies = new List() { "gb", "us", "fr", "gb", "ru", "rz" };
string mainRedArmy = "gb";
*/
List chiefs = new List();
foreach (string section in sections)
{
if (f.exist(section))
{
int num = f.lines(section);
Console.WriteLine("{0}: {1} lines", section, num);
for (int i = 0; i < num; i++)
{
f.get(section, i, out key, out value);
/* Example lines
* [Stationary]
Static9 Stationary.Environment.JerryCan_GER1_1 nn 264829.47 166242.72 659.10
Static6 Stationary.Environment.JerryCan_GER1_1 nn 264819.81 166258.67 659.10
Static5 Stationary.Radar.Wotan_II de 264833.13 166251.84 659.10
Static9 is KEY and the remainder is VALUE. dur.
*/
double x = 0;
double y = 0;
if (!double.TryParse(values[2], out x)) continue;
if (!double.TryParse(values[3], out y)) continue;
if (x == 0 && y == 0) continue;
int terr = GamePlay.gpFrontArmy(x,y);
if (terr <= 0 || terr > 2) continue;
foreach (string oldarmy in armyLists[3 - terr])
{
string newvalue = value.Replace(" " + oldarmy + " ", " " + mainArmy[terr] + " ");
if (newvalue.Length >= 3 && newvalue.TrimEnd().Substring(newvalue.Length - 3) == " " + oldarmy)
newvalue = newvalue.TrimEnd().Substring(0, newvalue.Length - 2) + mainArmy[terr];
if (!newvalue.Equals(value))
{
f.set(section, key, newvalue);
break;
}
}
}
}
}
Console.WriteLine("Returning: St: {0} Ch: {1}", f.lines("Stationary"), f.lines("Chiefs"));
return f;
}
catch (Exception ex) { Console.WriteLine("Calcs.changeArmyToTerritory_SectionFile ERROR: " + ex.ToString()); return f; }
}
public static ISectionFile changeArmy_Waypoints_SectionFile(ISectionFile f, maddox.game.IGamePlay GamePlay, AMission mission, int changeToArmy, int maxWaypoints_remove = 0, double maxPercentWaypoints_remove = 0 )
{
try
{
string key = "";
string value = "";
List oldarmies = new List() { "nn" };
string newarmy = "nn";
if (changeToArmy == 1)
{
oldarmies = new List() { "de", "it", "hu", "fi", "ja", "ro", "sa" };
newarmy = "gb";
}
if (changeToArmy == 2)
{
oldarmies = new List() { "gb", "us", "fr", "gb", "ru", "rz" };
newarmy = "de";
}
List sections = new List() { "Chiefs", "Stationary" };
List chiefs = new List();
foreach (string section in sections)
{
if (f.exist(section))
{
int num = f.lines(section);
Console.WriteLine("{0}: {1} lines", section, num);
for (int i = 0; i < num; i++)
{
f.get(section, i, out key, out value);
if (section == "Chiefs") chiefs.Add(key);
foreach (string oldarmy in oldarmies)
{
string newvalue = value.Replace(" " + oldarmy + " ", " " + newarmy + " ");
if (newvalue.Length >= 3 && newvalue.TrimEnd().Substring(newvalue.Length - 3) == " " + oldarmy)
newvalue = newvalue.TrimEnd().Substring(0, newvalue.Length - 2) + newarmy;
if (!newvalue.Equals(value))
{
Console.WriteLine("New: {0:n0} {1} {2} ", i, key, newvalue);
f.set(section, key, newvalue);
break;
}
}
}
}
}
Console.WriteLine("No. of Chiefs found: {0:n0}", chiefs.Count);
foreach (string chief in chiefs)
{
string section = chief + "_Road";
Console.WriteLine("Checking for: {0}", section);
if (f.exist(section))
{
int num = f.lines(section);
double maxNumToTrim = num * maxPercentWaypoints_remove / 100.0;
if (maxNumToTrim > maxWaypoints_remove) maxNumToTrim = maxWaypoints_remove;
int numWaypoints_remove = clc_random.Next(Convert.ToInt32(Math.Round(maxNumToTrim)));
Console.WriteLine("Removing Waypoints in {3}: MaxnumtoTrim {0:n0} numWaypoints_remove {1:n0}, num total: {2:n0}", maxNumToTrim, numWaypoints_remove, num, section);
if (numWaypoints_remove > 0) for (int i = numWaypoints_remove - 1; i >= 0; i--)
{
f.delete(section, i);
}
int newnum = f.lines(section);
for (int i = 0; i < newnum; i++)
{
f.get(section, i, out key, out value);
}
}
}
Console.WriteLine("Returning: St: {0} Ch: {1}", f.lines("Stationary"), f.lines("Chiefs"));
return f;
}
catch (Exception ex) { Console.WriteLine("Calcs.printSectionFile ERROR: " + ex.ToString()); return f; }
}
public static int numBuildingsInSector(double x, double y)
{
return numBuildingsInSector(new Point3d(x, y, 0));
}
public static int numBuildingsInSector(Point3d pos)
{
try
{
int iX = Convert.ToInt32(pos.x) / 10000;
int iY = Convert.ToInt32(pos.y) / 10000;
int ct = twcLandscape.getBuildingCountInBlock(iX, iY);
if (ct == 0) return 0;
int remX = Convert.ToInt32(pos.x) % 10000;
int remY = Convert.ToInt32(pos.y) % 10000;
int secX = remX / 32;
int secY = remY / 32;
int secNum = 32 * secY + secX;
int[] blockOffset;
int blockCount;
int[] codes;
int codeslength;
int ct2 = twcLandscape.getBuildingBlocks(iX, iY, out blockOffset, out blockCount, out codes, out codeslength);
if (blockCount == 0) return 0;
if (blockOffset.Length <= secNum) return 0;
if (blockOffset[secNum] == -1) return 0;
int begNum = blockOffset[secNum];
int endNum = codeslength;
for (int i = secNum + 1; i < blockOffset.Length; i++)
{
if (i % 32 == 0) Console.Write("\n");
if (blockOffset[i] == -1) continue;
endNum = blockOffset[i];
break;
}
return endNum - begNum;
}
catch (Exception ex) { Console.WriteLine("ERROR Calcs.numBuildingsInSector: " + ex.ToString()); return 0; }
}
public static bool isPointInOrNearWater(maddox.game.IGamePlay GamePlay, Point3d pos, int radius_m = 10)
{
if (GamePlay.gpLandType(pos.x, pos.y) == maddox.game.LandTypes.WATER) return true;
int steps = radius_m / 3;
for (int i = 0; i < steps; i++)
{
Point3d checkPos = new Point3d();
checkPos.x = pos.x + Math.Cos(i) * radius_m;
checkPos.y = pos.y + Math.Sin(i) * radius_m;
if (GamePlay.gpLandType(checkPos.x, checkPos.y) == maddox.game.LandTypes.WATER) return true;
}
return false;
}
public static bool isPointOnWaterSimple(maddox.game.IGamePlay GamePlay, Point3d pos)
{
if (GamePlay.gpLandType(pos.x, pos.y) == maddox.game.LandTypes.WATER) return true;
return false;
}
private static int lSOFcount = 0;
private static int lSOFruns = 0;
public static ISectionFile loadSmokeOrFire(maddox.game.IGamePlay GamePlay, AMission mission, double x, double y, double z, string type = "BuildingFireSmall", double duration_s = 300, ISectionFile f = null, bool resetCount = false)
{
/* Sample: Static556 Smoke.Environment.Smoke1 nn 63718.50 187780.80 110.00 /hstart 16.24
possible types: Smoke1 Smoke2 BuildingFireSmall BuildingFireBig BigSitySmoke_0 BigSitySmoke_1
Not sure if height is above sea level or above ground level.
NOTE THAT as of CloD 4.57 you can create these objects but you can't get their handle back via groundstationarys to delete/remove/destroy them later.
These are the only groundstationaries I know about that have this problem.
Example of how to get groundstationaries within a distance of a given point--except not that it will NOT list any smoke or fire groundstationaries!
[code]
[/code]
*/
if ((type.ToLower().Contains("crater") || type.ToLower().Contains("fire") ||
(type.ToLower().Contains("smoke") && clc_random.Next(10) > 0))
&& isPointInOrNearWater(GamePlay, new Point3d(x, y, z), radius_m: 10)) return f;
lSOFruns++;
if (resetCount) lSOFcount = 0;
bool returnFile = true;
if (f == null) { f = GamePlay.gpCreateSectionFile(); returnFile = false; }
string sect = "Stationary";
string key = "Static_TWCLSOF_R" + lSOFruns + "_" + lSOFcount.ToString("F0");
string value = "Smoke.Environment." + type + " nn " + x.ToString("0.00") + " " + y.ToString("0.00") + " " + (duration_s / 60).ToString("0.0") + " /hstart " + z.ToString("0.00");
f.add(sect, key, value);
lSOFcount++;
Console.WriteLine("PostmissionLoad: LoadSmokeOrFire");
if (!returnFile) GamePlay.gpPostMissionLoad(f);
return f;
}
/*************************************************
*
* Handle smoke, fire, crater ISection files for area bombing, civilian bombing, airport bombing
* Specifically, craters & smoke for airport bombing
*
********************************************************/
public static void loadCratersAndSmoke(IGamePlay GamePlay, Mission msn, double x, double y, double z, string type = "", double duration_s = 300, string path = "", string type2 = "")
{
/*
NOTE THAT as of CloD 4.57 you can create these objects but you can't get their handle back via groundstationarys to delete/remove/destroy them later.
These are the only groundstationaries I know about that have this problem.
Example of how to get groundstationaries within a distance of a given point--except not that it will NOT list any smoke or fire groundstationaries!
[code]
[/code]
*/
/* Samples:
* Static555 Smoke.Environment.Smoke1 nn 63748.22 187791.27 110.00 /height 16.24
Static556 Smoke.Environment.Smoke1 nn 63718.50 187780.80 110.00 /height 16.24
Static557 Smoke.Environment.Smoke2 nn 63688.12 187764.03 110.00 /height 16.24
Static534 Smoke.Environment.BuildingFireSmall nn 63432.15 187668.28 110.00 /height 15.08
Static542 Smoke.Environment.BuildingFireBig nn 63703.02 187760.81 110.00 /height 15.08
Static580 Smoke.Environment.BigSitySmoke_0 nn 63561.45 187794.80 110.00 /height 17.01
Static580 Smoke.Environment.BigSitySmoke_1 nn 63561.45 187794.80 110.00 /height 17.01
Static0 Stationary.Environment.BombCrater_firmSoil_mediumkg nn 251217.50 257427.39 -520.00
Static2 Stationary.Environment.BombCrater_firmSoil_largekg nn 251211.73 257398.98 -520.00
Static1 Stationary.Environment.BombCrater_firmSoil_smallkg nn 251256.22 257410.66 -520.00
Not sure if height is above sea level or above ground level.
*/
if ((type.ToLower().Contains("crater") || type2.ToLower().Contains("fire"))
&& GamePlay.gpLandType(x, y) == maddox.game.LandTypes.WATER) return;
msn.Timeout(duration_s, () =>
{
Point2d P = new Point2d(x, y);
foreach (GroundStationary sta in GamePlay.gpGroundStationarys(x, y, 2))
{
if (sta == null) continue;
Console.WriteLine("Deleting " + sta.Name + " " + sta.Title);
if (sta.Name.Contains("smoke") || sta.Title.Contains("fire") || sta.Title.Contains("crater"))
{
Console.WriteLine("Deleting stationary bomb effect " + sta.Name + " - end of life");
sta.Destroy();
}
}
});
ISectionFile f = GamePlay.gpCreateSectionFile();
string sect = "Stationary";
string keybase = "Static_TWCLCOS_";
int count = 0;
List types = new List { };
if (type.Length > 0) types.Add(type);
if (type2.Length > 0) types.Add(type2);
foreach (string t in types)
{
string ttemp = t;
string val1 = "Smoke";
if (t.Contains("BombCrater")) val1 = "Stationary";
int lines = 1;
if (t == "BombCrater_firmSoil_EXlargekg")
{
ttemp = "BombCrater_firmSoil_largekg";
lines = 2;
}
count++;
string key = keybase + count.ToString();
string value = val1 + ".Environment." + ttemp + " nn " + x.ToString("0.00") + " " + y.ToString("0.00") + " " + clc_random.Next(0, 181).ToString("0.0") + " /hstart " + z.ToString("0.00");
f.add(sect, key, value);
if (lines == 2)
{
count++;
key = keybase + count.ToString();
value = val1 + ".Environment." + ttemp + " nn " + (x + 9).ToString("0.00") + " " + (y - 9).ToString("0.00") + " " + clc_random.Next(0, 181).ToString("0.0") + " /hstart " + z.ToString("0.00");
f.add(sect, key, value);
count++;
key = keybase + count.ToString();
value = val1 + ".Environment." + ttemp + " nn " + (x - 9).ToString("0.00") + " " + (y + 9).ToString("0.00") + " " + clc_random.Next(0, 181).ToString("0.0") + " /hstart " + z.ToString("0.00");
f.add(sect, key, value);
}
}
msn.Timeout(clc_random.NextDouble() * 45, () => {
if (msn.ON_TESTSERVER) Console.WriteLine("PostmissionLoad: LoadcratorOrsmoke");
GamePlay.gpPostMissionLoad(f);
});
}
public static void loadStatic(maddox.game.IGamePlay GamePlay, Mission mission, double x, double y, double z, string type = "Stationary.Opel_Blitz_cargo", double heading = 0, string side = "nn", string staticprefix = null)
{
/* side = nn , gb, or de
* Static4 Stationary.Environment.Table_empty_UK-GER_1 nn 14334.77 15015.75 661.10
Static2 Stationary.Scammell_Pioneer_R100 gb 14357.38 15036.04 661.10
Static7 Stationary.Airfield.Sign_Table_UK1 nn 14295.63 15054.30 661.10
Static5 Stationary.Environment.Table_w_chess_UK-GER_1 nn 14308.39 15048.51 661.10
Static6 Stationary.Environment.Table_w_dinner_UK-GER_1 nn 14306.36 15060.39 661.10
Static1 Stationary.Opel_Blitz_cargo de 14321.43 15065.61 661.10
Static0 Stationary.Horch_830_B1 de 14350.42 15056.62 661.10
Static65 Stationary.Humans.Kdo_Hi_Ger35_passenger_4 de 14345.22 15051.82 661.10 2
Static120 Stationary.Humans.Soldier_Krupp_L2H43_Driver_1 de 14342.67 15055.75 661.10 3
Static48 Stationary.Humans.Soldier_MG_TA_Passenger_1 de 14341.79 15056.98 661.10 4
Static66 Stationary.Humans.Ladder_passenger_ger_1 de 14344.66 15053.11 661.10 5
Static50 Stationary.Humans.150_cm_Flakscheinwerfer_gunner1 de 14343.99 15055.41 661.10 6
Static123 Stationary.Humans.Soldier_Krupp_L2H43_pak_Driver_1 de 14344.14 15054.25 661.10 7
Static119 Stationary.Humans.Soldier_Sdkfz105_Gunner de 14346.02 15052.77 661.10 8
Static71 Stationary.Humans.Portable_Siren_ger_passenger de 14347.25 15052.80 661.10 9
*/
ISectionFile f = GamePlay.gpCreateSectionFile();
string sect = "Stationary";
string key = "Static_TWCLoadStatic_1";
if (staticprefix != null) key = "Static_LS_" + staticprefix.Replace(' ','_') + "_1";
string value = type + " " + side + " " + x.ToString("0.00") + " " + y.ToString("0.00") + " " + heading.ToString("0.0") + " /hstart " + z.ToString("0.00");
f.add(sect, key, value);
if (mission.ON_TESTSERVER) Console.WriteLine("PostmissionLoad: LoadStatic");
GamePlay.gpPostMissionLoad(f);
}
private static int staticCount = 0;
private static int runCount = 0;
public static ISectionFile makeStatic(ISectionFile f, maddox.game.IGamePlay GamePlay, AMission mission, double x, double y, double z, string type = "Stationary.Opel_Blitz_cargo", double heading = 0, string side = "nn", int radiusHide = 0, int? chiefNum = null, bool resetCount = false, bool desertskin=false, string addString = "", string staticprefix = "", string sect = null)
{
/* side = nn , gb, or de
* Static4 Stationary.Environment.Table_empty_UK-GER_1 nn 14334.77 15015.75 661.10
Static2 Stationary.Scammell_Pioneer_R100 gb 14357.38 15036.04 661.10
Static7 Stationary.Airfield.Sign_Table_UK1 nn 14295.63 15054.30 661.10
Static5 Stationary.Environment.Table_w_chess_UK-GER_1 nn 14308.39 15048.51 661.10
Static6 Stationary.Environment.Table_w_dinner_UK-GER_1 nn 14306.36 15060.39 661.10
Static1 Stationary.Opel_Blitz_cargo de 14321.43 15065.61 661.10
Static0 Stationary.Horch_830_B1 de 14350.42 15056.62 661.10
Static65 Stationary.Humans.Kdo_Hi_Ger35_passenger_4 de 14345.22 15051.82 661.10 2
Static120 Stationary.Humans.Soldier_Krupp_L2H43_Driver_1 de 14342.67 15055.75 661.10 3
Static48 Stationary.Humans.Soldier_MG_TA_Passenger_1 de 14341.79 15056.98 661.10 4
Static66 Stationary.Humans.Ladder_passenger_ger_1 de 14344.66 15053.11 661.10 5
Static50 Stationary.Humans.150_cm_Flakscheinwerfer_gunner1 de 14343.99 15055.41 661.10 6
Static123 Stationary.Humans.Soldier_Krupp_L2H43_pak_Driver_1 de 14344.14 15054.25 661.10 7
Static119 Stationary.Humans.Soldier_Sdkfz105_Gunner de 14346.02 15052.77 661.10 8
Static71 Stationary.Humans.Portable_Siren_ger_passenger de 14347.25 15052.80 661.10 9
*/
if (resetCount)
{
staticCount = 0;
runCount++;
}
string key = "Static_TWC" + runCount.ToString() + "_" + staticCount.ToString("F0");
string newstaticprefix = staticprefix.Replace(' ', '_').Replace('.', '_').Replace('\\', '_');
if (staticprefix.Length > 0) key = "Static_TWC" + runCount.ToString() + "_" + newstaticprefix + staticCount.ToString("F0");
string value = type + " " + side + " " + x.ToString("0.0") + " " + y.ToString("0.0") + " " + (heading % 360).ToString("0.0") + " /hstart " + z.ToString("0.0") + "/radius_hide " + radiusHide.ToString("F0");
if (chiefNum.HasValue) value += "/target AIChief_" + chiefNum.Value.ToString("F0");
if (desertskin)
{
/*
string armyAdd = "RAF";
if (side == "de") armyAdd = "LW";
else if (side == "nn")
{
int ground = GamePlay.gpFrontArmy(x, y);
if (ground == 1) armyAdd = "RAF";
if (ground == 2) armyAdd = "LW";
}
*/
value += "/skin materialsDesert1";
}
if (sect == "StaticCamera")
{
key = type + "_" + staticprefix.Replace(' ', '_') + runCount.ToString() + "_" + staticCount.ToString("F0");
value = x.ToString("0") + " " + y.ToString("0") + " " + z.ToString("0");
}
f.add(sect, key, value);
staticCount++;
return f;
}
public static ISectionFile makeAIChief(ISectionFile f, maddox.game.IGamePlay GamePlay, AMission mission, double x, double y, double z, double radius, double chiefNum = 0, double heading = 0, bool resetCount = false, string chiefprefix = "")
{
/* side = nn , gb, or de
*[AIChiefs]
AIChief_0 0 12383 17457/r 500
(coordinates and the name of his can be set by creator)
then by hand only, alas, the relevant anti-aircraft guns tied to Chief, "/target AIChief_0 ", like this:
[Stationary]
Static0 Artillery.3_inch_20_CWT_QF_Mk_I gb 12329.35 17412.88 0.00 /timeout 0/radius_hide 0 /target AIChief_0
Static5 Artillery.3_7_inch_QF_Mk_I gb 12308.17 17452.48 0.00 /timeout 0/radius_hide 0 /target AIChief_0
*/
if (resetCount) staticCount = 0;
string sect = "AIChiefs";
string key = "AIChief_TWCAIC_"+ chiefprefix + "_" + chiefNum.ToString("F0");
f.add(sect, key, value);
staticCount++;
return f;
}
{
int count = 0;
int count2 = 0;
List ggList = new List(GamePlay.gpGroundStationarys().ToList());
foreach (GroundStationary gg in ggList)
{
if (gg == null) continue;
/*bool match = false;
foreach (string s in types_to_remove)
{
count2++;
if (gg.Title.ToLower().Contains(s.ToLower()))
{
match = true;
break;
}
}
*/
try
{
Console.WriteLine("listStatics: Name: {0} category: {1} title: {2} type: {3} ", gg.Name, gg.Category, gg.Title, gg.Type.ToString());
}
catch (Exception ex)
{
if (gg != null) Console.WriteLine("listStatics: Couldn't do something with name {0}", gg.Name);
else { Console.WriteLine("listStatics: couldn't do something ERROR"); }
}
count++;
}
Console.WriteLine("listedStatics: Listed {0} items of {1} ... ", count, count2);
}
{
{
Console.WriteLine("mainmission removeStatics: Starting");
try
{
int count = 0;
List ggList = new List(GamePlay.gpGroundStationarys(x, y, radius_m).ToList());
{
try
{
try
{
}
catch (Exception ex)
{
if (gg != null) Console.WriteLine("removeStatics: Couldn't do something with name {0}", gg.Name);
else { Console.WriteLine("removeStatics: couldn't do something ERROR"); }
}
if (gg == null) continue;
if (army != -1)
{
if (army == 1 && gg.country != "gb") continue;
if (army == 2 && gg.country != "de") continue;
if (army == 0 && gg.country != "nn") continue;
}
bool match = false;
string types = gg.Title + gg.Type.ToString() + gg.Category;
if (types.Contains("tank")) Console.WriteLine("RemoveStatic - checking: {0} ", types);
if (types_to_remove == null) match = true;
else foreach (string s in types_to_remove)
{
if (types.ToLower().Contains(s.ToLower()))
{
match = true;
break;
}
}
if (match && types_to_retain != null) foreach (string s in types_to_retain)
{
if (types.ToLower().Contains(s.ToLower()))
{
match = false;
break;
}
}
if (match && preserveOnWater)
{
if (Calcs.isPointInOrNearWater(GamePlay, gg.pos, radius_m: 10)) match = false;
}
if (!match) continue;
if (types.Contains("tank")) Console.WriteLine("RemoveStatic - matched! Removing: {0} ", types);
count++;
}
catch (Exception ex)
{
if (gg != null) Console.WriteLine("removeStatics Loop ERROR: Couldn't do something with name {0}", gg.Name);
else { Console.WriteLine("removeStatics Loop ERROR: couldn't do anything with a NULL static ERROR"); }
}
}
Console.WriteLine("removeStatics: Removed {0} items ... ", count);
}
catch (Exception ex) { Console.WriteLine("removeStatics ERROR: " + ex.ToString()); }
}
{
{
Console.WriteLine("mainmission removeStaticsOnEnemyTerritory: Starting");
try
{
ISectionFile f = GamePlay.gpCreateSectionFile();
int count = 0;
List ggList = new List();
if (addX) f = Calcs.makeStatic(f, GamePlay, msn, center.x, center.y, 0, "Stationary.Environment.Polotnische_X_white_1", 0, "nn", staticprefix: "remove_enemy_neutral");
if (radius_m ==0 ) ggList = new List(GamePlay.gpGroundStationarys().ToList());
else ggList = new List(GamePlay.gpGroundStationarys(center.x, center.y, radius_m).ToList());
{
try
{
if (gg == null) continue;
if (armyToRemove != -1)
{
if (armyToRemove == 1 && gg.country != "gb") continue;
if (armyToRemove == 2 && gg.country != "de") continue;
if (armyToRemove == 0 && gg.country != "nn") continue;
}
string types = gg.Title + gg.Type.ToString() + gg.Category;
if (types.Contains("tank")) Console.WriteLine("RemoveStatic - checking: {0} ", types);
bool match = false;
if (types_to_remove == null) match = true;
else foreach (string s in types_to_remove)
{
if (types.ToLower().Contains(s.ToLower()))
{
match = true;
break;
}
}
if (match && types_to_retain != null) foreach (string s in types_to_retain)
{
if (types.ToLower().Contains(s.ToLower()))
{
match = false;
break;
}
}
if (match && preserveOnWater)
{
if (Calcs.isPointInOrNearWater(GamePlay, gg.pos, radius_m: 10)) match = false;
}
if (!match) continue;
if (types.Contains("tank")) Console.WriteLine("RemoveStatic - matched! Removing: {0} ", types);
int terr = GamePlay.gpFrontArmy(gg.pos.x, gg.pos.y);
if (!clearNeutral && terr == 0) continue;
int ggarmy = -1;
if (gg.country == "gb") ggarmy = 1;
if (gg.country == "de") ggarmy = 2;
if (ggarmy == -1) continue;
if (ggarmy == terr) continue;
if (replaceThem)
{
string typ = "Stationary.Environment.JerryCan_GER1_2";
string names = (gg.Type.ToString() + gg.Title).ToLower();
if (names.Contains("industrial")) typ = "Stationary.Environment.CamoNetPlaneBig";
else if (names.Contains("airfield")) typ = "Stationary.Environment.CamoNetPlane";
else if (names.Contains("aircraft")) typ = "Stationary.GladiatorMkII";
else if (names.Contains("tent")) typ = "Stationary.Environment.CamoNetTank";
else if (names.Contains("car")) typ = "Stationary.Opel_Blitz_fuel";
else if (names.Contains("tank")) typ = "Stationary.Environment.TelegaBallon_UK1";
else if (names.Contains("truck")) typ = "Stationary.Ford_G917";
else if (clc_random.Next(5) < 1) typ = "Stationary.Environment.CamoNetPlane";
f = Calcs.makeStatic(f, GamePlay, msn, gg.pos.x, gg.pos.y, 0, typ, 0, "nn", staticprefix: "remove_enemy_neutral");
}
count++;
}
catch (Exception ex)
{
if (gg != null) Console.WriteLine("removeEnemyStatics Loop ERROR: Couldn't do something with name {0}", gg.Name);
else { Console.WriteLine("removeEnemyStatics Loop ERROR: couldn't do anything with a NULL static ERROR"); }
}
}
if (replaceThem)
{
msn.Timeout(clc_random.Next(5, 120), () => {
GamePlay.gpPostMissionLoad(f);
f.save(msn.CLOD_PATH + msn.FILE_PATH + "/sectionfiles" + "/replaced_enemy_objects_" + clc_random.Next(1,100).ToString());
});
}
Console.WriteLine("removeEnemyStatics: Removed {0} items ... ", count);
}
catch (Exception ex) { Console.WriteLine("removeEnemyStatics ERROR: " + ex.ToString()); }
}
/*
*
*
*
*
Aircraft.Ju-88A-1
Aircraft.Bf-110C-4B
Aircraft.Bf-110C-4
Aircraft.Bf-110C-4Late
Aircraft.Bf-109E-4B_Late
Aircraft.Bf-109E-3B
Aircraft.G50
Aircraft.Bf-109E-1
Aircraft.Bf-109E-1B
Aircraft.He-111P-2
Aircraft.He-111H-2
Aircraft.Bf-109E-3
Aircraft.BR-20M
Aircraft.Ju-87B-2
Aircraft.Bf-109E-4
Aircraft.BlenheimMkIV_Late
Aircraft.BlenheimMkIVNF_Late
Aircraft.BeaufighterMkIF
Aircraft.BeaufighterMkINF
Aircraft.SpitfireMkI
Aircraft.BlenheimMkIV
Aircraft.SpitfireMkIa
Aircraft.SpitfireMkIa_100oct
Aircraft.BlenheimMkIVF
Aircraft.HurricaneMkI_100oct
Aircraft.BlenheimMkIVNF
Aircraft.BlenheimMkIVF_Late
Aircraft.SpitfireMkI_100oct
Aircraft.HurricaneMkI_100oct-NF
Aircraft.HurricaneMkI_dH5-20_100oct
Aircraft.HurricaneMkI_dH5-20
Aircraft.HurricaneMkI_100oct
Aircraft.HurricaneMkI_FB
* */
/* CLOD 4.5 version
public static Dictionary> FullAircraftList = new Dictionary>
{
{ 1, new Dictionary() {
{"bob:Aircraft.BlenheimMkIV_Late",true},
{"bob:Aircraft.HurricaneMkI_100oct",true},
{"bob:Aircraft.BlenheimMkIV", true},
{"bob:Aircraft.SpitfireMkIa_100oct",true},
{ "bob:Aircraft.BeaufighterMkIF", true},
{"bob:Aircraft.BeaufighterMkINF", false},
{"bob:Aircraft.BlenheimMkIVF",false},
{"bob:Aircraft.BlenheimMkIVF_Late",false},
{"bob:Aircraft.BlenheimMkIVNF",false},
{"bob:Aircraft.BlenheimMkIVNF_Late",false},
{"bob:Aircraft.WellingtonMkIc",false},
{"bob:Aircraft.DH82A-2",false},
{"bob:Aircraft.HurricaneMkI",false},
{"bob:Aircraft.HurricaneMkI_100oct-NF",false},
{"bob:Aircraft.HurricaneMkI_dH5-20",false},
{"bob:Aircraft.HurricaneMkI_dH5-20_100oct",false},
{"bob:Aircraft.HurricaneMkI_FB",true},
{"bob:Aircraft.SpitfireMkI",false},
{"bob:Aircraft.SpitfireMkIa",false},
{"bob:Aircraft.SpitfireMkI_100oct",false},
{"bob:Aircraft.SpitfireMkIIa",false}
} },
{ 2, new Dictionary (){
{"bob:Aircraft.Ju-88A-1",true},
{ "bob:Aircraft.Bf-109E-3",true},
{"bob:Aircraft.Ju-87B-2",true},
{"bob:Aircraft.G50",true},
{"bob:Aircraft.Bf-109E-1",true},
{"bob:Aircraft.Bf-109E-1B",true},
{"bob:Aircraft.Bf-109E-3B",true},
{"bob:Aircraft.Bf-109E-4",false},
{"bob:Aircraft.Bf-109E-4_Late",false},
{"bob:Aircraft.Bf-110C-2",true},
{"bob:Aircraft.Bf-110C-4",true},
{"bob:Aircraft.Bf-110C-4-NJG",false},
{"bob:Aircraft.Bf-110C-4B" ,false},
{"bob:Aircraft.Bf-110C-4Late",false},
{"bob:Aircraft.Bf-110C-4N",false},
{"bob:Aircraft.Bf-110C-7",false},
{"bob:Aircraft.BR-20M",true},
{"bob:Aircraft.DH82A-2",false},
{"bob:Aircraft.He-111H-2",true},
{"bob:Aircraft.He-111P-2",false},
{"bob:Aircraft.Do-17Z-2",false},
{"bob:Aircraft.Bf-109E-4B",false},
{"bob:Aircraft.Bf-109E-4B_Late",false},
{"bob:Aircraft.Bf-109E-4N",false},
{"bob:Aircraft.Bf-109E-4N_Late",false},
}
}
};
*********************************/
public static Dictionary> FullAircraftList = new Dictionary>
{
{ 1, new Dictionary() {
{"bob:Aircraft.BeaufighterMkIF", true},
{"bob:Aircraft.BeaufighterMkINF", true},
{"bob:Aircraft.BlenheimMkIV", true},
{"bob:Aircraft.BlenheimMkIV_Late", true},
{"bob:Aircraft.BlenheimMkIVF", true},
{"bob:Aircraft.BlenheimMkIVF_Late", true},
{"bob:Aircraft.BlenheimMkIVNF", true},
{"bob:Aircraft.BlenheimMkIVNF_Late", true},
{"bob:Aircraft.DH82A", true},
{"bob:Aircraft.DH82A_1940", true},
{"bob:Aircraft.DH82A-1", true},
{"bob:Aircraft.DH82A-2", true},
{"bob:Aircraft.GladiatorMkII", true},
{"bob:Aircraft.HurricaneMkI", true},
{"bob:Aircraft.HurricaneMkI_100oct", true},
{"bob:Aircraft.HurricaneMkI_100oct-NF", true},
{"bob:Aircraft.HurricaneMkI_dH5-20", true},
{"bob:Aircraft.HurricaneMkI_dH5-20_100oct", true},
{"bob:Aircraft.HurricaneMkI_FB", true},
{"bob:Aircraft.SpitfireMkI", true},
{"bob:Aircraft.SpitfireMkI_100oct", true},
{"bob:Aircraft.SpitfireMkI_Heartbreaker", true},
{"bob:Aircraft.SpitfireMkIa", true},
{"bob:Aircraft.SpitfireMkIa_100oct", true},
{"bob:Aircraft.SpitfireMkIIa", true},
{"bob:Aircraft.WellingtonMkIc", true},
{"tobruk:Aircraft.BeaufighterMkIC", true},
{"tobruk:Aircraft.BeaufighterMkIC_Trop", false},
{"tobruk:Aircraft.BeaufighterMkIF_Late", true},
{"tobruk:Aircraft.BeaufighterMkIF_Late_Trop", false},
{"tobruk:Aircraft.BeaufighterMkINF_Late", true},
{"tobruk:Aircraft.BeaufighterMkINF_Late_Trop", false},
{"tobruk:Aircraft.BlenheimMkIV_Late_Trop", false},
{"tobruk:Aircraft.BlenheimMkIV_Trop", false},
{"tobruk:Aircraft.BlenheimMkIVF_Late_Trop", false},
{"tobruk:Aircraft.BlenheimMkIVNF_Late_Trop", false},
{"tobruk:Aircraft.D520_Serie1", true},
{"tobruk:Aircraft.D520_Serie1_Trop", false},
{"tobruk:Aircraft.DH82A_Trop", false},
{"tobruk:Aircraft.GladiatorMkII_trop", false},
{"tobruk:Aircraft.HurricaneMkI_FB-Trop", false},
{"tobruk:Aircraft.HurricaneMkIIa", true},
{"tobruk:Aircraft.HurricaneMkIIaTrop", false},
{"tobruk:Aircraft.HurricaneMkIIb", true},
{"tobruk:Aircraft.HurricaneMkIIb-Late", true},
{"tobruk:Aircraft.HurricaneMkIIbTrop", false},
{"tobruk:Aircraft.HurricaneMkIIbTrop-Late", false},
{"tobruk:Aircraft.HurricaneMkIIc", true},
{"tobruk:Aircraft.HurricaneMkIIc-Late", true},
{"tobruk:Aircraft.HurricaneMkIIc-Trop", false},
{"tobruk:Aircraft.HurricaneMkIIc-Trop-Late", false},
{"tobruk:Aircraft.HurricaneMkIId", true},
{"tobruk:Aircraft.HurricaneMkIId-Trop", false},
{"tobruk:Aircraft.KittyhawkMkIA", true},
{"tobruk:Aircraft.KittyhawkMkIA-Trop", false},
{"tobruk:Aircraft.MartletMkIII", true},
{"tobruk:Aircraft.MartletMkIII_Trop", false},
{"tobruk:Aircraft.SpitfireMkIIb", true},
{"tobruk:Aircraft.SpitfireMkVa", true},
{"tobruk:Aircraft.SpitfireMkVb", true},
{"tobruk:Aircraft.SpitfireMkVb-HF", true},
{"tobruk:Aircraft.SpitfireMkVb-HF-Late", true},
{"tobruk:Aircraft.SpitfireMkVb-HF-Trop", true},
{"tobruk:Aircraft.SpitfireMkVbLate", true},
{"tobruk:Aircraft.SpitfireMkVbTrop", true},
{"tobruk:Aircraft.TomahawkMkII", true},
{"tobruk:Aircraft.TomahawkMkII-Late", true},
{"tobruk:Aircraft.TomahawkMkII-Late-Trop", false},
{"tobruk:Aircraft.TomahawkMkII-Trop", false},
{"tobruk:Aircraft.WellingtonMkIc_Late", true},
{"tobruk:Aircraft.WellingtonMkIc_Late_trop", false},
{"tobruk:Aircraft.WellingtonMkIc_t", true},
{"tobruk:Aircraft.WellingtonMkIc_Torpedo", true},
{"tobruk:Aircraft.WellingtonMkIc_Torpedo_Trop", true},
{"tobruk:Aircraft.WellingtonMkIc_trop", false},
} },
{ 2, new Dictionary (){
{"bob:Aircraft.Bf-108B-2", true},
{"bob:Aircraft.Bf-109E-1", true},
{"bob:Aircraft.Bf-109E-1B", true},
{"bob:Aircraft.Bf-109E-3", true},
{"bob:Aircraft.Bf-109E-3B", true},
{"bob:Aircraft.Bf-109E-4", true},
{"bob:Aircraft.Bf-109E-4_Late", true},
{"bob:Aircraft.Bf-109E-4B", true},
{"bob:Aircraft.Bf-109E-4B_Late", true},
{"bob:Aircraft.Bf-109E-4N", true},
{"bob:Aircraft.Bf-109E-4N_Late", true},
{"bob:Aircraft.Bf-110C-2", true},
{"bob:Aircraft.Bf-110C-4", true},
{"bob:Aircraft.Bf-110C-4B", true},
{"bob:Aircraft.Bf-110C-4Late", true},
{"bob:Aircraft.Bf-110C-4N", true},
{"bob:Aircraft.Bf-110C-4-NJG", true},
{"bob:Aircraft.Bf-110C-6", true},
{"bob:Aircraft.Bf-110C-7", true},
{"bob:Aircraft.BR-20M", true},
{"bob:Aircraft.CR42", true},
{"bob:Aircraft.DH82A", true},
{"bob:Aircraft.DH82A_1940", true},
{"bob:Aircraft.DH82A-1", true},
{"bob:Aircraft.DH82A-2", true},
{"bob:Aircraft.G50", true},
{"bob:Aircraft.He-111H-2", true},
{"bob:Aircraft.He-111P-2", true},
{"bob:Aircraft.Ju-87B-2", true},
{"bob:Aircraft.Ju-88A-1", true},
{"tobruk:Aircraft.Bf-108B-2_Trop", false},
{"tobruk:Aircraft.Bf-109E-7", true},
{"tobruk:Aircraft.Bf-109E-7_Trop", false},
{"tobruk:Aircraft.Bf-109E-7N", true},
{"tobruk:Aircraft.Bf-109E-7N_Trop", false},
{"tobruk:Aircraft.Bf-109E-7Z", true},
{"tobruk:Aircraft.Bf-109F-1", true},
{"tobruk:Aircraft.Bf-109F-2", true},
{"tobruk:Aircraft.Bf-109F-2_Late", true},
{"tobruk:Aircraft.Bf-109F-2_Trop", false},
{"tobruk:Aircraft.Bf-109F-4", true},
{"tobruk:Aircraft.Bf-109F-4_Derated", true},
{"tobruk:Aircraft.Bf-109F-4_trop", false},
{"tobruk:Aircraft.Bf-109F-4_trop_Derated", false},
{"tobruk:Aircraft.Bf-109F-4Z", true},
{"tobruk:Aircraft.Bf-109F-4Z_trop", false},
{"tobruk:Aircraft.Bf-110C-4B_Trop", false},
{"tobruk:Aircraft.Bf-110C-4N-NJG_Trop", false},
{"tobruk:Aircraft.Bf-110C-6_Trop", false},
{"tobruk:Aircraft.Bf-110C-7_Trop", false},
{"tobruk:Aircraft.BR-20M_Trop", false},
{"tobruk:Aircraft.CR42_Trop", false},
{"tobruk:Aircraft.D520_Serie1", true},
{"tobruk:Aircraft.D520_Serie1_Trop", false},
{"tobruk:Aircraft.DH82A_Trop", false},
{"tobruk:Aircraft.G50_Trop", false},
{"tobruk:Aircraft.He-111H-2_Trop", false},
{"tobruk:Aircraft.He-111H-6", true},
{"tobruk:Aircraft.He-111H-6_Trop", false},
{"tobruk:Aircraft.Ju-87B-2_Trop", false},
{"tobruk:Aircraft.Ju-88A-5", true},
{"tobruk:Aircraft.Ju-88A-5_Trop", false},
{"tobruk:Aircraft.Ju-88A-5Late", true},
{"tobruk:Aircraft.Ju-88A-5Late_Trop", false},
{"tobruk:Aircraft.Ju-88C-1", true},
{"tobruk:Aircraft.Ju-88C-2", true},
{"tobruk:Aircraft.Ju-88C-2_Trop", false},
{"tobruk:Aircraft.Ju-88C-4", true},
{"tobruk:Aircraft.Ju-88C-4_Trop", false},
{"tobruk:Aircraft.Ju-88C-4Late", true},
{"tobruk:Aircraft.Ju-88C-4Late_Trop", false},
{"tobruk:Aircraft.Macchi-C202-SeriesIII", true},
{"tobruk:Aircraft.Macchi-C202-SeriesIII-AltoQuota", true},
{"tobruk:Aircraft.Macchi-C202-SeriesVII", true},
{"tobruk:Aircraft.Macchi-C202-SeriesVII-AltoQuota", true},
}
}
};
public static ISectionFile CreateBirthPlace(ISectionFile f, string name,double x, double y, double z, int army, int maxplanes = 1, bool setonpark = true, bool isparachute = true, string _country = "", string _hierarchy = "", string _regiment = "", bool _warmed = false)
{
try
{
string sect;
string key;
string value;
sect = "BirthPlace";
key = "BirthPlace" + clc_random.Next(1000, 9999).ToString("F0");
if (name != null & name.Length > 0) key = name.Trim();
int maxLen = 24;
int setOnPark = 0;
if (setonpark)
setOnPark = 1;
int isParachute = 0;
if (isparachute)
isParachute = 1;
string country = ".";
if (_country != null && _country.Length > 0)
country = _country;
string hierarchy = ".";
if (_hierarchy != null && _hierarchy.Length > 0)
hierarchy = _hierarchy;
string regiment = ".";
if (_regiment != null && _regiment.Length > 0)
regiment = _regiment;
int warmed = 0;
if (_warmed)
warmed = 1;
value = army.ToString(CultureInfo.InvariantCulture) + " " + x.ToString("F0") + " "
+ y.ToString("F0") + " " + z.ToString("F0") + " "
+ maxplanes.ToString("F0") + " " + setOnPark.ToString("F0") + " "
+ isParachute.ToString("F0") + " " + country + " " + hierarchy + " " + regiment + " " + warmed.ToString("F0");
Console.WriteLine("Creating Birthplace: " + value);
f.add(sect, key, value);
sect = "BirthPlace0";
Dictionary planeSet = FullAircraftList[army];
if (planeSet.Count > 0)
foreach (string plane in planeSet.Keys)
{
if (!planeSet[plane]) continue;
key = plane;
value = "";
f.add(sect, key, value);
}
return f;
}
catch (Exception ex) { Console.WriteLine("ERROR CALCS.CreateBirthPlace! " + ex.ToString()); return f; }
}
public static ISectionFile addFlights (string section, ISectionFile f, int numToAdd, int maxInFlight, int maxFlights)
{
int count = 0;
string k, v;
Console.WriteLine("Fl: {0} {1} {2}", section, numToAdd, maxInFlight, maxFlights);
for (int i = 0; i= numToAdd) break;
}
k = "Flight" + i.ToString(); v = flight; f.add(section, k, v);
Console.WriteLine("Fl: {0} {1} {2}", section, k, v);
if (count >= numToAdd) break;
}
return f;
}
public static ISectionFile BuildBomber(IGamePlay GamePlay, Mission mission, int bomberArmy, double vel_kmh, double alt_m, Point3d p1, Point3d p2, Point3d gat, Point3d p4, Point3d gap, Point3d p6, Point3d lan, string gat_targ = "1_Chief 1", string gap_targ = "", string attack_type="LEVEL", double airportBombChance = 0.15, int numInFlight = 2)
{
try
{
ISectionFile f = GamePlay.gpCreateSectionFile();
string aircraft = Calcs.randSTR(new string[] { "tobruk:Aircraft.Ju-88A-5Late_Trop", "tobruk:Aircraft.Ju-88A-5_Trop", "tobruk:Aircraft.Ju-88A-5", "tobruk:Aircraft.Ju-88A-5", "tobruk:Aircraft.Ju-88A-5", "tobruk:Aircraft.Ju-88A-5", "tobruk:Aircraft.Ju-87B-2_Trop", "tobruk:Aircraft.Ju-87B-2_Trop","bob:Aircraft.Ju-87B-2","bob:Aircraft.Ju-87B-2", "tobruk:Aircraft.Bf-110C-4B_Trop", "bob:Aircraft.Bf-110C-4B", "bob:Aircraft.Bf-110C-4B", "tobruk:Aircraft.BR-20M_Trop","tobruk:Aircraft.BR-20M_Trop","tobruk:Aircraft.BR-20M_Trop","tobruk:Aircraft.BR-20M_Trop", "bob:Aircraft.BR-20M", "bob:Aircraft.He-111H-2"
});
string weapons = "1 1 1 1 1 1 4";
string groupname = "tobruk:Tobruk_LW_JG3_II." + clc_random.Next(1, 15).ToString("00");
List detonatorL = new List() {"Bomb.SC-500_GradeIII_K 0 -1 0.08", "Bomb.SD-250 0 -1 0.08", "Bomb.SC-250_Type1_J 2 -1 0.08", "Bomb.SD-500_A 0 -1 0.08", "Bomb.SC-50_GradeII_J 1 -1 0.08" };
if (bomberArmy == 1)
{
weapons = "1 1 5 0 2";
detonatorL = new List() { "Bomb.Bomb_GP_40lb_MkIII 0 30 0.025", "Bomb.Bomb_GP_250lb_MkIV 0 30 0.025", "Bomb.Bomb_GP_500lb_MkIV 0 30 0.025" };
groupname = "BoB_RAF_B_7Sqn." + clc_random.Next(1, 15).ToString("00");
}
Console.WriteLine("Bumrush Attack group: " + aircraft);
if (aircraft.Contains("Ju-87"))
{
weapons = "1 1 2 1";
detonatorL = new List() { "Bomb.SC-500_GradeIII_J 0 -1 0.08", "Bomb.SC-50_GradeII_J_DivePreferred 0 -1 0.08", "Bomb.SC-250_Type1_J 2 -1 0", "Bomb.SD-250_JB 0 -1 0.08", "Bomb.SD-500_E 0 -1 0.08", "Bomb.SC-250_Type2_J 0 -1 0.08" };
attack_type = "DIVE";
if (p2.z < 2000) p2.z = 2000;
if (gat.z < 2000) gat.z = 2000;
}
if (aircraft.Contains("Ju-88"))
{
weapons = "1 1 1 1 1 1 4";
}
else if (aircraft.Contains("BR-20"))
{
weapons = "1 1 1 1";
detonatorL = new List() { "Bomb.Bomb_GP_40lb_MkIII 0 30 0.025", "Bomb.Bomb_GP_250lb_MkIV 0 30 0.025", "Bomb.Bomb_GP_500lb_MkIV 0 30 0.025" };
}
else if (aircraft.Contains("Bf-110"))
{
weapons = "1 1 1 4";
}
else if (aircraft.Contains("He-111"))
{
weapons = "1 1 1 1 1 1 2";
}
else if (aircraft.Contains("BlenheimMkIV_Late"))
{
weapons = "1 1 5 1 2";
}
else if (aircraft.Contains("Blenheim"))
{
weapons = "1 1 5 0 2";
}
else if (aircraft.Contains("WellingtonMkIc"))
{
detonatorL = new List() { "Bomb.Bomb_GP_1000lb_MkI 3 0 0.025" };
}
else if (aircraft.Contains("Wellington"))
{
detonatorL = new List() { "Bomb.Bomb_GP_1000lb_MkI 3 0 0.025", "Bomb.Bomb_GP_250lb_MkIV 3 0 0.12", "Bomb.Bomb_GP_500lb_MkIV 3 0 0.12" };
}
else if (aircraft.Contains("Sunderland"))
{
weapons = "1 1 1 1 1 1";
}
else if (aircraft.Contains("Beaufighter"))
{
weapons = "1 1 1";
}
else if (aircraft.Contains("Aircraft.HurricaneMkIIc"))
{
weapons = "1 1 1 1 1 1 2";
if (alt_m > 800) alt_m = clc_random.Next(400, 800);
}
string s = "";
string k = "";
string v = "";
s = "AirGroups";
k = groupname; v = ""; f.add(s, k, v);
s = groupname;
f = addFlights(s, f, numInFlight, 3, 3);
/*
k = "Flight0"; v = Calcs.randSTR(new string[] { "1", "1", "1", "1 2", "1 2", "1 2", "1 2", "1 2 3", "1 2 3" }); f.add(s, k, v);
string adder = "1 2 3";
bool secondFl = false;
if (nextFlightChance >= 0.8)
{
adder = "1 2 3 4";
secondFl = true;
if (formation.Contains("LINEASTERN")) formation = "LINEABREAST";
}
bool avoidThirdFl = false;
if (clc_random.NextDouble() < nextFlightChance * nextFlightMult || secondFl)
{
k = "Flight1"; v = Calcs.randSTR(new string[] { "11", "11", "11 12", "11 12", "11 12", "11 12", "11 12", "11 12 13", "11 12 13" }); f.add(s, k, v);
if (nextFlightChance >= 0.95) { f.add(s, k, "1 2 3 4"); avoidThirdFl = true; }
}
if (clc_random.NextDouble() < nextFlightChance * nextFlightMult && !avoidThirdFl) {
k = "Flight2"; v = Calcs.randSTR(new string[] { "", "", "", "", "21", "21", "", "21 22", "21 22" }); f.add(s, k, v);
}
*/
k = "Class"; v = aircraft; f.add(s, k, v);
k = "Formation"; v = formation; f.add(s, k, v);
k = "Fuel"; v = "40"; f.add(s, k, v);
k = "Weapons"; v = weapons; f.add(s, k, v);
foreach (string d in detonatorL)
{
k = "Detonator"; v = d; f.add(s, k, v);
}
k = "Skill"; v = string.Format("{0:N2} {1:N2} {2:N2} {3:N2} {4:N2} {5:N2} {6:N2} {7:N2}", new object[] {clc_random.Next(25,75)/100.0, clc_random.Next(25, 75) / 100.0, clc_random.Next(25, 75) / 100.0,
k = "Aging"; v = clc_random.Next(5, 90).ToString(); f.add(s, k, v);
s = groupname + "_Way";
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p1.x, p1.y, p1.z, vel_kmh }); f.add(s, k, v);
double gatGapDistance_m = Calcs.CalculatePointDistance(gat, gap);
if (gatGapDistance_m > 600)
{
if (aircraft.Contains("Ju-87")) { k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p2.x, p2.y, p2.z, vel_kmh }); f.add(s, k, v); }
else { k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { p2.x, p2.y, p2.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v); }
k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gat.x, gat.y, gat.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v);
if (aircraft.Contains("Ju-87")) { k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { gat.x + 100, gat.y + 100, 100, vel_kmh }); f.add(s, k, v); }
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p4.x, p4.y, p4.z, vel_kmh}); f.add(s, k, v);
if (clc_random.NextDouble() < airportBombChance || gap_targ.Length>0)
{
if (gap_targ.Length == 0) { k = "GATTACK_POINT"; v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, gap.z, vel_kmh }); f.add(s, k, v); }
else { k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gap.x, gap.y, gap.z, vel_kmh, gap_targ, attack_type }); f.add(s, k, v); }
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p6.x, p6.y, p6.z, vel_kmh }); f.add(s, k, v);
}
else
{
double angle = clc_random.NextDouble() * 2 * Math.PI;
double distance = clc_random.Next(500, 1500);
k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gat.x, gat.y, gat.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v);
if (aircraft.Contains("Ju-87")) { k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { gat.x + 100, gat.y + 100, 100, vel_kmh }); f.add(s, k, v); }
k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { p2.x, p2.y, p2.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v);
k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gat.x, gat.y, gat.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v);
if (aircraft.Contains("Ju-87")) { k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { gat.x + 100, gat.y + 100, 100, vel_kmh }); f.add(s, k, v); }
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p4.x, p4.y, p4.z, vel_kmh }); f.add(s, k, v);
if (gap_targ.Length == 0) { k = "GATTACK_POINT"; v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, gap.z, vel_kmh }); f.add(s, k, v); }
else { k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gap.x, gap.y, gap.z, vel_kmh, gap_targ, attack_type }); f.add(s, k, v); }
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p6.x, p6.y, p6.z, vel_kmh }); f.add(s, k, v);
}
}
{
double p1GapDistance_m = Calcs.CalculatePointDistance(p1, gap);
if (p1GapDistance_m < 1) p1GapDistance_m = 1;
Point3d newPoint = new Point3d((gap.x - p1.x) / p1GapDistance_m * 3000 + gap.x, (gap.y - p1.y) / p1GapDistance_m * 3000 + gap.y, gap.z);
if (clc_random.Next(2) == 0)
{
k = "GATTACK_POINT"; v = String.Format("{0} {1} {2} {3}", new object[] { gat.x, gat.y, gat.z, vel_kmh }); f.add(s, k, v);
} else
{
k = "GATTACK_TARG"; v = String.Format("{0} {1} {2} {3} {4} 0 /GAttackType {5}", new object[] { gat.x, gat.y, gat.z, vel_kmh, gat_targ, attack_type }); f.add(s, k, v);
}
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { newPoint.x, newPoint.y, newPoint.z, vel_kmh }); f.add(s, k, v);
k = "NORMFLY"; v = String.Format("{0} {1} {2} {3}", new object[] { p6.x, p6.y, p6.z, vel_kmh }); f.add(s, k, v);
}
double minY = 6666 - 10000;
double maxX = 362000 + 10000;
double maxY = 362000 + 10000;
Point3d l = lan;
if (l.x > maxX) l.x = maxX;
if (l.x > minX) l.x = minX;
if (l.y > maxY) l.y = maxY;
if (l.y > minY) l.y = minY;
double mu = clc_random.NextDouble() * 5 + 2;
Point3d apLook = new Point3d (mu*(p6.x + l.x)/2, mu*(p6.y + l.y)/8, lan.z);
AiAirport ap = mission.covermission.Stb_nearestAirport(apLook, bomberArmy, isSeaplane: false);
if (ap != null && CalculatePointDistance(ap.Pos(), p6) > 10000)
{
k = "LANDING"; v = String.Format("{0} {1} {2} {3}", new object[] { ap.Pos().x, ap.Pos().y, lan.z, vel_kmh }); f.add(s, k, v);
}
else
{
k = "LANDING"; v = String.Format("{0} {1} {2} {3}", new object[] { l.x, l.y, l.z, vel_kmh }); f.add(s, k, v);
}
return f;
}
catch (Exception ex) {
Console.WriteLine("Calcs Build Bomber ERROR: " + ex.ToString());
return GamePlay.gpCreateSectionFile();
}
}
public static ISectionFile BuildFighter(IGamePlay GamePlay, Mission mission, int planeArmy, double vel_kmh, double alt_m, Point3d p1, Point3d p2, Point3d gat, Point3d p4, Point3d gap, Point3d p6, Point3d lan, string gat_targ = "1_Chief 1", string gap_targ = "", int numInFlight = 2)
{
try
{
ISectionFile f = GamePlay.gpCreateSectionFile();
string aircraft = Calcs.randSTR(new string[] { "tobruk:Aircraft.Bf-109E-7N_Trop", "tobruk:Aircraft.Bf-109E-7_Trop", "tobruk:Aircraft.Bf-109F-2_Trop", "tobruk:Aircraft.Bf-110C-4N-NJG_Trop",
"tobruk:Aircraft.BR-20M_Trop", "tobruk:Aircraft.G50_Trop", "tobruk:Aircraft.Macchi-C202-SeriesIII-AltoQuota", "tobruk:Aircraft.Macchi-C202-SeriesVII-AltoQuota"
});
string groupname = "tobruk:Tobruk_LW_JG3_II." + clc_random.Next(1, 15).ToString("00");
string weapons = "";
List detonatorL = new List() { };
if (planeArmy == 1)
{
aircraft = Calcs.randSTR(new string[] { "tobruk:Aircraft.BeaufighterMkIF_Late_Trop", "tobruk:Aircraft.BeaufighterMkINF_Late_Trop", "tobruk:Aircraft.BlenheimMkIVNF_Late_Trop", "tobruk:Aircraft.HurricaneMkIIbTrop", "tobruk:Aircraft.HurricaneMkIIc-Trop", "tobruk:Aircraft.HurricaneMkIId-Trop", "tobruk:Aircraft.MartletMkIII_Trop", "tobruk:Aircraft.TomahawkMkII-Late-Trop", "tobruk:Aircraft.HurricaneMkIIaTrop", "tobruk:Aircraft.BeaufighterMkIF_Late_Trop", "tobruk:Aircraft.HurricaneMkIIaTrop"
groupname = "BoB_RAF_B_7Sqn." + clc_random.Next(1, 15).ToString("00");
}
Console.WriteLine("Bumrush Attack FIGHTER group: " + aircraft);
string s = "";
string k = "";
string v = "";
s = "AirGroups";
k = groupname; v = ""; f.add(s, k, v);
s = groupname;
f = addFlights(s, f, numInFlight, 3, 3);
k = "Class"; v = aircraft; f.add(s, k, v);
k = "Formation"; v = formation; f.add(s, k, v);
k = "Fuel"; v = "40"; f.add(s, k, v);
/*
k = "Weapons"; v = weapons; f.add(s, k, v);
foreach (string d in detonatorL)
{
k = "Detonator"; v = d; f.add(s, k, v);
}
*/
k = "Skill"; v = string.Format("{0:N2} {1:N2} {2:N2} {3:N2} {4:N2} {5:N2} {6:N2} {7:N2}", new object[] {clc_random.Next(25,75)/100.0, clc_random.Next(25, 75) / 100.0, clc_random.Next(25, 76) / 100.0,
k = "Aging"; v = clc_random.Next(5, 90).ToString(); f.add(s, k, v);
string[] tsks = new string[] { "HUNTING", "HUNTING", "HUNTING", "AATTACK_FIGHTERS", "AATTACK_FIGHTERS", "AATTACK_FIGHTERS", "AATTACK_FIGHTERS", "AATTACK_FIGHTERS", "AATTACK_FIGHTERS" };
s = groupname + "_Way";
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { p1.x, p1.y, alt_m, vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, alt_m + clc_random.Next(-300, 300), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { p2.x, p2.y, alt_m, vel_kmh}); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, alt_m + clc_random.Next(-300, 300), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { gat.x + 100, gat.y + 100, alt_m + clc_random.Next(-100,100), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, alt_m + clc_random.Next(-300, 300), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { p4.x, p4.y, alt_m + clc_random.Next(-150, 150), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { gap.x, gap.y, alt_m + clc_random.Next(-300, 300), vel_kmh }); f.add(s, k, v);
k = Calcs.randSTR(tsks); v = String.Format("{0} {1} {2} {3}", new object[] { p6.x, p6.y, p6.z, vel_kmh }); f.add(s, k, v);
Point3d apLook = new Point3d((3 * p6.x + lan.x) / 4, (3 * p6.y + lan.y) / 4, lan.z);
AiAirport ap = mission.covermission.Stb_nearestAirport(apLook, planeArmy, isSeaplane: false);
if (ap != null && CalculatePointDistance(ap.Pos(), p6) > 10000)
{
k = "LANDING"; v = String.Format("{0} {1} {2} {3}", new object[] { ap.Pos().x, ap.Pos().y, lan.z, vel_kmh }); f.add(s, k, v);
}
else
{
k = "LANDING"; v = String.Format("{0} {1} {2} {3}", new object[] { lan.x, lan.y, lan.z, vel_kmh }); f.add(s, k, v);
}
return f;
}
catch (Exception ex)
{
Console.WriteLine("Calcs Build Fighter ERROR: " + ex.ToString());
return GamePlay.gpCreateSectionFile();
}
}
/*
public static void RemoveRoutedEventHandlers(Delegate element, Event routedEvent)
{
var eventHandlersStoreProperty = typeof(UIElement).GetProperty(
"EventHandlersStore", BindingFlags.Instance | BindingFlags.NonPublic);
object eventHandlersStore = eventHandlersStoreProperty.GetValue(element, null);
if (eventHandlersStore == null)
return;
var getRoutedEventHandlers = eventHandlersStore.GetType().GetMethod(
"GetRoutedEventHandlers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var routedEventHandlers = (RoutedEventHandlerInfo[])getRoutedEventHandlers.Invoke(
eventHandlersStore, new object[] { routedEvent });
foreach (var routedEventHandler in routedEventHandlers)
element.RemoveHandler(routedEvent, routedEventHandler.Handler);
}
{
foreach (Delegate d in E.GetInvocationList())
{
E -= (FindClickedHandler)d;
}
}
*/
public static void RemoveDelegates(Object b)
{
PropertyInfo pi = b.GetType().GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
EventHandlerList list = (EventHandlerList)pi.GetValue(b, null);
}
public static IEnumerable GetEventKeysList(Component issuer)
{
System.Reflection.PropertyInfo eventsProp = typeof(Component).GetProperty("Events", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
return
from key in issuer.GetType().GetFields(BindingFlags.Static |
BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)
where key.Name.StartsWith("Event")
select key.Name;
}
public static string randSTR(string[] strings)
{
return strings[clc_random.Next(strings.Length)];
}
public static string randSTR(List strings)
{
return strings[clc_random.Next(strings.Count)];
}
public static void Randomize(T[] items)
{
Random rand = new Random();
for (int i = 0; i < items.Length - 1; i++)
{
int j = rand.Next(i, items.Length);
T temp = items[i];
items[i] = items[j];
items[j] = temp;
}
}
public static int seedObj(object[] objs)
{
string amalg = "";
foreach (object o in objs) amalg += o.ToString();
byte[] bytes = Encoding.ASCII.GetBytes(amalg);
ulong seed = 3;
foreach (byte b in bytes) seed += (ulong)b;
return Convert.ToInt32(seed);
}
public class ReverseComparer2 : IComparer
{
///
{
return y.CompareTo(x);
}
}
public sealed class ReverseComparer : IComparer
{
private readonly IComparer inner;
public ReverseComparer() : this(null) { }
public ReverseComparer(IComparer inner)
{
this.inner = inner ?? Comparer.Default;
}
int IComparer.Compare(T x, T y) { return inner.Compare(y, x); }
}
/*
public static IEnumerable Randomize(this IEnumerable source)
{
Random rnd = new Random();
return source.OrderBy((item) => rnd.Next());
}
*/
namespace Ini
{
public class IniFile
{
public string path;
public int iniErrorCount;
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
public IniFile(string INIPath)
{
path = INIPath;
iniErrorCount = 0;
}
///
{
WritePrivateProfileString(Section, null, null, this.path);
}
No description available.
{
WritePrivateProfileString(Section, Key, "\"" + Value + "\"", this.path);
}
//Console.WriteLine("INIW: Count" + Value.Count.ToString()); //Console.WriteLine("INIW: Count" + Section + " " + Key + "[" + count.ToString() + "]" + " " + s);
{
int count = 0;
WritePrivateProfileString(Section, "Count", Value.Count.ToString(), this.path);
foreach (string s in Value)
{
WritePrivateProfileString(Section, Key + "[" + count.ToString() + "]", "\"" + s + "\"", this.path);
count++;
}
}
///
{
List l = new List() { };
int total = IniReadValue(Section, "Count", (int)0);
if (total == 0) return l;
for (int x = 0; x < total; x++)
{
l.Add(IniReadValue(Section, Key + "[" + x.ToString() + "]", ""));
}
return l;
}
if (temp.ToString().Trim() == "1") temp = new StringBuilder("True", 4); //allow 0 & 1 to be used, or True/true/False/false Circular array which operates as a limited size queue OR stack Based on https://www.codeproject.com/Articles/31652/A-Generic-Circular-Array //Array in queue order (first queued = first of array) //Array in stack order (last queued = first of array) int pos = _head - 1 + 2 * _baseArray.Length; //by adding 2*_baseArray.Length we can count downwards by _baseArray.Length with no worries about going below 0 for our index. We have to go 2* bec _head might be zero meaning our starting point might be -1 //Console.WriteLine("ArrayStack: " + i.ToString() + " " + pos.ToString());
{
StringBuilder temp = new StringBuilder(1024);
int i = GetPrivateProfileString(Section, Key, "", temp, 1024, this.path);
if (temp.ToString().Trim() == "0") temp = new StringBuilder("False", 5);
bool a;
if (temp.Length > 0 && bool.TryParse(temp.ToString(), out a)) return a;
else
{
IniReadError(Section, Key);
return def;
}
}
private void IniReadError(String Section, String Key)
{
iniErrorCount++;
Console.WriteLine("-main.cs: ERROR reading .ini file: Key {0} in Section {1} was not found.", Key, Section);
}
}
}
public class CircularArray
{
private readonly T[] _baseArray;
private readonly T[] _facadeArray;
private int _head;
private bool _isFilled;
public CircularArray(int length)
{
_baseArray = new T[length];
_facadeArray = new T[length];
}
public T[] Array
{
get
{
try
{
int pos = _head;
for (int i = 0; i < _baseArray.Length; i++)
{
Math.DivRem(pos, _baseArray.Length, out pos);
_facadeArray[i] = _baseArray[pos];
pos++;
}
return _facadeArray;
}
catch (Exception ex)
{
Console.WriteLine("CircularArray ERROR: " + ex.ToString());
return _facadeArray;
}
}
}
public T[] ArrayStack
{
get
{
try
{
for (int i = 0; i < _baseArray.Length; i++)
{
Math.DivRem(pos, _baseArray.Length, out pos);
_facadeArray[i] = _baseArray[pos];
pos--;
pos = pos < 0 ? pos + _baseArray.Length : pos;
}
return _facadeArray;
}
catch (Exception ex)
{
Console.WriteLine("ArrayStack ERROR: " + ex.ToString());
return _facadeArray;
}
}
}
public T[] BaseArray
{
get { return _baseArray; }
}
public bool IsFilled
{
get { return _isFilled; }
}
//Gets end of queue (ie, the first value entered) if 0 or 2nd, 3rd, etc value entered if index 1, 2, 3 etc //10/2018 - this seems incorrect. This gets the last value pushed onto the array if 0, 2nd to last if 1, etc.
{
try
{
if (!_isFilled && _head == _baseArray.Length - 1)
_isFilled = true;
Math.DivRem(_head, _baseArray.Length, out _head);
_baseArray[_head] = value;
_head++;
}
catch (Exception ex)
{
Console.WriteLine("Push ERROR: " + ex.ToString());
}
}
//Gets top of the stack (ie, the last value entered) if 0 or 2nd to last, 3rd to last, etc if index 1, 2, 3 etc ////10/2018 - this seems incorrect. This gets the tail of the array, ie the first value pushed onto the array (that still remains), ie the oldest value in the array, if 0, 2nd to last if 1, etc.
{
try {
int pos = _head - indexBackFromHead - 1;
pos = pos < 0 ? pos + _baseArray.Length : pos;
Math.DivRem(pos, _baseArray.Length, out pos);
return _baseArray[pos];
}
catch (Exception ex)
{
Console.WriteLine("Get ERROR: " + ex.ToString());
return _baseArray[0];
}
}
//-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- // Type.GetEvent(s) gets all Events for the type AND it's ancestors // Type.GetField(s) gets only Fields for the exact type. // (BindingFlags.FlattenHierarchy only works on PROTECTED & PUBLIC // doesn't work because Fieds are PRIVATE) // NEW version of this routine uses .GetEvents and then uses .DeclaringType // to get the correct ancestor type so that we can get the FieldInfo...
{
try {
int pos = _head + indexForwardFromHead;
pos = pos < 0 ? pos + _baseArray.Length : pos;
Math.DivRem(pos, _baseArray.Length, out pos);
return _baseArray[pos];
}
catch (Exception ex)
{
Console.WriteLine("GetStack ERROR: " + ex.ToString());
return _baseArray[0];
}
}
}
/*
namespace cevent
{
static public class cEventHelper
{
static Dictionary> dicEventFieldInfos = new Dictionary>();
static BindingFlags AllBindings
{
get { return BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; }
}
static List GetTypeEventFields(Type t)
{
if (dicEventFieldInfos.ContainsKey(t))
return dicEventFieldInfos[t];
List lst = new List();
BuildEventFields(t, lst);
dicEventFieldInfos.Add(t, lst);
return lst;
}
static void BuildEventFields(Type t, List lst)
{
foreach (EventInfo ei in t.GetEvents(AllBindings))
{
Type dt = ei.DeclaringType;
FieldInfo fi = dt.GetField(ei.Name, AllBindings);
if (fi != null)
lst.Add(fi);
}
/*
foreach (FieldInfo fi in t.GetFields(AllBindings))
{
EventInfo ei = t.GetEvent(fi.Name, AllBindings);
if (ei != null)
{
lst.Add(fi);
Console.WriteLine(ei.Name);
}
}
if (t.BaseType != null)
}
static EventHandlerList GetStaticEventHandlerList(Type t, object obj)
{
MethodInfo mi = t.GetMethod("get_Events", AllBindings);
return (EventHandlerList)mi.Invoke(obj, new object[] { });
}
public static void RemoveAllEventHandlers(object obj) { RemoveEventHandler(obj, ""); }
public static void RemoveEventHandler(object obj, string EventName)
{
if (obj == null)
return;
Type t = obj.GetType();
List event_fields = GetTypeEventFields(t);
EventHandlerList static_event_handlers = null;
foreach (FieldInfo fi in event_fields)
{
if (EventName != "" && string.Compare(EventName, fi.Name, true) != 0)
continue;
if (fi.IsStatic)
{
if (static_event_handlers == null)
static_event_handlers = GetStaticEventHandlerList(t, obj);
object idx = fi.GetValue(obj);
Delegate eh = static_event_handlers[idx];
if (eh == null)
continue;
Delegate[] dels = eh.GetInvocationList();
if (dels == null)
continue;
EventInfo ei = t.GetEvent(fi.Name, AllBindings);
foreach (Delegate del in dels)
ei.RemoveEventHandler(obj, del);
}
else
{
EventInfo ei = t.GetEvent(fi.Name, AllBindings);
if (ei != null)
{
object val = fi.GetValue(obj);
Delegate mdel = (val as Delegate);
if (mdel != null)
{
foreach (Delegate del in mdel.GetInvocationList())
ei.RemoveEventHandler(obj, del);
}
}
}
}
}
}
}
*/
class twcLandscape : maddox.core.WLandscape
{
public static double HQ(double x, double y)
{
double height = twcLandscape.cHQ((float)x, (float)y);
return height;
}
public static double H(double x, double y)
{
double height = twcLandscape.cH((float)x, (float)y);
return height;
}
public static double Hmax(double x, double y)
{
double height = twcLandscape.cHmax((float)x, (float)y);
return height;
}
public static double Hmin(double x, double y)
{
double height = twcLandscape.cHmin((float)x, (float)y);
return height;
}
public static double HQ_air(double x, double y)
{
double height = twcLandscape.cHQ_Air((float)x, (float)y);
return height;
}
public static double HQ_forestHeightHere(double x, double y)
{
double height = twcLandscape.cHQ_forestHeightHere((float)x, (float)y);
return height;
}
/* dangerous/exception of protected memory access - but don't need this anyway, just use
* twcLandscape.getBuildingCountInBlock(int x, int y)
public static int twcGetBuildingCountInBlock(int x, int y)
{
int count = twcLandscape.getBuildingCountInBlock(x, y);
return count;
}
public static bool twcisAnyBuildingInBlock(int x, int y)
{
bool ret = twcLandscape.isAnyBuildingInBlock(x, y);
return ret;
}
*/
public static int twcgetSizeX()
{
int ret = twcLandscape.getSizeX();
return ret;
}
public static int twcgetSizeY()
{
int ret = twcLandscape.getSizeY();
return ret;
}
public static int twcgetMinMax(out int MinX, out int MinY, out int MaxX, out int MaxY)
{
int ret = twcLandscape.getMinMax(out MinX, out MinY, out MaxX, out MaxY);
Console.WriteLine("getMinMax: {0} {1} {2} {3}", MinX, MinY, MaxX, MaxY);
return ret;
}
}
/*
public class twcWeather : maddox.core.WWeather
{
public static bool twc_windGetStatisticalWindOnHeight(double height, out maddox.GP.Vector3d v3d)
{
bool ret = twcWeather.windGetStatisticalWindOnHeight(height, out v3d);
return ret;
}
}
*/
/*
public static void TWCTimeout(int interval_ms, Action eventToCall)
{
var aTimer = new System.Timers.Timer();
aTimer.Interval = interval_ms;
aTimer.Elapsed += eventToCall;
aTimer.Elapsed += aTimer.Dispose();
aTimer.AutoReset = false;
aTimer.Enabled = true;
Dispatcher
}
*/