1C Home   |   Register   |   Today Posts   |   Members   |   UserCP   |   Calendar   |   Search   |   FAQ

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

Reply
 
Thread Tools Display Modes
  #1  
Old 02-27-2012, 01:23 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default Scripting methods for mission operation

Method for mission listing within script

Method for Random selection of missions

Method for Triggered missions for Player

Method for Objective mission loading for Player

Firstly I’d like to point out that I am in a learning curve with C# and the methods outlined may be or may not be the best or most efficient way. In many cases I have revised and improved concepts as I go. Secondly much of the core key aspects or syntax is learned from browsing these forums where I have modified for my own purpose or concepts, as such I wanted to return these alternatives I have been working on to the forums. Thirdly got to thank Kodiak for help on the really sticky bits of C# and how they work with CLOD. Finally, this is work in progress, but at a stage where I’d like some feedback on the scripting.

The main purpose of this script is supply a dynamical feel to a mission, by their very nature missions (especially from IL2) have felt scripted and a little sterile. As it happens in my day job I have been developing water management irrigation which simulates rain, the world is chaotic and it in that field applying with chaos changes the reactions more in line with reality. So I am attempting to apply that thought pattern to scripting to simulate a feeling of unknown results. You still have missions, but when they are loaded is unknown.

The second purpose of my methods layout is to make life easier on those who are completely lost with scripting, I am attempting to create scripts which are easy to add missions of users own design, and the script is just an engine that more or less can be just dropped in.
As Kodiak has pointed out in another thread, use of visual express is advisable. It is free for our purpose so why not, it is just a tool to help nothing more.

For the new user of C#, the following layout is setup in blocks of importance (for me anyway), in some cases the order or where the block of script is wrapped is important, but most cases you can place sections just about anywhere and it will still function. Think of the code as lots of small separate scripts talking to each other in a group than a sequential path. (although technically all code is sequential somewhere along the line).

First bit of useful code is to do with C# and visual express
Setting up regions where you can place blocks of scripting makes editing scripts easier. Visual express sees these (CLOD ignores them), so you can hide sections that are not being worked on.

You can use as many as you like

# Region [region title here]

//Script block here

#End region

Ok this shows the regions with title of what is contained, if you click the little (-) or (+) to the left of the screen it opens and closes the regions. Note I also add simple txt separators as well for those who may edit with note pad, the line separators block for visual reference.

This shows the first part of my methods, “Simplified paths”, here I have the main mission path and sub mission paths, and the type is called a “string” with the abbreviated name I called them “MP”, “MPsub” and ” MPtm”. In the core engine we just call MP, MPsub or MPtm as required, but if the user needs to edit the path they only have to edit the main string.

Code:
 /*=========================================*/

    #region Mission paths
        
    string MP = "missions/Multi/Dogfight/ScrimBase/";//simplifying Txt MissionPath
    string MPsub = "missions/Multi/Dogfight/ScrimBase/sub/";//simplifying Txt MissionPath sub missions
    string MPtm = "missions/Multi/Dogfight/ScrimBase/tm/";//simplifying Txt MissionPath triggered missions
    
    #endregion

    /*=========================================*/
Attached Images
File Type: jpg regionspaths.jpg (16.0 KB, 22 views)

Last edited by Smokeynz; 02-27-2012 at 01:59 AM.
Reply With Quote
  #2  
Old 02-27-2012, 01:24 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Next block is all the mission lists; here I am using a part of C# “lists”. Here I am making life easier for a user by a simple layout to add user missions, the syntax is quite simple. Also note I have places for mission and messages. To add missions just add a new line within code block brackets and add a coma for each new line, noting the last list line does not have a coma.

new SubM (mission, Message all, Message Red, Message Blue)

