Fulqrum Publishing Home   |   Register   |   Today Posts   |   Members   |   UserCP   |   Calendar   |   Search   |   FAQ

Go Back   Official Fulqrum Publishing forum > Fulqrum Publishing > IL-2 Sturmovik: Cliffs of Dover > FMB, Mission & Campaign builder Discussions

Reply
 
Thread Tools Display Modes
  #91  
Old 04-26-2012, 02:18 PM
FG28_Kodiak FG28_Kodiak is offline
Approved Member
 
Join Date: Dec 2009
Location: Swabia->Bavaria->Germany
Posts: 884
Default

No its not
Current Version, added routine to merge Airgroups better, to avoid 'splittering' added a short time delay (for testing)
To Do: complete the Radar Mission Menu, hope i finish it this weekend, so the script is usable on servers.
Future: Create a DLL and Configuration via XML-file, so the handling will be easier for missionbuilders.
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using maddox.game;
using maddox.game.world;
using maddox.GP;


public class Mission : AMission
{

    private static string userdocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    private static string CLODO_FILE_PATH = userdocpath + @"\1C SoftClub\il-2 sturmovik cliffs of dover\";
    private static string FILE_PATH = @"missions\RadarTest\Radar.mis"; // adjust to your needs
    private static string MISSION_FILE = CLODO_FILE_PATH + FILE_PATH;

    List<LocalHeadquarters> Headquarters = new List<LocalHeadquarters>{
        {new LocalHeadquarters("Luton (Ash)", "CallSign24", 242928.64, 251773.16, 
            new ObserverStation( "Static0","AN,16","AN,17","AN,18","AN,19","AO,16","AO,17","AO,18","AO,19","AP,16","AP,17","AP,18","AP,19","AQ,16","AQ,17","AQ,18","AQ,19"), //Dover
            new ObserverStation( "Static2","AL,20","AL,21","AL,22","AM,20","AM,21","AM,22","AN,20","AN,21","AN,22","AO,20","AO,21","AO,22"))}, // Dunkirk
        {new LocalHeadquarters("RadPoe (Woodchurch)", "CallSign32", 208162.91, 227726.61, 
            new ObserverStation( "Static1","AJ,15","AJ,16","AJ,17","AJ,18","AK,15","AK,16","AK,17","AK,18","AL,15","AL,16","AL,17","AL,18","AM,15","AM,16","AM,17","AM,18"), //Rye
            new ObserverStation( "Royal Observer Corps I","AK,19","AK,20","AK,21","AL,19","AL,20","AL,21","AM,19","AM,20","AM,21"))}, // fake simulation of Royal Observer Corps, none destructable
        //{new LocalHeadquarters("Forest (Woodchurch)", "CallSign15", 208162.91, 227726.61, new ObserverStation( "Static4","E,1","E,2","E,3"), new ObserverStation( "Static5","F,1","F,2","F,3"))}
    };


    LandMarkHandling LandMarks = new LandMarkHandling(
        new LandMark("Dover", 245577.51, 234521.20),
        new LandMark("Folkestone", 235333.17, 229568.64),
        new LandMark("St.Magarets's at Cliffe", 250423.81, 238001.64),
        new LandMark("Deal", 250985.14, 244801.80),
        new LandMark("Dymchurch", 223734.62, 222437.79),
        new LandMark("New Romney", 220005.71, 218110.40),
        new LandMark("Rye", 205758.66, 213525.22),
        new LandMark("Hastings", 195366.28, 203132.83),
        new LandMark("Eastbourne", 174755.54, 191963.14),
        new LandMark("Brighton", 144909.86, 197927.40),
        new LandMark("Calais", 284654.87, 215707.54)
        );


    Random random = new Random();


    internal class LandMark
    {
        public string LandMarkName { get; set; }
        public Point2d LandMarkPosition { get; set; }

        public LandMark(string landMarkName, double x, double y)
        {
            this.LandMarkName = landMarkName;
            this.LandMarkPosition = new Point2d(x, y);
        }
    }


    internal class LandMarkHandling
    {
        List<LandMark> LandMarkList = new List<LandMark>();

        public LandMarkHandling(params LandMark[] mark)
        {
            if (mark != null)
                LandMarkList.AddRange(mark);
        }


        public LandMark getNearestLandMarkTo(Point3d position)
        {

            if (!(LandMarkList.Count > 0))
                return null;

            LandMark NearestLandMark = null;
            Point2d currentPosition = new Point2d(position.x, position.y);

            LandMarkList.ForEach(item =>
            {
                if (NearestLandMark != null)
                {
                    if (NearestLandMark.LandMarkPosition.distance(ref currentPosition) > item.LandMarkPosition.distance(ref currentPosition))
                        NearestLandMark = item;
                }
                else NearestLandMark = item;
            });

            return NearestLandMark;
        }
    }


