1. Hi!

    I am looking to get when a helicopter has despawned or "retired" when leaving the map so I can send information to console or a player.

    So far I cannot figure anything out from looking at Assembly-CSharp. Any ideas?


    Cheers!
     
    Last edited by a moderator: Mar 11, 2017
  2. Code:
            private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
            {
                if (entity is BaseHelicopter)
                {
                    Puts("Heli death msg to console");
                    rust.BroadcastChat("Heli death msg to players");
                }
            }
     

  3. Unfortunately with the way the helicopter is disposed of it doesn't trigger that hook:
    Code:
      public void Retire()
      {
        if (this.isRetiring)
          return;
        this.isRetiring = true;
        this.Invoke("DestroyMe", 240f);
        float num1 = TerrainMeta.Size.x;
        float num2 = 200f;
        Vector3 newPos = Vector3Ex.Range(-1f, 1f);
        newPos.y = 0.0f;
        newPos.Normalize();
        newPos *= num1 * 20f;
        newPos.y = num2;
        this.ExitCurrentState();
        this.State_Move_Enter(newPos);
      }  public void DestroyMe()
      {
        this.helicopterBase.Kill(BaseNetworkable.DestroyMode.None);
      }
    
     
  4. Yes it does, it just takes awhile. It takes about 2 to 5 mins for it to despawn after it starts flying away.
     
  5. My plugin contains the code:
    Code:
            void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
            {
                if (helicopterDestroyedAnnouncement && entity is BaseHelicopter)
                {
                    if (helicopterDestroyedAnnouncementWithDestroyer)
                    {
                        CreateAnnouncement(helicopterDestroyedAnnouncementWithDestroyerText.Replace("{playername}", LastHitPlayer), BannerTintRed, TextWhite);
                        LastHitPlayer = String.Empty;
                    }
                    else
                    {
                        CreateAnnouncement(helicopterDestroyedAnnouncementText, BannerTintRed, TextWhite);
                    }
                    ....
                }
            }
    
    And it does not do anything when the helicopter is destroyed the way that the aforementioned DestroyMe() method does. Same with the plugin DeathNotes.
     
    Last edited by a moderator: Mar 11, 2017
  6. Hey I am really sorry, you are absolutely right. I just graded some code out of the heli plugin I wrote awhile ago and didn't remember I ran into the same problem. Looks like my work around was to store the heli BaseHelicopter into a var and check the var with a timer every second until it equals null.
     
  7. That's an idea definitely.
    I was just looking at InfoPanel and it seems to do it a rather complicated way with extra classes and events. I don't understand yet exactly how it works, so I can't tell which way would be the most efficient yet (in terms of performance).
     
  8. My plugin already has to have the one second timer so it was a ok solution for me. There probably is a more efficient way, you should post what you find. :)
     
  9. Couldn't you use OnEntityKill?
     
  10. I wasn't aware of that hook.

    EDIT: Yep just looked through the Oxide Git repo and found that. Worth testing.
     
  11. It's not in the docs (they're out of date), but it gets called when a BaseNetworkable has Kill called. It should work for both heli being shot down and heli despawning :)
    [DOUBLEPOST=1489273324][/DOUBLEPOST]
    Code:
    void OnEntityKill(BaseNetworkable entity)
    {
      if (entity is BaseHelicopter)
        Puts("Heli is gone :(");
    }
     
  12. Since I have code for it being shot down and despawning, I will have to figure out a way to tell the difference between the two for the correct text to be sent.

    EDIT: I can't think of anything... Maybe a timer from the last time it was damaged? If it despawns and wasn't damaged after say one minute we can safely assume it retired? Unless you use HeliControl to make it keep targeting you even when it is supposed to be leaving, that way it can just despawn in front of you. Concerned of the performance of constantly destroying and recreating a timer everytime the helicopter takes damage.
     
    Last edited by a moderator: Mar 12, 2017
  13. If OnEntityKill is the despawning code and OnEntityDeath is the shot down code, don't you already have your solution?
     
  14. I hadn't tested anything yet, so I was going by what ignignokt84 said it doing both instead of just for despawning.
     
  15. I was just being factual :) OnEntityKill does get called for both, but is not necessarily the best to use for both events. Like Shady said, you could use OnEntityDeath to handle shot down, then you could just grab the net ID, toss it in a list, and ignore it on OnEntityKill... But there are always alternatives ;)
     
  16. Woops, I didn't read the part where it said it's called for both types of deaths.
     
  17. I just tested it, I had both OnEntityDeath and OnEntityKill checking if the entity is BaseHelicopter then output to console when that method gets called. I shot down a helicopter and only OnEntityDeath was called. I let one despawn and only OnEntityKill gets called. But on the odd occasion probably due to processing time I get both. So ignoring the entity ID in OnEntityKill with a timer delay could work before checking.

    Code:
            private List<uint> HeliNetIDs = new List<uint>();        void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
            {
                if (helicopterDestroyedAnnouncement && entity is BaseHelicopter)
                {
                    var entityNetID = entity.net.ID;
                    if (helicopterDespawnAnnouncement)
                        HeliNetIDs.Add(entityNetID);
                    if (helicopterDestroyedAnnouncementWithDestroyer)
                    {
                        CreateAnnouncement(helicopterDestroyedAnnouncementWithDestroyerText.Replace("{playername}", LastHitPlayer), helicopterDestroyedAnnouncementBannerColor, helicopterDestroyedAnnouncementTextColor);
                        LastHitPlayer = String.Empty;
                    }
                    else
                    {
                        CreateAnnouncement(helicopterDestroyedAnnouncementText, helicopterDestroyedAnnouncementBannerColor, helicopterDestroyedAnnouncementTextColor);
                    }
                }
            }        void OnEntityKill(BaseNetworkable entity)
            {
                if (entity is BaseHelicopter)
                {
                    var entityNetID = entity.net.ID;
                    timer.Once(2, () =>
                    {
                        if (HeliNetIDs.Contains(entityNetID))
                            HeliNetIDs.Remove(entityNetID);
                        else if (helicopterDespawnAnnouncement)
                            CreateAnnouncement(helicopterDespawnAnnouncementText, helicopterDespawnAnnouncementBannerColor, helicopterDespawnAnnouncementTextColor);
                    });
                }
            }
    
    That seems to do the job. I did notice however that I cannot use entity.net.ID in OnEntityKill all the way through the timer, as it produces an NRE, so it would seem that throwing the ID into a variable asap is necessary.
     
    Last edited by a moderator: Mar 13, 2017