Create an account


Creating Birthplaces (spawnpoints) in CloD scripting via code, and various solutions

#1
In IL2 Cliffs of Dover FMB scripting, it is possible to create a spawnpoint on the fly and load it mid-mission.

A spawn point is thing that makes and airport "active" - ie, so that you can come in at that airport.  You can also create airspawns.  And, you can delete spawnpoints (Birthplaces) making a previously active airport inactive.

However, in making new Birthplaces there are a few nasty tricks and pitfalls.  The ones i know about:
  • First: Apparently, you can't use decimal points in specifying the location.

    So for example #1 is OK but #2 is NOT OK:

    #1:
    Code:
      Amien_rest_39 2 321978 101321 0 1 1 1 . . .

    #2:
    Code:
      Amien_rest_39 2 321978.2 101321.7 0 1 1 1 . . .

    This is odd because decimal points are allowed in specifying every other position in CloD .mis files. But not here!

  • Second: There are pretty tight restrictions on the type of name you can use. Safest is to use a fairly short name, no spaces (use the underline character instead) and no characters other than letters & numbers.  Second safest, you can try included spaces and special characters like , () [] etc, but keep the length of the name to 25 characters.  You will see that if you include spaces in the name, CloD will automatically enclose that name in quotation marks in the .mis file it creates.


Example function usage:

Code:
                ISectionFile f = GamePlay.gpCreateSectionFile();                                string bname = "My_Favorite_Birthplace"; //apparently birthplace names can't be too long? And you might need to be careful of spaces and special characters?               
                f = CreateBirthPlace(f, bname,125000, 257000, 1000, 1); //create the ISectionFile with the birthplace info and located at x,y (125000,257000) and altitude 1000 meters.  To create a spawnpoint at an airport, specify a location within the airport boundaries (not sure exactly how close it must be?) and altitude 0.               
                GamePlay.gpPostMissionLoad(f);           
                    
                f.save(@"MYFAVORITEDIRECTORYPATH/" + bname + ".mis"); //save the resulting file to disk--very helpful for troubleshooting

Utility function to create the needed sectionfile and pass it back to you:

Code:
//Based on code by Kodiak, our hero
    //http://forum.1cpublishing.eu/showpost.php?p=438212&postcount=40
    //
    public static ISectionFile CreateBirthPlace(ISectionFile f, string name,double x, double y, double z, int army, int maxplanes = 1, bool setonpark = true, bool isparachute = true, string _country = "", string _hierarchy = "", string _regiment = "")
    {

        //ISectionFile f = GamePlay.gpCreateSectionFile();
        string sect;
        string key;
        string value;

        sect = "BirthPlace";

        key = "BirthPlace" + clc_random.Next(1000, 9999).ToString("F0");

        if (name != null & name.Length > 0) key = name.Trim();

        int setOnPark = 0;

        if (setonpark)
            setOnPark = 1;

        int isParachute = 0;

        if (isparachute)
            isParachute = 1;


        string country = ".";

        if (_country != null && _country.Length > 0)
            country = _country;


        string hierarchy = ".";

        if (_hierarchy != null && _hierarchy.Length > 0)
            hierarchy = _hierarchy;

        string regiment = ".";

        if (_regiment != null && _regiment.Length > 0)
            regiment = _regiment;


        //And so apparently the x,y,z coordinates here cannot have any decimal points.
        //Despite the fact the they are OK in EVERY other similar place.  Arrggghhh.
        value = army.ToString(CultureInfo.InvariantCulture) + " " + x.ToString("F0") + " "
            + y.ToString("F0") + " " + z.ToString("F0") + " "
            + maxplanes.ToString("F0") + " " + setOnPark.ToString("F0") + " "
            + isParachute.ToString("F0") + " " + country + " " + hierarchy + " " + regiment;

        Console.WriteLine("Creating Birthplace: " + value);

        f.add(sect, key, value);

        sect = "BirthPlace0";
        Dictionary<string, bool> planeSet = FullAircraftList[army];
        if (planeSet.Count > 0)
            foreach (string plane in planeSet.Keys)
            {
                if (!planeSet[plane]) continue;
                key = plane;
                value = "";
                f.add(sect, key, value);
            }

        return f;
    }

That could be improved by enforcing the restrictions on the name of the birthplace, as described above. 

Also--I'm not sure what happens if you enter a BirthPlace name that duplicates an existing Birthplace (or existing AiAirport name already existing in CloD).  Generally that causes problems but I'm not sure if it would replace the previous BirthPlace with that name, or just give an error, or just silently reject the new BirthPlace.

But in general, avoid duplicating already-existing names.

Example of how to step through all existing Birthplaces in a mission:

Code:
foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
            {
                if (bp != null & bp.Pos().distance(ref pos) <= ap.FieldR())
                {
                    if (bp.Name() != null && !(bp.Name().ToUpper().Contains("BIRTHPLACE"))) apName = bp.Name();  //This is just an example of something you could do with each birthplace - in this case, figure out if it is close to something
                    break;
                }
            }

Example of how to destroy/remove a Birthplace associated with an airport:

Code:
AiAirport ap = $$$$something$$$$$ //you have to get the airport you want to work with here, somehow.
        //disable any birthplace associated with/near this airport - thus, no spawning here
        foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
        {
            Point3d bp_pos = bp.Pos();
            if (ap.Pos().distance(ref bp_pos) <= ap.FieldR()) bp.destroy();//Removes the spawnpoint associated with that airport (ie, if located within the field radius of the airport)
        }

Example of how to step through every airport in the game--in this case to find the nearest airport to a certain point:

Code:
//nearest airport to a point
    //army=0 is neutral, meaning found airports of any army
    //otherwise, find only airports matching that army
    public static AiAirport nearestAirport(this IGamePlay GamePlay, Point3d location, int army = 0)
    {
        AiAirport NearestAirfield = null;
        AiAirport[] airports = GamePlay.gpAirports();
        Point3d StartPos = location;

        if (airports != null)
        {
            foreach (AiAirport airport in airports)
            {
                AiActor a = airport as AiActor;
                if (army != 0 && GamePlay.gpFrontArmy(a.Pos().x, a.Pos().y) != army) continue;
                if (NearestAirfield != null)
                {
                    if (NearestAirfield.Pos().distanceSquared(ref StartPos) > airport.Pos().distanceSquared(ref StartPos))
                        NearestAirfield = airport;
                }
                else NearestAirfield = airport;
            }
        }
        return NearestAirfield;
    }
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)