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)
-   -   how to trigger the big yellow messages? (http://forum.fulqrumpublishing.com/showthread.php?t=32713)

FG28_Kodiak 06-28-2012 01:46 PM

SpawnPlace Managment
 
1 Attachment(s)
So new Version. Now it's possible to limit every PlaneType seperately, it's now possible to transfer one Airplane from one Birthplace to an other (the other must be specify in the Birthcontrol). It's also possible to resupply the places.

Version to test:
Code:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using maddox.GP;
using maddox.game;
using maddox.game.world;
using part;


public class Mission : AMission
{
    private bool battleEnded;

    internal static class ActorObservation
    {
        internal class ActorDetail
        {
            public AiActor Actor { get; set; }
            private DateTime TimeStamp;
            private Point3d LastPosition;
            public bool Started { get; private set; }
            public bool Destroyed { get; private set; }
            public bool IsParachuted { get; set; }

            public ActorDetail(AiActor actor)
            {
                Actor = actor;
                TimeStamp = DateTime.Now;
                LastPosition = actor.Pos();
            }


            public TimeSpan CheckActor()
            {
                TimeSpan positionNotChangedSince = new TimeSpan();
                Point3d CurrentPos = Actor.Pos();


                if (Actor is AiAircraft)
                    if ((Actor as AiAircraft).getParameter(ParameterTypes.Z_AltitudeAGL, -1) > 20)
                        // Plane counts as started if Altitude over Ground is larger than 20m
                        Started = true;

                // Actor does not change Position
                if (LastPosition.distance(ref CurrentPos) < 0.5 && Started)
                    positionNotChangedSince = DateTime.Now.Subtract(TimeStamp);
                else
                {
                    LastPosition = CurrentPos;
                    TimeStamp = DateTime.Now;
                }

                return positionNotChangedSince;
            }

            public void Destroy()
            {
                AiCart cart = Actor as AiCart;

                if (cart != null)
                {
                    cart.Destroy();
                    Destroyed = true;
                }
            }
        }

        private static List<ActorDetail> ActorsInGame = new List<ActorDetail>();


        public static void StoreActor(AiActor actor)
        {
            if (actor is AiAircraft)
                ActorsInGame.Add(new ActorDetail(actor));
        }


        public static void ForceActorDestroyNotPosChangeAfter(int seconds)
        {
            ActorsInGame.ForEach(item =>
            {
                if (item.CheckActor().TotalSeconds > seconds)
                    item.Destroy();
            });
            ActorsInGame.RemoveAll(item => item.Destroyed);
        }


        public static void RemoveActor(AiActor actor)
        {
            if (ActorsInGame.Exists(item => item.Actor == actor))
            {
                ActorsInGame.RemoveAll(item => item.Actor == actor);
            }
        }


        public static void MarkAsParachuted(AiActor actor)
        {
            if (ActorsInGame.Exists(item => item.Actor == actor))
                ActorsInGame.Find(item => item.Actor == actor).IsParachuted = true;
        }



        public static bool IsParachuted(AiActor actor)
        {
            if (ActorsInGame.Exists(item => item.Actor == actor))
                return ActorsInGame.Find(item => item.Actor == actor).IsParachuted;

            return false;
        }



        public static List<AiActor> GetStoredActors()
        {
            List<AiActor> actors = new List<AiActor>();

            ActorsInGame.ForEach(item => actors.Add(item.Actor));

            return actors;
        }

    }


    internal class SpawnPlace
    {
        public AiBirthPlace BirthPlace { get; set; }
        public IGamePlay GamePlay { get; set; }
        private bool _isAvalable;
        private bool _transferAllowed;
        private Dictionary<string, int> Store = new Dictionary<string, int>();
        private List<AiAircraft> PlanesInUse = new List<AiAircraft>();

        public SpawnPlace(IGamePlay gamePlay, AiBirthPlace birthPlace, bool transferAllowed, Dictionary<string, int> stores)
        {
            GamePlay = gamePlay;
            BirthPlace = birthPlace;
            _transferAllowed = transferAllowed;
            if (stores != null)
            {
                Store = stores;

                if (stores.Count > 0)
                    _isAvalable = true;
            }
        }

        public int CountAllAvailablePlanes()
        {
            int count = 0;

            foreach (KeyValuePair<string, int> kvp in Store)
                count += kvp.Value;
       
            return count;
        }

        public int NumberOfPlanesInUse()
        {
            return PlanesInUse.Count;
        }

        public void CheckPlaneOut(AiActor actor)
        {
            AiAircraft aircraft = actor as AiAircraft;

            if (aircraft != null)
            {
                if (PlanesInUse.Exists(item => item == aircraft)) return;

                PlanesInUse.Add(aircraft);

                int numberOfPlanes = 0;

                string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");

                if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
                {
                    if (numberOfPlanes > 0)
                    {
                        numberOfPlanes--;
                        Store[storedPlaneName] = numberOfPlanes;
                        ShowStorage();
                    }
                }

                if (numberOfPlanes <= 0)
                {
                    foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                    {
                        if (bp.Name().Equals(BirthPlace.Name()))
                        {
                            bp.destroy();
                        }
                    }

                    ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());

                    if (newBirthPlace != null)
                    {
                        GamePlay.gpPostMissionLoad(newBirthPlace);
                    }
                }
            }
        }


        public void CheckPlaneIn(AiActor actor)
        {
            AiAircraft aircraft = actor as AiAircraft;
            bool recreateBirthplace = false;
            int numberOfPlanes;

            if (aircraft != null)
            {
                if (IsActorDown(actor) && CheckIsHomeBase(actor, 800.0)) // Plane landed on correct Homebase if in 800m Radius from SpawnplaceLocation
                {
                    PlanesInUse.Remove(actor as AiAircraft);

                    string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");
                   
                    if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
                    {
                        if (numberOfPlanes <= 0)
                            recreateBirthplace = true;

                        numberOfPlanes++;
                        Store[storedPlaneName] = numberOfPlanes;
                        ShowStorage();

                    }
                }
                else if (IsActorDown(actor) && CheckBase(actor, 800.0) && _transferAllowed) //Plane is landed on other existing Base
                {
                    BirthControl.RemoveActor(actor); // Remove the actor from other Birthplace

                    GamePlay.gpLogServer(null, "Gelandet auf fremden Platz", null);

                    string storedPlaneName = aircraft.InternalTypeName().Replace("bob:", "");

                    if (Store.TryGetValue(storedPlaneName, out numberOfPlanes))
                    {
                        if (numberOfPlanes <= 0)
                            recreateBirthplace = true;

                        numberOfPlanes++;
                        Store[storedPlaneName] = numberOfPlanes;
                        ShowStorage();

                    }
                    else
                    {
                        Store.Add(storedPlaneName, 1);
                        recreateBirthplace = true;
                        ShowStorage();
                    }
                }
                else PlanesInUse.Remove(actor as AiAircraft); // Plane is lost

                if (recreateBirthplace)
                {
                    foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                        if (bp.Name().Equals(BirthPlace.Name()))
                            bp.destroy();

                    ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());

                    if (newBirthPlace != null)
                        GamePlay.gpPostMissionLoad(newBirthPlace);
                }
            }
        }

        public void RemoveActor(AiActor actor)
        {
            AiAircraft aircraft = actor as AiAircraft;

            if (aircraft != null)
                if (PlanesInUse.Exists(item => item == aircraft))
                    PlanesInUse.Remove(aircraft);
        }



        public void ResupplyAll(int nrOfAdditionalPlanes, int nrOfMaxPlanes)
        {
            List<string> keyList = new List<string>();
            bool recreateBirthplace = false;

            keyList.AddRange(Store.Keys);

            foreach (string st in keyList)
            {
                int value = 0;

                if (Store.TryGetValue(st, out value))
                {
                    if (value <= 0)
                        recreateBirthplace = true;
                    value += nrOfAdditionalPlanes;

                    if (value > nrOfMaxPlanes)
                        value = nrOfMaxPlanes;

                    Store[st] = value;
                }
            }

            if(recreateBirthplace)
            {
                foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                    if (bp.Name().Equals(BirthPlace.Name()))
                        bp.destroy();

                ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());

                if (newBirthPlace != null)
                    GamePlay.gpPostMissionLoad(newBirthPlace);
            }

            ShowStorage();

        }


        public void Resupply(string planeName, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
        {
            int value = 0;
            bool recreateBirthplace = false;

            if (Store.TryGetValue(planeName, out value))
            {
                if (value <= 0)
                    recreateBirthplace = true;

                value += nrOfAdditionalPlanes;

                if(value > nrOfMaxPlanes)
                    value = nrOfMaxPlanes;

                Store[planeName] = value;
            }
            else
            {
                recreateBirthplace = true;
                Store.Add(planeName, nrOfAdditionalPlanes);
            }

            if (recreateBirthplace)
            {
                foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                    if (bp.Name().Equals(BirthPlace.Name()))
                        bp.destroy();

                ISectionFile newBirthPlace = RecreateBirthPlace(BirthPlace, GetAircrafts());

                if (newBirthPlace != null)
                    GamePlay.gpPostMissionLoad(newBirthPlace);
            }

            ShowStorage();
        }


        private bool CheckIsHomeBase(AiActor actor, double maxdistance)
        {
            Point3d actorPos = actor.Pos();

            if (PlanesInUse.Exists(item => item == actor))
            {
                Point3d HomeBasePos = new Point3d(BirthPlace.Pos().x, BirthPlace.Pos().y, 0.0);
                if (HomeBasePos.distance(ref actorPos) < maxdistance)
                    return true;
            }
            return false;
        }

        private bool CheckBase(AiActor actor, double maxdistance)
        {
            Point3d actorPos = actor.Pos();

            Point3d BasePos = new Point3d(BirthPlace.Pos().x, BirthPlace.Pos().y, 0.0);
            if (BasePos.distance(ref actorPos) < maxdistance && actor.Army() == BirthPlace.Army())
                return true;

            return false;
        }

        private string ParsePlaneType(string planeName)
        {

            if (planeName.StartsWith("bob:Aircraft."))
                return planeName.Replace("bob:Aircraft.", "");

            if (planeName.StartsWith("Aircraft."))
                return planeName.Replace("Aircraft.", "");

            return planeName;
        }

        private string[] GetAircrafts()
        {

            List<string> aircrafts = new List<string>();

            foreach (KeyValuePair<string, int> kvp in Store)
            {
                if (kvp.Value > 0)
                {
                    if (!aircrafts.Exists(item => item == kvp.Key))
                    {
                        aircrafts.Add(kvp.Key);
                    }
                }
            }
            return aircrafts.ToArray();
        }

        private bool IsActorDown(AiActor actor)
        {
            AiAircraft aircraft = actor as AiAircraft;
            if (aircraft != null && (aircraft.getParameter(ParameterTypes.Z_AltitudeAGL, -1) <= 2.0
                                                && aircraft.getParameter(ParameterTypes.Z_VelocityTAS, -1) <= 1.0))
                return true;

            return false;
        }

        private ISectionFile RecreateBirthPlace(AiBirthPlace birthPlace, string[] aircraftTypes)
        {
            if (aircraftTypes == null || aircraftTypes.Length == 0)
                return null;

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

            sect = "BirthPlace";

            key = birthPlace.Name();

            int setOnPark = 0;

            if (birthPlace.IsSetOnPark())
                setOnPark = 1;

            int isParachute = 0;

            if (birthPlace.IsParachute())
                isParachute = 1;


            string country = ".";

            if (birthPlace.Country() != null)
                country = birthPlace.Country();


            string hierachy = ".";

            if (birthPlace.Hierarchy() != null)
                hierachy = birthPlace.Hierarchy();

            string regiment = ".";

            if (birthPlace.Regiment() != null)
                regiment = birthPlace.Regiment().name();


            value = " " + birthPlace.Army().ToString(CultureInfo.InvariantCulture) + " " + birthPlace.Pos().x.ToString(CultureInfo.InvariantCulture) + " "
                + birthPlace.Pos().y.ToString(CultureInfo.InvariantCulture) + " " + birthPlace.Pos().z.ToString(CultureInfo.InvariantCulture) + " "
                + birthPlace.MaxPlanes().ToString(CultureInfo.InvariantCulture) + " " + setOnPark.ToString(CultureInfo.InvariantCulture) + " "
                + isParachute.ToString(CultureInfo.InvariantCulture) + " " + country + " " + hierachy + " " + regiment;

            f.add(sect, key, value);

            sect = "BirthPlace0";
            string[] planeSet = aircraftTypes;
            if (planeSet.Length > 0)
                for (int j = 0; j < planeSet.Length; j++)
                {
                    key = planeSet[j];
                    value = "";
                    f.add(sect, key, value);
                }

            return f;
        }

        private void ShowStorage()
        {
            List<Player> players = new List<Player>();

            if (GamePlay.gpPlayer() != null)
                players.Add(GamePlay.gpPlayer());
            if (GamePlay.gpRemotePlayers() != null)
                players.AddRange(GamePlay.gpRemotePlayers());

            players.RemoveAll(item => item.Army() != BirthPlace.Army());

            if (players.Count > 0)
            {
                GamePlay.gpLogServer(players.ToArray(), "Available on Airfield {0}:", new object[] { BirthPlace.Name() });
                foreach (KeyValuePair<string, int> kvp in Store)
                {
                    GamePlay.gpLogServer(players.ToArray(), "{0} {1}", new object[] { kvp.Value, ParsePlaneType(kvp.Key) });
                }
            }
        }
    }


    internal static class BirthControl
    {
        private static List<SpawnPlace> _spawnPlaces = new List<SpawnPlace>();
        public static IGamePlay GamePlay { get; set; }


        public static void Limitations(bool transferAllowed, params KeyValuePair<string, Dictionary<string, int>>[] keyValuePair)
        {
            foreach (KeyValuePair<string, Dictionary<string, int>> kvp in keyValuePair)
            {
                foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                {
                    if (kvp.Key.Equals(bp.Name()))
                        _spawnPlaces.Add(new SpawnPlace(GamePlay, bp, transferAllowed, kvp.Value));
                }
            }
        }


        public static void CheckPlaneOut(AiActor actor)
        {
            if (actor == null) return;

            AiBirthPlace birthPlace = GetNearestBirthplace(actor);

            foreach (SpawnPlace spawnPlace in _spawnPlaces)
            {
                if (spawnPlace.BirthPlace == birthPlace)
                    spawnPlace.CheckPlaneOut(actor);
            }
        }


        public static void CheckPlaneIn(AiActor actor)
        {
            if (actor == null) return;

            AiBirthPlace birthPlace = GetNearestBirthplace(actor);

            foreach (SpawnPlace spawnPlace in _spawnPlaces)
            {
                if (spawnPlace.BirthPlace == birthPlace)
                    spawnPlace.CheckPlaneIn(actor);
            }
        }

        internal static void RemoveActor(AiActor actor)
        {
            foreach (SpawnPlace sp in _spawnPlaces)
                sp.RemoveActor(actor);
        }

        public static int CountAvailablePlanes(int army)
        {
            int count = 0;

            _spawnPlaces.ForEach(item =>
            {
                if (item.BirthPlace != null)
                    if (item.BirthPlace.Army() == army)
                        count += item.CountAllAvailablePlanes();
            });

            return count;
        }


        public static int CountPlanesInUse(int army)
        {
            int count = 0;

            _spawnPlaces.ForEach(item =>
            {
                if (item.BirthPlace != null)
                    if (item.BirthPlace.Army() == army)
                        count += item.NumberOfPlanesInUse();
            });

            return count;
        }


        private static AiBirthPlace GetNearestBirthplace(AiActor actor)
        {
            AiBirthPlace nearestBirthplace = null;

            if (actor == null) return null;

            Point3d pos = actor.Pos();

            if (_spawnPlaces != null)
            {
                foreach (SpawnPlace airport in _spawnPlaces)
                {
                    if (nearestBirthplace != null)
                    {
                        if (nearestBirthplace.Pos().distance(ref pos) > airport.BirthPlace.Pos().distance(ref pos))
                            nearestBirthplace = airport.BirthPlace;
                    }
                    else nearestBirthplace = airport.BirthPlace;
                }
            }
            return nearestBirthplace;
        }


        public static void Resupply(string birthPlace, string planeType, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
        {
            _spawnPlaces.ForEach(item =>
                                    {
                                        if (item.BirthPlace.Name().Equals(birthPlace))
                                            item.Resupply(planeType, nrOfAdditionalPlanes, nrOfMaxPlanes);
                                    });
        }



        public static void Resupply(string birthPlace, int nrOfAdditionalPlanes, int nrOfMaxPlanes)
        {
            _spawnPlaces.ForEach(item =>
            {
                if (item.BirthPlace.Name().Equals(birthPlace))
                    item.ResupplyAll(nrOfAdditionalPlanes, nrOfMaxPlanes);
            });
        }



        public static void ResupplyAll(int nrOfAdditionalPlanes, int nrOfMaxPlanes)
        {
            _spawnPlaces.ForEach(item => item.ResupplyAll(nrOfAdditionalPlanes, nrOfMaxPlanes));
        }

    }


    private bool IsDestroyable(AiActor actor)
    {
        AiCart cart = actor as AiCart;

        if (cart != null)
        {
            //check if a player is present in actor
            for (int i = 0; i < cart.Places(); i++)
                if (cart.Player(i) != null)
                    return false;
        }
        return true;
    }


    private void Destroy(AiActor actor)
    {
        AiCart cart = actor as AiCart;

        if (cart != null)
            cart.Destroy();

        ActorObservation.RemoveActor(actor);
    }


    #region Overrides
    public override void OnBattleStarted()
    {
        base.OnBattleStarted();

        MissionNumberListener = -1;

        BirthControl.GamePlay = GamePlay;

        BirthControl.Limitations(true, new KeyValuePair<string, Dictionary<string, int>>("GermanPlace", new Dictionary<string, int>
                                                                                                      {
                                                                                                          {"Aircraft.Bf-109E-1", 10},
                                                                                                          {"Aircraft.Bf-109E-3", 5},
                                                                                                          {"Aircraft.Bf-109E-4", 5}
                                                                                                      }),
                                new KeyValuePair<string, Dictionary<string, int>>("GermanPlace2", new Dictionary<string, int>
                                                                                                      {
                                                                                                          {"Aircraft.Bf-109E-1", 10},
                                                                                                          {"Aircraft.Bf-109E-3", 5}
                                                                                                      }),
                                new KeyValuePair<string, Dictionary<string, int>>("BritishPlace", new Dictionary<string, int>
                                                                                                      {
                                                                                                          {"Aircraft.SpitfireMkIa", 10},
                                                                                                          {"Aircraft.SpitfireMkIIa", 5},
                                                                                                          {"Aircraft.HurricaneMkI", 20}
                                                                                                      }));
    }


   
    public override void OnPersonMoved(AiPerson person, AiActor fromCart, int fromPlaceIndex)
    {
        base.OnPersonMoved(person, fromCart, fromPlaceIndex);

        if (person.Player() != null)
            if (((person.Cart() == null) && (fromCart is AiAircraft)) && (fromCart as AiAircraft).IsAirborne())
                ActorObservation.MarkAsParachuted(fromCart);
    }


    public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceEnter(player, actor, placeIndex);

        BirthControl.CheckPlaneOut(actor);

        if (player.PlacePrimary() <= 0 && player.PlaceSecondary() == -1)
        {
            if (actor is AiCart)
                ActorObservation.StoreActor(actor);
        }
    }


    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
        base.OnPlaceLeave(player, actor, placeIndex);

        if (IsDestroyable(actor) && !ActorObservation.IsParachuted(actor))
            Destroy(actor);
    }


    public override void OnActorDestroyed(int missionNumber, string shortName, AiActor actor)
    {
        base.OnActorDestroyed(missionNumber, shortName, actor);

        BirthControl.CheckPlaneIn(actor);

        if (actor.Army() == 1 && BirthControl.CountAvailablePlanes(1) == 0 && BirthControl.CountPlanesInUse(1) == 0 && !battleEnded)
        {
            battleEnded = true;
            GamePlay.gpHUDLogCenter(null, "Blue Wins!");
        }
        else if (actor.Army() == 2 && BirthControl.CountAvailablePlanes(2) == 0 && BirthControl.CountPlanesInUse(2) == 0 && !battleEnded)
        {
            battleEnded = true;
            GamePlay.gpHUDLogCenter(null, "Red Wins");
        }
    }


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

       
        if (Time.tickCounter() % 216000 == 215999) // Two hours
        {
            BirthControl.ResupplyAll(4, 10); // All SpawnPlaces get resupply
            //BirthControl.Resupply("GermanPlace", 4, 10); // Resupply only the GermanPlace Spawnplace
            //BirthControl.Resupply("GermanPlace", "Aircraft.Bf-109E-4", 4, 10); // Resupply only the AircraftType Bf109E-4 on GermanPlace
        }

        if (Time.tickCounter() % 300 == 299) // check every 10 sec
        {
            ActorObservation.ForceActorDestroyNotPosChangeAfter(60); // if actor not changed position destroy it after 1 min (must be started before)
        }
    }
    #endregion
}