    private List<string> getRadarCreationStrings(string filename)
    {
        List<string> list = new List<string>();
        
        if (!File.Exists(filename))
            GamePlay.gpLogServer(new Player[] { GamePlay.gpPlayer() }, "Missionfile {0} not found! Please check settings", new object[] { FILE_PATH });

        using (StreamReader reader = new StreamReader(filename))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                if (line.Contains("Stationary.Radar"))
                {
                    list.Add(line);
                }
            }
        }
        return list;
    }

    
    private ISectionFile createRadarTriggers()
    {
        ISectionFile trigger = GamePlay.gpCreateSectionFile();

        List<string> Radarstations = getRadarCreationStrings(MISSION_FILE);

        if (Radarstations.Count > 0)
        {
            int i = 0;
            Radarstations.ForEach(item =>
                {
                    item = item.TrimStart(' ');
                    string[] splittet = item.Split(' ');
                    string keyTr, valueTr;

                    keyTr = "Radar" + string.Format("{0:00}", i) +"Destroyed";
                    valueTr = " TGroundDestroyed 50 " + splittet[3] + " " + splittet[4] + " 100"; //TGroundDestroyedTrigger 50% destroyed in radius 100m
                    trigger.add("Trigger", keyTr, valueTr);

                    Headquarters.ForEach(hq => { hq.AddTriggerToObserver(splittet[0], keyTr); });
                    i++;
                });
        }
        return trigger;
    }


    #region Calculations

    private int ToAngels(double altitude)
    {
        double altAngels = (altitude / 0.3048) / 1000;

        if (altAngels > 1)
            altAngels = Math.Round(altAngels, MidpointRounding.AwayFromZero);
        else
            altAngels = 1;

        return (int)altAngels;
    }


    private int ToMiles(double distance)
    {
        double distanceMiles = 0;
        distanceMiles = Math.Round(((distance / 1609.3426)), 0, MidpointRounding.AwayFromZero);   // distance in Miles

        return (int)distanceMiles;
    }


    private 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))];
    }

    // to get the correct bearing its nessesary to make a litte enter the matrix operation.
    // the Vector2d.direction() (same as atan2) has 0° at the x-axis and goes counter clockwise, but we need 0° at the y-axis
    // and clockwise direction
    // so to convert it we need 
    // |0 1| |x|   |0*x + 1*y|    |y|
    // |   | | | = |         | =  | |   // ok not very surprising ;)
    // |1 0| |y|   |1*x + 0*y|    |x|

    private double calculateBearingDegree(Vector3d vector)
    {
        Vector2d matVector = new Vector2d(vector.y, vector.x);
        // the value of direction is in rad so we need *180/Pi to get the value in degrees
        return matVector.direction() * 180.0 / Math.PI;
    }


    private double calculateBearingDegree(Vector2d vector)
    {
        Vector2d newVector = new Vector2d(vector.y, vector.x);

        return newVector.direction() * 180.0 / Math.PI;
    }


    private 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));
    }


    private 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));
    }


    private int getDegreesIn10Step(double degrees)
    {
        degrees = Math.Round((degrees / 10), MidpointRounding.AwayFromZero) * 10;

        if ((int)degrees == 360)
            degrees = 0.0;

        return (int) degrees;
    }

    private int noOfAircraft(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
            return (int)firstDecimal;
    }
    
    #endregion


    internal class LocalHeadquarters
    {
        public string Name { get; set; }
        public Point2d LocationCoords { get; set; }
        public string Callsign { get; set; }
        private List<ObserverStation> AttachedObservers = new List<ObserverStation>();

        public LocalHeadquarters(string name, string callsign, double x, double y, params ObserverStation[] observerStations)
        {
            this.Name = name;
            this.Callsign = callsign;
            this.LocationCoords = new Point2d(x, y);

            if (observerStations != null)
                AttachedObservers.AddRange(observerStations);
        }


        public bool ObserveSector(string sectorName)
        {

            List<string> AttachedSectors = new List<string>();

            if (AttachedObservers.Count > 0)
            {
                AttachedObservers.ForEach(item =>
                {
                    if (item.IsActive)
                        AttachedSectors.AddRange(item.observedSectors);
                });
            }

            if (AttachedSectors.Exists(item => item.Equals(sectorName)))
                return true;
            else
                return false;
        }


        public List<ObserverStation> GetObservers()
        {
            return AttachedObservers;
        }


        public List<string> GetObservedSectors()
        {
            List<string> sectorList = new List<string>();

            AttachedObservers.ForEach(item =>
                {
                    if (item.IsActive)
                    {
                        item.observedSectors.ForEach(sector =>
                            {
                                if (!sectorList.Exists(newsector => sector == newsector))
                                    sectorList.Add(sector);
                            });
                    };
                });
            return sectorList;
        }


        public List<string> GetLostObservedSectors()
        {
            List<string> sectorList = new List<string>();

            AttachedObservers.ForEach(item =>
            {
                if (!item.IsActive)
                {
                    item.observedSectors.ForEach(sector =>
                    {
                        if (!sectorList.Exists(newsector => sector == newsector))
                            sectorList.Add(sector);
                    });
                };
            });

            if (sectorList.Count > 0)
            {
                List<string> CurrentObservedSectors = GetObservedSectors();

                if (CurrentObservedSectors.Count > 0)
                {
                    CurrentObservedSectors.ForEach(item =>
                        {
                            if (sectorList.Exists(sector => sector == item))
                            {
                                sectorList.RemoveAll(sector => sector == item);
                            }
                        });

                }

            }
            return sectorList;
        }

        public void SetObserverInactive(string triggerName)
        {

            if (AttachedObservers.Exists(item => item.TriggerName == triggerName))
            {
                AttachedObservers[AttachedObservers.FindIndex(item => item.TriggerName == triggerName)].IsActive = false;
            }
        }


        public void AddTriggerToObserver(string staticName, string triggerName)
        {
            if (AttachedObservers.Exists(item => item.StaticName == staticName))
            {
                AttachedObservers[AttachedObservers.FindIndex(item => item.StaticName == staticName)].TriggerName = triggerName;
            }
        }


        public double GetDistance(Player player)
        {
            Point2d playerLocation = new Point2d(player.Place().Pos().x, player.Place().Pos().y);

            double distance = LocationCoords.distance(ref playerLocation);

            return distance;
        }

    }

    internal class ObserverStation
    {
        public bool IsActive { get; set; }
        public string StaticName { get; set; }
        public string TriggerName { get; set; }

        public List<string> observedSectors = new List<string>();

        public ObserverStation(string staticName, params string[] sectorNames)
        {
            this.StaticName = staticName;
            this.IsActive = true;

            if (sectorNames != null)
                observedSectors.AddRange(sectorNames);
        }


        public ObserverStation(string staticName, string triggerName, params string[] sectorNames)
        {
            this.StaticName = staticName;
            this.TriggerName = triggerName;
            this.IsActive = true;

            if (sectorNames != null)
                observedSectors.AddRange(sectorNames);
        }


        public void SetTriggerName(string triggerName)
        {
            this.TriggerName = triggerName;
        }

    }


    internal class Pilot
    {
        public Player player { get; set; }
        public LocalHeadquarters connectedHeadquarter;
        public DateTime TimeStamp { get; set; }
        public bool RadarUsed { get; set; }

        public Pilot(Player player)
        {
            this.player = player;
            this.RadarUsed = false;
        }
    }


    internal List<Pilot> PilotsInGame = new List<Pilot>();


    public void checkSectors(Player player)
    {
        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);

            if (PilotsInGame[i].RadarUsed) return;

            PilotsInGame[i].RadarUsed = true;

            if (PilotsInGame[i].connectedHeadquarter != null)
            {
                if (Headquarters.Exists(hq => hq == PilotsInGame[i].connectedHeadquarter))
                {
                    LocalHeadquarters localHQ = PilotsInGame[i].connectedHeadquarter;
                    Dictionary<AiAirGroup, int> planePulks = getPulks(GamePlay.gpAirGroups((player.Army() == 1) ? 2 : 1), 1600.0); //all Airgroups in 1600m radius count as one

                    Dictionary<string, string> Messages = new Dictionary<string, string>();
                    //List<string> Messages = new List<string>();

                    if (planePulks != null && planePulks.Count > 0)
                    {
                        bool foundEnemy = false;

                        foreach (var kvp in planePulks)
                        {
                            string sectorName = GamePlay.gpSectorName(kvp.Key.Pos().x, kvp.Key.Pos().y);

                            if (localHQ.ObserveSector(sectorName) && kvp.Key.Pos().z > 600.00)
                            {
                                foundEnemy = true;
                                string tmpKey = "";
                                string message = "";
                                Point3d destinationPoint = kvp.Key.Pos();
                                LandMark NearestLandMark = LandMarks.getNearestLandMarkTo(kvp.Key.Pos());
                                Point2d AirgroupPos = new Point2d(kvp.Key.Pos().x, kvp.Key.Pos().y);
                                Vector2d AirgroupVector = new Vector2d(kvp.Key.Vwld().x, kvp.Key.Vwld().y);

                                if (kvp.Value > 3) // only if more than 3 planes in a pulk generate a message
                                {
                                    if (NearestLandMark != null)
                                    {
                                        tmpKey = string.Format("Enemy {0} miles {1} from {2} at Angels {3}, Heading {4}", ToMiles(NearestLandMark.LandMarkPosition.distance(ref AirgroupPos)), degreesToWindRose(calculateBearingFromOrigin(AirgroupPos, NearestLandMark.LandMarkPosition)), NearestLandMark.LandMarkName, ToAngels(kvp.Key.Pos().z), getDegreesIn10Step(calculateBearingDegree(AirgroupVector)));
                                        message = string.Format("{0}+ Enemy {1} miles {2} from {3} at Angels {4}, Heading {5}", noOfAircraft(kvp.Value), ToMiles(NearestLandMark.LandMarkPosition.distance(ref AirgroupPos)), degreesToWindRose(calculateBearingFromOrigin(AirgroupPos, NearestLandMark.LandMarkPosition)), NearestLandMark.LandMarkName, ToAngels(kvp.Key.Pos().z), getDegreesIn10Step(calculateBearingDegree(AirgroupVector)));
                                    }
                                    else
                                    {
                                        tmpKey = string.Format("Enemy in Sector: {0} heading {1}", noOfAircraft(kvp.Value), sectorName, getDegreesIn10Step(calculateBearingDegree(AirgroupVector)));
                                        message = string.Format("{0}+ Enemy in Sector: {1} heading {2}", noOfAircraft(kvp.Value), sectorName, getDegreesIn10Step(calculateBearingDegree(AirgroupVector)));
                                    }
                                    if (!Messages.ContainsKey(tmpKey))
                                    {
                                        Messages.Add(tmpKey, message);
                                    }
                                }
                                
                            }
                        }

                        Timeout(3, () =>
                        {
                            GamePlay.gpLogServer(new[] { player }, "From {0}:", new object[]{localHQ.Name });
                            
                            if (Messages.Count > 0)
                                foreach(var kvp in Messages)
                                {
                                        GamePlay.gpLogServer(new[] { player }, kvp.Value, null);
                                };

                            if (localHQ.GetLostObservedSectors().Count > 0)
                            {
                                string lostSectors = "";

                                localHQ.GetLostObservedSectors().ForEach(item =>
                                {
                                    lostSectors += item + " ";
                                });

                                lostSectors = lostSectors.TrimEnd(' ');
                                GamePlay.gpLogServer(null, "Radar blind for Sectors {0}!", new[] { lostSectors });
                                
                                if (!foundEnemy)
                                    GamePlay.gpLogServer(new[] { player }, "No Enemy in other available Sectors spottet", null);
                            }
                            else if (!foundEnemy)
                                GamePlay.gpLogServer(new[] { player }, "No Enemy in Range", null);
                        });
                    }
                }
            }
            Timeout(13.0, () => // delay for next use
                {
                    PilotsInGame[i].RadarUsed = false;
                });
        }
    }


    private Dictionary<AiAirGroup, int> getPulks(AiAirGroup[] airgroups, double maxdistance)
    {
        Dictionary<AiAirGroup, List<AiAirGroup>> Pulks = new Dictionary<AiAirGroup, List<AiAirGroup>>(); 

        if (airgroups != null && airgroups.Length > 1)
        {
            Pulks.Add(airgroups[0], new List<AiAirGroup>());  //leaderGroup //'attached' groups (in radius maxdistance)

            for (int i = 1; i < airgroups.Length; i++)
            {
                bool airgroupAdded = false;
                foreach (var kvp in Pulks)
                {
                    Point3d airgroupPos = kvp.Key.Pos();

                    if (airgroups[i].Pos().distance(ref airgroupPos) < maxdistance)
                    {
                        kvp.Value.Add(airgroups[i]);
                        airgroupAdded = true;
                    }
                }
                if (!airgroupAdded)
                    Pulks.Add(airgroups[i], new List<AiAirGroup>());
            }
        }

        Dictionary<AiAirGroup, int> planePulks = new Dictionary<AiAirGroup, int>();

        foreach (var kvp in Pulks)
        {
            int numberOfPlanes = 0;

            numberOfPlanes += kvp.Key.NOfAirc;

            if (kvp.Value.Count > 0)
                kvp.Value.ForEach(item =>
                    {
                        numberOfPlanes += item.NOfAirc;
                    });

            planePulks.Add(kvp.Key, numberOfPlanes);
        }

        return planePulks;
    }


    private void connectToHeadquarterSpeech(AiAircraft aircraft, LocalHeadquarters localHQ)
    {
        double initTime = 0.0;
        
        aircraft.SayToGroup(aircraft.AirGroup(), "Hello_guys");

        Timeout(initTime += 2, () =>
            {
                aircraft.SayToGroup(aircraft.AirGroup(), "This_is");
            });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), localHQ.Callsign);
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), "n2"); // to is missing as ogg
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), aircraft.CallSign());
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), "leader__");
        });
    }


    #region mission menus

    #region class Menu

    internal class Menu
    {
        internal class MenuEntry
        {
            internal string MenuName { get; set; }
            internal bool active { get; set; }
        }

        internal List<MenuEntry> menuEntries = new List<MenuEntry>();

        public void AddMenuEntry(string description, bool active)
        {
            MenuEntry NewMenuEntry = new MenuEntry();

            NewMenuEntry.MenuName = description;
            NewMenuEntry.active = active;

            menuEntries.Add(NewMenuEntry);
        }

        public string[] GetMenuDescriptions()
        {
            List<string> Descriptions = new List<string>();

            menuEntries.ForEach(item =>
            {
                Descriptions.Add(item.MenuName);
            });

            return Descriptions.ToArray();
        }

        public bool[] GetActives()
        {
            List<bool> Actives = new List<bool>();

            menuEntries.ForEach(item =>
            {
                Actives.Add(item.active);
            });

            return Actives.ToArray();
        }

        public bool IsValid()
        {
            if (menuEntries == null || menuEntries.Count < 1)
                return false;
            else
                return true;

        }

    }

    #endregion

    
    public void SetMainMenu(Player player)
    {
        if (player.Army() == 1) // red Side
            GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { "Radaroperations" }, new bool[] { true });
        else
            GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { "Not Available" }, new bool[] { true });
    }


    public void SetRadarMenu(Player player)
    {
        string headQuarter = "Select Headquarter";
        string connectedTo = "";

        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);

            if (PilotsInGame[i].connectedHeadquarter != null)
                connectedTo = string.Format(" (connected: {0})", PilotsInGame[i].connectedHeadquarter.Name);
        }
        headQuarter += connectedTo;

        if(PilotsInGame.Exists(item=> item.player == player))
        {
            int i = PilotsInGame.FindIndex(item=> item.player == player);
            if(PilotsInGame[i].RadarUsed)
                GamePlay.gpSetOrderMissionMenu(player, true, 100, new string[] { headQuarter, "Get Radar Information" }, new bool[] { true, false });
            else
                GamePlay.gpSetOrderMissionMenu(player, true, 100, new string[] { headQuarter, "Get Radar Information" }, new bool[] { true, true });
        }
    }


    public void SetConnectToHeadquarterMenu(Player player, double maxdistanceToHq)
    {
        Menu NewMenu = new Menu();
        LocalHeadquarters headQuarter = null;

        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);
            headQuarter = PilotsInGame[i].connectedHeadquarter;
        }

        Headquarters.ForEach(item =>
        {
            if (headQuarter != null && item == headQuarter && item.GetDistance(player) < maxdistanceToHq)
            {
                NewMenu.AddMenuEntry(item.Name + " *", true);
            }
            else
                NewMenu.AddMenuEntry(item.Name, true);
        });

        if (NewMenu.IsValid())
            GamePlay.gpSetOrderMissionMenu(player, true, 101, NewMenu.GetMenuDescriptions() , NewMenu.GetActives());
        else
            GamePlay.gpSetOrderMissionMenu(player, true, 101, new string[]{ "Not available" }, new bool[]{true});
    }


    public void SetHeadQuarter(Player player, int menuItemIndex)
    {
        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);
            PilotsInGame[i].connectedHeadquarter = Headquarters[menuItemIndex-1];
            if (player.Place() != null)
                connectToHeadquarterSpeech((player.Place() as AiAircraft), PilotsInGame[i].connectedHeadquarter);
        }

    }


    public override void OnOrderMissionMenuSelected(Player player, int ID, int menuItemIndex)
    {
        if (ID == 0)
        { // main menu
            if (menuItemIndex == 1)
            {
                SetRadarMenu(player);
            }
        }

        if (ID == 100)
        {
            //Radar Menu
            if (menuItemIndex == 1)
            {
                SetConnectToHeadquarterMenu(player, 50000.0);
            }

            if (menuItemIndex == 2)
            {
                checkSectors(player);
                SetMainMenu(player);
            }
            if (menuItemIndex == 0)
                SetMainMenu(player);
        }

        if (ID == 101)
        {
            //Radar Menu
            if (menuItemIndex == 0)
                SetRadarMenu(player);
            else
            {
                SetHeadQuarter(player, menuItemIndex);
                SetRadarMenu(player);
            }
        }
    }

    #endregion


    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;
        GamePlay.gpPostMissionLoad(createRadarTriggers());
    }


    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);

        if (!PilotsInGame.Exists(item => item.player == player))
        {
            PilotsInGame.Add(new Pilot(player));
        }

        SetMainMenu(player);
    }


    public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        base.OnTrigger(missionNumber, shortName, active);
        
        if (shortName.StartsWith("Radar") && shortName.EndsWith("Destroyed"))
        {
            GamePlay.gpLogServer(null, "Radar destroyed", null);

            Headquarters.ForEach(item =>
                {
                    item.SetObserverInactive(shortName);
                });
        }
    }

}

