Official Fulqrum Publishing forum

Official Fulqrum Publishing forum (http://forum.fulqrumpublishing.com/index.php)
-   FMB, Mission & Campaign builder Discussions (http://forum.fulqrumpublishing.com/forumdisplay.php?f=203)
-   -   Organising flights in a multisquad campaign. (http://forum.fulqrumpublishing.com/showthread.php?t=30979)

Osprey 04-12-2012 06:08 PM

It was going to be one of my suggestions, however I have grave reservations about the ability to destroy radar. Although yes, a tactical war campaign that is perfectly sensible the impact would be:

1. Not historical. During the entire BoB, RDF was lost for under 2 hours in one sector only.
2. Lost RDF means that, on such a large map, that you are unlikely to meet each other in the sky, which is the whole point.

If it came to that, the first thing one would do would be to send out the entire squadron to each station and strike the object with 1 jabo. Job done. In reality an entire bombing group had little success. When we had Radar in the USL I made it so that it wasn't worth the attempt since it would detract from the historical nature of the missions that were developed.

FG28_Kodiak 04-12-2012 06:12 PM

Hm a sector is 10*10Km or more, so i don't think its to easy, and if no symbols in options a pilot must know where he is himself :rolleyes:, and there will be a time delay between request and answer, and a delay before a pilot can request again, so a player could not ask every 5 seconds. (not implemented yet).

But i can create Radars, each radar then has it's sectors to observe and is attached to a HQ. If a radar is destroyed the HQ is blind in this sectors.
Must test if a radar is an Actor, so i can 'see' if it is destroyed (the destroy with bombs ;)).

5./JG27.Farber 04-12-2012 06:20 PM

Quote:

Originally Posted by Osprey (Post 408163)
It was going to be one of my suggestions, however I have grave reservations about the ability to destroy radar. Although yes, a tactical war campaign that is perfectly sensible the impact would be:

1. Not historical. During the entire BoB, RDF was lost for under 2 hours in one sector only.
2. Lost RDF means that, on such a large map, that you are unlikely to meet each other in the sky, which is the whole point.

Radar stations were knocked out in BoB. It is well documented. You wont be able to miss 100+ aircraft :)
Mobile units were used when this happened and were not as effective due to their short hieght which effect wave length and the distance they could "see".

Quote:

Originally Posted by FG28_Kodiak (Post 408165)
Hm a sector is 10*10Km or more, so i don't think its to easy, and if no symbols in options a pilot must know where he is himself :rolleyes:, and there will be a time delay between request and answer, and a delay before a pilot can request again, so a player could not ask every 5 seconds. (not implemented yet).

But i can create Radars, each radar then has it's sectors to observe and is attached to a HQ. If a radar is destroyed the HQ is blind in this sectors.
Must test if a radar is an Actor, so i can 'see' if it is destroyed (the destroy with bombs ;)).

The English Radar 1, it is one object made of 4 towers, it would make the ideal actor. It can assigned a side (red/blue) and be destroyed with bombs. ;)

Osprey 04-13-2012 06:46 AM

One 250kg bomb from a single fight will knock out that radar. The towers in the BoB weren't destroyed anywhere despite several attempts by entire bomber squadrons. There were a couple of single events where radar was damaged, one because a bomb happened to land on one of the essential buildings in the complex.

I'm really not sure where this is going, what is the bigger objective of the campaign? I am seeing long term a tactical reason for this. From my perspective I honestly don't care if you bomb the crap out of every target as long as we get to meet you in the skies in the same interception fashion as the boys of the day did, but if you knock out our eyes then that won't happen - you can come in from anywhere, anytime across a big map.

5./JG27.Farber 04-13-2012 08:45 AM

Dont worry Osprey, it will be fine. I cant give to much away ;)

Osprey 04-13-2012 11:02 AM

Forgive my panickyness......

FG28_Kodiak 04-13-2012 12:27 PM

Ok Problem, this Radars are not normal Actors, so i can't register their creation nor their destroying via script, must add TGroundDestroyed-Triggers to every radar. More unconfortable for mission-builder. :rolleyes:

41Sqn_Banks 04-13-2012 12:56 PM

Quote:

Originally Posted by FG28_Kodiak (Post 408467)
Ok Problem, this Radars are not normal Actors, so i can't register their creation nor their destroying via script, must add TGroundDestroyed-Triggers to every radar. More unconfortable for mission-builder. :rolleyes:

Didn't know that TGroundDestroyed is fired for "strange actors", thanks for the info, comes handy for IL2DCE.

You could parse the mission file OnBattleStart (or one of the init events before) and create a mission file that contains triggers for each radar station and then postload the trigger file (remember to set MissionNumberListener = -1;). The script has to know the path to the mission file though.

FG28_Kodiak 04-13-2012 01:04 PM

Yes i could, but would :rolleyes: :grin:

Gib ihnen den kleinen Finger ... :rolleyes:

FG28_Kodiak 04-14-2012 06:03 PM

1 Attachment(s)
Ok added the possibility to destroy Radars so the HQ gets blind in attached sectors.
For triggers i scan the mis file for the Radarstations:
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 FILE_PATH = userdocpath + @"\1C SoftClub\il-2 sturmovik cliffs of dover\missions\";
    private static string MISSION_FILE = FILE_PATH + @"RadarTest\RadarTest.mis";


    private List<string> getRadarCreationStrings(string filename)
    {
        List<string> list = new List<string>();
       
        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(' ');
                    //Radar02Destroyed TGroundDestroyed 50 23438 20849 750
                    string keyTr, valueTr;

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

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


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


    #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


    internal class Pilot
    {
        public Player player { get; set; }
        public LocalHeadquarters connectedHeadquarter;

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


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


    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 string GetNotObservedSectors()
        {
            string sectorList = "";

            if (AttachedObservers.Exists(item => item.IsActive == false))
            {
                AttachedObservers[AttachedObservers.FindIndex(item => item.IsActive == false)].observedSectors.ForEach(sector =>
                    {
                        sectorList += sector + " ";
                    });

                sectorList = sectorList.Replace(',', '/');
                sectorList = sectorList.TrimEnd(' ');
            }
            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;
            }
        }
    }


    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 void SetTriggerName(string triggerName)
        {
            this.TriggerName = triggerName;
        }

    }


    List<LocalHeadquarters> Headquarters = new List<LocalHeadquarters>{
        {new LocalHeadquarters("Luton", "CallSign24", 100.0, 100.0, new ObserverStation( "Static0","A,1","A,2","A,3"), new ObserverStation( "Static1","B,1","B,2","B,3"))},
        {new LocalHeadquarters("RadPoe", "CallSign32", 200.0, 200.0, new ObserverStation( "Static2","C,1","C,2","C,3"), new ObserverStation( "Static3","D,1","D,2","D,3"))},
        {new LocalHeadquarters("Forest", "CallSign15", 300.0, 300.0, new ObserverStation( "Static4","E,1","E,2","E,3"), new ObserverStation( "Static5","F,1","F,2","F,3"))}
    };


    public void checkSectors(Player player)
    {

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

            if (PilotsInGame[i].connectedHeadquarter != null)
            {
                if (Headquarters.Exists(hq => hq == PilotsInGame[i].connectedHeadquarter))
                {
                    LocalHeadquarters localHQ = PilotsInGame[i].connectedHeadquarter;
                    AiAirGroup[] EnemyAirgroups = GamePlay.gpAirGroups((player.Army() == 1) ? 2 : 1);

                    if (EnemyAirgroups != null)
                    {
                        bool foundEnemy = false;
                       
                        foreach (AiAirGroup aag in EnemyAirgroups)
                        {
 
                            string sectorName = GamePlay.gpSectorName(aag.Pos().x, aag.Pos().y);

                            if (localHQ.ObserveSector(sectorName) && aag.Pos().z > 600.00)
                            {
                                foundEnemy = true;
                                string type = "";

                                if (aag.isAircraftType(AircraftType.Bomber) || aag.isAircraftType(AircraftType.DiveBomber))
                                    type = "Bombers";
                                else if (aag.isAircraftType(AircraftType.Fighter))
                                    type = "Fighters";

                                GamePlay.gpLogServer(new[] { player }, "{0} Enemy {1} in Sector: {2}", new object[] { aag.NOfAirc, type, sectorName });
                            }
                        }


                        if (localHQ.GetNotObservedSectors() != "")
                        {
                            GamePlay.gpLogServer(null, "Attention Informations for Sectors {0} not available!", new[] { localHQ.GetNotObservedSectors() });
                            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);

                    }
                }
            }
        }
    }


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


    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__");
        });


    }


   
    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;

        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;

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

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


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

}

Example in the attached file. Change the MISSION_FILE variable in the cs to your needs, please.


All times are GMT. The time now is 12:41 AM.

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