Code:
/*=========================================*/

    #region Inputs  for Missions, Triggered Missions & Messages

    //NOTE: place sub missions into "sub" folder
    //NOTE: sub mis 0~99 series nums
    //If you add sub missions to input region, add new lines to list below(index numbering)
    //Mis Input layout: new SubM(Mission, Message all, Message Red, Message Blue)    

    List<SubM> SubMs = new List<SubM>
    {       
        new SubM ("Sub00.mis", "Hurricanes on Patrol", "Hun Patrol !!", "Auctung Hurricanes !"),
        new SubM ("Sub01.mis", "Messers on Patrol", "JG on Patrol", "RAF Search !!"),
        new SubM ("Sub02.mis", "Bomber Command", "Bomber Escort required", "Auctung Englander Bombers"),
        new SubM ("Sub03.mis", "KG Forming up", "Scramble Bombers inbound", "Angels 8"), 
        new SubM ("Subnull.mis", "random null Sub4", null, null),
        new SubM ("Subnull.mis", "random null Sub5", null, null),
        new SubM ("Subnull.mis", "random null Sub6", null, null),
        new SubM ("Subnull.mis", "random null Sub7", null, null),
        new SubM ("Subnull.mis", "random null Sub8", null, null),
        new SubM ("Subnull.mis", "random null Sub9", null, null),
        new SubM ("Subnull.mis", "random null Sub10", null, null) 
    };
  
    /*=========================================*/

    // Triggered Mission inputs and setup
    //NOTE: place triggered missions into "tm" folder

    /*=========================================*/

    //Triggered Mission lists for UK
    //NOTE: UK = 100~149 series num    
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM100> TM100s = new List<TM100>
    { 
        new TM100 ("t100.mis", "Triggered mission 100", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t101.mis", "Triggered mission 101", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t102.mis", "Triggered mission 102", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t103.mis", "Triggered mission 103", "Intercept the blue hound", "Intercepters are coming Blue"),// add comma for each new line
        new TM100 ("t104.mis", "Triggered mission 104", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("tnull.mis", "random null TM5", null, null),
        new TM100 ("tnull.mis", "random null TM6", null, null),
        new TM100 ("tnull.mis", "random null TM7", null, null),
        new TM100 ("tnull.mis", "random null TM8", null, null),
        new TM100 ("tnull.mis", "random null TM9", null, null),
        new TM100 ("tnull.mis", "random null TM10", null, null)
    };

    /*=========================================*/

    //Objective Triggered Mission lists for UK
    //NOTE: UK = 150~199 series num    
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM150> TM150s = new List<TM150>
    { 
        new TM150 ("t150.mis", "Objective mission 150 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t151.mis", "Objective mission 151 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t152.mis", "Objective mission 152 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t153.mis", "Objective mission 153 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),// add comma for each new line
        new TM150 ("t154.mis", "Objective mission 154 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!")        
    };

    /*=========================================*/
    
    // Triggered Mission lists for DE
    //NOTE: DE = 200~249 series num 
    //If you add missions to input region, add new lines to list below(index numbering)
    
    List<TM200> TM200s = new List<TM200>
    { 
        new TM200 ("t200.mis", "Triggered mission 200", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t201.mis", "Triggered mission 201", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t202.mis", "Triggered mission 202", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t203.mis", "Triggered mission 203", "Interceptors coming RED", "Intercept the Red devil"),// add comma for each new line
        new TM200 ("t204.mis", "Triggered mission 204", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("tnull.mis", "random null TM5", null, null),
        new TM200 ("tnull.mis", "random null TM6", null, null),
        new TM200 ("tnull.mis", "random null TM7", null, null),
        new TM200 ("tnull.mis", "random null TM8", null, null),
        new TM200 ("tnull.mis", "random null TM9", null, null),
        new TM200 ("tnull.mis", "random null TM10", null, null)

    };

    /*=========================================*/

    // Triggered Objective missions lists for DE uk
    //NOTE: DE = 250~299 series num 
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM250> TM250s = new List<TM250>
    { 
        new TM250 ("t250.mis", "Objective mission 250 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t251.mis", "Objective mission 251 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t252.mis", "Objective mission 252 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t253.mis", "Objective mission 253 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),// add comma for each new line
        new TM250 ("t254.mis", "Objective mission 254 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!")
    };

    #endregion

    /*=========================================*/
The observant will have noticed I have some null missions aswell, this is the neat bit of random dynamic play. Note I have in the sub missions folder a null mission of the map in use, but nothing else. If you call a mission even a null you need to load something or the server will create an error, so hence we load just the map name.

Why? You may ask; this is about chance, there will be a chance that on the time period nothing happens. Lists actually numbers missions by their input location, their actual name is irrelevant, and so you can actually list the same mission several times as I have done with the null mission.

Example of chance, if you are calling the listed missions by random chance and you had 100 missions where 50 were nulls, 10 were mission x and the rest were single missions. There is 50% chance nothing will happen on the selection time period, there is also 10% chance mission x will load and 1% chance any of the others will load. Basically you can weight the chances of what mission will load by having more of the same mission in the list, but note keeping null missions where nothing happens is important as well. The reason is this allows the frequency of the main timers to run faster, but then not overload the map with too many missions running at once.

All missions in the script are randomised selection, I have lists for, Sub missions (SubM), Triggered missions UK (TM100), DE (TM200) and objective lists UK(TM150) and DE(TM250).

Note, I use fairly generic naming for all subs, triggered and objective missions and only name the main mission for the title name. Long names in code just wastes space, also makes editing harder.

Last edited by Smokeynz; 02-27-2012 at 01:32 AM.
Reply With Quote
  #3  
Old 02-27-2012, 01:26 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

The next region block is inputs for timer periods for the core engine, and random input names. If you add more random names, add the random name here. Also the block contains some references to Triggers and 2D locations of trigger locations.

The timers are editable, but note I have setup four periods on fairly tight time periods (1min repeats), where they can overlap at times. Slightly pulsing effect. Again layout is so that edits happen here and you don’t need to touch core engine.

Code:
    /*=========================================*/

    #region Repeats and delays & Random selection varibles

    //tick time can alter length due to processing damands, however assume 30/sec 
    //1 sec = 30 ticks
    //1 min = 1800 ticks
    //1hour = 108000 ticks

    //note, r value must be bigger than d value

    private int rt0 = 9000;//5 min repeat
    private int dt0 = 1800;//1 min delay 

    private int rt1 = 9000;//5 min repeat
    private int dt1 = 3600;//2 min delay

    private int rt2 = 18000;//10 min repeat
    private int dt2 = 5400;//3 min delay  

    private int rt3 = 27000;//15 min repeat
    private int dt3 = 7200;//4 min delay 

    //timer reset(start value, gets randomised 100~900 in map selection,)
    //auto reset switch delay stops multible trigger loading, this version resets by random time period(100~900 secs)
    //for fixed value unrem the pvt double below, rem out random version in map selection
    //private double rsukS1 = 300;   

    Random rsukS1 = new Random();
    private int ukS1 = 1;
    Random rsukS2 = new Random();
    private int ukS2 = 1;
    Random rsukS3 = new Random();
    private int ukS3 = 1;

    private double rsukS4 = 3600;
    private int ukS4 = 1;
    
    Random rsdeS1 = new Random();
    private int deS1 = 1;
    Random rsdeS2 = new Random();
    private int deS2 = 1;
    Random rsdeS3 = new Random();
    private int deS3 = 1;

    private double rsdeS4 = 3600;    
    private int deS4 = 1; 

    Random rand = new Random();//random mis selection

    #endregion

    /*=========================================*/
The next region block actually is part of the lists, these classes pull in the lists into the code to be available for use. If you add more lists, you need another relevant class by name sake to pull the list data into the script.

Code:
 /*=========================================*/

    #region Mission classes

    internal class SubM //SubMission
    {
        public string MN { get; set; }//MissionName
        public string MM { get; set; }//MissionMessage
        public string MMR { get; set; }//MissionMessageRed
        public string MMB { get; set; }//MissionMessageBlue

        public SubM(string mn, string mm, string mmr, string mmb)
        {
            this.MN = mn;
            this.MM = mm;
            this.MMR = mmr;
            this.MMB = mmb;
        }
    }

    internal class TM100 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM100(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM150 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM150(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM200 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM200(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM250 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM250(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    #endregion

    /*=========================================*/

Last edited by Smokeynz; 02-27-2012 at 01:35 AM.
Reply With Quote
  #4  
Old 02-27-2012, 01:27 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Next block is constants and parameters, although I have listed some despawntime variables in here as well, these are for altered the despawning time period for AI in game, depending on flight paths and so on and mission design you alter this period for ai time in game before despawn. I have 3 timers, for different conditions. The main, despawntime is set to 2700 or 45mins.

Code:
 /*=========================================*/

    #region const's and params

    //Tx's To
    private const int All = -1;
    private const int Allies = 1;
    private const int Axis = 2;    

    //Despawner time varible
    //To times 5min=300 10min=600 15min=900 30min=1800 45min=2700 60min=3600
    private double despawntime = 2700;//ai aircraft despawn
    private double despawntime2 = 300;//secondary ai aircraft despawn
    private double despawntime3 = 2700;//ground ai despawn

    //Goes with time indicator, set period for cycle repeat period: value = seconds 
    //1mins=60sec=1800ticks 
    private double ts = 60;

    //trigger boolean start point condition
    bool pDE1 = false;
    bool pDE2 = false;
    bool pDE3 = false;
    bool pDE4 = false;
    bool pUK1 = false;
    bool pUK2 = false;
    bool pUK3 = false;
    bool pUK4 = false;
    private int rm;
    private int bm;
/*        
     [Trigger]
  uk1 TPassThrough 5 2 12025 10315 15000
  uk2 TPassThrough 5 2 12025 10315 10000
  uk3 TPassThrough 5 2 12025 10315 5000  
  de1 TPassThrough 5 1 30440 31260 15000
  de2 TPassThrough 5 1 30440 31260 10000
  de3 TPassThrough 5 1 30440 31260 5000  
*/

    Point2d DEr1 = new Point2d(30440, 31260);// radar trigger(Red active)
    Point2d UKr1 = new Point2d(12025, 10315);// radar trigger(Blue active)    

    //listen to events from all missions.
    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1; 
    }

    #endregion

    /*=========================================*/
The next block is the main core engine for sub mission loading on random selection. Before I explain operation here I need to mention alterations to the messaging setup, otherwise it will look complex when it is not.

This is Kodiaks last messaging script, but I have modified with abbreviations, because the other code becomes smaller when you do this. The core change is the abbreviation “STxA” which means Screen text to armies and “Tx”, which means text.

Code:
 /*=========================================*/

    #region STxA Screen Text to Armies

    private void STxA(int army, string Tx, params object[] args)
    { 
        List<Player> Consignees = new List<Player>();
        if (GamePlay.gpPlayer() != null)
            Consignees.Add(GamePlay.gpPlayer());
        if (GamePlay.gpRemotePlayers() != null)
            Consignees.AddRange(GamePlay.gpRemotePlayers());

        if (army == -1)
            GamePlay.gpHUDLogCenter(null, Tx);
        else if (Consignees.Exists(item => item.Army() == army))
            GamePlay.gpHUDLogCenter(Consignees.FindAll(item => item.Army() == army).ToArray(), Tx);        
    }

    #endregion

    /*=========================================*/

Last edited by Smokeynz; 02-27-2012 at 01:37 AM.
Reply With Quote
  #5  
Old 02-27-2012, 01:29 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

The first part of my core is a simple timer to test time periods, intension is to edit out later but is there to check time mission has played. There is some error because of delays and it does not display every minute due to being overridden by mission loading text.

Now the core engine, note rt0 is repeat and dt0 is delay start, periods setup in previous code,
I set an “int” (interger) “i” as zero as a base of the random selection range, then call the SubM list through the classes input and it becomes SubMs, each mission in the list has its independent list number, this is the random range, zero =>number of missions in list(hence why nulls are important). A mission from the list is randomly selected then loaded, note mission path “MPsub +SubMs[i].MN”, “i” is the list number and MN is mission name, the following line is messages where it selects the mission and relative mission message, MM is mission message. I then wait 2 seconds and display messages to each team, MMR, message to red, MMB message to blue.

Code:
   /*=========================================*/

    #region Main mission operation

    public override void OnTickGame()
    {
        base.OnTickGame();

        /*=========================================*/
        /*    Server timer for mis time testing    */
        /*         rem out when not in use         */
        /*=========================================*/

        // Time. current() in seconds from Battle Start
        if (Time.current() >= ts)
        {
            GamePlay.gpHUDLogCenter("Elapsed Time:Min:" + ts / 60 + " Secs:" + ts + " Ticks:" + ts * 30);
            ts = ts + ts;
        }

        /*=========================================*/

        //tick counter mission random loader
       
        if (Time.tickCounter() % rt0 == dt0)
        {            
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);  
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt1 == dt1)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt2 == dt2)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt3 == dt3)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
    }
  
    #endregion

    /*=========================================*/

That is the core random engine, but I repeat these four times so as to have four timer periods which because of the timing sometimes happen at the same time. Note: messages that appear at the same will only show the last to load. Just one of those things, you could code around that if you wanted too.
So far the core operates quite well on its own without triggers and objectives, and on appearance in game behaves different every time I test it. This is even though in the test setup we have only 4 sub missions and 7 null missions. I anticipate having 50 or more in sub selection eventually with 50 nulls or something like that. Total user discretion.

Last edited by Smokeynz; 02-27-2012 at 01:40 AM.
Reply With Quote
  #6  
Old 02-27-2012, 01:35 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

The next block is triggers, this is a nasty area at the moment due to bugs in CLOD. Here though the focus is on Player activity not AI triggering AI. Some guides on scripting for AI has mostly being posted in other threads, in the script here I only use the AI and general trigger function as text to know what is happening and indirectly triggering player triggers.

The setup in this script is representing Radar ranges. In the mission I have a radar unit as the centre piece location and set the triggers as army pass through, 3 triggers same centre different ranges representing zones.

Static46 Stationary.Radar.EnglishRadar1 gb 12025.00 10315.00 50.00
Static44 Stationary.Radar.EnglishRadar1 de 30440.00 31260.00 45.00

[Trigger]
uk1 TPassThrough 5 2 12025 10315 15000
uk2 TPassThrough 5 2 12025 10315 10000
uk3 TPassThrough 5 2 12025 10315 5000
de1 TPassThrough 5 1 30440 31260 15000
de2 TPassThrough 5 1 30440 31260 10000
de3 TPassThrough 5 1 30440 31260 5000

in the script the 2D locations are set as the same centre point.

Point2d DEr1 = new Point2d(30440, 31260);// radar trigger(Red active)
Point2d UKr1 = new Point2d(12025, 10315);// radar trigger(Blue active)

Now the tricky bit,the triggers in the mission activate a list to take note of players within the mission where they are listed as Plebs, then I go through those Plebs and refernce against the 2D location and actual location of the Pleb(player). Then set true or false conditions for each zone range, outside all the zones all are false and nothing happens.

At the end of these checks is a call condition, if any of the above is true then call TrigMis(), this is the random mission selection trigger set up as a private void. The reason this is separate to the Ontrigger is that I also use the triggered loader for objectives aswell.(yes they are randomised aswell).

Before I leave the OnTrigger operation I have typical triggers for AI generating text to players, mainly for checks at this stage, however I do intend to have different missions loading for AI in addition to Player triggering the same zones.

Code:
 /*=========================================*/
    
    #region Mission triggers

    internal double getDistanceFromTo(Point2d startPoint, Point2d endPoint)
    {
        return startPoint.distance(ref endPoint);
    }
          
    public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        base.OnTrigger(missionNumber, shortName, active);        
            
        List<Player> plebs = new List<Player>();
        if (GamePlay.gpPlayer() != null)            
            plebs.Add(GamePlay.gpPlayer());
        if (GamePlay.gpRemotePlayers() != null)            
            plebs.AddRange(GamePlay.gpRemotePlayers());

        plebs.ForEach(item =>
        {
            if (item.Place() != null)
            {
                Point2d ActorPos = new Point2d(item.Place().Pos().x, item.Place().Pos().y);
                //radar circles
                if (item.Army() == 1)
                {
                    if (getDistanceFromTo(ActorPos, DEr1) > 15000.1)
                    {
                        pDE1 = false;
                        pDE2 = false;
                        pDE3 = false;
                    }

                    if (getDistanceFromTo(ActorPos, DEr1) < 15000)
                        if (getDistanceFromTo(ActorPos, DEr1) > 10000.1)
                        {
                            pDE1 = true;
                            pDE2 = false;
                            pDE3 = false;
                        }

                    if (getDistanceFromTo(ActorPos, DEr1) < 10000)
                        if (getDistanceFromTo(ActorPos, DEr1) > 5000.1)
                        {
                            pDE1 = false;
                            pDE2 = true;
                            pDE3 = false;
                        }
                    if (getDistanceFromTo(ActorPos, DEr1) < 5000)
                    {
                        pDE1 = false;
                        pDE2 = false;
                        pDE3 = true;
                    }                    
                }
                                                                                
                if (item.Army() == 2)
                {
                    if (getDistanceFromTo(ActorPos, UKr1) > 15000.1)
                    {
                        pUK1 = false;
                        pUK2 = false;
                        pUK3 = false;
                    }
                    if (getDistanceFromTo(ActorPos, UKr1) < 15000)
                        if (getDistanceFromTo(ActorPos, UKr1) > 10000.1)
                        {
                            pUK1 = true;
                            pUK2 = false;
                            pUK3 = false;

                        }
                    if (getDistanceFromTo(ActorPos, UKr1) < 10000)
                        if (getDistanceFromTo(ActorPos, UKr1) > 5000.1)
                        {
                            pUK1 = false;
                            pUK2 = true;
                            pUK3 = false;
                        }
                    if (getDistanceFromTo(ActorPos, UKr1) < 5000)
                    {
                        pUK1 = false;
                        pUK2 = false;
                        pUK3 = true;
                    }
                }               
            }
        });

        if ((pDE1 | pDE2 | pDE3 | pUK1 | pUK2 | pUK3) == true)
            TrigMis();
                
          
        // ai as triggers (AI can be treated separately here)
        if (shortName.Equals("de1") && active)        
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        if (shortName.Equals("de2") && active)
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        if (shortName.Equals("de3") && active)
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        //if (shortName.Equals("de4") && active)
        //{
            //STxA(-1, shortName + " ai trigger check(blue bomber)");// rem out once checks complete 
        //}
        if (shortName.Equals("uk1") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        if (shortName.Equals("uk2") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        if (shortName.Equals("uk3") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        //if (shortName.Equals("uk4") && active)
        //{
            //STxA(-1, shortName + " ai trigger check(red bomber)");// rem out once checks complete 
        //}

        if (shortName.Equals("killkubel") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + " YOU KILLED BILL"); });
            ukS4 = 1;
        }
        if (shortName.Equals("safekubel") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + "BILL IS SAFE"); });            
        }

        if (shortName.Equals("killbob") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + " YOU KILLED BOB"); });
            deS4 = 1;
        }
        if (shortName.Equals("safebob") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + "BOB IS SAFE"); });            

        }
    }


    private void TrigMis()
    {
        /*===================de triggered mis=====================*/
        if (pDE1 == true)
        {
            switch (deS1)
            {
                case 1:
                    deS1 = 2;//on off switch for trigger operation
                    Timeout(rsdeS1.Next(100, 901), () => { deS1 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de1 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE1 = false;
        }

        if (pDE2 == true)
        {
            switch (deS2)
            {
                case 1:
                    deS2 = 2;//on off switch for trigger operation
                    Timeout(rsdeS2.Next(100, 901), () => { deS2 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de2 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE2 = false;
        }

        if (pDE3 == true)
        {
            switch (deS3)
            {
                case 1:
                    deS3 = 2;//on off switch for trigger operation
                    Timeout(rsdeS3.Next(100, 901), () => { deS3 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de3 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE3 = false;
        }
                
        /*===================uk triggered mis======================*/

        if (pUK1 == true)
        {
            switch (ukS1)
            {
                case 1:
                    ukS1 = 2;//on off switch for trigger operation
                    Timeout(rsukS1.Next(100, 901), () => { ukS1 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk1 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK1 = false;
        }

        if (pUK2 == true)
        {
            switch (ukS2)
            {
                case 1:
                    ukS2 = 2;//on off switch for trigger operation
                    Timeout(rsukS2.Next(100, 901), () => { ukS2 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk2 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK2 = false;
        }

        if (pUK3 == true)
        {
            switch (ukS3)
            {
                case 1:
                    ukS3 = 2;//on off switch for trigger operation
                    Timeout(rsukS3.Next(100, 901), () => { ukS3 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk3 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK3 = false;
        }

        /*===================de objective mis======================*/

        if (pDE4 == true)
        {
            switch (deS4)
            {
                case 1:
                    deS4 = 2;//on off switch for trigger operation
                    Timeout(rsdeS4, () => { deS4 = 1; });//timer reset function
                    //int bm = 0;
                    if (TM250s.Count > 0)
                        bm = rand.Next(0, TM250s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM250s[bm].TN);
                    Timeout(4.0, () => { STxA(-1, TM250s[bm].TM); });
                    Timeout(6.0, () => { STxA(1, TM250s[bm].TMR); STxA(2, TM250s[bm].TMB); });
                    break;
                case 2:
                    //Timeout(6.0, () => { STxA(-1, "Objective trigger already in action"); });// rem out once checks complete
                    Timeout(6.0, () => { STxA(1, TM250s[bm].TMR); STxA(2, TM250s[bm].TMB); });// repeat mission objective tx
                    break;
            }
            pDE4 = false;
        }

        /*===================uk objective mis======================*/

        if (pUK4 == true)
        {
            switch (ukS4)
            {
                case 1:
                    ukS4 = 2;//on off switch for trigger operation
                    Timeout(rsukS4, () => { ukS4 = 1; });// timer reset function
                    //int rm = 0;
                    if (TM150s.Count > 0)
                        rm = rand.Next(0, TM150s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM150s[rm].TN);
                    Timeout(4.0, () => { STxA(-1, TM150s[rm].TM); });
                    Timeout(6.0, () => { STxA(1, TM150s[rm].TMR); STxA(2, TM150s[rm].TMB); });
                    break;
                case 2:
                    //Timeout(6.0, () => { STxA(-1, "Objective trigger already in action"); });// rem out once checks complete
                    Timeout(6.0, () => { STxA(1, TM150s[rm].TMR); STxA(2, TM150s[rm].TMB); });// repeat mission objective tx
                    break;
            }
            pUK4 = false;
        }
    }

    #endregion

    /*=========================================*/

Ok now the second part to trigger operation, the loading of missions. These as you may of guessed are randomly selected as per sub missions, the lists are different for the triggered armies, ie Blue planes spawn for red triggering the radar ranges and visa versa. What spawns though is selected randomly exactly the same way as the core engine. The difference however,is there is a reset function timer. This is so that the trigger zones don’t load a whole pile of missions with every player crossing the line.

I should explain the reset funtion a little for those new to C#, here I am using a “Switch” which is a case selection tool, ie in the case of a number being 2 “case 2” is selected and all code within it is run. I simply have a number switching between 1 and 2, when it is 1 the loading sequence is active and when it is 2 the loader is inactive. Actived I set the case select number to 2 then a timer runs which sets a timer in motion for the random generated period to reset the case to 1 again. Hence switch operation.
The timer reset period though is randomised between 100 and 900 seconds where each zone can be in operation at different times depending how deep the player enters the radar region. For testing I have messages telling players that the zone is already activated, the intension is that players won’t normally get a message.

Last edited by Smokeynz; 03-01-2012 at 08:53 PM.
Reply With Quote
  #7  
Old 02-27-2012, 01:38 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Ok now I am going to jump to objective missions which is blocked region after the AI despawner.

Here I have modified an Onplace enter piece of code, original from the collection at 1C, but when the player enters a plane an objective is created, I trigger the TrigMis(), again this triggers the list of objectives in the objective mission list and randomly selects an objective. The selection times out after 30 minutes (period for testing) before objective reset and another objective mission could be loaded. Every player who enters an aircraft wll get a message of the current objective, the opposing team gets a warning a player enters and gets the message to defend that objective, or they could go after their objective. Again as other random lists of missions sets you can have nulls, (there is plenty to play with anyway), currently even though I have a number of objective missions in the lists for each side there is only one objective mission, I’ve yet to create some more, maybe some users can create some! The time reset is still under consideration, deciding on reset on completion or time reset, or both. At the moment objectives do reset on completion and time resets, but not in the case of non completion.


Code:
/*=========================================*/

    #region OnPlaceEnter Welcome Tx, objective creation

    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);
        AiAircraft aircraft = actor as AiAircraft;
        if (aircraft != null)            
            switch (aircraft.Army())
            {
                case 1:
                    if (aircraft.Type() == AircraftType.Bomber)
                    {
                        { GamePlay.gpHUDLogCenter(new Player[] { player }, "Bombers, Check your maps for targets!"); }                        
                    }
                    else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Fighters, Escort Bombers or Patrol the lines!"); }                    
                    pUK4 = true;// set main mission objective group activation true/false
                    TrigMis();// apply the truth
                    break;
                case 2:
                    if (aircraft.Type() == AircraftType.Bomber)
                    {
                        { GamePlay.gpHUDLogCenter(new Player[] { player }, "Bombers, uberprüfen Sie Ihre Karten fur Ziele!"); }                        
                    }
                    else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Fighters, Escort Bombers oder Patrol den Zeilen!"); }                    
                    pDE4 = true;
                    TrigMis();
                break;
            }           
    }

    #endregion

    /*=========================================*/

Last edited by Smokeynz; 02-27-2012 at 01:47 AM.
Reply With Quote
  #8  
Old 02-27-2012, 01:41 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Despawner, I have taken the original code and added reset timers, many of the current users use hard code, if you leave the aircraft the plane despawns. The issue for me with this is in the case of controlling a flight of planes. Eg taking a flight of light bombers to a target and swap from plane to plane to bomb the area then take them home again. Why not!

Anyway I set a timer running on creation, on place leave and added on task completed. I actually have 3 timer periods, set via the editable inputs near start in constants and parameters section. I also added ground object removal for objects after the first base mission. The default is 45mins so be aware of what is going on.

Code:
 /*=========================================*/

    #region Despawner  

    /*
    despawner timer added to original code, sets overall time period for actors,
    Advantage is, if delayed, say trying to land behind masses of planes, actors despawn at timer period set anyway.
    allows for players to fly groups of planes, 
    Player can re eneter flights or groups, as bombers take them to target, use each at target then fly group home
    despawn only triggers once player leaves whole group
*/
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);

        // note despawntime (set as varible at start of cs) 
        if (actor is AiGroundActor && missionNumber > 0)//main mission is left alone
            //if ((actor as AiGroundActor).Type() != maddox.game.world.AiGroundActorType.AAGun)//all ai ground except aa guns
            Timeout(despawntime3, () =>
            {
                if (actor != null)
                { (actor as AiGroundActor).Destroy(); }
            });

        if (actor is AiAircraft)        
            Timeout(despawntime, () => { damageAiControlledPlane(actor); });     
    }
 
    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceLeave(player, actor, placeIndex);
        Timeout(despawntime, () => { damageAiControlledPlane(actor); });        
    }
    
    // Path completion despawner, when flight path ends despawner action triggered
    // note:final despawner detects players in group    

    public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorTaskCompleted(missionNumber, shortName, actor);
        if (actor is AiGroundActor) 
            if (actor != null)
                Timeout(despawntime2, () => { (actor as AiGroundActor).Destroy(); });
            
        Timeout(despawntime2, () => { damageAiControlledPlane(actor); });
    }

    //check if a player is in any of the "places"
    private bool isAiControlledPlane(AiAircraft aircraft)
    {
        if (aircraft == null) return false;        
        for (int i = 0; i < aircraft.Places(); i++)
            if (aircraft.Player(i) != null)
                return false;
        return true;
    }

    private void destroyPlane(AiAircraft aircraft)
    {
        if (aircraft != null)
            aircraft.Destroy();
    }

    //actual Aiaircraft despawner, note it polls player detection
    private void damageAiControlledPlane(AiActor actorMain)
    {
        //Timeout(1, () => { STxA(-1, "Despawn time completes for Actor, Despawning"); });//indicates action about to happen, rem out after mission checks complete
        foreach (AiActor actor in actorMain.Group().GetItems())
        {
            if (actor == null || !(actor is AiAircraft))
                return;
            AiAircraft aircraft = (actor as AiAircraft);
            if (!isAiControlledPlane(aircraft))
                return;
            if (aircraft == null)
                return;
            (actor as AiAircraft).Destroy();
        }
    }

    #endregion

    /*=========================================*/

Last edited by Smokeynz; 02-27-2012 at 01:48 AM.
Reply With Quote
  #9  
Old 02-27-2012, 01:45 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Complete code

Code:
/**ScrimBase.cs**/
//
//By Smokeynz
//collated collection of parts from 1c, many thanks to credits to all envolved, especially Kodiak,
//Parts modified plus own iterations and random thoughts
//lastmod 25/2/2012
//Dedicated server compatible

using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using System.Collections.Generic;
using System.Diagnostics;

public class Mission : AMission
{
    /*=========================================*/

    #region Mission paths
        
    string MP = "missions/Multi/Dogfight/ScrimBase/";//simplifying Txt MissionPath
    string MPsub = "missions/Multi/Dogfight/ScrimBase/sub/";//simplifying Txt MissionPath sub missions
    string MPtm = "missions/Multi/Dogfight/ScrimBase/tm/";//simplifying Txt MissionPath triggered missions
    
    #endregion

    /*=========================================*/
    /*=========================================*/

    #region Inputs  for Missions, Triggered Missions & Messages

    //NOTE: place sub missions into "sub" folder
    //NOTE: sub mis 0~99 series nums
    //If you add sub missions to input region, add new lines to list below(index numbering)
    //Mis Input layout: new SubM(Mission, Message all, Message Red, Message Blue)    

    List<SubM> SubMs = new List<SubM>
    {       
        new SubM ("Sub00.mis", "Hurricanes on Patrol", "Hun Patrol !!", "Auctung Hurricanes !"),
        new SubM ("Sub01.mis", "Messers on Patrol", "JG on Patrol", "RAF Search !!"),
        new SubM ("Sub02.mis", "Bomber Command", "Bomber Escort required", "Auctung Englander Bombers"),
        new SubM ("Sub03.mis", "KG Forming up", "Scramble Bombers inbound", "Angels 8"), 
        new SubM ("Subnull.mis", "random null Sub4", null, null),
        new SubM ("Subnull.mis", "random null Sub5", null, null),
        new SubM ("Subnull.mis", "random null Sub6", null, null),
        new SubM ("Subnull.mis", "random null Sub7", null, null),
        new SubM ("Subnull.mis", "random null Sub8", null, null),
        new SubM ("Subnull.mis", "random null Sub9", null, null),
        new SubM ("Subnull.mis", "random null Sub10", null, null) 
    };
  
    /*=========================================*/

    // Triggered Mission inputs and setup
    //NOTE: place triggered missions into "tm" folder

    /*=========================================*/

    //Triggered Mission lists for UK
    //NOTE: UK = 100~149 series num    
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM100> TM100s = new List<TM100>
    { 
        new TM100 ("t100.mis", "Triggered mission 100", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t101.mis", "Triggered mission 101", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t102.mis", "Triggered mission 102", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("t103.mis", "Triggered mission 103", "Intercept the blue hound", "Intercepters are coming Blue"),// add comma for each new line
        new TM100 ("t104.mis", "Triggered mission 104", "Intercept the blue hound", "Intercepters are coming Blue"),
        new TM100 ("tnull.mis", "random null TM5", null, null),
        new TM100 ("tnull.mis", "random null TM6", null, null),
        new TM100 ("tnull.mis", "random null TM7", null, null),
        new TM100 ("tnull.mis", "random null TM8", null, null),
        new TM100 ("tnull.mis", "random null TM9", null, null),
        new TM100 ("tnull.mis", "random null TM10", null, null)
    };

    /*=========================================*/

    //Objective Triggered Mission lists for UK
    //NOTE: UK = 150~199 series num    
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM150> TM150s = new List<TM150>
    { 
        new TM150 ("t150.mis", "Objective mission 150 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t151.mis", "Objective mission 151 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t152.mis", "Objective mission 152 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),
        new TM150 ("t153.mis", "Objective mission 153 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!"),// add comma for each new line
        new TM150 ("t154.mis", "Objective mission 154 KILL BILL", "Bill has fled the building fire, get him!", "Save Bill!")        
    };

    /*=========================================*/
    
    // Triggered Mission lists for DE
    //NOTE: DE = 200~249 series num 
    //If you add missions to input region, add new lines to list below(index numbering)
    
    List<TM200> TM200s = new List<TM200>
    { 
        new TM200 ("t200.mis", "Triggered mission 200", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t201.mis", "Triggered mission 201", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t202.mis", "Triggered mission 202", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("t203.mis", "Triggered mission 203", "Interceptors coming RED", "Intercept the Red devil"),// add comma for each new line
        new TM200 ("t204.mis", "Triggered mission 204", "Interceptors coming RED", "Intercept the Red devil"),
        new TM200 ("tnull.mis", "random null TM5", null, null),
        new TM200 ("tnull.mis", "random null TM6", null, null),
        new TM200 ("tnull.mis", "random null TM7", null, null),
        new TM200 ("tnull.mis", "random null TM8", null, null),
        new TM200 ("tnull.mis", "random null TM9", null, null),
        new TM200 ("tnull.mis", "random null TM10", null, null)

    };

    /*=========================================*/

    // Triggered Objective missions lists for DE uk
    //NOTE: DE = 250~299 series num 
    //If you add missions to input region, add new lines to list below(index numbering)

    List<TM250> TM250s = new List<TM250>
    { 
        new TM250 ("t250.mis", "Objective mission 250 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t251.mis", "Objective mission 251 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t252.mis", "Objective mission 252 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),
        new TM250 ("t253.mis", "Objective mission 253 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!"),// add comma for each new line
        new TM250 ("t254.mis", "Objective mission 254 KILL BOB", "Save BOB!", "BOB has fled the building fire, get him!")
    };

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region Repeats and delays & Random selection varibles

    //tick time can alter length due to processing damands, however assume 30/sec 
    //1 sec = 30 ticks
    //1 min = 1800 ticks
    //1hour = 108000 ticks

    //note, r value must be bigger than d value

    private int rt0 = 9000;//5 min repeat
    private int dt0 = 1800;//1 min delay 

    private int rt1 = 9000;//5 min repeat
    private int dt1 = 3600;//2 min delay

    private int rt2 = 18000;//10 min repeat
    private int dt2 = 5400;//3 min delay  

    private int rt3 = 27000;//15 min repeat
    private int dt3 = 7200;//4 min delay 

    //timer reset(start value, gets randomised 100~900 in map selection,)
    //auto reset switch delay stops multible trigger loading, this version resets by random time period(100~900 secs)
    //for fixed value unrem the pvt double below, rem out random version in map selection
    //private double rsukS1 = 300;   

    Random rsukS1 = new Random();
    private int ukS1 = 1;
    Random rsukS2 = new Random();
    private int ukS2 = 1;
    Random rsukS3 = new Random();
    private int ukS3 = 1;

    private double rsukS4 = 3600;
    private int ukS4 = 1;
    
    Random rsdeS1 = new Random();
    private int deS1 = 1;
    Random rsdeS2 = new Random();
    private int deS2 = 1;
    Random rsdeS3 = new Random();
    private int deS3 = 1;

    private double rsdeS4 = 3600;    
    private int deS4 = 1; 

    Random rand = new Random();//random mis selection

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region Mission classes

    internal class SubM //SubMission
    {
        public string MN { get; set; }//MissionName
        public string MM { get; set; }//MissionMessage
        public string MMR { get; set; }//MissionMessageRed
        public string MMB { get; set; }//MissionMessageBlue

        public SubM(string mn, string mm, string mmr, string mmb)
        {
            this.MN = mn;
            this.MM = mm;
            this.MMR = mmr;
            this.MMB = mmb;
        }
    }

    internal class TM100 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM100(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM150 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM150(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM200 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM200(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    internal class TM250 //Triggered missions
    {
        public string TN { get; set; }//MissionName
        public string TM { get; set; }//MissionMessage
        public string TMR { get; set; }//MissionMessageRed
        public string TMB { get; set; }//MissionMessageBlue

        public TM250(string tn, string tm, string tmr, string tmb)
        {
            this.TN = tn;
            this.TM = tm;
            this.TMR = tmr;
            this.TMB = tmb;
        }
    }

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region const's and params

    //Tx's To
    private const int All = -1;
    private const int Allies = 1;
    private const int Axis = 2;    

    //Despawner time varible
    //To times 5min=300 10min=600 15min=900 30min=1800 45min=2700 60min=3600
    private double despawntime = 2700;//ai aircraft despawn
    private double despawntime2 = 300;//secondary ai aircraft despawn
    private double despawntime3 = 2700;//ground ai despawn

    //Goes with time indicator, set period for cycle repeat period: value = seconds 
    //1mins=60sec=1800ticks 
    private double ts = 60;

    //trigger boolean start point condition
    bool pDE1 = false;
    bool pDE2 = false;
    bool pDE3 = false;
    bool pDE4 = false;
    bool pUK1 = false;
    bool pUK2 = false;
    bool pUK3 = false;
    bool pUK4 = false;
    private int rm;
    private int bm;
/*        
     [Trigger]
  uk1 TPassThrough 5 2 12025 10315 15000
  uk2 TPassThrough 5 2 12025 10315 10000
  uk3 TPassThrough 5 2 12025 10315 5000  
  de1 TPassThrough 5 1 30440 31260 15000
  de2 TPassThrough 5 1 30440 31260 10000
  de3 TPassThrough 5 1 30440 31260 5000  
*/

    Point2d DEr1 = new Point2d(30440, 31260);// radar trigger(Red active)
    Point2d UKr1 = new Point2d(12025, 10315);// radar trigger(Blue active)    

    //listen to events from all missions.
    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1; 
    }

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region Main mission operation

    public override void OnTickGame()
    {
        base.OnTickGame();

        /*=========================================*/
        /*    Server timer for mis time testing    */
        /*         rem out when not in use         */
        /*=========================================*/

        // Time. current() in seconds from Battle Start
        if (Time.current() >= ts)
        {
            GamePlay.gpHUDLogCenter("Elapsed Time:Min:" + ts / 60 + " Secs:" + ts + " Ticks:" + ts * 30);
            ts = ts + ts;
        }

        /*=========================================*/

        //tick counter mission random loader
       
        if (Time.tickCounter() % rt0 == dt0)
        {            
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);  
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt1 == dt1)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt2 == dt2)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
        if (Time.tickCounter() % rt3 == dt3)
        {
            int i = 0;
            if (SubMs.Count > 0)
                i = rand.Next(0, SubMs.Count);
            GamePlay.gpPostMissionLoad(MPsub + SubMs[i].MN);
            STxA(-1, SubMs[i].MM);
            Timeout(2.0, () => { STxA(1, SubMs[i].MMR); STxA(2, SubMs[i].MMB); });
        }
    }
  
    #endregion

    /*=========================================*/
    /*=========================================*/
    
    #region Mission triggers

    internal double getDistanceFromTo(Point2d startPoint, Point2d endPoint)
    {
        return startPoint.distance(ref endPoint);
    }
          
    public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        base.OnTrigger(missionNumber, shortName, active);        
            
        List<Player> plebs = new List<Player>();
        if (GamePlay.gpPlayer() != null)            
            plebs.Add(GamePlay.gpPlayer());
        if (GamePlay.gpRemotePlayers() != null)            
            plebs.AddRange(GamePlay.gpRemotePlayers());

        plebs.ForEach(item =>
        {
            if (item.Place() != null)
            {
                Point2d ActorPos = new Point2d(item.Place().Pos().x, item.Place().Pos().y);
                //radar circles
                if (item.Army() == 1)
                {
                    if (getDistanceFromTo(ActorPos, DEr1) > 15000.1)
                    {
                        pDE1 = false;
                        pDE2 = false;
                        pDE3 = false;
                    }

                    if (getDistanceFromTo(ActorPos, DEr1) < 15000)
                        if (getDistanceFromTo(ActorPos, DEr1) > 10000.1)
                        {
                            pDE1 = true;
                            pDE2 = false;
                            pDE3 = false;
                        }

                    if (getDistanceFromTo(ActorPos, DEr1) < 10000)
                        if (getDistanceFromTo(ActorPos, DEr1) > 5000.1)
                        {
                            pDE1 = false;
                            pDE2 = true;
                            pDE3 = false;
                        }
                    if (getDistanceFromTo(ActorPos, DEr1) < 5000)
                    {
                        pDE1 = false;
                        pDE2 = false;
                        pDE3 = true;
                    }                    
                }
                                                                                
                if (item.Army() == 2)
                {
                    if (getDistanceFromTo(ActorPos, UKr1) > 15000.1)
                    {
                        pUK1 = false;
                        pUK2 = false;
                        pUK3 = false;
                    }
                    if (getDistanceFromTo(ActorPos, UKr1) < 15000)
                        if (getDistanceFromTo(ActorPos, UKr1) > 10000.1)
                        {
                            pUK1 = true;
                            pUK2 = false;
                            pUK3 = false;

                        }
                    if (getDistanceFromTo(ActorPos, UKr1) < 10000)
                        if (getDistanceFromTo(ActorPos, UKr1) > 5000.1)
                        {
                            pUK1 = false;
                            pUK2 = true;
                            pUK3 = false;
                        }
                    if (getDistanceFromTo(ActorPos, UKr1) < 5000)
                    {
                        pUK1 = false;
                        pUK2 = false;
                        pUK3 = true;
                    }
                }               
            }
        });

        if ((pDE1 | pDE2 | pDE3 | pUK1 | pUK2 | pUK3) == true)
            TrigMis();
                
          
        // ai as triggers (AI can be treated separately here)
        if (shortName.Equals("de1") && active)        
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        if (shortName.Equals("de2") && active)
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        if (shortName.Equals("de3") && active)
        {
            STxA(-1, shortName + " ai trigger check(red in blue)");// rem out once checks complete 
        }
        //if (shortName.Equals("de4") && active)
        //{
            //STxA(-1, shortName + " ai trigger check(blue bomber)");// rem out once checks complete 
        //}
        if (shortName.Equals("uk1") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        if (shortName.Equals("uk2") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        if (shortName.Equals("uk3") && active)
        {
            STxA(-1, shortName + " ai trigger check(blue in red)");// rem out once checks complete 
        }
        //if (shortName.Equals("uk4") && active)
        //{
            //STxA(-1, shortName + " ai trigger check(red bomber)");// rem out once checks complete 
        //}

        if (shortName.Equals("killkubel") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + " YOU KILLED BILL"); });
            ukS4 = 1;
        }
        if (shortName.Equals("safekubel") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + "BILL IS SAFE"); });            
        }

        if (shortName.Equals("killbob") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + " YOU KILLED BOB"); });
            deS4 = 1;
        }
        if (shortName.Equals("safebob") && active)
        {
            Timeout(8.0, () => { STxA(-1, shortName + "BOB IS SAFE"); });            

        }
    }


    private void TrigMis()
    {
        /*===================de triggered mis=====================*/
        if (pDE1 == true)
        {
            switch (deS1)
            {
                case 1:
                    deS1 = 2;//on off switch for trigger operation
                    Timeout(rsdeS1.Next(100, 901), () => { deS1 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de1 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE1 = false;
        }

        if (pDE2 == true)
        {
            switch (deS2)
            {
                case 1:
                    deS2 = 2;//on off switch for trigger operation
                    Timeout(rsdeS2.Next(100, 901), () => { deS2 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de2 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE2 = false;
        }

        if (pDE3 == true)
        {
            switch (deS3)
            {
                case 1:
                    deS3 = 2;//on off switch for trigger operation
                    Timeout(rsdeS3.Next(100, 901), () => { deS3 = 1; });//random timer reset function
                    int i = 0;
                    if (TM200s.Count > 0)
                        i = rand.Next(0, TM200s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM200s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM200s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM200s[i].TMR); STxA(2, TM200s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "de3 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pDE3 = false;
        }
                
        /*===================uk triggered mis======================*/

        if (pUK1 == true)
        {
            switch (ukS1)
            {
                case 1:
                    ukS1 = 2;//on off switch for trigger operation
                    Timeout(rsukS1.Next(100, 901), () => { ukS1 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk1 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK1 = false;
        }

        if (pUK2 == true)
        {
            switch (ukS2)
            {
                case 1:
                    ukS2 = 2;//on off switch for trigger operation
                    Timeout(rsukS2.Next(100, 901), () => { ukS2 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk2 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK2 = false;
        }

        if (pUK3 == true)
        {
            switch (ukS3)
            {
                case 1:
                    ukS3 = 2;//on off switch for trigger operation
                    Timeout(rsukS3.Next(100, 901), () => { ukS3 = 1; });//random timer reset function
                    int i = 0;
                    if (TM100s.Count > 0)
                        i = rand.Next(0, TM100s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM100s[i].TN);
                    Timeout(4.0, () => { STxA(-1, TM100s[i].TM); });
                    Timeout(6.0, () => { STxA(1, TM100s[i].TMR); STxA(2, TM100s[i].TMB); });
                    break;
                case 2:
                    Timeout(6.0, () => { STxA(-1, "uk3 trigger already in action"); });// rem out once checks complete
                    break;
            }
            pUK3 = false;
        }

        /*===================de objective mis======================*/

        if (pDE4 == true)
        {
            switch (deS4)
            {
                case 1:
                    deS4 = 2;//on off switch for trigger operation
                    Timeout(rsdeS4, () => { deS4 = 1; });//timer reset function
                    //int bm = 0;
                    if (TM250s.Count > 0)
                        bm = rand.Next(0, TM250s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM250s[bm].TN);
                    Timeout(4.0, () => { STxA(-1, TM250s[bm].TM); });
                    Timeout(6.0, () => { STxA(1, TM250s[bm].TMR); STxA(2, TM250s[bm].TMB); });
                    break;
                case 2:
                    //Timeout(6.0, () => { STxA(-1, "Objective trigger already in action"); });// rem out once checks complete
                    Timeout(6.0, () => { STxA(1, TM250s[bm].TMR); STxA(2, TM250s[bm].TMB); });// repeat mission objective tx
                    break;
            }
            pDE4 = false;
        }

        /*===================uk objective mis======================*/

        if (pUK4 == true)
        {
            switch (ukS4)
            {
                case 1:
                    ukS4 = 2;//on off switch for trigger operation
                    Timeout(rsukS4, () => { ukS4 = 1; });// timer reset function
                    //int rm = 0;
                    if (TM150s.Count > 0)
                        rm = rand.Next(0, TM150s.Count);
                    GamePlay.gpPostMissionLoad(MPtm + TM150s[rm].TN);
                    Timeout(4.0, () => { STxA(-1, TM150s[rm].TM); });
                    Timeout(6.0, () => { STxA(1, TM150s[rm].TMR); STxA(2, TM150s[rm].TMB); });
                    break;
                case 2:
                    //Timeout(6.0, () => { STxA(-1, "Objective trigger already in action"); });// rem out once checks complete
                    Timeout(6.0, () => { STxA(1, TM150s[rm].TMR); STxA(2, TM150s[rm].TMB); });// repeat mission objective tx
                    break;
            }
            pUK4 = false;
        }
    }

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region Despawner  

    /*
    despawner timer added to original code, sets overall time period for actors,
    Advantage is, if delayed, say trying to land behind masses of planes, actors despawn at timer period set anyway.
    allows for players to fly groups of planes, 
    Player can re eneter flights or groups, as bombers take them to target, use each at target then fly group home
    despawn only triggers once player leaves whole group
*/
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);

        // note despawntime (set as varible at start of cs) 
        if (actor is AiGroundActor && missionNumber > 0)//main mission is left alone
            //if ((actor as AiGroundActor).Type() != maddox.game.world.AiGroundActorType.AAGun)//all ai ground except aa guns
            Timeout(despawntime3, () =>
            {
                if (actor != null)
                { (actor as AiGroundActor).Destroy(); }
            });

        if (actor is AiAircraft)        
            Timeout(despawntime, () => { damageAiControlledPlane(actor); });     
    }
 
    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceLeave(player, actor, placeIndex);
        Timeout(despawntime, () => { damageAiControlledPlane(actor); });        
    }
    
    // Path completion despawner, when flight path ends despawner action triggered
    // note:final despawner detects players in group    

    public override void OnActorTaskCompleted(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorTaskCompleted(missionNumber, shortName, actor);
        if (actor is AiGroundActor) 
            if (actor != null)
                Timeout(despawntime2, () => { (actor as AiGroundActor).Destroy(); });
            
        Timeout(despawntime2, () => { damageAiControlledPlane(actor); });
    }

    //check if a player is in any of the "places"
    private bool isAiControlledPlane(AiAircraft aircraft)
    {
        if (aircraft == null) return false;        
        for (int i = 0; i < aircraft.Places(); i++)
            if (aircraft.Player(i) != null)
                return false;
        return true;
    }

    private void destroyPlane(AiAircraft aircraft)
    {
        if (aircraft != null)
            aircraft.Destroy();
    }

    //actual Aiaircraft despawner, note it polls player detection
    private void damageAiControlledPlane(AiActor actorMain)
    {
        //Timeout(1, () => { STxA(-1, "Despawn time completes for Actor, Despawning"); });//indicates action about to happen, rem out after mission checks complete
        foreach (AiActor actor in actorMain.Group().GetItems())
        {
            if (actor == null || !(actor is AiAircraft))
                return;
            AiAircraft aircraft = (actor as AiAircraft);
            if (!isAiControlledPlane(aircraft))
                return;
            if (aircraft == null)
                return;
            (actor as AiAircraft).Destroy();
        }
    }

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region OnPlaceEnter Welcome Tx, objective creation

    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);
        AiAircraft aircraft = actor as AiAircraft;
        if (aircraft != null)            
            switch (aircraft.Army())
            {
                case 1:
                    if (aircraft.Type() == AircraftType.Bomber)
                    {
                        { GamePlay.gpHUDLogCenter(new Player[] { player }, "Bombers, Check your maps for targets!"); }                        
                    }
                    else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Fighters, Escort Bombers or Patrol the lines!"); }                    
                    pUK4 = true;// set main mission objective group activation true/false
                    TrigMis();// apply the truth
                    break;
                case 2:
                    if (aircraft.Type() == AircraftType.Bomber)
                    {
                        { GamePlay.gpHUDLogCenter(new Player[] { player }, "Bombers, uberprüfen Sie Ihre Karten fur Ziele!"); }                        
                    }
                    else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Fighters, Escort Bombers oder Patrol den Zeilen!"); }                    
                    pDE4 = true;
                    TrigMis();
                break;
            }           
    }

    #endregion

    /*=========================================*/
    /*=========================================*/

    #region STxA Screen Text to Armies

    private void STxA(int army, string Tx, params object[] args)
    { 
        List<Player> Consignees = new List<Player>();
        if (GamePlay.gpPlayer() != null)
            Consignees.Add(GamePlay.gpPlayer());
        if (GamePlay.gpRemotePlayers() != null)
            Consignees.AddRange(GamePlay.gpRemotePlayers());

        if (army == -1)
            GamePlay.gpHUDLogCenter(null, Tx);
        else if (Consignees.Exists(item => item.Army() == army))
            GamePlay.gpHUDLogCenter(Consignees.FindAll(item => item.Army() == army).ToArray(), Tx);        
    }

    #endregion

    /*=========================================*/    
}
//note the last bracket wraps Amission

Last edited by Smokeynz; 03-01-2012 at 08:53 PM.
Reply With Quote
  #10  
Old 02-27-2012, 01:48 AM
Smokeynz Smokeynz is offline
Senior Member
 
Join Date: Apr 2011
Posts: 106
Default

Known bugs, On task completed generates one bug I have found. If a path of a flight crosses the last path point of its own path or another operating mission path, even the line from the second to last point to the last point, then that flight that passes over the previous path will trigger the on task completed and despawn. Oh that’s a pain! This bug will trigger for anyone using on task completed so just be aware if planes despawn in places you are not expecting. A method to bypass the bug is to place the last waypoint section to side of flights. Also don’t land planes on takeoff points, the spawning plane with despawn due to being at the operating task completed path.


Finally here is the complete code and mission setup
Please test, I am looking for bugs and quirks and general xxxx.

*****Updates*****
last version 2/3/2012
Attached Files
File Type: zip ScrimBase.zip (22.4 KB, 13 views)

Last edited by KG26_Alpha; 03-13-2012 at 05:35 PM.
Reply With Quote
Reply

Thread Tools
Display Modes

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 09:43 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
Copyright © 2007 1C Company. All rights reserved.