Last edited by FG28_Kodiak; 04-26-2012 at 02:23 PM.
Reply With Quote
  #92  
Old 04-26-2012, 02:24 PM
5./JG27.Farber 5./JG27.Farber is offline
Approved Member
 
Join Date: Aug 2011
Posts: 1,958
Default

Speedy reply!

You sir, are a credit to the community and our forth coming campaign!

S!
Reply With Quote
  #93  
Old 04-26-2012, 03:31 PM
von Brühl von Brühl is offline
Approved Member
 
Join Date: Jan 2012
Posts: 215
Default

Quote:
Originally Posted by 5./JG27.Farber View Post

Could radar actually tell the difference between fighters and bombers? Maybe it should say aircraft?
Ok, you've asked this several times and I haven't seen an answer. Yes, they could, but not in the sense that the radar operator would say "Ooo, look, 15 He-111s just popped up over Calais!" Instead, they would see the size of the return, and plot the speed, maybe see how fast it changed direction/altitude, and determine if it was a bomber or fighter. (Although I've read somewhere it could be fooled with very tight formations) With your 4 minute returns, I think that would give the Home Chain enough time to determine roughly what they were looking at.
Reply With Quote
  #94  
Old 04-26-2012, 06:49 PM
Osprey's Avatar
Osprey Osprey is offline
Approved Member
 
Join Date: Jan 2010
Location: Gloucestershire, England
Posts: 1,264
Default

Credit where credit is due Kodiak, this is an epic program that shoud add a big dimension to immersion. ~S~ !!
Reply With Quote
  #95  
Old 04-29-2012, 01:57 PM
5./JG27.Farber 5./JG27.Farber is offline
Approved Member
 
Join Date: Aug 2011
Posts: 1,958
Default

What pattern would a radar "emit"?

Which pattern is closets to reality?







Reply With Quote
  #96  
Old 04-29-2012, 04:06 PM
Osprey's Avatar
Osprey Osprey is offline
Approved Member
 
Join Date: Jan 2010
Location: Gloucestershire, England
Posts: 1,264
Default

Here's the coverage but this is 2D in a 3D world. The stations overlapped to complete the coverage.




Or are you asking what Kodiak's RDF covers?

Last edited by Osprey; 04-29-2012 at 04:09 PM.
Reply With Quote
  #97  
Old 04-29-2012, 05:35 PM
5./JG27.Farber 5./JG27.Farber is offline
Approved Member
 
Join Date: Aug 2011
Posts: 1,958
Default

No, Kodiaks system covers what you tell it to. I think they were like the third example but more elipse and over lapping like you said... I dont intend to use 20 radar to cover the South East like real BoB, as you reds will have to switch channels constantly and with one shot every four minutes that would not be much good. Also there was Chain Home high and low for different altitudes. So its simpler and better to use high and low combined with say 4 radar operating... Covering an unrealistic area...

Otherwise one radar might only be high or low and only cover 40km wide and 120km long... So you would check in with that radar and be locked out for 4 mins! There would in all likelyness be nothing in that slim sector and therefore the radar would be useless.

So, in clonclusion its better, faster and simpler to let one radar cover a bigger area both high and low... You might argue its unrealistic but any gap in the field is still a gap and an entire air armada can be sailed through a 40km gap! So its more realistc to fudge it. Also Kodiak has included Air Obsever Corps, so any inland grid sqaures can be set to them. Think Ill go with something like picture 2. - but wider with AOC taking up the slck near the cone point.!

Last edited by 5./JG27.Farber; 04-29-2012 at 05:43 PM.
Reply With Quote
  #98  
Old 04-29-2012, 05:45 PM
FG28_Kodiak FG28_Kodiak is offline
Approved Member
 
Join Date: Dec 2009
Location: Swabia->Bavaria->Germany
Posts: 884
Default

You can let them overlapp.
So if one Radarstation is destroyed your HQ lost not all sectors from this observer, only the unique.
Reply With Quote
  #99  
Old 04-29-2012, 07:03 PM
FG28_Kodiak FG28_Kodiak is offline
Approved Member
 
Join Date: Dec 2009
Location: Swabia->Bavaria->Germany
Posts: 884
Default

So the menu should now work correctly, but i was to busy to test it properly, so i hope you will testing it for me
At the moment i use a time delay from 30sec. for the station answer, and a additional 10sec before the radar can be reused (for testing no problem to change the timings) . Please check the messages, i don't know how the radar communication exactly was, so maybe i must change them.
The communication is only possible if in range to the station for testing 50Km at the moment, you can only choose the HQs in range and you can lost the connection.
Only airgroups larger than 3 are detected, 5+ (4-7), 10+ (8-17planes) 20+(18-27) 30+ (28-37) etc.

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using maddox.game;
using maddox.game.world;
using maddox.GP;


public class Mission : AMission
{

    private static string userdocpath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    private static string CLODO_FILE_PATH = userdocpath + @"\1C SoftClub\il-2 sturmovik cliffs of dover\";
    private static string FILE_PATH = @"missions\RadarTest\Radar.mis"; // adjust to your needs
    private static string MISSION_FILE = CLODO_FILE_PATH + FILE_PATH;

    List<LocalHeadquarters> Headquarters = new List<LocalHeadquarters>{
        {new LocalHeadquarters("Luton (Ash)", "CallSign24", 50000.0, 242928.64, 251773.16, 
            new ObserverStation( "Static0","AN,16","AN,17","AN,18","AN,19","AO,16","AO,17","AO,18","AO,19","AP,16","AP,17","AP,18","AP,19","AQ,16","AQ,17","AQ,18","AQ,19"), //Dover
            new ObserverStation( "Static2","AL,20","AL,21","AL,22","AM,20","AM,21","AM,22","AN,20","AN,21","AN,22","AO,20","AO,21","AO,22"))}, // Dunkirk
        {new LocalHeadquarters("RadPoe (Woodchurch)", "CallSign32", 50000.0, 208162.91, 227726.61, 
            new ObserverStation( "Static1","AJ,15","AJ,16","AJ,17","AJ,18","AK,15","AK,16","AK,17","AK,18","AL,15","AL,16","AL,17","AL,18","AM,15","AM,16","AM,17","AM,18"), //Rye
            new ObserverStation( "Royal Observer Corps I","AK,19","AK,20","AK,21","AL,19","AL,20","AL,21","AM,19","AM,20","AM,21"))}, // fake simulation of Royal Observer Corps, none destructable
        //{new LocalHeadquarters("Forest (Woodchurch)", "CallSign15", 208162.91, 227726.61, new ObserverStation( "Static4","E,1","E,2","E,3"), new ObserverStation( "Static5","F,1","F,2","F,3"))}
    };


    LandMarkHandling LandMarks = new LandMarkHandling(
        new LandMark("Dover", 245577.51, 234521.20),
        new LandMark("Folkestone", 235333.17, 229568.64),
        new LandMark("St.Magarets's at Cliffe", 250423.81, 238001.64),
        new LandMark("Deal", 250985.14, 244801.80),
        new LandMark("Dymchurch", 223734.62, 222437.79),
        new LandMark("New Romney", 220005.71, 218110.40),
        new LandMark("Rye", 205758.66, 213525.22),
        new LandMark("Hastings", 195366.28, 203132.83),
        new LandMark("Eastbourne", 174755.54, 191963.14),
        new LandMark("Brighton", 144909.86, 197927.40),
        new LandMark("Calais", 284654.87, 215707.54)
        );


    Random random = new Random();


    internal class LandMark
    {
        public string LandMarkName { get; set; }
        public Point2d LandMarkPosition { get; set; }

        public LandMark(string landMarkName, double x, double y)
        {
            this.LandMarkName = landMarkName;
            this.LandMarkPosition = new Point2d(x, y);
        }
    }


    internal class LandMarkHandling
    {
        List<LandMark> LandMarkList = new List<LandMark>();

        public LandMarkHandling(params LandMark[] mark)
        {
            if (mark != null)
                LandMarkList.AddRange(mark);
        }


        public LandMark getNearestLandMarkTo(Point3d position)
        {

            if (!(LandMarkList.Count > 0))
                return null;

            LandMark NearestLandMark = null;
            Point2d currentPosition = new Point2d(position.x, position.y);

            LandMarkList.ForEach(item =>
            {
                if (NearestLandMark != null)
                {
                    if (NearestLandMark.LandMarkPosition.distance(ref currentPosition) > item.LandMarkPosition.distance(ref currentPosition))
                        NearestLandMark = item;
                }
                else NearestLandMark = item;
            });

            return NearestLandMark;
        }
    }


    private List<string> getRadarCreationStrings(string filename)
    {
        List<string> list = new List<string>();
        
        if (!File.Exists(filename))
            GamePlay.gpLogServer(new Player[] { GamePlay.gpPlayer() }, "Missionfile {0} not found! Please check settings", new object[] { FILE_PATH });

        using (StreamReader reader = new StreamReader(filename))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                if (line.Contains("Stationary.Radar"))
                {
                    list.Add(line);
                }
            }
        }
        return list;
    }

    
    private ISectionFile createRadarTriggers()
    {
        ISectionFile trigger = GamePlay.gpCreateSectionFile();

        List<string> Radarstations = getRadarCreationStrings(MISSION_FILE);

        if (Radarstations.Count > 0)
        {
            int i = 0;
            Radarstations.ForEach(item =>
                {
                    item = item.TrimStart(' ');
                    string[] splittet = item.Split(' ');
                    string keyTr, valueTr;

                    keyTr = "Radar" + string.Format("{0:00}", i) +"Destroyed";
                    valueTr = " TGroundDestroyed 50 " + splittet[3] + " " + splittet[4] + " 100"; //TGroundDestroyedTrigger 50% destroyed in radius 100m
                    trigger.add("Trigger", keyTr, valueTr);

                    Headquarters.ForEach(hq => hq.AddTriggerToObserver(splittet[0], keyTr));
                    i++;
                });
        }
        return trigger;
    }


    #region Calculations

    private int ToAngels(double altitude)
    {
        double altAngels = (altitude / 0.3048) / 1000;

        if (altAngels > 1)
            altAngels = Math.Round(altAngels, MidpointRounding.AwayFromZero);
        else
            altAngels = 1;

        return (int)altAngels;
    }


    private int ToMiles(double distance)
    {
        double distanceMiles = 0;
        distanceMiles = Math.Round(((distance / 1609.3426)), 0, MidpointRounding.AwayFromZero);   // distance in Miles

        return (int)distanceMiles;
    }


    private 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))];
    }

    // to get the correct bearing its nessesary to make a litte enter the matrix operation.
    // the Vector2d.direction() (same as atan2) has 0° at the x-axis and goes counter clockwise, but we need 0° at the y-axis
    // and clockwise direction
    // so to convert it we need 
    // |0 1| |x|   |0*x + 1*y|    |y|
    // |   | | | = |         | =  | |   // ok not very surprising ;)
    // |1 0| |y|   |1*x + 0*y|    |x|

    private double calculateBearingDegree(Vector3d vector)
    {
        Vector2d matVector = new Vector2d(vector.y, vector.x);
        // the value of direction is in rad so we need *180/Pi to get the value in degrees
        return matVector.direction() * 180.0 / Math.PI;
    }


    private double calculateBearingDegree(Vector2d vector)
    {
        Vector2d newVector = new Vector2d(vector.y, vector.x);

        return newVector.direction() * 180.0 / Math.PI;
    }


    private 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));
    }


    private 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));
    }


    private int getDegreesIn10Step(double degrees)
    {
        degrees = Math.Round((degrees / 10), MidpointRounding.AwayFromZero) * 10;

        if ((int)degrees == 360)
            degrees = 0.0;

        return (int) degrees;
    }

    private int noOfAircraft(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
            return (int)firstDecimal;
    }
    
    #endregion


    internal class LocalHeadquarters
    {
        public string Name { get; set; }
        public Point2d LocationCoords { get; set; }
        public string Callsign { get; set; }

        public double MaxRange { get; set; }

        private List<ObserverStation> AttachedObservers = new List<ObserverStation>();

        public LocalHeadquarters(string name, string callsign, double maxRange, double x, double y, params ObserverStation[] observerStations)
        {
            this.Name = name;
            this.Callsign = callsign;
            this.LocationCoords = new Point2d(x, y);
            this.MaxRange = maxRange;

            if (observerStations != null)
                AttachedObservers.AddRange(observerStations);
        }


        public bool CheckInRange(Player player)
        {
            if (player.Place() == null) return false;
            
            bool inRange = false;
            Point2d currentPos = new Point2d(player.Place().Pos().x, player.Place().Pos().y);

            if (LocationCoords.distance(ref currentPos) < MaxRange)
                return true;

            return false;
        }


        public bool ObserveSector(string sectorName)
        {

            List<string> AttachedSectors = new List<string>();

            if (AttachedObservers.Count > 0)
            {
                AttachedObservers.ForEach(item =>
                {
                    if (item.IsActive)
                        AttachedSectors.AddRange(item.observedSectors);
                });
            }

            if (AttachedSectors.Exists(item => item.Equals(sectorName)))
                return true;
            else
                return false;
        }


        public List<ObserverStation> GetObservers()
        {
            return AttachedObservers;
        }


        public List<string> GetObservedSectors()
        {
            List<string> sectorList = new List<string>();

            AttachedObservers.ForEach(item =>
                {
                    if (item.IsActive)
                    {
                        item.observedSectors.ForEach(sector =>
                            {
                                if (!sectorList.Exists(newsector => sector == newsector))
                                    sectorList.Add(sector);
                            });
                    };
                });
            return sectorList;
        }


        public List<string> GetLostObservedSectors()
        {
            List<string> sectorList = new List<string>();

            AttachedObservers.ForEach(item =>
            {
                if (!item.IsActive)
                {
                    item.observedSectors.ForEach(sector =>
                    {
                        if (!sectorList.Exists(newsector => sector == newsector))
                            sectorList.Add(sector);
                    });
                };
            });

            if (sectorList.Count > 0)
            {
                List<string> CurrentObservedSectors = GetObservedSectors();

                if (CurrentObservedSectors.Count > 0)
                {
                    CurrentObservedSectors.ForEach(item =>
                        {
                            if (sectorList.Exists(sector => sector == item))
                            {
                                sectorList.RemoveAll(sector => sector == item);
                            }
                        });

                }

            }
            return sectorList;
        }

        public void SetObserverInactive(string triggerName)
        {

            if (AttachedObservers.Exists(item => item.TriggerName == triggerName))
            {
                AttachedObservers[AttachedObservers.FindIndex(item => item.TriggerName == triggerName)].IsActive = false;
            }
        }


        public void AddTriggerToObserver(string staticName, string triggerName)
        {
            if (AttachedObservers.Exists(item => item.StaticName == staticName))
            {
                AttachedObservers[AttachedObservers.FindIndex(item => item.StaticName == staticName)].TriggerName = triggerName;
            }
        }


        public double GetDistance(Player player)
        {
            Point2d playerLocation = new Point2d(player.Place().Pos().x, player.Place().Pos().y);

            double distance = LocationCoords.distance(ref playerLocation);

            return distance;
        }

    }

    internal class ObserverStation
    {
        public bool IsActive { get; set; }
        public string StaticName { get; set; }
        public string TriggerName { get; set; }

        public List<string> observedSectors = new List<string>();

        public ObserverStation(string staticName, params string[] sectorNames)
        {
            this.StaticName = staticName;
            this.IsActive = true;

            if (sectorNames != null)
                observedSectors.AddRange(sectorNames);
        }


        public ObserverStation(string staticName, string triggerName, params string[] sectorNames)
        {
            this.StaticName = staticName;
            this.TriggerName = triggerName;
            this.IsActive = true;

            if (sectorNames != null)
                observedSectors.AddRange(sectorNames);
        }


        public void SetTriggerName(string triggerName)
        {
            this.TriggerName = triggerName;
        }

    }


    internal class Pilot
    {
        public Player player { get; set; }
        public LocalHeadquarters ConnectedHeadquarter;
        public DateTime TimeStamp { get; set; }
        public bool RadarUsed { get; set; }

        public Pilot(Player player)
        {
            this.player = player;
            this.RadarUsed = false;
        }
    }


    internal List<Pilot> PilotsInGame = new List<Pilot>();


    public void checkSectors(Player player)
    {

        double timeDelay = 0.0;
        
        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);

            if (PilotsInGame[i].RadarUsed) return;
            
            

            if (PilotsInGame[i].ConnectedHeadquarter != null && PilotsInGame[i].ConnectedHeadquarter.CheckInRange(player))
            {
                PilotsInGame[i].RadarUsed = true;

                if (Headquarters.Exists(hq => hq == PilotsInGame[i].ConnectedHeadquarter))
                {
                    LocalHeadquarters localHQ = PilotsInGame[i].ConnectedHeadquarter;

                    Timeout(timeDelay += 2.0, () => 
                        {
                            GamePlay.gpLogServer(new[]{player},"From {0} to {1}:", new object[]{localHQ.Name, player.Name()});
                            GamePlay.gpLogServer(new[] { player }, "Collecting available informations - stay patient", null);
                        });

                    Dictionary<AiAirGroup, int> planePulks = getPulks(GamePlay.gpAirGroups((player.Army() == 1) ? 2 : 1), 1600.0); //all Airgroups in 1600m radius count as one

                    Dictionary<string, string> Messages = new Dictionary<string, string>();
                   

                    if (planePulks != null && planePulks.Count > 0)
                    {
                        bool foundEnemy = false;

                        foreach (var kvp in planePulks)
                        {
                            string sectorName = GamePlay.gpSectorName(kvp.Key.Pos().x, kvp.Key.Pos().y);

                            if (localHQ.ObserveSector(sectorName) && kvp.Key.Pos().z > 600.00)
                            {
                                foundEnemy = true;
                                string tmpKey = "";
                                string message = "";
                                Point3d destinationPoint = kvp.Key.Pos();
                                LandMark nearestLandMark = LandMarks.getNearestLandMarkTo(kvp.Key.Pos());
                                Point2d airgroupPos = new Point2d(kvp.Key.Pos().x, kvp.Key.Pos().y);
                                Vector2d airgroupVector = new Vector2d(kvp.Key.Vwld().x, kvp.Key.Vwld().y);

                                if (kvp.Value > 3) // only if more than 3 planes in a pulk generate a message
                                {
                                    if (nearestLandMark != null)
                                    {
                                        tmpKey = string.Format("Enemy {0} miles {1} from {2} at Angels {3}, Heading {4}", ToMiles(nearestLandMark.LandMarkPosition.distance(ref airgroupPos)), degreesToWindRose(calculateBearingFromOrigin(airgroupPos, nearestLandMark.LandMarkPosition)), nearestLandMark.LandMarkName, ToAngels(kvp.Key.Pos().z), getDegreesIn10Step(calculateBearingDegree(airgroupVector)));
                                        message = string.Format("{0}+ Enemy {1} miles {2} from {3} at Angels {4}, Heading {5}", noOfAircraft(kvp.Value), ToMiles(nearestLandMark.LandMarkPosition.distance(ref airgroupPos)), degreesToWindRose(calculateBearingFromOrigin(airgroupPos, nearestLandMark.LandMarkPosition)), nearestLandMark.LandMarkName, ToAngels(kvp.Key.Pos().z), getDegreesIn10Step(calculateBearingDegree(airgroupVector)));
                                    }
                                    else
                                    {
                                        tmpKey = string.Format("Enemy in Sector: {0} heading {1}", noOfAircraft(kvp.Value), sectorName, getDegreesIn10Step(calculateBearingDegree(airgroupVector)));
                                        message = string.Format("{0}+ Enemy in Sector: {1} heading {2}", noOfAircraft(kvp.Value), sectorName, getDegreesIn10Step(calculateBearingDegree(airgroupVector)));
                                    }
                                    if (!Messages.ContainsKey(tmpKey))
                                    {
                                        Messages.Add(tmpKey, message);
                                    }
                                }
                                
                            }
                        }

                        Timeout(timeDelay += 28, () =>
                        {
                            GamePlay.gpLogServer(new[] { player }, "From {0}:", new object[]{localHQ.Name });
                            
                            if (Messages.Count > 0)
                                foreach(var kvp in Messages)
                                {
                                        GamePlay.gpLogServer(new[] { player }, kvp.Value, null);
                                };

                            if (localHQ.GetLostObservedSectors().Count > 0)
                            {
                                string lostSectors = "";

                                localHQ.GetLostObservedSectors().ForEach(item =>
                                {
                                    lostSectors += item + " ";
                                });

                                lostSectors = lostSectors.TrimEnd(' ');
                                GamePlay.gpLogServer(null, "Radar blind for Sectors {0}!", new[] { lostSectors });
                                
                                if (!foundEnemy)
                                    GamePlay.gpLogServer(new[] { player }, "No Enemy in other available Sectors spottet", null);
                            }
                            else if (!foundEnemy)
                                GamePlay.gpLogServer(new[] { player }, "No Enemy in Range", null);
                        });
                    }
                }
            }
            else
            {
                GamePlay.gpLogServer(new[] { player }, "Connection to HQ lost (out of Range)", null);
            }




            Timeout(timeDelay += 10.0, () => // delay for next use
                {
                    PilotsInGame[i].RadarUsed = false;
                });
        }
    }


    private Dictionary<AiAirGroup, int> getPulks(AiAirGroup[] airgroups, double maxdistance)
    {
        Dictionary<AiAirGroup, List<AiAirGroup>> Pulks = new Dictionary<AiAirGroup, List<AiAirGroup>>(); 

        if (airgroups != null && airgroups.Length > 1)
        {
            Pulks.Add(airgroups[0], new List<AiAirGroup>());  //leaderGroup //'attached' groups (in radius maxdistance)

            for (int i = 1; i < airgroups.Length; i++)
            {
                bool airgroupAdded = false;
                foreach (var kvp in Pulks)
                {
                    Point3d airgroupPos = kvp.Key.Pos();

                    if (airgroups[i].Pos().distance(ref airgroupPos) < maxdistance)
                    {
                        kvp.Value.Add(airgroups[i]);
                        airgroupAdded = true;
                    }
                }
                if (!airgroupAdded)
                    Pulks.Add(airgroups[i], new List<AiAirGroup>());
            }
        }

        Dictionary<AiAirGroup, int> planePulks = new Dictionary<AiAirGroup, int>();

        foreach (var kvp in Pulks)
        {
            int numberOfPlanes = 0;

            numberOfPlanes += kvp.Key.NOfAirc;

            if (kvp.Value.Count > 0)
                kvp.Value.ForEach(item =>
                    {
                        numberOfPlanes += item.NOfAirc;
                    });

            planePulks.Add(kvp.Key, numberOfPlanes);
        }

        return planePulks;
    }


    private void connectToHeadquarterSpeech(AiAircraft aircraft, LocalHeadquarters localHQ)
    {
        double initTime = 0.0;
        
        aircraft.SayToGroup(aircraft.AirGroup(), "Hello_guys");

        Timeout(initTime += 2, () =>
            {
                aircraft.SayToGroup(aircraft.AirGroup(), "This_is");
            });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), localHQ.Callsign);
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), "n2"); // to is missing as ogg
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), aircraft.CallSign());
        });

        Timeout(initTime += 2, () =>
        {
            aircraft.SayToGroup(aircraft.AirGroup(), "leader__");
        });
    }


    #region mission menus

    #region class Menu

    internal class Menu
    {
        internal class MenuEntry
        {
            internal string MenuName { get; set; }
            internal bool active { get; set; }
        }

        internal List<MenuEntry> menuEntries = new List<MenuEntry>();

        public void AddMenuEntry(string description, bool active)
        {
            MenuEntry NewMenuEntry = new MenuEntry();

            NewMenuEntry.MenuName = description;
            NewMenuEntry.active = active;

            menuEntries.Add(NewMenuEntry);
        }

        public string[] GetMenuDescriptions()
        {
            List<string> Descriptions = new List<string>();

            menuEntries.ForEach(item =>
            {
                Descriptions.Add(item.MenuName);
            });

            return Descriptions.ToArray();
        }

        public bool[] GetActives()
        {
            List<bool> Actives = new List<bool>();

            menuEntries.ForEach(item =>
            {
                Actives.Add(item.active);
            });

            return Actives.ToArray();
        }

        public bool IsValid()
        {
            if (menuEntries == null || menuEntries.Count < 1)
                return false;
            else
                return true;

        }

    }

    #endregion

    
    public void SetMainMenu(Player player)
    {
        if (player.Army() == 1) // red Side
            GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { "Fighter Command HQs" }, new bool[] { true });
        //else // blue Side
        //    GamePlay.gpSetOrderMissionMenu(player, false, 0, new string[] { "Nothing Available" }, new bool[] { true });
    }


    public void SetRadarMenu(Player player)
    {
        if (player.Army() != 1) return;
        
        string headQuarter = "Select Headquarter";
        string connectedTo = "";

        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);

            if (PilotsInGame[i].ConnectedHeadquarter != null)
                connectedTo = string.Format(" (connected: {0})", PilotsInGame[i].ConnectedHeadquarter.Name);
        }
        headQuarter += connectedTo;

        if(PilotsInGame.Exists(item=> item.player == player))
        {
            int i = PilotsInGame.FindIndex(item=> item.player == player);
            if (PilotsInGame[i].ConnectedHeadquarter == null)
                GamePlay.gpSetOrderMissionMenu(player, true, 100, new string[] { headQuarter, "Get Radar Information" }, new bool[] { true, false });
            else if (PilotsInGame[i].RadarUsed)
                GamePlay.gpSetOrderMissionMenu(player, true, 100, new string[] { headQuarter, "Get Radar Information" }, new bool[] { false, false });
            else
                GamePlay.gpSetOrderMissionMenu(player, true, 100, new string[] { headQuarter, "Get Radar Information" }, new bool[] { true, true });
        }
    }


    public void SetConnectToHeadquarterMenu(Player player)
    {

        Menu NewMenu = new Menu();
        LocalHeadquarters headQuarter = null;
        int i = -1;

        if (PilotsInGame.Exists(item => item.player == player))
        {
            i = PilotsInGame.FindIndex(item => item.player == player);
            headQuarter = PilotsInGame[i].ConnectedHeadquarter;
        }

        if (i < 0 && PilotsInGame[i].RadarUsed == true) return;


        Headquarters.ForEach(item =>
        {
            if (headQuarter != null && item == headQuarter && headQuarter.CheckInRange(player))
            {
                NewMenu.AddMenuEntry(item.Name + " *", true);
            }
            else if (item.CheckInRange(player))
                NewMenu.AddMenuEntry(item.Name, true);
        });

        if (NewMenu.IsValid())
            GamePlay.gpSetOrderMissionMenu(player, true, 101, NewMenu.GetMenuDescriptions() , NewMenu.GetActives());
        else
            GamePlay.gpSetOrderMissionMenu(player, true, 101, new string[]{ "None available" }, new bool[]{false});
    }


    public void SetHeadQuarter(Player player, int menuItemIndex)
    {
        if (PilotsInGame.Exists(item => item.player == player))
        {
            int i = PilotsInGame.FindIndex(item => item.player == player);

            if (Headquarters[menuItemIndex - 1].CheckInRange(player) && !PilotsInGame[i].RadarUsed)
            {
                PilotsInGame[i].ConnectedHeadquarter = Headquarters[menuItemIndex - 1];
                if (player.Place() != null)
                {
                   // connectToHeadquarterSpeech((player.Place() as AiAircraft), PilotsInGame[i].ConnectedHeadquarter);
                    Timeout(2.0, () => 
                        {
                            GamePlay.gpLogServer(new[] { player }, "From {0} to {1}:", new object[] { PilotsInGame[i].ConnectedHeadquarter.Name, player.Name() });
                            GamePlay.gpLogServer(new[] { player }, "You are welcome!", null);
                        });
                }
            }
            PilotsInGame[i].RadarUsed = false;
        }

    }




    public void MenuPartRadarOperations(Player player, int id, int menuItemIndex)
    {
        if (id == 100)
        {
            if (PilotsInGame.Exists(item => item.player == player))
            {
                if (!PilotsInGame[PilotsInGame.FindIndex(item => item.player == player)].RadarUsed)
                {
                    //Radar Menu
                    if (menuItemIndex == 1)
                    {
                        SetConnectToHeadquarterMenu(player);
                    }

                    if (menuItemIndex == 2)
                    {

                        checkSectors(player);
                        SetMainMenu(player);
                    }
                }
                else
                {
                    SetMainMenu(player);
                }
            }
        }

        if (id == 101)
        {
            //Radar Menu
            if (menuItemIndex == 0)
                SetRadarMenu(player);
            else
            {
                SetHeadQuarter(player, menuItemIndex);
                SetRadarMenu(player);
            }
        }
    }
        
    






    public override void OnOrderMissionMenuSelected(Player player, int ID, int menuItemIndex)
    {
        base.OnOrderMissionMenuSelected(player, ID, menuItemIndex);

        
        if (ID == 0)
        { // main menu
            if (menuItemIndex == 1)
            {
                SetRadarMenu(player);
            }
        }


        MenuPartRadarOperations(player, ID, menuItemIndex);

    }

    #endregion


    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;
        GamePlay.gpPostMissionLoad(createRadarTriggers());
    }


    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);

        if (!PilotsInGame.Exists(item => item.player == player))
        {
            PilotsInGame.Add(new Pilot(player));
        }

        SetMainMenu(player);
    }


    public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        base.OnTrigger(missionNumber, shortName, active);
        
        if (shortName.StartsWith("Radar") && shortName.EndsWith("Destroyed"))
        {
            GamePlay.gpLogServer(null, "Radar destroyed", null);

            Headquarters.ForEach(item =>
                {
                    item.SetObserverInactive(shortName);
                });
        }
    }

}

Last edited by FG28_Kodiak; 04-29-2012 at 07:14 PM.
Reply With Quote
  #100  
Old 04-29-2012, 07:37 PM
5./JG27.Farber 5./JG27.Farber is offline
Approved Member
 
Join Date: Aug 2011
Posts: 1,958
Default

Sounds good. We will test if for you.

Thanks Kodiak, you really are a diamond!
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 04:35 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright © 2007 Fulqrum Publishing. All rights reserved.