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

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

Reply
 
Thread Tools Display Modes
  #1  
Old 05-17-2011, 06:04 PM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default

Quote:
Originally Posted by FG28_Kodiak View Post
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(); }
            }
                    );
    }
    ****/
}
Reply With Quote
  #2  
Old 05-17-2011, 07:01 PM
C_G C_G is offline
Approved Member
 
Join Date: Nov 2008
Posts: 95
Default

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
Great stuff!
I may one day even move myself to borrow a C# for Dummies!
Reply With Quote
  #3  
Old 05-18-2011, 04:11 AM
TheEnlightenedFlorist TheEnlightenedFlorist is offline
Approved Member
 
Join Date: May 2011
Location: SLC, Utah, USA
Posts: 143
Default

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();
    }
}
Attached Files
File Type: zip triggerTest.zip (2.6 KB, 6 views)
Reply With Quote
  #4  
Old 05-18-2011, 05:38 AM
ZaltysZ's Avatar
ZaltysZ ZaltysZ is offline
Approved Member
 
Join Date: Sep 2008
Location: Lithuania
Posts: 426
Default

Quote:
Originally Posted by TheEnlightenedFlorist View Post
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 View Post
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.

Last edited by ZaltysZ; 05-18-2011 at 06:30 AM.
Reply With Quote
  #5  
Old 05-18-2011, 09:11 AM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default

Quote:
Originally Posted by TheEnlightenedFlorist View Post
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?

Last edited by Ataros; 05-18-2011 at 09:30 AM.
Reply With Quote
  #6  
Old 05-18-2011, 10:12 AM
TheEnlightenedFlorist TheEnlightenedFlorist is offline
Approved Member
 
Join Date: May 2011
Location: SLC, Utah, USA
Posts: 143
Default

Quote:
Originally Posted by Ataros View Post
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 View Post
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.
Reply With Quote
  #7  
Old 05-18-2011, 10:22 AM
TheEnlightenedFlorist TheEnlightenedFlorist is offline
Approved Member
 
Join Date: May 2011
Location: SLC, Utah, USA
Posts: 143
Default

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.
Reply With Quote
  #8  
Old 05-18-2011, 10:34 AM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default

Quote:
Originally Posted by TheEnlightenedFlorist View Post
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 View Post
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 View Post
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 View Post
It's 4:30 in the morning here!


Where are you located?

Last edited by Ataros; 05-18-2011 at 10:40 AM.
Reply With Quote
  #9  
Old 05-18-2011, 11:14 AM
Ataros Ataros is offline
Approved Member
 
Join Date: Jun 2010
Location: USSR
Posts: 2,439
Default

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.
Attached Files
File Type: zip BoF2.zip (16.7 KB, 12 views)
Reply With Quote
  #10  
Old 05-18-2011, 11:02 PM
TheEnlightenedFlorist TheEnlightenedFlorist is offline
Approved Member
 
Join Date: May 2011
Location: SLC, Utah, USA
Posts: 143
Default

Quote:
Originally Posted by Ataros View Post
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 View Post
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.

Quote:
Originally Posted by Ataros View Post
Where are you located?
Salt Lake City, Utah, USA. Opposite side of the planet.
Reply With Quote
Reply

Thread Tools
Display Modes

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

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

Forum Jump


All times are GMT. The time now is 09:16 PM.


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