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)
-   -   Online War - FMB scripting (http://forum.fulqrumpublishing.com/showthread.php?t=21518)

Ataros 05-12-2011 08:23 AM

Great thread on searchlights and adding AA to trains and trucks

http://forum.1cpublishing.eu/showthr...t=22740&page=2

335th_GRAthos 05-13-2011 11:58 AM

Quote:

Originally Posted by Ataros (Post 282006)
Great thread on searchlights and adding AA to trains and trucks

http://forum.1cpublishing.eu/showthr...t=22740&page=2



WOW!

I start getting depressed that flying at 400kmh, jinking like mad, the last thing I will want to do is looking a the detail of the AAA shooting at me.... :-)

It looks as if the mission builders will have as much fun as the pilots with this sim...

Great job, we will go throgh hell finding out about the details but, great job!


Nice week end to all !

Groundhog 05-13-2011 04:46 PM

Ataros

thanks for all the scripting info.
I am trying your tmp script with three sub missions.
It gets as far as loading the first sub mission and then my plane explodes.
The text message is shown in cockpit then boom!
Please help.

Disregard..pilot error :)
GH

TheEnlightenedFlorist 05-14-2011 09:16 PM

Thanks for the thread Ataros. Very helpful.

Is there a reason you guys are using "ticks" to measure time. C# has a few different ways of keeping track of time. Here's an example using the Stopwatch class. Don't get me wrong, modulus is great but this stopwatch is probably more accurate and it's a heck of a lot more readable. :)

Code:

using System;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;
using System.Diagnostics;  //contains Stopwatch class

public class Mission : AMission
{
    int timesRun = 0;  //count how many times sub-mission has been run

    Stopwatch timer = new Stopwatch();  //timer. Counts... time...

    public override void OnTickGame()
    {
       
        //if sub-mission has never been run, run it
        if (timesRun == 0)
        {
            //start timer
            timer.Start();

            GamePlay.gpPostMissionLoad("missions/Multi/MyMissions/mission1.mis");
            timesRun++;

            // prints message on screen after mission load
            GamePlay.gpHUDLogCenter("Hello, world! Mission1.mis loaded!");
        }

        //if five or more minutes have elapsed since the timer was started, run sub-mission
        if (timer.Elapsed.Minutes >= 5)
        {
            GamePlay.gpPostMissionLoad("missions/Multi/MyMissions/mission1.mis");
            timesRun++;

            GamePlay.gpHUDLogCenter("Hello, world! Mission1.mis loaded!");

            //reset timer to zero and restart it
            timer.Restart();
        }
    }
}


ZaltysZ 05-14-2011 09:58 PM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 283300)
Don't get me wrong, modulus is great but this stopwatch is probably more accurate and it's a heck of a lot more readable. :)

The problem with external timing is that you will get time according to your system and not to game. Simulation can slow down because of lag, and external timer won't take that into account, i.e. briefing can say that bombers start at 9:00, however you may see that start greatly off its planned time (according to game clock), if you use external timer.

If you want to get rid of counting ticks, you can use this:
Code:

        //Runs once, when mission is loaded
        public override void Init(maddox.game.ABattle battle, int missionNumber)
        {
                base.Init(battle,missionNumber);
                //Planned missions
                MissionLoader(30,10,"missions/Multi/Dogfight/bombers1.mis");  // 10s from main mission start and repeatedly every 30s
                MissionLoader(100,60,"missions/Multi/Dogfight/bombers2.mis"); // 60s from main mission start and repeatedly every 100s
        }
       
        public void MissionLoader(int period, int offset, string mission)
        {
                if (offset > 0)
                        Timeout(offset, () => {MissionLoader(period,0,mission);});
                else
                        {
                                GamePlay.gpPostMissionLoad(mission);       
                                Timeout(period, () => {MissionLoader(period,0,mission);});               
                        }
        }


TheEnlightenedFlorist 05-15-2011 11:19 PM

Oh, I'm sorry. I thought that you guys wanted to base the intervals that missions run on on real time not on game time.

TheEnlightenedFlorist 05-16-2011 07:09 AM

1 Attachment(s)
Okay. I think I've got a handle on how to create and manipulate "MissionMarkers" aka Front Markers in a script. I've attached a simple, commented example. Shoot down the bomber in front of you and the southwest airfield's front marker changes to blue.

Quote:

Originally Posted by Ataros (Post 279210)
Can someone program a small 3 airfields battle based on it? Say a middle airfield becomes red or blue based on which tanks remain alive after taking the airfield. Then spawn new groups of tanks in say 20 minutes for a new round.

I'm confident that if you gave me a mission with an appropriate trigger, I could move and change front markers, but I don't have much experience with the FMB. I've only created single player missions thus far. I don't know how to create an airfield where multiple players can choose an aircraft and spawn at, and I certainly don't know how to change who can spawn at an airfield in a script. Does the code you posted do this? I see mention of "BirthPlaces" in the script, but I don't see any "BirthPlaces" in the FMB.

Do you have a link to a tutorial on how to create multiplayer missions?

Ataros 05-16-2011 11:42 AM

1 Attachment(s)
Quote:

Originally Posted by TheEnlightenedFlorist (Post 283813)
Does the code you posted do this? I see mention of "BirthPlaces" in the script, but I don't see any "BirthPlaces" in the FMB.

Do you have a link to a tutorial on how to create multiplayer missions?

MP missions are different from SP only by this FMB object called "birthplace" (at least in Russian version) or spawnpoint in English I guess. You find it in Object Browser the same way as other objects like an airfield or a tank. In its property window you can select side it belongs to and list of aircraft available for players. In a mission consisting of many submissions you place birthplaces in the 1st 'main' mission. See my mission as example attached.

When new submission is loaded it can contain a new moved frontline and a new birthplace (e.g. red one) in the location where the blue one used to be. The problem is the old birthplace is not removed by loading a new submission and blue aircraft still can be created in the newly captured red airfield. That is why you need to destroy an old blue birthplace with a script I guess:
Code:

foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
        {
            if (bp != null)
                bp.destroy();
       
        }

E.g. in my Repka mission we have both red and blue airfields in D3. The main mission loads 3 (will be 4 soon) relatively big submissions in itself and 2 small ones.

Ideally I would like to move the frontline and change side of these 2 birthplaces based on results of a recent submission. Say if reds loose more aircrafts or tanks (or more then say 70%) in recent mission reds loose an airfield in D3. If they win next mission they take it back, etc. and repeat it forever.

In the future I believe this script can be used to move frontline across the whole map to create an ongoing war.

Please find a recent version of my mission attached.

Ataros 05-16-2011 06:49 PM

Could some C# experts check this part of script for errors. Trying to randomize submission loading here. Thanks to Groundhog for idea.

Intended to run in cycle forever. Does not work for me (
Need help please.

Code:

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

public class Mission : AMission
{
 
 
// loading sub-missions
public override void OnTickGame()
{
   
    if (Time.tickCounter() % 54000 == 12600) // 54000=30 min repeat. 12600=7 min delay.
  {
        // randomly selects 1 of several submissions
        Random RandomIncident = new Random();

        switch (RandomIncident.Next(1, 3))
        {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air01.mis");
                // GamePlay.gpHUDLogCenter("mis1 loaded!");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                });
            break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_sea01.mis");
                // GamePlay.gpHUDLogCenter("mis2 loaded");

                double initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });
           
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                });
            break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air02.mis");
                // GamePlay.gpHUDLogCenter("mis3 loaded!");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                });
            break;
        }
    }

    ///////////////////////

    //loads small submissions w/o messages
   
    if (Time.tickCounter() % 216000 == 108000) // 216000=120 min repeat. 108000=60 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small01.mis");
    }

    if (Time.tickCounter() % 216000 == 215999) // 216000=120 min repeat. 215999=120 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small02.mis");
    }
}     
}


TheEnlightenedFlorist 05-16-2011 11:06 PM

Thanks for the help Ataros, I'll start experimenting with that right away.

As for your code, what exactly isn't working? I can tell you right now that case 3 will never run because the Next(int, int) method returns an integer greater than or equal to the smaller number, but only less than the larger number. In other words, it will never return three, just one or two. It should look like this:

switch (RandomIncident.Next(1, 4))

See here: http://msdn.microsoft.com/en-us/library/2dx6wyd4.aspx

Ataros 05-17-2011 06:24 AM

1 Attachment(s)
Quote:

Originally Posted by TheEnlightenedFlorist (Post 284195)
It should look like this:

switch (RandomIncident.Next(1, 4))

See here: http://msdn.microsoft.com/en-us/library/2dx6wyd4.aspx

Thanks, changed this. Should there be a space between the figures or does not matter?

I am trying to run this script with reduced delays for testing purposes and it does not load any submission or prints any message at all.
Please try to run it if you have time to see. Mission is attached.



Code:

// v.1_17_05. script by oreva, zaltys, small_bee

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

