Results 1 to 21 of 21

Thread: A better despawn script

  1. #1
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    A better despawn script

    A project for the talented scripters in the community based on feedback in this thread: http://theairtacticalassaultgroup.co...ead.php?t=8009

    It's happened to us all I'm sure. You bounce an opponent at high altitude and either kill the pilot or cripple his aircraft. For whatever reason, your opponent decides to quit the server, hit alt+F2, or maybe even bail out and his now abandoned aircraft continues on. If his aircraft was trimmed for level flight it might take several minutes for it to fall back to earth and award you the kill. However, the clock is already ticking. By exiting the aircraft the despawn timer has started and in moments his plane will simply vanish like nothing ever happened. The only evidence of the encounter being the ammunition you wasted.

    To me this is one of the biggest problems in the sim. An air combat game which does not record kills accurately is simply mind boggling. But can we fix it or at least improve the situation? Every mission file has a despawn script but is it even doing anything or is the despawn behavior now hard coded? I know originally there was no despawn behavior and the server would fill with AI controlled planes buzzing all over. One of the patches changed this so landed and crash landed planes would now disappear without a script.

    I use the following code in my missions which can be found on 1c forums:

    Code:
        public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
        {
            base.OnPlaceLeave(player, actor, placeIndex);
    
            if (actor != null && actor is AiAircraft)
            {
                //check limited aircraft
                switch ((actor as AiAircraft).InternalTypeName())
                {
    
                }
            }
    
            Timeout(1, () => { damageAiControlledPlane(actor); } );
        }
    
        private bool isAiControlledPlane(AiAircraft aircraft)
        {
            if (aircraft == null)
                return false;
    
            //check if a player is in any of the "places"
            for (int i = 0; i < aircraft.Places(); i++)
                if (aircraft.Player(i) != null)
                    return false;
    
            return true;
        }
    
        private void destroyPlane(AiAircraft aircraft)
        {
            if (aircraft != null)
                aircraft.Destroy();
        }
    
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                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(300, () => { destroyPlane(aircraft); });
            }
        }
    Now I can't write code to save my life and everything I use in my missions comes from those more talented. But if I understand this correctly when a player leaves his aircraft after 1 second the game disables all control surfaces and kills the fuel pump. 300 seconds later the aircraft would despawn. However, in real world testing the aircraft in air despawn much sooner, probably a minute or two.

    So the question to the coders is how can this be improved? Obviously, a balance is required to keep abandoned aircraft from stacking up on the airfields and clogging up the server but there has to be a way keep aircraft in the air from simply disappearing.

    I remember a mission ATAG used to run long ago, either the work of Salmo or Wolf, but in that mission when a player quit his aircraft in air it exploded after a few seconds. I thought this was a pretty good solution as everybody got what they wanted. The plane was removed and the attacker got the kill. I would love to hear what thoughts Salmo, Reddog, or Colander have on this problem.

  2. #2
    Team Fusion Salmo's Avatar
    Join Date
    Nov 2011
    Posts
    2,332
    Post Thanks / Like
    Total Downloaded
    191.25 MB

    Re: A better despawn script

    Quote Originally Posted by 9./JG52 Hans Gruber View Post
    ..... You bounce an opponent at high altitude and either kill the pilot or cripple his aircraft. For whatever reason, your opponent decides to quit the server, hit alt+F2, or maybe even bail out and his now abandoned aircraft continues on. If his aircraft was trimmed for level flight it might take several minutes for it to fall back to earth and award you the kill. However, the clock is already ticking. By exiting the aircraft the despawn timer has started and in moments his plane will simply vanish like nothing ever happened. The only evidence of the encounter being the ammunition you wasted....
    Why would you want to despawn a plane when an opponent quits the server, hit alt+F2, or bails out? Just despawn planes after they land, that way a despawn timer despawning planes in the air & before they're counted as kills won't occur.


    Quote Originally Posted by 9./JG52 Hans Gruber View Post
    I use the following code in my missions which can be found on 1c forums:

    Code:
        public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
        {
            base.OnPlaceLeave(player, actor, placeIndex);
    
            if (actor != null && actor is AiAircraft)
            {
                //check limited aircraft
                switch ((actor as AiAircraft).InternalTypeName())
                {
    
                }
            }
    
            Timeout(1, () => { damageAiControlledPlane(actor); } );
        }
    
        private bool isAiControlledPlane(AiAircraft aircraft)
        {
            if (aircraft == null)
                return false;
    
            //check if a player is in any of the "places"
            for (int i = 0; i < aircraft.Places(); i++)
                if (aircraft.Player(i) != null)
                    return false;
    
            return true;
        }
    
        private void destroyPlane(AiAircraft aircraft)
        {
            if (aircraft != null)
                aircraft.Destroy();
        }
    
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                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(300, () => { destroyPlane(aircraft); });
            }
        }
    I don't understand why you're damaging planes in the OnPlaceLeave event? if I move from the pilot to the gunner seat, the OnPlaceLeave event is triggered & the plane will be damaged. Surely, your not aiming to damage planes when players change places?

    Does this help? Just despawn Ai aircraft a short time after they land ....

    Code:
        public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
            // remove Ai's after landing
            if (isAiControlledPlane(aircraft))
            {
                Timeout(120, () =>
                {   // remove aircraft after 2 minutes
                    if (aircraft != null) aircraft.Destroy();
                });
            }
        }
    Last edited by Salmo; Jan-17-2014 at 23:42.

  3. #3
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Quote Originally Posted by Salmo View Post
    Why would you want to despawn a plane when an opponent quits the server, hit alt+F2, or bails out? Just despawn planes after they land, that way a despawn timer despawning planes in the air & before they're counted as kills won't occur.
    Because if you don't at least disable the aircraft after the player quits the AI takes over and will keep flying. Based on your responses I'm guessing you don't use any kind of despawn script which might explain why on some missions after a player lands and exits, the plane takes off again and circles the airfield. Soon enough your server is bogged down with abandoned aircraft which are now being flown by the AI. This script has been used by mission makers to disable AI planes since the games release.

    http://www.airwarfare.com/sow/index....t-to-remove-ai


    Quote Originally Posted by Salmo View Post
    I don't understand why you're damaging planes in the OnPlaceLeave event? if I move from the pilot to the gunner seat, the OnPlaceLeave event is triggered & the plane will be damaged. Surely, your not aiming to damage planes when players change places?
    That's not how it functions. There is no problem changing positions in aircraft.

    Quote Originally Posted by Salmo View Post
    Does this help? Just despawn Ai aircraft a short time after they land ....

    Code:
        public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
            // remove Ai's after landing
            if (isAiControlledPlane(aircraft))
            {
                Timeout(120, () =>
                {   // remove aircraft after 2 minutes
                    if (aircraft != null) aircraft.Destroy();
                });
            }
        }
    The game will despawn a/c automatically after OnAircraftLanded & OnAircraftCrashLanded.

    Perhaps the answer is to simply remove Timeout(300, () => { destroyPlane(aircraft); });?

  4. #4
    Ace
    Join Date
    May 2013
    Location
    Stamford, Lincs, UK
    Posts
    1,033
    Post Thanks / Like
    Blog Entries
    8
    Total Downloaded
    7.46 MB

    Re: A better despawn script

    My understanding is that the despawn script is on the SERVER, not in the mission here at ATAG.

  5. #5
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Quote Originally Posted by 92 Sqn. Reddog (QJ-R) View Post
    My understanding is that the despawn script is on the SERVER, not in the mission here at ATAG.
    There is despawn hard coded in the game for landed and crash landed aircrafts, this much I am certain. If you do not have any code in your missions to despawn aircraft OnPlaceLeave that could explain unexplained build ups of AI you are experiencing in your missions.

    I did some testing with the despawn timer commented out in a mission and learned the following:

    - Nothing happens until the player exits the aircraft (bail out, alt +F2, spawns a new new aircraft, exits server, etc..)
    - Aircraft spawned and then abandoned will disappear after ~50 seconds.
    - Aircraft landed and then abandoned will disappear after ~70 seconds.
    - Aircraft crash landed and then abandoned will disappear after ~12 seconds.
    - Occasionally an aircraft will crash land and no event is triggered. This aircraft will never disappear. Ex. I took an He 111 up to 6km trimmed for level flight, set autopilot then bailed out. Per the damage AI script the engines immediately died and the a/c began a lazy corkscrew with elevators locked up. After 10 minutes the a/c eventually glided down into a field making a surprisingly soft landing. I waited for a few minutes then walked away. 20 mintues later the a/c was still sitting in the field. This is why you need the despawn timer.

    Then I had an epiphany. Instead of fighting the despawn timer why not find the correct combination of damages to cause the a/c to crash quicker? I began experimenting with different types of damage and the only way I could get the a/c down quickly was to chop off a wing.

    Code:
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                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);
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0FuelSecondariesFire);
                ///aircraft.hitNamed(part.NamedDamageTypes.FuelTank0Fire);
    
                aircraft.cutLimb(part.LimbNames.WingR1);
                aircraft.cutLimb(part.LimbNames.WingR2);
                aircraft.cutLimb(part.LimbNames.WingR3);
                aircraft.cutLimb(part.LimbNames.WingR4);
                aircraft.cutLimb(part.LimbNames.WingR5);
                aircraft.cutLimb(part.LimbNames.WingR6);
                aircraft.cutLimb(part.LimbNames.WingR7);
    
                ///aircraft.cutLimb(part.LimbNames.AileronL0);
                ///aircraft.cutLimb(part.LimbNames.AileronR0);
                ///aircraft.cutLimb(part.LimbNames.ElevatorL0);
                ///aircraft.cutLimb(part.LimbNames.ElevatorR0);
                ///aircraft.cutLimb(part.LimbNames.Rudder0);
    
                ///aircraft.cutLimb(part.LimbNames.StabilizerL0);
    	    ///aircraft.cutLimb(part.LimbNames.StabilizerL1);
                ///aircraft.cutLimb(part.LimbNames.StabilizerR0);
    	    ///aircraft.cutLimb(part.LimbNames.StabilizerR1);
    
                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(300, () => { destroyPlane(aircraft); });
            }
        }
    As you can see I tried several different types of damage but none worked as well. Cutting off the elevators caused the a/c to enter a dive but the a/c ends up inverted and it looked really corny. I tested this with every a/c in the game and it worked. The pilot leaves, a second later the wing breaks off, the engine smokes, the a/c enters a tight spiral all the way to the ground. From 6km it's over in less than 30 seconds. The only negative is on aircraft with wing tanks in a certain position (Br.20, G.50, Ju87, Ju88) there is a secondary fuel explosion. Unless somebody can find a better combination of damages this might be as good as it gets. For example if there was a method to lock one aileron up and the other down you could accomplish the same thing. I also tested against a formation of AI bombers and their behavior was unaffected. They bailed out as normal with no additional damage enforced. Thoughts?

  6. #6
    Ace
    Join Date
    May 2013
    Location
    Stamford, Lincs, UK
    Posts
    1,033
    Post Thanks / Like
    Blog Entries
    8
    Total Downloaded
    7.46 MB

    Re: A better despawn script

    There's no build up of AI in my missions. I have in-mission despawn in a variety of methods. However, I believe that there is an additional layer of despawn being applied by the server.

    Your suggestion looks fine, but I personally don't see the need to worry about it. It must be a minute proportion of the kills on the server?

  7. #7
    Combat pilot Klaus_Kaltherzig's Avatar
    Join Date
    May 2012
    Location
    Ontario, Canada
    Posts
    158
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Hans is correct it is a problem - it may not be a high % of total kills on the server but it is a significant % of all high altitude PKs especially if pilot is flying level when he is killed - couldn't even count the # of times I have chased a dead pilot plane bumper to bumper wasting all my ammo trying to shoot it up bad enough that it will start to go down
    Anything that can be done script wise would IMHO be a step in the right direction

  8. #8
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Yes Klaus, it is a most most frustrating problem. But I have a solution and hopefully other mission makers choose to include it. Building off what I posted earlier I was worried about removing the wing to make the aircraft crash. This was an extreme method and as I suspected the wings do not despawn so over time severed wings begin to build-up floating in the air and around airfields. So I dig a little deeper into damage system and discover hitLimb, which can be used to inflict damage on specific parts. This is what I put together:

    Code:
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                if (actor == null || !(actor is AiAircraft))
                    return;
    
                AiAircraft aircraft = (actor as AiAircraft);
    
                if (!isAiControlledPlane(aircraft))
                    return;
    
                if (aircraft == null)
                    return;
    
                aircraft.hitNamed(part.NamedDamageTypes.FuelPumpFailure); 
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0OilSecondariesFire);
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0TotalSeizure); 
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0GovernorSeizure); 
                aircraft.hitNamed(part.NamedDamageTypes.ControlsGenericKickdown); 
                aircraft.hitNamed(part.NamedDamageTypes.ControlsElevatorDisabled);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsAileronsDisabled);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsRudderDisabled);
    
                aircraft.hitLimb(part.LimbNames.WingL1, -0.5); 
                aircraft.hitLimb(part.LimbNames.WingL2, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL3, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL4, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL5, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL6, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL7, -0.5);
    
    
                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(120, () => { destroyPlane(aircraft); });
    
            }
        }
    Basically, what happens now is that 1 second after player leaves aircraft this script is called which kills engine & controls. It also causes small engine fire which forces the AI pilot to bail out, important for alt+F2 or when player exits server. The fire often goes out but if not leaves a feint grey smoke trail which is a nice effect not often seen. Now the important part, damage is applied all along the left wing, which will cause the wing to drop & the aircraft to roll departing from level flight and beginning its quick descent to the ground. This wing damage is not visible to the player. The damage value can be increased but anything above 0.5 causes the damage to be visible (i.e. big holes in the wing) which does cause the aircraft to roll quicker but is a little obtrusive. I have tested this on all aircraft models in game and it works like a charm. From altitudes of 7km aircraft trimmed for level flight will crash in 10-15 seconds after the player exits. The only odd thing about this method is that if aircraft is abandoned on the ground it's engine will smoke but in less than a minute it despawns anyway so no harm is done.

    So now in those high altitude scenarios if the opposition quits on you there will be instant feedback to the player. Belch of smoke from the engine, AI pilot bails out, and a/c rolls into death dive. Problem solved.

  9. #9
    Team Fusion ATAG_Bliss's Avatar
    Join Date
    Feb 2011
    Location
    United States of China
    Posts
    4,135
    Post Thanks / Like
    Total Downloaded
    457.02 MB

    Re: A better despawn script

    That's a great idea putting the AI out of the flight. I'll get with Colander (after TF 4.01 is out) and see if he has some magic up his sleeve regarding keeping people in the plane. I do agree that it should be like 1946 where you should have to bailout or land before exiting the aircraft. The problem, of course, is that Clod lets you switch to different aircraft, tanks, guns etc. so the issue is somehow allowing people to still do that but only while not on the ground.

    There is even a realism setting for this server side called "enable plane switching". And it would keep people in their planes just as the old game did. The issue though, is that you are only allowed one plane spawn while this is enabled. So even after you have landed or bailed out, the only way to take another plane is to reconnect to the server. So they almost had it right But your idea is a great one in the meantime.


    "The dissenter is every human being at those moments of his life when he resigns momentarily from the herd and thinks for himself". - Archibald Macleish


  10. #10
    Team Fusion Salmo's Avatar
    Join Date
    Nov 2011
    Posts
    2,332
    Post Thanks / Like
    Total Downloaded
    191.25 MB

    Re: A better despawn script

    Quote Originally Posted by ATAG_Bliss View Post
    ... I'll get with Colander (after TF 4.01 is out) and see if he has some magic up his sleeve regarding keeping people in the plane. .....
    I believe you can 'force' players back into their plane using script, something like ....

    Code:
    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
          	base.OnPlaceLeave(player, actor, placeIndex);
    	if (actor is AiAircraft)
    	{
    		Player.Place() = (Actor as AiAircraft).Place(placeIndex);
    	}
    }

  11. #11
    Novice Pilot
    Join Date
    Jul 2013
    Posts
    50
    Post Thanks / Like
    Blog Entries
    2
    Total Downloaded
    78.01 MB

    Re: A better despawn script

    Quote Originally Posted by Salmo View Post
    I believe you can 'force' players back into their plane using script, something like ....

    Code:
    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
          	base.OnPlaceLeave(player, actor, placeIndex);
    	if (actor is AiAircraft)
    	{
    		Player.Place() = (Actor as AiAircraft).Place(placeIndex);
    	}
    }
    Yes there is option to do that, its already implemented in SoW Campaigns....It is a little bit more complicated than that because of events being called after Player wants to leave aircraft or create new one...
    Notice that You can re spawn two ways, once click on flag in mission menu or just create new plane by clicking on map...

    Code:
    
        private int[] AFL = new int[200];
        private int bob = 0;
        private List<string> restrictedPlanes = new List<string>();
        private List<string> restrictedName = new List<string>();
        private String CurPlane, CurPilot;
    
     private bool isAiControlledPlane(AiAircraft aircraft)
        {
            if (aircraft == null)
                return false;
    
           
            for (int i = 0; i < aircraft.Places(); i++)
                if (aircraft.Player(i) != null)
                    return false;
    
            return true;
        }
    
     public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
        {
            base.OnPlaceLeave(player, actor, placeIndex);
    
            AiAircraft aircraft = actor as AiAircraft;
    
            base.OnPlaceLeave(player, actor, placeIndex);
    
    
            #region cockpit lock
            Player a = player;
            Player[] aa = { a };
    
           
            if (!(player.IsConnected())) return;
            if (!(isAiControlledPlane(actor as AiAircraft))) return;
    
            bool lnd = false;
            bool hm = false;
            bool jp = false;
    
            if (((actor as AiAircraft).Person(0) == null) && ((actor as AiAircraft) != null))
                jp = true;
    
            if (jp)
            {
                if (restrictedName.Contains(a.Name()))
                {
                    restrictedName.Remove(a.Name());
                }
    
                return;
            }
    
            if (!((actor as AiAircraft).Person(0).Health > 0))
            {
                if (restrictedName.Contains(a.Name()))
                {
                    restrictedName.Remove(a.Name());
                }
    
                return;
            }
    
    
            double x = (actor as AiAircraft).Pos().x;
            double y = (actor as AiAircraft).Pos().y;
            double z = (actor as AiAircraft).Pos().z;
    
            //if ((actor as AiAircraft).IsAirborne())
            {
                if (isAiControlledPlane(actor as AiAircraft))
                {
                    Timeout((a.Ping() + 50) * 0.002, () =>
                    {
    
    
                        string name = (actor as AiAircraft).Name();
                        double xxx = ((actor as AiAircraft).Pos().x - x) * ((actor as AiAircraft).Pos().x - x);
                        double yyy = ((actor as AiAircraft).Pos().y - y) * ((actor as AiAircraft).Pos().y - y);
                        ///-----------------------------------------------
    
    
                        if ((xxx < 1) && (yyy < 1))
                        {
                            if (restrictedPlanes.Contains(name))
                            {
                                restrictedPlanes.Remove(name);
                            }
                            if (restrictedName.Contains(a.Name()))
                            {
                                restrictedName.Remove(a.Name());
                            }
                        }
    
    
    
                        if (restrictedPlanes.Contains(name))
                        {
                            //restrictedName.Remove(a.Name());
                            if (((actor as AiAircraft) != null) && (player != null)) 
                            {
    
                                a.PlaceEnter((actor as AiAircraft), 0);
                                //serverMessage(a.Name() + " Not Allowed to leave airplane in the air");
                                if (player != null)
                                {
                                    GamePlay.gpHUDLogCenter(aa, "Not Allowed to leave airplane in the air");
                                }
    
                                
                                if ((CurPilot == a.Name()) && (CurPlane != name)) bob++;
                                else bob = 0;
                                if (bob > 10)
                                {
                                    (actor as AiAircraft).Destroy();
                                    bob = 0;
                                    restrictedPlanes.Remove(name);
                                }
                                CurPilot = a.Name();
                                CurPlane = name;
    
                            }
                        }
                    });
                }
    
            }
            #endregion
    }
    
     public override void OnPlaceEnter(Player player, AiActor actor, int placeIndex)
     {
            base.OnPlaceEnter(player, actor, placeIndex);
    
    #region plane escape lock
                if (!restrictedPlanes.Contains((actor as AiAircraft).Name()))
                {
                    if (restrictedName.Contains(player.Name()))
                    {
                        if ((actor as AiAircraft) != null) (actor as AiAircraft).Destroy();
                        restrictedName.Add(player.Name());
                        return;
                    }
                    restrictedName.Add(player.Name());
                    restrictedPlanes.Add((actor as AiAircraft).Name());
                }
    
     #endregion
    }



    It works flawless, i took it more less from old Repka server missions, and added few bits and pieces but idea stayed the same .....

    Vogler...
    Last edited by Nephilim; Jan-19-2014 at 21:26.

  12. #12
    Supporting Member 9./JG52 Ziegler's Avatar
    Join Date
    Feb 2013
    Location
    Coast of Maine - Halfway between the equator and the North Pole
    Posts
    1,195
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Gruber's despawn tweek works like a champ. I also tested several types from 6k+ and they were all down in short order.
    Last edited by 9./JG52 Ziegler; Jan-20-2014 at 08:31.
    Corsair 600T-Gigabite Gigabyte Z77-UD5 mobo-I7 Ivy Bridge 3770k@3.5ghz-Scythe Ninja 3 -16g HyperX- EVGA GTX 670 FTW-HyperX SSD-Logitech G19-Cyborg Ratz 9-CH Thrustmaster Warthog HOTAS and throttle with MFG Crosswind pedals, BenQ 2420T monitor, Track IR-5, Obutto Rev3. http://9jg52.com/

    Glückliche sieben

  13. #13
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    The full code is below. It works like a champ. Please put it in your missions until TF comes up with a better solution. ATAG should make it mandatory.

    Code:
        public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
        {
            base.OnPlaceLeave(player, actor, placeIndex);
    
            if (actor != null && actor is AiAircraft)
            {
                //check limited aircraft
                switch ((actor as AiAircraft).InternalTypeName())
                {
    
                }
            }
    
            Timeout(1, () => { damageAiControlledPlane(actor); } );
        }
    
        public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
        {
            base.OnActorDead(missionNumber, shortName, actor, damages);
            if (actor != null && actor is AiGroundActor)
                Timeout(300, () => { (actor as AiGroundActor).Destroy(); ; });
        }
    
        public override void OnAircraftCrashLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
    		// COLANDER
            //Timeout(120, () => { destroyPlane(aircraft); } );
        }
        public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftLanded(missionNumber, shortName, aircraft);
    		// COLANDER
            //Timeout(120, () => { destroyPlane(aircraft); } );
        }
    
        private bool isAiControlledPlane(AiAircraft aircraft)
        {
            if (aircraft == null)
                return false;
    
            //check if a player is in any of the "places"
            for (int i = 0; i < aircraft.Places(); i++)
                if (aircraft.Player(i) != null)
                    return false;
    
            return true;
        }
    
        private void destroyPlane(AiAircraft aircraft)
        {
            if (aircraft != null)
                aircraft.Destroy();
        }
    
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                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);
                aircraft.hitNamed(part.NamedDamageTypes.Eng0TotalFailure);
                aircraft.hitNamed(part.NamedDamageTypes.ElecPrimaryFailure);
                aircraft.hitNamed(part.NamedDamageTypes.ElecBatteryFailure);
    
                aircraft.hitLimb(part.LimbNames.WingL1, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL2, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL3, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL4, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL5, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL6, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL7, -0.5);
    
    
                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(300, () => { destroyPlane(aircraft); });
    
            }
        }
    Last edited by 9./JG52 Hans Gruber; Mar-15-2014 at 09:21.

  14. #14
    Ace 56RAF_klem's Avatar
    Join Date
    Sep 2011
    Location
    UK, West Sussex
    Posts
    569
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Quote Originally Posted by 9./JG52 Hans Gruber View Post
    The full code is below. It works like a champ. Please put it in your missions until TF comes up with a better solution. ATAG should make it mandatory.

    Code:
        public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
        {
            base.OnPlaceLeave(player, actor, placeIndex);
    
            if (actor != null && actor is AiAircraft)
            {
                //check limited aircraft
                switch ((actor as AiAircraft).InternalTypeName())
                {
    
                }
            }
    
            Timeout(1, () => { damageAiControlledPlane(actor); } );
        }
    
        public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
        {
            base.OnActorDead(missionNumber, shortName, actor, damages);
            if (actor != null && actor is AiGroundActor)
                Timeout(300, () => { (actor as AiGroundActor).Destroy(); ; });
        }
    
        public override void OnAircraftCrashLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftCrashLanded(missionNumber, shortName, aircraft);
    		// COLANDER
            //Timeout(120, () => { destroyPlane(aircraft); } );
        }
        public override void OnAircraftLanded(int missionNumber, string shortName, AiAircraft aircraft)
        {
            base.OnAircraftLanded(missionNumber, shortName, aircraft);
    		// COLANDER
            //Timeout(120, () => { destroyPlane(aircraft); } );
        }
    
        private bool isAiControlledPlane(AiAircraft aircraft)
        {
            if (aircraft == null)
                return false;
    
            //check if a player is in any of the "places"
            for (int i = 0; i < aircraft.Places(); i++)
                if (aircraft.Player(i) != null)
                    return false;
    
            return true;
        }
    
        private void destroyPlane(AiAircraft aircraft)
        {
            if (aircraft != null)
                aircraft.Destroy();
        }
    
        private void damageAiControlledPlane(AiActor actorMain)
        {
            foreach (AiActor actor in actorMain.Group().GetItems())
            {
                if (actor == null || !(actor is AiAircraft))
                    return;
    
                AiAircraft aircraft = (actor as AiAircraft);
    
                if (!isAiControlledPlane(aircraft))
                    return;
    
                if (aircraft == null)
                    return;
    
                aircraft.hitNamed(part.NamedDamageTypes.FuelPumpFailure);
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0OilSecondariesFire);
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0TotalSeizure);
    	    aircraft.hitNamed(part.NamedDamageTypes.Eng0GovernorSeizure);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsGenericKickdown);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsElevatorDisabled);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsAileronsDisabled);
                aircraft.hitNamed(part.NamedDamageTypes.ControlsRudderDisabled);
    
                aircraft.hitLimb(part.LimbNames.WingL1, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL2, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL3, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL4, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL5, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL6, -0.5);
                aircraft.hitLimb(part.LimbNames.WingL7, -0.5);
    
    
                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(180, () => { destroyPlane(aircraft); });
    
            }
        }
    Hi Gruber,

    this is exactly what I want for our training server missions, a simple despawn script to clear the debris. I have one problem which goes away if I rem out this part because the console reports a 'List not known in this context' error:

    public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
    {......
    }

    Any thoughts? My only plagiarised additions for the entire script are:

    using System;
    using System.IO;
    using maddox.game;
    using maddox.game.world;
    using maddox.core;
    using maddox.GP;
    using part;


    public class Mission : AMission
    {
    ....despawn script as your post.....

    }
    klem
    http://firebirds.2ndtaf.org.uk/

    ASUS Sabertooth X58 /i7 950 @ 3.6 GHz / 12Gb DDR3 1600 CAS8 / EVGA GTX980 GPU 4Gb superclocked /128Gb SSD + 256Gb SSD/ Corsair 750HXUK 750W PSU
    Windows 7 64 bit Home Premium / 3 x AOC 27" e2752vq @ 1920x1080 in Nvidia "Surround" plus 23" 1920x1080 instruments display below/ TrackIR4 with TrackIR5 software / Saitek X52 Pro, MFG Crosswind Rudders / CH CM

  15. #15
    Team Fusion Salmo's Avatar
    Join Date
    Nov 2011
    Posts
    2,332
    Post Thanks / Like
    Total Downloaded
    191.25 MB

    Re: A better despawn script

    Quote Originally Posted by 56RAF_klem View Post
    Hi Gruber,

    this is exactly what I want for our training server missions, a simple despawn script to clear the debris. I have one problem which goes away if I rem out this part because the console reports a 'List not known in this context' error:

    public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
    {......
    }

    Any thoughts? My only plagiarised additions for the entire script are:

    using System;
    using System.IO;
    using maddox.game;
    using maddox.game.world;
    using maddox.core;
    using maddox.GP;
    using part;


    public class Mission : AMission
    {
    ....despawn script as your post.....

    }
    Klem,
    You could try removing the redundant semicolon ....

    public override void OnActorDead(int missionNumber, string shortName, AiActor actor, List<DamagerScore> damages)
    {
    base.OnActorDead(missionNumber, shortName, actor, damages);
    if (actor != null && actor is AiGroundActor)
    Timeout(300, () => { (actor as AiGroundActor).Destroy(); ; });
    }

  16. #16
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    After a month of real world testing the script is working as well I could hope. On the missions using it incidents of unawarded kills has dropped dramatically. The only change I am making is the removal of "aircraft.hitNamed(part.NamedDamageTypes.Eng0OilSe condariesFire);" from the inflicted damages. On aircraft with canopies which could be jettisoned, it was discovered that the canopies do not despawn with the rest of the aircraft. So at airfields where a/c were often abandoned on the ground a large amount of canopies were building up around the spawn points over several hours. This did not impact performance, it was just an odd sight. I have updated my earlier post (#13) to correct this.

    Klemm, I apologize as I did not see your post till now. Did you figure it out?

  17. #17
    Ace 56RAF_klem's Avatar
    Join Date
    Sep 2011
    Location
    UK, West Sussex
    Posts
    569
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Quote Originally Posted by 9./JG52 Hans Gruber View Post
    After a month of real world testing the script is working as well I could hope. On the missions using it incidents of unawarded kills has dropped dramatically. The only change I am making is the removal of "aircraft.hitNamed(part.NamedDamageTypes.Eng0OilSe condariesFire);" from the inflicted damages. On aircraft with canopies which could be jettisoned, it was discovered that the canopies do not despawn with the rest of the aircraft. So at airfields where a/c were often abandoned on the ground a large amount of canopies were building up around the spawn points over several hours. This did not impact performance, it was just an odd sight. I have updated my earlier post (#13) to correct this.

    Klemm, I apologize as I did not see your post till now. Did you figure it out?
    I'm afraid not. I get an error message in console at line 29: "The Type or Namespace 'List' could not be found....". Am I missing a reference in my post #14? I just copied them from another mission.
    klem
    http://firebirds.2ndtaf.org.uk/

    ASUS Sabertooth X58 /i7 950 @ 3.6 GHz / 12Gb DDR3 1600 CAS8 / EVGA GTX980 GPU 4Gb superclocked /128Gb SSD + 256Gb SSD/ Corsair 750HXUK 750W PSU
    Windows 7 64 bit Home Premium / 3 x AOC 27" e2752vq @ 1920x1080 in Nvidia "Surround" plus 23" 1920x1080 instruments display below/ TrackIR4 with TrackIR5 software / Saitek X52 Pro, MFG Crosswind Rudders / CH CM

  18. #18
    Ace 9./JG52 Hans Gruber's Avatar
    Join Date
    Mar 2012
    Location
    USA
    Posts
    577
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Post #13 has been updated. If a human player abandons their bomber on the ground the AI would arm bombs and jettison the bomb load. If the airfield was an objective this would blow up the airfield. I have revised the damage types inflicted after a human quits the a/c to disable the electrical systems and prevent the arming & release of bombs.

  19. #19
    Banned
    Join Date
    Mar 2013
    Location
    new zealand
    Posts
    422
    Post Thanks / Like
    Total Downloaded
    0

    Re: A better despawn script

    Quote Originally Posted by 9./JG52 Hans Gruber View Post
    Post #13 has been updated. If a human player abandons their bomber on the ground the AI would arm bombs and jettison the bomb load. If the airfield was an objective this would blow up the airfield. I have revised the damage types inflicted after a human quits the a/c to disable the electrical systems and prevent the arming & release of bombs.
    Very nice work.

  20. #20
    Ace
    Join Date
    May 2015
    Location
    Kansas City, Missouri area
    Posts
    515
    Post Thanks / Like
    Total Downloaded
    130.02 MB

    Re: A better despawn script

    Quote Originally Posted by Salmo View Post
    I believe you can 'force' players back into their plane using script, something like ....

    Code:
    public override void OnPlaceLeave(Player player, AiActor actor, int placeIndex)
    {
          	base.OnPlaceLeave(player, actor, placeIndex);
    	if (actor is AiAircraft)
    	{
    		Player.Place() = (Actor as AiAircraft).Place(placeIndex);
    	}
    }

    I believe it is more like this:

    Code:
    AiAircraft aircraft
    Player player
    int place
    
                player.PlaceEnter(aircraft, place);
    Also I believe you can do player.PlaceLeave() & some other similar.

    The following code has the effect of killing the player, though it may not be the preferred/best way to do it:

    Code:
    Battle.OnActorDead(0, player.Name(), actor, null);
    You can see more similar "things you can do" (possibly!) by looking at the reference here and searching for "OnEventGame" and "GameEventId".
    Last edited by TWC_Flug; Dec-29-2016 at 20:32.

  21. #21
    Supporting Member Karaya's Avatar
    Join Date
    Sep 2013
    Posts
    1,614
    Post Thanks / Like
    Total Downloaded
    155.92 MB

    Re: A better despawn script

    Does this script still work with 5.0 or is there a newer, better way to handle this?

    I'm asking because there are issues with aircraft kills not being tracked in the ITAF run campaigns (BoB, Tobruk). Reason for this seems to be that when someone (player, AI) bails the aircraft despawns immediately and isn't tracked as destroyed/shot down.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •