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-24-2012 08:53 AM

BTW I made the script - it's your part to test it ;)

David198502 06-24-2012 09:45 AM

i will take that duty with joy!
testing it now-report will follow soon:grin:

David198502 06-24-2012 12:11 PM

well Kodiak...this works perfect from what i have tested so far!great work.thank you!

David198502 06-25-2012 07:25 AM

ok Kodiak, as already mentioned, the script works perfect!
after a few tests on my own, some of my squad members tried a mission with this script.
it was great fun, and everything works....
but i have seen one minor thing, which is distracting a bit....if one bails out, the plane will disappear immediately.thats the only thing i would like to have changed.

on the other side, i like the fact, that if you spawn on a base(on ground), and leave the plane, it will get back into the pool as well.thats good if you forgot to change your loadout for example....
and i also like the fact, that the planes disappear in general after one leaves the plane...but when you are in a dogfight, it loooks weird, when the pilot in front of you bails out, and the plane suddenly is gone...besides, i think that one doesnt get the kill for it in this situation(though im not sure on this).

i assume, that i probably have to change only one line in the script to cure this problem, but i dont know which one....

FG28_Kodiak 06-25-2012 08:37 AM

Hm must take a look at this, problem is both leaving the plane via Esc and parachuting called OnPlaceLeaved so i must try a other way to get this fixed.

David198502 06-25-2012 10:04 AM

ah ok...well its not a major issue...but if it can be solved without too much effort, i would be glad...if not, im happy as well with what i already have.

FG28_Kodiak 06-25-2012 10:14 AM

Ok new version, should work can't test it at the moment (not at my gaming Pc at the moment):

see new version at
http://forum.1cpublishing.eu/showpos...2&postcount=40

David198502 06-25-2012 10:18 AM

hey Kodiak...no problem, its my duty and a honor to test it!
thx for the really quick fix,.....will try it now..

David198502 06-25-2012 10:41 AM

seems to work!
i spawned the plane, and left it on the ground with hitting ALT F2, and the plane despawned immediately, just like it used to be.
then i spawned again, took off the runway, bailed out, and the plane kept flying until it crashed into the channel...so everything seems to work now as intended..:grin:

good job Kodiak

FG28_Kodiak 06-26-2012 04:15 PM

Found a problem by removing the spawnplace more than one time. :rolleyes:

Corrected Version:
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 int NumberOfPlanes { get; set; }
        public AiBirthPlace BirthPlace { get; set; }
        public IGamePlay GamePlay { get; set; }
        private bool _isAvalable;

        private List<AiAircraft> PlanesInUse = new List<AiAircraft>(); 


        public SpawnPlace(IGamePlay gamePlay, AiBirthPlace birthPlace, int maxNumber)
        {
            GamePlay = gamePlay;
            BirthPlace = birthPlace;
            NumberOfPlanes = maxNumber;
            if (maxNumber > 0)
                _isAvalable = true;
        }


        public void CheckPlaneOut(AiActor actor)
        {
            if (actor != null && (actor is AiAircraft))
            {
                if (PlanesInUse.Exists(item => item == actor)) return;

                PlanesInUse.Add(actor as AiAircraft);

                NumberOfPlanes--;

                GamePlay.gpLogServer(null, "Airfield: {0}: {1} plane(s) avaiable, {2} in use.", new object[] { BirthPlace.Name(), NumberOfPlanes, PlanesInUse.Count });
               
                if (NumberOfPlanes <= 0 && _isAvalable)
                {
                    foreach (AiBirthPlace bp in GamePlay.gpBirthPlaces())
                    {
                        if (bp.Name().Equals(BirthPlace.Name()))
                            bp.destroy();
                    }
                    _isAvalable = false;
                }
            }
        }


        public void CheckPlaneIn(AiActor actor)
        {
            if (actor != null && actor is AiAircraft)
              if (IsActorDown(actor) && CheckIsHomeBase(actor, 800.0)) // Plane landed on correct Homebase if in 800m Radius from SpawnplaceLocation
                {
                    PlanesInUse.Remove(actor as AiAircraft);
                    NumberOfPlanes++;

                    GamePlay.gpLogServer(null, "Airfield: {0}: {1} plane(s) avaiable", new object[] { BirthPlace.Name(), NumberOfPlanes });

                    if (!_isAvalable)
                    {
                        GamePlay.gpPostMissionLoad(CreateBirthPlace(BirthPlace));
                        _isAvalable = true;
                    }
                }
              else PlanesInUse.Remove(actor as AiAircraft); // Plane is lost
        }


        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 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;
        }


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


        internal ISectionFile CreateBirthPlace(AiBirthPlace birthPlace)
        {

            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 = birthPlace.GetAircraftTypes();
            if (planeSet.Length > 0)
                for (int j = 0; j < planeSet.Length; j++)
                {
                    key = planeSet[j];
                    value = "";
                    f.add(sect, key, value);
                }

            return f;
        }
    }


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

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

 
        private static AiBirthPlace GetBirthPlaceByName(string birthPlaceName)
        {
            foreach (SpawnPlace sp in _spawnPlaces)
            {
                if (sp.BirthPlace.Name().Equals(birthPlaceName))
                    return sp.BirthPlace;
            }
            return null;
        }


        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 int CountAvailablePlanes(int army)
        {
            int count = 0;

            _spawnPlaces.ForEach(item =>
                                    {
                                        if (item.BirthPlace != null)
                                            if (item.BirthPlace.Army() == army)
                                                count += item.NumberOfPlanes;
                                    });
           
            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;
        }



        public static void DebugPrint()
        {
            _spawnPlaces.ForEach(item => GamePlay.gpLogServer(null, "BirthPlaces: {0}  In Store: {1} In Use: {2}", new object[] { item.BirthPlace.Name(), item.NumberOfPlanes, item.NumberOfPlanesInUse() }));
        }


        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);
            }
        }
    }


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

        MissionNumberListener = -1;

        SpawnPlaceManagement.GamePlay = GamePlay;

        SpawnPlaceManagement.Limitations(
                new KeyValuePair<string, int>("Spits", 10), // Name of Birthplace, Number of Max Available planes
                new KeyValuePair<string, int>("Bf109E", 10)
            );
    }


    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);
    }


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

        SpawnPlaceManagement.CheckPlaneOut(actor);

        if (player.PlacePrimary() <= 0 && player.PlaceSecondary() == -1)
        {
            if (actor is AiCart)
                ActorObservation.StoreActor(actor);
           
            int availablePlanes = SpawnPlaceManagement.CountAvailablePlanes(player.Army());
            if (availablePlanes ==  5) // Message if only 5 planes left, change to your needs
            {
                if (player.Army() == 1)
                    GamePlay.gpHUDLogCenter(null, "Attention RED only {0} planes left!", new object[] { availablePlanes } );
                if (player.Army() == 2)
                    GamePlay.gpHUDLogCenter(null, "Attention BLUE only {0} planes left!", new object[] { availablePlanes });
            }
        }
    }


    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 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);

        SpawnPlaceManagement.CheckPlaneIn(actor);

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


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

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



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

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