public class Mission : AMission
{
 
 
// loading sub-missions
public override void OnTickGame()
{
   
    if (Time.tickCounter() % 1800 == 1000) // 54000=30 min repeat. 12600=7 min delay.
  {
        // randomly selects 1 of several submissions

        Random RandomIncident = new Random();

        switch (RandomIncident.Next(1,4))
        {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air01.mis");
                GamePlay.gpHUDLogCenter("mission 1 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                });
            break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_sea01.mis");
                GamePlay.gpHUDLogCenter("mission 2 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });
           
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                });
            break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air02.mis");
                GamePlay.gpHUDLogCenter("mission 3 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                });
            break;
        }
    }

    ///////////////////////

    //loads small submissions w/o messages
   
    if (Time.tickCounter() % 216000 == 108000) // 216000=120 min repeat. 108000=60 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small01.mis");
    }

    if (Time.tickCounter() % 216000 == 215999) // 216000=120 min repeat. 215999=120 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small02.mis");
    }
     
}
////////////////////////////////////////////////////////////////////////////////////////////////////

// destroys aircraft abandoned by a player.
    private bool isAiControlledPlane (AiAircraft aircraft)
    {
                if (aircraft == null)
        {
                        return false;
                }

                Player [] players = GamePlay.gpRemotePlayers ();
                foreach (Player p in players)
        {   
                        if (p != null && (p.Place () is AiAircraft) && (p.Place () as AiAircraft) == aircraft)
            {
                                return false;
                        }
                }

                return true;
        }

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

        private void explodeFuelTank (AiAircraft aircraft)
    {
                if (aircraft != null)
        {
                        aircraft.hitNamed (part.NamedDamageTypes.FuelTank0Exploded);
                }
        }

        private void destroyAiControlledPlane (AiAircraft aircraft) {
                if (isAiControlledPlane (aircraft)) {
                        destroyPlane (aircraft);
                }
        }

        private void damageAiControlledPlane (AiActor actor) {
                if (actor == null || !(actor is AiAircraft)) {
                        return;
                }

                AiAircraft aircraft = (actor as AiAircraft);

                if (!isAiControlledPlane (aircraft)) {
                        return;
                }

                if (aircraft == null) {
                        return;
                }

                aircraft.hitNamed (part.NamedDamageTypes.ControlsElevatorDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.ControlsAileronsDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.ControlsRudderDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.FuelPumpFailure);

        int iNumOfEngines = (aircraft.Group() as AiAirGroup).aircraftEnginesNum();
        for (int i = 0; i < iNumOfEngines; i++)
        {
            aircraft.hitNamed((part.NamedDamageTypes)Enum.Parse(typeof(part.NamedDamageTypes), "Eng" + i.ToString() + "TotalFailure"));
        }

        /***Timeout (240, () =>
                {explodeFuelTank (aircraft);}
            );
        * ***/

        Timeout (300, () =>
                                {destroyPlane (aircraft);}
                        );
        }

    //////////////////////////////////////////

        public override void OnPlaceLeave (Player player, AiActor actor, int placeIndex)
    {
                base.OnPlaceLeave (player, actor, placeIndex);
                Timeout (1, () =>
                                {damageAiControlledPlane (actor);}
                        );
        }

        public override void OnAircraftCrashLanded (int missionNumber, string shortName, AiAircraft aircraft)
    {
                base.OnAircraftCrashLanded (missionNumber, shortName, aircraft);
                Timeout (300, () =>
            { destroyPlane(aircraft); }
                        );
        }
    public override void OnAircraftLanded (int missionNumber, string shortName, AiAircraft aircraft)
    {
        base.OnAircraftLanded(missionNumber, shortName, aircraft);
        Timeout(300, () =>
            { destroyPlane(aircraft); }
            );
    }
   
   
//////////////////////////////////////////////////////////////////////////////////////////////////

    //Listen to events of every mission
    public override void Init(maddox.game.ABattle battle, int missionNumber)
    {
        base.Init(battle, missionNumber);
        MissionNumberListener = -1; //Listen to events of every mission
    }

 //////////////////////////////////////////////////////////////////////////////////////////////////

    //Ground objects (except AA Guns) will die after 55 min when counted from their birth

    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);
        //Ground objects (except AA Guns) will die after 55 min when counted from their birth
        if (actor is AiGroundActor)
            if ((actor as AiGroundActor).Type() != maddox.game.world.AiGroundActorType.AAGun)
                Timeout(3300, () =>
                {
                    if (actor != null)
                    { (actor as AiGroundActor).Destroy(); }
                }
                        );
    }

    /****
    //Ground objects will die after 55 min when counted from their birth
   
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);

        //Ground objects will die after 55 min when counted from their birth
        if (actor is AiGroundActor)
            Timeout(3300, () =>
            {
                if (actor != null)
                { (actor as AiGroundActor).Destroy(); }
            }
                    );
    }
    ****/
}


TheEnlightenedFlorist 05-17-2011 09:54 AM

Quote:

Originally Posted by Ataros (Post 284278)
Thanks, changed this. Should there be a space between the figures or does not matter?

I am trying to run this script with reduced delays for testing purposes and it does not load any submission or prints any message at all.
Please try to run it if you have time to see. Mission is attached.

The space does not matter. "Whitespace is ignored", as they say.

I'm not at my desktop so I can't run your mission, but I can't see why that code wouldn't work.

FG28_Kodiak 05-17-2011 12:51 PM

@Ataros

Code:

        switch (RandomIncident.Next(1,4))
        {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air01.mis");
                GamePlay.gpHUDLogCenter("mission 1 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                });
            break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_sea01.mis");
                GamePlay.gpHUDLogCenter("mission 2 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });
           
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                });
            break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air02.mis");
                GamePlay.gpHUDLogCenter("mission 3 objectives loaded...");

                double initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                });
            break;

Made the declaration double initTime = 0.0 before the switch case and only onetimes. Then your script should work.

It should look like:
Code:

public override void OnTickGame()
{

  double initTime;   

    if (Time.tickCounter() % 1800 == 1000) // 54000=30 min repeat. 12600=7 min delay.
  {
        // randomly selects 1 of several submissions

        Random RandomIncident = new Random();
       
        switch (RandomIncident.Next(1,4))
        {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air01.mis");
                GamePlay.gpHUDLogCenter("mission 1 objectives loaded...");

              initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                });
            break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_sea01.mis");
                GamePlay.gpHUDLogCenter("mission 2 objectives loaded...");

              initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });
           
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                });
            break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air02.mis");
                GamePlay.gpHUDLogCenter("mission 3 objectives loaded...");

                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                });
            break;
        }
    }


Ataros 05-17-2011 01:50 PM

Quote:

Originally Posted by FG28_Kodiak (Post 284418)
Made the declaration double initTime = 0.0 before the switch case and only onetimes. Then your script should work.

It should look like:

Thank you very much!! Works great!

Would it be hard to exclude the last mission flown from random selection for the next round? As I am getting case #3 like 4 times in a row, than case 2 2 times. It can become boring for players. (I am planning to add more various missions to it in the future.)

We will test the script on Repka 2 for some time and then move it to Repka 1.

Welcome to our servers!

FG28_Kodiak 05-17-2011 03:39 PM

It's possible to avoid repeating of last mission:

Code:

public class Mission : AMission
{
    int LastMissionLoaded=0;
 
    // loading sub-missions
    public override void OnTickGame()
    {
   
        if (Time.tickCounter() % 1800 == 1000) // 54000=30 min repeat. 12600=7 min delay.
        {
            // randomly selects 1 of several submissions

            Random RandomIncident = new Random();
            int CurrentMissionSelected;

            do
            {
                CurrentMissionSelected = RandomIncident.Next(1,4);
            }               
            while (LastMissionLoaded == CurrentMissionSelected);
                               
            LastMissionLoaded = CurrentMissionSelected;

            switch (CurrentMissionSelected)
            {


bigchump 05-17-2011 04:47 PM

I use C# everyday and I can't imagine using any of the .NET stuff to code a flight sim.

Ataros 05-17-2011 06:04 PM

Quote:

Originally Posted by FG28_Kodiak (Post 284492)
It's possible to avoid repeating of last mission:

Thank you so much again! I love this beautiful C# language. I had only some very limited acquaintance with Basiс long time ago (

Tested offline and now put up on Repka 2 for online test. Randomization will give us possibility to add more missions and overlap them randomly in time to make the airwar environment absolutely unpredictable.

I consider Repka server as a sandbox or a demo for the game-engine possibilities hoping that more people from community would be involved in mission-building and even in creation of online wars like ADW, Bellum or AFW as soon as they see how far the engine allows them to go compared to limited IL-2 COOPs or Dogfights. Unfortunately I do not have enough knowledge in C# myself.

Your help is highly appreciated.

Complete code as of today for Repka 2.
Code:

// v.1_17_05. script by FG28_Kodiak, ZaltysZ, oreva, small_bee

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

public class Mission : AMission
{

    int LastMissionLoaded = 0;

    double initTime;

    // loading sub-missions
    public override void OnTickGame()
    {
        if (Time.tickCounter() % 45000 == 9000) // 45000=25 min repeat. 9000=5 min delay.
        {
            // randomly selects 1 of several submissions excluding the recent one

            Random RandomIncident = new Random();
            int CurrentMissionSelected;

            do
                {
                CurrentMissionSelected = RandomIncident.Next(1, 4);
                }
            while (LastMissionLoaded == CurrentMissionSelected);

            LastMissionLoaded = CurrentMissionSelected;

            switch (CurrentMissionSelected)

            {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air01.mis");
                GamePlay.gpHUDLogCenter("mission objectives updated.");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                });
                break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_sea01.mis");
                GamePlay.gpHUDLogCenter("mission objectives updated..");
                    //500
                initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });

                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                });
                break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_air02.mis");
                GamePlay.gpHUDLogCenter("mission objectives updated...");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                });
                break;
        }
    }

    ///////////////////////

    //loads small submissions w/o messages
   
    if (Time.tickCounter() % 216000 == 108000) // 216000=120 min repeat. 108000=60 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small01.mis");
    }

    if (Time.tickCounter() % 216000 == 215999) // 216000=120 min repeat. 215999=120 min delay.
    {
        GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/BoF1/BoF1_small02.mis");
    }
     
}
////////////////////////////////////////////////////////////////////////////////////////////////////