Simple Sample Mission in attachment.

David198502 07-02-2012 09:26 AM

Hey Kodiak!sorry i didnt answers sooner, but i didint recognize until now, that you have improved the script further!thats great!thank you very much!
will have to try it out now....
thx!

David198502 07-04-2012 06:30 AM

hey Kodiak!

this script works perfect!

the nice thing is, that the messages which show the state of each airfield, are only visible for your own side...
we tested it yesterday, and honestly, i cant think of any possible improvement!!
great work!

David198502 07-04-2012 09:03 AM

btw Kodiak!
now that you have wrote so many scripts for me/our squad, and we all have great fun with your work, how about jumping in,joining us, and enjoy the fun you have created!?

you are welcome any time...if you are in the mood to fly, look in the lobby section and watch for a lobby called ACG...thats us!i would be pleased.

btw, whats your playername in steam?

FG28_Kodiak 07-04-2012 02:15 PM

My playername is FG28_Kodiak ;)

David198502 07-04-2012 02:44 PM

will add you as a friend

Edit: steam doesnt find you...:(

Smokeynz 07-05-2012 01:36 AM

steam isn't friendly:-)

FG28_Kodiak 07-05-2012 04:11 AM

Quote:

Originally Posted by David198502 (Post 441251)
will add you as a friend

Edit: steam doesnt find you...:(

Ah mistake steamname for steam nickname so try:
Kodiak1968

David198502 07-05-2012 12:55 PM

still no joy....
i hate steam regarding this,....i have all the time trouble to find people in steam

FG28_Kodiak 07-05-2012 02:48 PM

How is yours?


All times are GMT. The time now is 07:02 AM.

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