// destroys aircraft abandoned by a player.
    private bool isAiControlledPlane (AiAircraft aircraft)
    {
                if (aircraft == null)
        {
                        return false;
                }

                Player [] players = GamePlay.gpRemotePlayers ();
                foreach (Player p in players)
        {   
                        if (p != null && (p.Place () is AiAircraft) && (p.Place () as AiAircraft) == aircraft)
            {
                                return false;
                        }
                }

                return true;
        }

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

        private void explodeFuelTank (AiAircraft aircraft)
    {
                if (aircraft != null)
        {
                        aircraft.hitNamed (part.NamedDamageTypes.FuelTank0Exploded);
                }
        }

        private void destroyAiControlledPlane (AiAircraft aircraft) {
                if (isAiControlledPlane (aircraft)) {
                        destroyPlane (aircraft);
                }
        }

        private void damageAiControlledPlane (AiActor actor) {
                if (actor == null || !(actor is AiAircraft)) {
                        return;
                }

                AiAircraft aircraft = (actor as AiAircraft);

                if (!isAiControlledPlane (aircraft)) {
                        return;
                }

                if (aircraft == null) {
                        return;
                }

                aircraft.hitNamed (part.NamedDamageTypes.ControlsElevatorDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.ControlsAileronsDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.ControlsRudderDisabled);
                aircraft.hitNamed (part.NamedDamageTypes.FuelPumpFailure);

        int iNumOfEngines = (aircraft.Group() as AiAirGroup).aircraftEnginesNum();
        for (int i = 0; i < iNumOfEngines; i++)
        {
            aircraft.hitNamed((part.NamedDamageTypes)Enum.Parse(typeof(part.NamedDamageTypes), "Eng" + i.ToString() + "TotalFailure"));
        }

        /***Timeout (240, () =>
                {explodeFuelTank (aircraft);}
            );
        * ***/

        Timeout (300, () =>
                                {destroyPlane (aircraft);}
                        );
        }

    //////////////////////////////////////////

        public override void OnPlaceLeave (Player player, AiActor actor, int placeIndex)
    {
                base.OnPlaceLeave (player, actor, placeIndex);
                Timeout (1, () =>
                                {damageAiControlledPlane (actor);}
                        );
        }

        public override void OnAircraftCrashLanded (int missionNumber, string shortName, AiAircraft aircraft)
    {
                base.OnAircraftCrashLanded (missionNumber, shortName, aircraft);
                Timeout (300, () =>
            { destroyPlane(aircraft); }
                        );
        }
    public override void OnAircraftLanded (int missionNumber, string shortName, AiAircraft aircraft)
    {
        base.OnAircraftLanded(missionNumber, shortName, aircraft);
        Timeout(300, () =>
            { destroyPlane(aircraft); }
            );
    }
   
   
//////////////////////////////////////////////////////////////////////////////////////////////////

    //Listen to events of every mission
    public override void Init(maddox.game.ABattle battle, int missionNumber)
    {
        base.Init(battle, missionNumber);
        MissionNumberListener = -1; //Listen to events of every mission
    }

 //////////////////////////////////////////////////////////////////////////////////////////////////

    //Ground objects (except AA Guns) will die after 55 min when counted from their birth

    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);
        //Ground objects (except AA Guns) will die after 55 min when counted from their birth
        if (actor is AiGroundActor)
            if ((actor as AiGroundActor).Type() != maddox.game.world.AiGroundActorType.AAGun)
                Timeout(3300, () =>
                {
                    if (actor != null)
                    { (actor as AiGroundActor).Destroy(); }
                }
                        );
    }

    /****
    //Ground objects will die after 55 min when counted from their birth
   
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorCreated(missionNumber, shortName, actor);

        //Ground objects will die after 55 min when counted from their birth
        if (actor is AiGroundActor)
            Timeout(3300, () =>
            {
                if (actor != null)
                { (actor as AiGroundActor).Destroy(); }
            }
                    );
    }
    ****/
}


C_G 05-17-2011 07:01 PM

I can understand this thread just enough to get excited by the possibilities for online wars. Otherwise you guys might as well be doing voodoo for all I can tell :D
Great stuff!
I may one day even move myself to borrow a C# for Dummies!

TheEnlightenedFlorist 05-18-2011 04:11 AM

1 Attachment(s)
Well, I've been messing around with changing spawn points for a while and I've got it mostly working except for one huge problem. The new spawn points don't update until I switch teams. For example, if I'm on red team and BirthPlace_1 switches to blue, I can still spawn there until I switch to blue and then back to red. I suspect it has something to do with the first mission still running after the second one is started, or the code isn't destroying BirthPlaces properly. It destroys "AiBirthPlaces". Do players use "AiBirthPlaces", or is that only for the AI. I saw no way to get a list of player "BirthPlaces".

Here's the code and the missions attached. If anybody sees any problems with it, please tell me. The spawn points and front lines will change sixty seconds after the mission starts.

Code:

using System;
using System.Collections;
using maddox.game;
using maddox.game.world;


public class Mission : AMission
{
    // MissionMarker class. Equivalent to "Front Markers" in FMB
    internal class MissionMarker
    {
        internal double x;  //x coordinate
        internal double y;  //y coordinate
        internal int army;  //army that "owns" the marker. 1 is red. 2 is blue.

        internal MissionMarker(double x, double y, int army) { this.x = x; this.y = y; this.army = army; }
    }

    //create mission markers
    private MissionMarker[] MissionMarkers = new MissionMarker[]
    {  new MissionMarker(12741, 16068, 1),
        new MissionMarker(17372, 11070, 1),
        new MissionMarker(23349, 23045, 2),
        new MissionMarker(29122, 22331, 2)
    };

    //wheter or not markers have been initialized
    bool markersNotInitialized = true;

    public override void OnTickGame()
    {
        //if markers are not initialized, they won't show up on the player's map
        if (markersNotInitialized)
        {
            //just setting the markers army equal to it's current army
            for (int i = 0; i < MissionMarkers.Length; i++)
                GamePlay.gpPostMissionLoad(CreateNewFrontLineMission(i, MissionMarkers[i].army));

            markersNotInitialized = false;
        }
    }

    internal ISectionFile CreateNewFrontLineMission(int markerNum, int newArmy)
    {
        //change the mission markers army to the new army
        MissionMarkers[markerNum].army = newArmy;

        //destroy all existing BirthPlaces/SpawnPoints, but only if the markers have been initialized
        if (!markersNotInitialized)
        {
            foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
            {
                if (bp != null)
                    bp.destroy();
            }
        }

        //?? This must be the code that turns MissionMarkers into FrontMarkers
        ISectionFile f = GamePlay.gpCreateSectionFile();
        string sect;
        string key;
        string value;
        sect = "FrontMarker";
        for (int i = 0; i < MissionMarkers.Length; i++)
        {
            key = "FrontMarker" + i.ToString();
            value = MissionMarkers[i].x.ToString(System.Globalization.CultureInfo.InvariantCulture.NumberFormat) + " " + MissionMarkers[i].y.ToString(System.Globalization.CultureInfo.InvariantCulture.NumberFormat) + " " + MissionMarkers[i].army.ToString();
            f.add(sect, key, value);
        }

        return f;
    }

    public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        //call base classes OnTrigger method.
        base.OnTrigger(missionNumber, shortName, active);

        //if the trigger that was called is the trigger that we're looking for
        if (shortName.Equals("trigger1") && active)
        {
            GamePlay.gpHUDLogCenter("Trigger1");

            //change the mission marker at 0 to blue army
            GamePlay.gpPostMissionLoad(CreateNewFrontLineMission(0, 2));

            //load new mission to change base ownership
            GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/triggerTest/changeBase.mis");

        }

        //not sure what this does either. Do some action. From where?
        AiAction action = GamePlay.gpGetAction(ActorName.Full(missionNumber, shortName));
        if (action != null)
            action.Do();
    }
}


ZaltysZ 05-18-2011 05:38 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284685)
I suspect it has something to do with the first mission still running after the second one is started, or the code isn't destroying BirthPlaces properly.

Mission loading is additive. This means that previous missions will still be running when you load the next one. This is why it is important to do clean up objects, if you don't need them anymore.

I suspect that BirthPlace has not much to do with creating planes, except as mean for UI making decision where it should show spawn points on map. Probably, we won't be able to handle this nicely until we get access to client UI (i.e. force refresh of UI).

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284685)
It destroys "AiBirthPlaces". Do players use "AiBirthPlaces", or is that only for the AI. I saw no way to get a list of player "BirthPlaces".

I don't think "Ai" is artificial intelligence in this case. Players should use AiBirthPlaces.

Ataros 05-18-2011 09:11 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284685)
Well, I've been messing around with changing spawn points for a while and I've got it mostly working except for one huge problem.

Do you mean this code does not destroy a birthplace for players who already use it?

Code:

            foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
            {
                if (bp != null)
                    bp.destroy();
            }

Probably there is a variable in code that stores player's recent bp. Can we access and change it with a script? Or onActorDead | placeExit (or what it is called) force a player to a default bp making him to select a desired bp again?


If we can change the frontline just by loading a new submission with moved frontline, why would we need the first part of the script defining the markers? I am a bit lost.

I came to a simple practical idea to prevent spawning after AF is lost:

1) set trigger starting final an attack on the airfield only when all ground units on it are killed
2) load tanks attacking the af
3) load submission containing new forntline and new bp based on trigger (tanks reached af)
4) spawn arty and tanks to patrol the af.
5) anyone from the side that lost the af spawning on it is killed by arty or tanks and learns a lesson to check the frontline position before spawning.

Not elegant but brutally practical. Did not have time to test it yet.

Anyway we have to find out how to solve the issue in a more user-friendly way ...or ...isn't it a brutal military sim?

klem 05-18-2011 09:30 AM

Quote:

Originally Posted by Ataros (Post 279210)
Sample shows moving frontline and changing spawnpoints from red to blue and vice versa based on trigger (flyby above an airfield).

Can someone program a small 3 airfields battle based on it? Say a middle airfield becomes red or blue based on which tanks remain alive after taking the airfield. Then spawn new groups of tanks in say 20 minutes for a new round.

Code:

......................................

Hi Ataros

I'm slowly getting to grips with this :D

I have a script for generating sub-missions, messages etc., and want to start a later flight in the same mission to make a second later attack on a convoy in the same mission but I can't seem to set a later start time in FMB Object Viewer. There's no way to change it from the main mission start time of 12:00 (which seems a bit daft). Can I script a start time for a planned mission or perhaps a spawn, aircraft. waypoints etc? I tried to follow your moving front line and army changes but I can't see how to make it work for a new flight.

Ataros 05-18-2011 09:44 AM

Quote:

Originally Posted by klem (Post 284739)
to start a later flight in the same mission to make a second later attack on a convoy in the same mission but I can't seem to set a later start time in FMB Object Viewer. There's no way to change it from the main mission start time of 12:00 (which seems a bit daft). Can I script a start time for a planned mission or perhaps a spawn, aircraft. waypoints etc?

I load delayed groups only with this submission loading script and do not know a better solution yet. http://forum.1cpublishing.eu/showpos...6&postcount=95

You can try setting both a timedelay trigger and action (with the same name as trigger) in FMB in script menu but it did not work for me if I used other scripts with this mission.

Maybe you can set only an "action" in FMB in script menu and then run it with a script with action.Do as in this example but delayed in time. Just guessing here.
Code:

        AiAction action = GamePlay.gpGetAction(ActorName.Full(missionNumber, shortName));
        if (action != null)
            action.Do();

It was a revelation for me that triggers (and probably actions) are stored in a mission file but not in a script. My bad :grin:

TheEnlightenedFlorist 05-18-2011 10:12 AM

Quote:

Originally Posted by Ataros (Post 284735)
Do you mean this code does not destroy a birthplace for players who already use it?

Not exactly. It doesn't matter if I've ever spawned from that particular base or not. If I was on red team before the switch, I can still spawn that base after the switch. On the contrary, if I was on blue team before the switch, I can't spawn at the new base after the switch. Of course, this all only applies to me as the host of the server. I can't confirm that the same is true of a client connected to a server.

Now that I think about it, I don't know what happens if I choose my army after the switch. It probably appears correctly then.


Quote:

Originally Posted by Ataros (Post 284735)
If we can change the frontline just by loading a new submission with moved frontline, why would we need the first part of the script defining the markers? I am a bit lost.

We can't load a new frontline by loading a new submission because as far as I know, there is no way to delete front markers that were created in a mission file. Basically, because we create the front markers ourselves in code, it's easier to keep track of them and change them. If you open my mission in the FMB, you'll see that there are no mission markers in the .mis file. I add these in code as soon as the mission is loaded.

The reason that we can change spawn points by loading a new mission is because we can get all of the birthplaces and destroy them one by one, then let the ones in the new mission replace them.

We can also create spawn points in code too, but I wanted to do that with a new mission because it was simpler. I'll try doing this tomorrow and see if it fixes my problem.

Ataros 05-18-2011 10:12 AM

1 Attachment(s)
Quote:

Originally Posted by TheEnlightenedFlorist (Post 284685)
Code:

        //not sure what this does either. Do some action. From where?
        AiAction action = GamePlay.gpGetAction(ActorName.Full(missionNumber, shortName));
        if (action != null)
            action.Do();


Attached is original mission. It is supposed to do as follows: on a flyby above an airfield a new enemy aircraft is spawn there and the af changes color to friendly.
Actions are listed in the mission file not the script. A surprise of the month for me! lol

TheEnlightenedFlorist 05-18-2011 10:22 AM

The method I used to delay the start of a flight is as follows. There could very well (and probably is) be a better way.

1. Create a trigger that fires after the desired amount of time in the FMB.

2. Create an action that spawns the aircraft you want in the FMB.

3. Put code like this in the script file. Specifically in the OnTrigger() method.

Code:

public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        //call base classes OnTrigger method.
        base.OnTrigger(missionNumber, shortName, active);

        //if the trigger that was called is the trigger that we're looking for
        if (shortName.Equals("triggerName") && active)
        {
            AiAction action = GamePlay.gpGetAction("actionName"));
            if (action != null)
                action.Do();

        }

"triggerName" and "actionName" are the names that you gave the trigger and action in the FMB.

TheEnlightenedFlorist 05-18-2011 10:27 AM

Quote:

Originally Posted by Ataros (Post 284761)
Attached is original mission. It is supposed to do as follows: on a flyby above an airfield a new enemy aircraft is spawn there and the af changes color to friendly.
Actions are listed in the mission file not the script. A surprise of the month for me! lol

Thanks. I'll look at that tomorrow. It's 4:30 in the morning here! :grin:

Ataros 05-18-2011 10:34 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284760)
We can't load a new frontline by loading a new submission because as far as I know, there is no way to delete front markers that were created in a mission file. Basically, because we create the front markers ourselves in code, it's easier to keep track of them and change them.

IIRC the devs mentioned that frontline is replaced automatically. I experimented with it 2 weeks ago and it moved, again IIRC. Try it. I thought I mentioned this in my previous posts. I can be mistaken of cause, will try to find my test missions later.

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284760)
The reason that we can change spawn points by loading a new mission is because we can get all of the birthplaces and destroy them one by one, then let the ones in the new mission replace them.

Great idea! I thought that we have to delete only one bp and that gave me headache ))
Later I think it will be possible to script removal of 1-2 af only.

BTW the greatest solution would be to have bp side changed automatically if a submission loads new frontline leaving the bp to enemy! That would be an excellent piece of code! C# geniuses are called for help :)

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284760)
We can also create spawn points in code too, but I wanted to do that with a new mission because it was simpler. I'll try doing this tomorrow and see if it fixes my problem.

I think placing everything in code gives more flexibility for a larger war/campaign where everything has to be automated (many battles for many cities and airfields). But adds complexity to coding. For a small mission with 5-8 submissions it would be easier to use FMB imho both for frontline and spawnpoints if possible.

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284766)
It's 4:30 in the morning here! :grin:

:shock::shock::shock:

Where are you located?

Ataros 05-18-2011 11:14 AM

1 Attachment(s)
Attached my test mission.

Frontline moves in 1800 ticks then tanks clear the captured AF from remaining enemy arty.

2 spawnpoints are placed at the same spot. Do not work as intended yet iirc.

TheEnlightenedFlorist 05-18-2011 11:02 PM

Quote:

Originally Posted by Ataros (Post 284770)
IIRC the devs mentioned that frontline is replaced automatically. I experimented with it 2 weeks ago and it moved, again IIRC. Try it. I thought I mentioned this in my previous posts. I can be mistaken of cause, will try to find my test missions later.

Just tried it. You are correct. That makes things a little bit simpler.

Quote:

Originally Posted by Ataros (Post 284770)
BTW the greatest solution would be to have bp side changed automatically if a submission loads new frontline leaving the bp to enemy! That would be an excellent piece of code! C# geniuses are called for help

I saw a method that looks like it could tell me which side of the front a particular point is on so this is probably very possible. Just one more thing I need to experiment with. :grin:

Quote:

Originally Posted by Ataros (Post 284770)
Where are you located?

Salt Lake City, Utah, USA. Opposite side of the planet. :grin:

TheEnlightenedFlorist 05-18-2011 11:35 PM

Quote:

Originally Posted by Ataros (Post 284761)
Attached is original mission. It is supposed to do as follows: on a flyby above an airfield a new enemy aircraft is spawn there and the af changes color to friendly.
Actions are listed in the mission file not the script. A surprise of the month for me! lol

Just tried this mission. It exhibits the same behavior as mine. :(

Edit:

This code will loop through all BirthPlaces and print a message to the screen if a BirthPlace is on the opposite side of the front line.

Code:

foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
        {
            if (GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y) != bp.Army())
                GamePlay.gpHUDLogCenter("Front and BirthPlace do not match!");
        }

I'm having fun. :)

Ataros 05-19-2011 07:13 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 285129)
Salt Lake City, Utah, USA. Opposite side of the planet. :grin:

The planet becomes smaller and smaller )
Moscow, Russia here.

Quote:

Originally Posted by TheEnlightenedFlorist (Post 285151)
This code will loop through all BirthPlaces and print a message to the screen if a BirthPlace is on the opposite side of the front line.

So we can change bp army if we find such a contradiction. Just great!


Another idea I have:

If we can track a ground group position we can simplify ground mission creation to the following:

- submission loads group of tanks with waypoints
- script reads current frontmarker positions from the mission
- every minute the game tracks tanks position and moves a frontmarker to this pos with say 3 minutes delay. if all tanks are killed within this 3 minutes the marker is not moved.
- thus several groups of tanks will move the frontline in real time
- enemy tanks will do the same pushing it backward
- if tanks are dead a new group is spawn on trigger in some distance behind frontlines
- tank battle will go on forever if players do not kill tanks themselves
- after a frontline moves further than an enemy airfield the airfield turns to friendly in say 10 minutes (to allow recapture within this period) and then AAA and new tanks spawn near it to patrol it killing enemy players if spawned there (new submission loaded)


If the above is possible a mission maker would have to manually create say only 10-20 tank spawning missions to have a huge battle for 10-20 cities/airfields.

I think we have to place tanks waypoints manually at this point because there are no bridges at some rivers and tanks may get stuck in some villages/cities making it impossible for tanks to get from one waypoint to another if the waypoints are generated 100% automatically. But I am sure a solution to this problem can be found in the future.

Have you heard of mission generator for original IL-2 by Starshoy? It automatically created online missions for IL-2 and was used in the majority of online war projects. I do not know if it is possible to convert it to C# to be used with CloD. At least some ideas can be borrowed for now I think.

And another one for offline I think http://www.lowengrin.com/news.php?90

Ataros 05-19-2011 09:06 AM

Some help from the devs.

File here http://www.sukhoi.ru/forum/attachmen...2&d=1305794840

Link http://www.sukhoi.ru/forum/showthrea...=1#post1622955
Quote:

Try, if you want to mission with the movement of the front line and the seizure of airfields:
CTF_cross_roundel.rar

There are four airfields on the map. They are your primary capture locations.
An aircraft is considered captured once the opposing sides armor enters its perimeter. The airfield perimeter is defended with artillery and flak. Once attacking armor is destroyed, a new group of armor will be spawned to continue the assault. Destroyed artillery and flak are not restored.
Once an airfield is captured, the front line will move and the airfield will change sides allowing the new owner to spawn there. Defending artillery will also spawn for the new owner, while the old owner will spawn an attacking armor group. Finally, capturing an airfield will spawn an AI-controlled aircraft group for the enemy, attacking both air and ground targets.
Capturing the most airfields is the overall objective for this mode.
The score system is simple. Capturing an airfield awards 10 points to the victorious side. Defending an airfield, that is, destroying an enemy armor group, awards 1 point.

To work correctly, the archive should be unpacked in the folder \ missions \ Multi \ Dogfight, whose mission should be run - \ missions \ Multi \ Dogfight \ CTF_cross_roundel.mis.
Podmissii are located in CTF_submissions.

MadTommy 05-19-2011 09:30 AM

Great thread.. very helpful. Personally not really interested in any capture the flag kind of gameplay, just not my thing, but i am playing with the random mission selection.

To this i have a question.

How do i alter ths code to add a case? I could guesses and i'm sure i would get there through trial & error, but i'm sure someone here can show me ;)

Can someone add a case to the below script so i can see how it is done? Thanks!

Code:

// randomly selects 1 of several submissions excluding the recent one

            Random RandomIncident = new Random();
            int CurrentMissionSelected;

            do
                {
                CurrentMissionSelected = RandomIncident.Next(1, 4);
                }
            while (LastMissionLoaded == CurrentMissionSelected);

            LastMissionLoaded = CurrentMissionSelected;

            switch (CurrentMissionSelected)

            {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R1.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated.");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                })*/
                ;
               
                break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R2.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated..");
                    //500
                initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });

                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                })*/
                ;
               
                break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R3.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated...");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                })*/
                ;
               
                break;
        }

(i'm not using the message system presently)

FG28_Kodiak 05-19-2011 10:22 AM

it is easy

Code:


          switch (CurrentMissionSelected)

            {
            case 1:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R1.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated.");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E3!");
                });
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Help is needed at E3/D4!");
                })*/
                ;
               
                break;
            case 2:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R2.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated..");
                    //500
                initTime = 0.0;
                Timeout(initTime += 500, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Cover your shipping at C4!");
                });

                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Ships are under attack at C4!");
                })*/
                ;
               
                break;
            case 3:
                GamePlay.gpPostMissionLoad("missions/Multi/15Sept1940/15Sept1940_R3.mis");
                /*
                GamePlay.gpHUDLogCenter("mission objectives updated...");
                    //600
                initTime = 0.0;
                Timeout(initTime += 600, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! Enemy activity is expected at E2!");
                });
                Timeout(initTime += 300, () =>
                {
                    GamePlay.gpHUDLogCenter("Attention! All airgroups please proceed to E2/D3!");
                })*/
                ;
               
                break;
     
  case 4:
            //your code
  break;

  case 5:
            //your code
  break;

   
}


Ataros 05-19-2011 10:54 AM

And in this line you put number of your cases+1

Code:

            do
                {
                CurrentMissionSelected = RandomIncident.Next(1, 4);
                }

4 for 3 cases
5 for 4 cases
etc

Ataros 05-19-2011 10:55 AM

Quote:

Originally Posted by Ataros (Post 285348)
Some help from the devs. Sorry no time to translate now.

File here http://www.sukhoi.ru/forum/attachmen...2&d=1305794840

Text googletranslated.
Link http://www.sukhoi.ru/forum/showthrea...=1#post1622955

Runs on Repka #3 now. just have a look ))

Flashman 05-20-2011 07:36 AM

Im having a bit of trouble with the command to load a new submission, and for it to load repeatedly. Here is the particular bit of script (pinched from an earlier Ataros script):

PHP Code:

    public override void OnTickGame()
    {

            if (
Time.tickCounter() % 216000 == 27000
            {
                
                
GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/RaBv7/bomberred1_0.mis");
                
GamePlay.gpHUDLogCenter("Intel: British Bomber Formation, E13 at 4000 metres heading SE"); 
            } 


its this part that doesn't seem to work:
if (Time.tickCounter() % 216000 == 27000)

As i understand it this means that every 216000 tick (120 mins) the action should happen (spawns bombers and shows a message), but it is postponed for 27000 ticks (15 mins).

However when I run the mission what happens is after 15 minutes the bombers spawn and the message shows, but it never happens again. I have checked through the logs of various runs of this mission and it is always the same, it only runs once.

Am i doing something wrong, or am I mistunderstanding the settings? What I want to happen is this:

Server starts>at 15 mins-mission and message loads>2hrs after first mission loads (i.e. 2-15 server time)-mission reloads>2 hours later mission loads again... and so on as long as the main mission runs.

ANy help appreciated!

klem 05-20-2011 07:44 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 284685)
Well, I've been messing around with changing spawn points for a while ..........

Hi TheEnlightenedFlorist

I'm pretty new to this but I see in your code you are playing with Spawn points. I see you creating new Mission markers (front line markers) but only destroying BirthPlaces, not creating them. I want to create a new BirthPlace, a Stuka Unit and waypoints including a shipping attack to an existing mission.

All this stems from the fact that I can't seem to set a delayed start time for a second sortie in FMB, I can't even see a start time for it in the .mis file, just the overall mission start time.

Ataros has suggested loading a second FMB mission at the appropriate time but I don't see how I can tie that to an existing mission i.e. an existing Convoy route that receives a second attack later on. It seems I would have to show the convoy route in the new mission to include the Attack and that would duplicate the one in the first misson.

Do you know the code for creating a new BirthpPlace and a Sortie in an existing mission?

Thanks

TheEnlightenedFlorist 05-20-2011 08:12 AM

Quote:

Originally Posted by klem (Post 285981)
Ataros has suggested loading a second FMB mission at the appropriate time but I don't see how I can tie that to an existing mission i.e. an existing Convoy route that receives a second attack later on. It seems I would have to show the convoy route in the new mission to include the Attack and that would duplicate the one in the first misson.

Hi klem, I think the best way to accomplish that would be to use a trigger, action, and a script. You would set a trigger to fire off after how ever many seconds you want, then create an airgroup to attack the convoy. In the airgroup's properties I believe you have to click a check box that says something like "script spawn only".

After that, create an action that will spawn the airgroup you just created. You could even make the action spawn the original airgroup if you want the second attack force to be exactly the same as the first. Just remember to uncheck "script spawn only" so that the airgroup spawns at the start of the mission like normal.

The script will look like this:

Code:

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

public class Mission : AMission
{
public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        //call base classes OnTrigger method.
        base.OnTrigger(missionNumber, shortName, active);

        //if the trigger that was called is the trigger that we're looking for
        if (shortName.Equals("attackConvoyDelay") && active)
        {
            AiAction action = GamePlay.gpGetAction("attackConvoy"));
            if (action != null)
                action.Do();

        }
}

So if you put this code into the mission's script file, it will trigger your action whenever your trigger... triggers.

Note that I've named the trigger "attackConvoyDelay" and the action "attackConvoy". You can change them to whatever you want, just make sure they are the same in both the mission and the script.

I hope this helps. :grin:

klem 05-20-2011 09:57 AM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 285993)
Hi klem, I think the best way to accomplish that would be to use a trigger, action, and a script..................

Thanks! I think I even understand that. Simpler than I expected :)

I've set up the Trigger, Action and Script, just got to add the rest of the waypoints. I'll finish it tonight and try it out.

Cheers

SYN_Flashman 05-20-2011 10:16 AM

I have just had a thought about scripts that start submissions.... can the submissions themselves have scripts? I think they can: when first testing the submission script i accidentally left a script in one of the submissions and it took ages for me to work out what the hell was going on!

Im at work so I can't test this but here is an idea to allow a mission to repeat every 2 hours or so. A few posts up I related how im having trouble doing this with the repeat part of the script but an alternative method might be this:

MAIN MISSION SCRIPT: Spawn bombergroup1 submission after 15 mins server time. NO repeats

15 mins main server time > bombergroup1 submission starts. It has a script itself which says: Spawn bombergroup 1 after 2 hours (i.e. it starts itself again)

2hr 15 min main server time> bombergroup1 submission starts again...

If this works correctly then so long as the server is running every two hours the bombergroup1 submission will spawn.

the bombergroup1 submission will last approx 90 mins plus however long it takes to despawn the landed/crashed planes (using Atatos et als script..which works well!). In other words it should finish and the aircraft despawn BEFORE it starts again.

Questions:

1) has anyone tried this? (I will later... damn I hate work!!)

2) when the submission starts, does it start its own tickcount from its creation, or does it 'read' the master mission tick count?

This is important because if it starts its own tickcount then the second time the bomber group spawns it will be 2 hours after the first. If however it uses the master mission tickcount it might start after 2 hours server time, but this is only 1 hr 45 after the first submission starts. This might mean that the next subsequent submission will not start at all.

3) Am i making any sense whatsoever?

PS I know that the tickcount isn't truly accurate with regards to time, but its close enough for my needs.

ZaltysZ 05-20-2011 10:26 AM

Quote:

Originally Posted by SYN_Flashman (Post 286039)
1) has anyone tried this? (I will later... damn I hate work!!)

Yes.

Quote:

Originally Posted by SYN_Flashman (Post 286039)
2) when the submission starts, does it start its own tickcount from its creation, or does it 'read' the master mission tick count?

I am at work too, so not sure, but I think Time comes from Battle and not from Mission. Basically Battle has its own OnTickGame() which iterates through all missions and calls their OnTickGame().


Quote:

Originally Posted by SYN_Flashman (Post 286039)
I3) Am i making any sense whatsoever?

Depends on what you want to do. :)

Ataros 05-20-2011 12:18 PM

Quote:

Originally Posted by Flashman (Post 285979)
its this part that doesn't seem to work:
if (Time.tickCounter() % 216000 == 27000)

Try reducing timings for testing purposes setting e.g. 3 min repeat 1 min delay and see what happens.

SYN_Flashman 05-20-2011 12:31 PM

Quote:

Originally Posted by Ataros (Post 286098)
Try reducing timings for testing purposes setting e.g. 3 min repeat 1 min delay and see what happens.

Should have mentioned this earlier.... I did test it with lower fihures and it worked.

probably should have mentioned that...

Ataros 05-20-2011 12:42 PM

Than it should work with bigger figures if you set the 1st figure greater than the 2nd in all cases. Try showing the complete code maybe someone finds a mistake in another part that influences this part. It helped me 2 times at least.

klem 05-21-2011 07:38 AM

I am using the following script to send an immediate message to the player when he enters the cockpit (picked up earlier from this thread):

Quote:

//SEND MESSAGE TO PLAYER WHEN THEY ENTER THE COCKPIT

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},"Get Organised! Attack briefed targets. Get escorts where possible!"); }
else
{ GamePlay.gpHUDLogCenter(new Player[] { player }, "Get Organised! Watch for Radar Controller information, plan your tactics and meet the enemy! Provide escort for bombers where possible."); }
break;
case 2:
if (aircraft.Type() == AircraftType.Bomber)
{ GamePlay.gpHUDLogCenter(new Player[] { player }, "Get Organised! Attack briefed targets. Get escorts where possible!"); }
else
{ GamePlay.gpHUDLogCenter(new Player[] { player }, "Get Organised! Escort our Bombers or locate and engage enemy fighters in Frei Jagd"); }
break;
}
}
}
Will all players see that or only the new player? If all will see it and I only want the new player to see it do I fit in something like the following?......

if (aircraft.Name (). Equals (GamePlay.gpPlayer (). Place (). Name ()))

edit:
And sorry to be so dumb but I want to get a carriage return/line feed into the longer messages. I tried:
{ GamePlay.gpHUDLogCenter(new Player[] { player }, "Get Organised! Watch for Radar Controller information. \r\n Plan your tactics and meet the enemy! Provide escort for bombers where possible."); }
but it doesn't like it. Any ideas?

Ataros 05-21-2011 10:34 AM

I think you should add Divebomber type to this script as stated here
http://forum.1cpublishing.eu/showpos...1&postcount=63

Can not answer other questions.

klem 05-21-2011 03:06 PM

Quote:

Originally Posted by Ataros (Post 286756)
I think you should add Divebomber type to this script as stated here
http://forum.1cpublishing.eu/showpos...1&postcount=63

Can not answer other questions.

Thanks, I have done that :)

Flashman 05-23-2011 06:12 PM

Im trying different things with these scripts by picking through other peoples. I have been trying various methods to ensure missions repeat, though so far they only repeat once for some reason.

Anyway instead of using the tick counter i have been looking at the init time settings people have been using. If i understand it correctly this allows a certaqin number of seconds to pass before carrying out whatever command you set.

This is a test script I am having problems with:

PHP Code:

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

public class 
Mission AMission
{
     public 
override void OnTickGame() 
    {
     
double initTime 0.0;

      
Timeout(initTime += 60, () =>
    
            {    
GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/Channelv1/BM2/sb1d.mis");    
                
GamePlay.gpHUDLogCenter("Intel: Stuka raid 1XXX inbound at Angels 13, heading W"); 
            });

        }


The purpose of the script is to run this mission (sb1d) 60 seconds after the script starts. It also has to only run the mission once. In this case the mission consists of a single AI stuka spawning, flying and then landing. Like I say, a simple test mission.

However when I test the mission, endless stukas spawn and blow each other up, in other words far more than 1!!!!

I have no idea about scripts, I have been picking bits out of other peoples, inserting them, hitting 'compile' and then testing the effects in game. I would be grateful if anyone can have a look and see where I am going wrong.

ZaltysZ 05-23-2011 07:09 PM

Flashman,

OnTickGame() is called 30 times in second and every second, so your script 30 times in second schedules a mission loading, and repeats that endlessly. You are abusing your computer :)

Put this into Init(), not in OnTickGame().

Flashman 05-23-2011 08:03 PM

Quote:

Originally Posted by ZaltysZ (Post 287844)
Flashman,

OnTickGame() is called 30 times in second and every second, so your script 30 times in second schedules a mission loading, and repeats that endlessly. You are abusing your computer :)

Put this into Init(), not in OnTickGame().


Hi Zaltys,

Thanks for your help, however please excuse my ignorance. I have tried putting Init() in carious places but I can't work it out. ANy chance you can edit my previous file and put it in the correct place so I can see how it should work? I really have no idea what im doing......

Thanks

ZaltysZ 05-23-2011 08:14 PM

PHP Code:

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

public class 
Mission AMission
{
    public 
override void Init(maddox.game.ABattle battleint missionNumber)
    {
        
base.Init(battle,missionNumber);
           
Timeout(60, () =>
    
            {    
GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/Channelv1/BM2/sb1d.mis");    
                
GamePlay.gpHUDLogCenter("Intel: Stuka raid 1XXX inbound at Angels 13, heading W"); 
            });

        }


If you forget base.Init(battle,missionNumber); in Init(), script won't work.

Flashman 05-23-2011 08:22 PM

Quote:

Originally Posted by ZaltysZ (Post 287869)
PHP Code:

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

public class 
Mission AMission
{
    public 
override void Init(maddox.game.ABattle battleint missionNumber)
    {
        
base.Init(battle,missionNumber);
           
Timeout(60, () =>
    
            {    
GamePlay.gpPostMissionLoad("missions/Multi/Dogfight/Channelv1/BM2/sb1d.mis");    
                
GamePlay.gpHUDLogCenter("Intel: Stuka raid 1XXX inbound at Angels 13, heading W"); 
            });

        }


If you forget base.Init(battle,missionNumber); in Init(), script won't work.

Thanks, that now works as I had hoped!

I had worked out I was missing the (battle, mission....) part but it still didn't work. it was the base.init part that made it function correctly, and I wouldn't have a clue about that.

Cheers!

klem 05-24-2011 07:20 AM

Quote:

Originally Posted by Ataros (Post 273522)
This sample script made for fun disables player controls. Maybe someone can use it to disable AI controls for say 10 minutes before destroying AI

Code:

using System;
 using maddox.game;
 using maddox.game.world;

    public class Mission: maddox.game.AMission
    {
          / / Override the method that is invoked when some of the planes will take off ...
        public override void OnAircraftTookOff (int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftTookOff (missionNumber, shortName, aircraft); / / call the base method (you never know ...)
            if (GamePlay.gpPlayer ()! = null) / / check if we have a player.
            {
                if (GamePlay.gpPlayer (). Place ()! = null) / / check that the player is sitting somewhere and not hanging out on the rag.
                {
                    if (aircraft.Name (). Equals (GamePlay.gpPlayer (). Place (). Name ())) / / if the plane took off - a player, then ...
                    {
                        aircraft.hitNamed (part.NamedDamageTypes.ControlsElevatorDisabled); / / ... disables  elevators ...
                        aircraft.hitNamed (part.NamedDamageTypes.ControlsAileronsDisabled); / / ...  aileron ...
                        aircraft.hitNamed (part.NamedDamageTypes.ControlsRudderDisabled); / / ...  rudder.
                                                / / Have a nice flight!
                    }
                }
            }
        }     
    }

More scripts here http://translate.google.com/translat...hp%3Ft%3D68369

Can anyone see what's wrong with the following? I get the first test message at about +45 seconds while still in the hangar (engine on or engine off), repeated every 20 seconds (which is strange) until about mission start +3mins but I never get the second test message or the messages that follow in the "if" statement:


//SEND MESSAGE TO PLAYER WHEN THEY HAVE TAKEN OFF

public override void OnAircraftTookOff(int missionNumber, string shortName, AiAircraft aircraft)
{
base.OnAircraftTookOff(missionNumber, shortName, aircraft);

GamePlay.gpHUDLogCenter("Takeoff messages start."); //Test/debug Message

if (aircraft.Name() == GamePlay.gpPlayer().Place().Name()) // if the plane took off - a player, then ...
{

GamePlay.gpHUDLogCenter("Switch section reached"); //Test/debug Message

switch (aircraft.Army())
{
case 1:
if ((aircraft.Type() == AircraftType.Bomber) || (aircraft.Type() == AircraftType.DiveBomber)) // if Bomber or Divebomber
{ GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Remember, Get Organised! Attack briefed targets!"); }
else
{ GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Organise Escorts and protect Convoy moving from Beachy Head to the Thames Estuary!"); }
break;
case 2:
if ((aircraft.Type() == AircraftType.Bomber) || (aircraft.Type() == AircraftType.DiveBomber)) // if Bomber or Divebomber
{ GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Remember, Get Organised and attack briefed Targets!"); }
else
{ GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Remember, Get Organised and protect our bombers by Escort or Frei Jagd!"); }
break;
}

}

} //end public override void OnAircraftTookOff

Iku_es 05-24-2011 11:08 AM

Hi,

I have never tried scripting for Clod, but as a C# programer, I'm going to make an educated guess:

Try changing this line:

if (aircraft.Name() == GamePlay.gpPlayer().Place().Name() )

for this one:

if ( aircraft.Name().Equals(GamePlay.gpPlayer().Place().Name()) )

I'm not sure of this because I don't know the types of the objects involved in the comparison (strings?), but try it anyway.

(Check this for more info about why: C# Value Type vs Reference Type)

Also you should check that aircraft is not null, and that GamePlay.gpPlayer().Place() is not null, for security reasons in order to avoid NullReference exceptions.

ZaltysZ 05-24-2011 01:18 PM

klem,

OnAircraftTookOff(() does not currently work for planes spawned at BirthPlaces. It should work for FMB planes with waypoints. I guess, you get first message showed because you have AI taking off.

ZaltysZ 05-24-2011 01:26 PM

Instead of;

Code:

if (aircraft.Name() == GamePlay.gpPlayer().Place().Name())
try

Code:

if (aircraft == GamePlay.gpPlayer().Place())
By the way, GamePlay.gpPlayer() returns player of offline mission. This won't return a client player in MP, so if you are doing MP mission, this won't work.

klem 05-24-2011 02:45 PM

Quote:

Originally Posted by ZaltysZ (Post 288151)
Instead of;

Code:

if (aircraft.Name() == GamePlay.gpPlayer().Place().Name())
try

Code:

if (aircraft == GamePlay.gpPlayer().Place())
By the way, GamePlay.gpPlayer() returns player of offline mission. This won't return a client player in MP, so if you are doing MP mission, this won't work.

Thanks guys.

It was for MP and for a BirthPlace so a double fail :(

btw I had it report aircraft.Name() and GamePlay.gpPlayer().Place().Name() and they were the same string so 'If == ' should have worked ok.

klem 05-24-2011 02:56 PM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 285993)
Hi klem, I think the best way to accomplish that would be to use a trigger, action, and a script..........................

The script will look like this:

Code:

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

public class Mission : AMission
{
public override void OnTrigger(int missionNumber, string shortName, bool active)
    {
        //call base classes OnTrigger method.
        base.OnTrigger(missionNumber, shortName, active);

        //if the trigger that was called is the trigger that we're looking for
        if (shortName.Equals("attackConvoyDelay") && active)
        {
            AiAction action = GamePlay.gpGetAction("attackConvoy"));
            if (action != null)
                action.Do();

        }
}

So if you put this code into the mission's script file, it will trigger your action whenever your trigger... triggers.

Note that I've named the trigger "attackConvoyDelay" and the action "attackConvoy". You can change them to whatever you want, just make sure they are the same in both the mission and the script.

I hope this helps. :grin:

Thought I'd report back on this, I eventually got the following to work:

public override void OnTrigger(int missionNumber, string shortName, bool active)

{
//call base classes OnTrigger method.
base.OnTrigger(missionNumber, shortName, active);
GamePlay.gpHUDLogCenter("shortname = " + shortName);
//if the trigger that was called is the trigger that we're looking for
if (shortName.Equals("AttackConvoy2Delay1"))
{
AiAction action = GamePlay.gpGetAction("AttackConvoy2_1") ;
if (action != null)
{ action.Do(); }
}


}

The '&& active' didn't work because:
1. It seems it should be + not &&
2. You can see I tested for the shortname and of course ("AttackConvoy2Delay1" + active) isn't equal to "AttackConvoy2Delay1". I don't know what 'active' comes back as but it would make the strings unequal.

Also, I put { } around the if(action != null) output as { action.Do(); } although that may not havebeen necessary.

Anyway it works !

Thanks for the help TheEnlightenedFlorist.

ZaltysZ 05-24-2011 03:09 PM

"active" is boolean (logical true or false). You should check "active" to see if trigger is active.

Code:

if (shortName.Equals("attackConvoyDelay") && active)
means: if trigger name is "attackConvoyDelay" AND (&&) this trigger is active, then do something...

klem 05-24-2011 03:54 PM

Aaahh! Got it. Thanks

Ataros 05-24-2011 07:41 PM

Quote:

Originally Posted by TheEnlightenedFlorist (Post 285151)

This code will loop through all BirthPlaces and print a message to the screen if a BirthPlace is on the opposite side of the front line.

Code:

foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
        {
            if (GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y) != bp.Army())
                GamePlay.gpHUDLogCenter("Front and BirthPlace do not match!");
        }

I'm having fun. :)

Getting back to moving frontline.
Does GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y) work at any point of map or only at frontline/border?

Where can I see the complete list of such commands/functions like GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y)? Should I add some game files to my project in Visual Studio? Till now I only opened separate .cs files with it.

TheEnlightenedFlorist 05-24-2011 11:18 PM

Quote:

Originally Posted by Ataros (Post 288356)
Getting back to moving frontline.
Does GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y) work at any point of map or only at frontline/border?

Where can I see the complete list of such commands/functions like GamePlay.gpFrontArmy(bp.Pos().x, bp.Pos().y)? Should I add some game files to my project in Visual Studio? Till now I only opened separate .cs files with it.

Yes, it should work for any point on the map.

Visual Studio will let you see all of the methods in roundabout way. Try this:

1. File >> New >> Project Type in a name and solution name at the bottom. Don't worry about what kind of project you create.

2. On the right side under "Solution Explorer", right click on "References", "Add Reference..."

3. Click on the "Browse" tab, navigate to "Steam/steamapps/common/il-2 sturmovik cliffs of dover/parts/core"

4. Go through each .dll file in that list and try to add it. Some will give you an error, just skip those.

After you've added all the .dll files, right click on the name of your project and do "Add Existing Item". Find one of your script files and add it. Now Visual Studio will show you all the possible methods as you're typing your code. You can also go to View >> Object Browser and have a look in there.

Important: When you import an existing item, Visual Studio makes a copy of the file so any changes you make won't be reflected in the original file, you'll have to copy the new one over it. If anybody knows how to change this, I'd be quite grateful.

Ataros 05-25-2011 07:34 AM

Thanks a lot for detailed explanation.

BTW did you see the scripting in this mission from the devs http://forum.1cpublishing.eu/showpos...&postcount=133

I was reading it yesterday and it just blows my mind away. There are some great pieces everyone should use:

- airfield capture with removal of old arty
- generating triggers names with variables (string str = "changeArmy" + i.ToString() + "_" + (j).ToString();)
- generating waypoints for bombers to attack the most close ground target
- scoring system
etc.

I'll try to convert this mission to the Channel map when I have time. Probably will need a lot of help on C# ))

Devs confirmed that there is a bug not allowing to use captured airfields before switching sides. They are working on it.

TheEnlightenedFlorist 05-25-2011 07:51 AM

Quote:

Originally Posted by Ataros (Post 288595)
Devs confirmed that there is a bug not allowing to use captured airfields before switching sides. They are working on it.

Cool. All of this would be in vain otherwise.:grin:

I've only glanced at that mission, but I've already learned a few things that will make things easier.

klem 05-25-2011 07:57 AM

I'm having trouble giving messages to a particular side under OnTickGame because I don't know how to find out which side I am on (" 'aircraft' is not valid in this context"). Any ideas please?

Code:

public override void OnTickGame()

      {

          if (Time.tickCounter() % 115200 == 1980) // Testing, reduced to 1 min. 1980 = 60secs delay.
          {
                GamePlay.gpHUDLogCenter("1 minute Timetick message.");
              //issue message after further 30 seconds (test)
                double initTime = 0.0;
                Timeout(initTime += 30, () =>
                    if (aircraft != null)    //error the name aircraft does not exist in the current context
                          {
                          switch (aircraft.Army())                          {               
                                case 1:
                              { GamePlay.gpHUDLogCenter("Red side message."); }
                                break;
                                case 2:
                              { GamePlay.gpHUDLogCenter("Blue side message"); }             
                            break;
                              }
                    });
          }

      }


hc_wolf 06-18-2011 04:23 AM

I converted the Dynamic campaign onto the Channel map. Works great.
 
I am trying to build a Falcon 4 type game where Germans advance towards cahnnel and English must drive them back.

SNAFU 06-21-2011 12:48 PM

Hi all, and sorry Klem, I can´t help you...:(

I started now with my attempt to get familar with scripting and C#... :-P:rolleyes:

I read through this thread a several times and copied some samples of the outlined scripts.

The problem at hand now, is that I want to include a script in the submissions, which will be loaded into a main, basic-map. This submission script shall contain

Sec 1- the trigger messages,

Sec 2-the instruction messages for new players and players which just took off (WIP:Message shall only be shown, if trigger is not activated yet)

Sec 3- a count of trigger states, so very time a victory-trigger is set to true a counter raises the number for the side, which activated the trigger

Sec 4- clean up procedure at a certain time from begin of submission, removing all AI loaded into the basic map with the submission

Following questions appeared now at this stage:

(A) I already found out how to theoretically get the trigger messages running, still have to get it right, how to show the message only if the otherside (red/blue) has not activated their trigger yet.
Is thiss possible by something like this?

if (<Trigger Red won> == active || <Trigger Blue won> == acitve)
<message red won>


(B) How do I get rid off of all the AI loaded on the basic map, when the submission has done its job?

I wanted to try following script sample to remove the AI after an hour into the submission:

//////////////// Section 4: get rid off all AI loaded with submission

//mod-start by SNAFU -> ZIEL: nach 1h AI-Flieger entfernen

public override void OnTickGame()
{
double initTime;

if (Time.tickCounter() % 108000 == 10799) // 108000=1h
{
//mod-end by SNAFU

foreach (int army in GamePlay.gpArmies())
{
foreach (AiAirGroup group in GamePlay.gpAirGroups(army))
{
if (ActorName.MissionNumber(group.Name()).Equals(Miss ionNumber)) /// <- delete line to kill all
{
AiActor[] members = group.GetItems();
for (int i = members.Length - 1; i > -1; i--)
{
(members[i] as AiAircraft).Destroy();
}
}
}
foreach (AiGroundGroup group in GamePlay.gpGroundGroups(army))
{
if (ActorName.MissionNumber(group.Name()).Equals(Miss ionNumber)) /// <- delete line to kill all
{
AiActor[] members = group.GetItems();
for (int i = members.Length - 1; i > -1; i--)
{
(members[i] as AiGroundActor).Destroy();
}
}
}
}
}


(C) I now loaded a briefing message into the basic map, so every player joining and taking off, will be briefed into the actual ongoing submission. The basic map listens to all events introduced with the submissions, ok. But...

If the the submission is over, how does the main script notice the that the submissions states, messages (f.e. the briefing messages) are not valid anymore? Ist that the "puplic override" I see everywhere?

Here the template for the submission script and sorry for all the silly questions: :rolleyes:
Code:

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

public class Mission : AMission

//////////////////////////////////////////////////////////////////////////////////////
///////////Section 1: Trigger messages

///to copy into

/////////////////////////////////////////////////Section 3: Briefing for new players

///WIP                if (<Trigger missions success red/blue> = false) /////WIP: Trigger Condition for Mission red/blue != true

{
        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)                                /////////////Nachricht für neue Spieler
                { GamePlay.gpHUDLogCenter(new Player[] {player},"Red Bomber Task"); }                /////////roter Bomber
                else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Red Fighter Task"); }        ///////////roter Jäger
                break;
            case 2:
                if (aircraft.Type() == AircraftType.Bomber)
                { GamePlay.gpHUDLogCenter(new Player[] { player }, "Blue Bomber Task"); }                ////////////blauer Bomber
                else { GamePlay.gpHUDLogCenter(new Player[] { player }, "Blue Fighter Task"); }            //////////// blauer Jäger
                break;

                }
    }

            public override void OnAircraftTookOff(int missionNumber, string shortName, AiAircraft aircraft)
    {
        base.OnAircraftTookOff(missionNumber, shortName, aircraft);

        if (GamePlay.gpPlayer().Place() != aircraft)
            return;
       
        switch (aircraft.Army())
                {
            case 1:
              if (aircraft.Type() == AircraftType.Bomber)                                                        /////////////Nachricht für neue Spieler
                { GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Red Bomber Task"); }                        /////////roter Bomber
                else { GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Red Fighter Task"); }                ///////////roter Jäger
              break;
            case 2:
                if ((aircraft.Type() == AircraftType.Bomber) || (aircraft.Type() == AircraftType.DiveBomber))
              { GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Blue Bomber Task"); }                      ////////////blauer Bomber
                else { GamePlay.gpHUDLogCenter(new Player[] { GamePlay.gpPlayer() }, "Red Bomber Task"); }                //////////// blauer Jäger
              break;

                }
    }

///WIP }

//////////////////////////////////////////////////////////////////////////////////////
//////////////// Section 3: Trigger count for overall win condition


// still no idea


//////////////////////////////////////////////////////////////////////////////////////
//////////////// Section 4: get rid off all AI loaded with submission

//mod-start by SNAFU -> ZIEL: nach 1h AI-Flieger entfernen

public override void OnTickGame()
{
  double initTime;   

    if (Time.tickCounter() % 108000 == 10799) // 108000=1h
  {
//mod-end by SNAFU

foreach (int army in GamePlay.gpArmies())
            {
                foreach (AiAirGroup group in GamePlay.gpAirGroups(army))
                {
                    if (ActorName.MissionNumber(group.Name()).Equals(MissionNumber)) /// <- delete line to kill all
                    {
                        AiActor[] members = group.GetItems();
                        for (int i = members.Length - 1; i > -1; i--)
                        {
                            (members[i] as AiAircraft).Destroy();
                        }
                    }
                }
                foreach (AiGroundGroup group in GamePlay.gpGroundGroups(army))
                {
                    if (ActorName.MissionNumber(group.Name()).Equals(MissionNumber)) /// <- delete line to kill all
                    {
                        AiActor[] members = group.GetItems();
                        for (int i = members.Length - 1; i > -1; i--)
                        {
                            (members[i] as AiGroundActor).Destroy();
                        }
                    }
                }
            }
}



All times are GMT. The time now is 07:14 PM.

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