Patrol Helicopter DeathNote
JO72yySHxmVfdYo.jpg abcde

I noticed death notice only works if heli killed player with their rockets (not turret). I guess the rocket damage has different entity name than the actual heli's entity. I tried to fix the code myself but it was way too complicated

Add this 

			if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("patrolhelicopter"))
			{
				if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("gib"))
				{
					data.KillerEntityType = CombatEntityType.Other;
				}
				else
				{
					data.KillerEntityType = CombatEntityType.Helicopter;
				}
			}

right above this line in OnEntityDeath

			if (data.KillerEntityType == CombatEntityType.Other || data.VictimEntityType == CombatEntityType.Other)
            {
				return;
			}
nMyfFlEnglczTD3.jpg pookins

Plugin was updated but still does not show kill/killed

for kill/killed fix you can add this

			if (victimEntity.name.ToLower().Contains("patrolhelicopter"))
			{
				if (victimEntity.name.ToLower().Contains("gib"))
				{
					data.VictimEntityType = CombatEntityType.Other;
				}
				else
				{
					data.VictimEntityType = CombatEntityType.Helicopter;
				}
			}

			if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("patrolhelicopter"))
			{
				if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("gib"))
				{
					data.KillerEntityType = CombatEntityType.Other;
				}
				else
				{
					data.KillerEntityType = CombatEntityType.Helicopter;
				}
			}
right above this line in OnEntityDeath
			if (data.KillerEntityType == CombatEntityType.Other || data.VictimEntityType == CombatEntityType.Other)
                       {
				return;
			}​
HypeIcQOxfZROOF.jpg SinKoh

Add this 

			if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("patrolhelicopter"))
			{
				if (victimEntity.lastAttacker.PrefabName.ToLower().Contains("gib"))
				{
					data.KillerEntityType = CombatEntityType.Other;
				}
				else
				{
					data.KillerEntityType = CombatEntityType.Helicopter;
				}
			}

right above this line in OnEntityDeath

			if (data.KillerEntityType == CombatEntityType.Other || data.VictimEntityType == CombatEntityType.Other)
            {
				return;
			}

Thanks but it is not working for me, I tried to fix with similar way before, I even scanned the whole plugin and changed heli to patrol heli but still not working.
For some reason, death notes only show if a player are killed by the patrol heli with the below config:

"KillerType": "Helicopter",
"VictimType": "Player",
"DamageType": "*",

But not vice versa. Still waiting for author to update the plugin.

Hi guys, so i have the same problem as all of you. I already tried to add the mentioned code above, that brings heli back but also the old OnEntityDeath error, which was fixed before (but no idea what triggered it). So today i found by accident the data file CombatEntityTypes.json. In this file i found the line "BaseHelicopter". I can remember that we had a couple plugins where we needed to change the "BaseHelicopter" to "PatrolHelicopter". So i tried to replace it, but it gets overwritten everytime i reload the mod, because it takes the data from here: http://files.laserhydra.com/config/DeathNotes/v6.3.6/CombatEntityTypes

What if Mevent replaces it in this list? Maybe that would fix it? 

@ilineus you can prevent it from downloading and overwriting to keep your own changes (may need to add Helicopter to the data file as well) if you change the Host string to:
            private const string Host = "http://dns.noresolve/config/DeathNotes/v6.3.6/";​

Oh so you mean changing the link to a unavailable link that doesn't excist? Hmm i will try. Thanks. 

any fix for this yet? I tried all of the above.

Schuu

any fix for this yet? I tried all of the above.

Nope, i also tried all fixes but nothing works. Guess we have to wait:) 

Commenting to bump this - we are also still having this issue.

Hello, has anyone had success yet? 

Visegrip52

Hello, has anyone had success yet? 

Unfortunately not.. 

Bump !

I noticed that there was no posted solution to the missing Patrol Helicopter death notes issue, so I decided to research it. You will all be happy to know that I have devised a solution. I'll recap the issues at the bottom of this thread, but first, let me share the necessary code fixes to make it work. Please note that I also included a new feature that I wanted, which is to announce who tags the Patrol Helicopter. You can omit that code if you wish. I also did the same for the Bradley APC, but did not include here since it was outside the scope of the issue.

First, add the 3 lines below toward the top of your Death Notes plugin. I added the two surrounding lines for context (don't copy them):

private readonly Dictionary<ulong, AttackInfo> _previousAttack = new Dictionary<ulong, AttackInfo>();
        
//These were added by Terceran
private readonly HitInfo patrolHeliHitInfo = new HitInfo();
private uint patrolHeliTaggedEpoch = 0;
 
private readonly Func<PluginConfiguration.DeathMessage, DeathData, bool>[] _messageMatchingStages =

Next, add the 3 lines of code below to your GetCombatEntityType method.

private CombatEntityType GetCombatEntityType(BaseEntity entity)
{
   if (entity == null)
      return CombatEntityType.None;
 
   if (_combatEntityTypes.Contents != null)
   {
      if (_combatEntityTypes.Contents.ContainsKey(entity.GetType().Name))
         return _combatEntityTypes.Contents[entity.GetType().Name];
 
      if (_combatEntityTypes.Contents.ContainsKey(entity.ShortPrefabName))
      return _combatEntityTypes.Contents[entity.ShortPrefabName];
   }

   //Added by Terceran
   if (entity.GetType().Name.Equals("PatrolHelicopter"))
      return CombatEntityType.Helicopter;​
if (entity is BaseOven)
      return CombatEntityType.HeatSource;

Add this entire new method to your code (I placed mine immediately before OnEntityDeath):

//This method tracks Patrol Helicopter (Karen) damage and reports whoever tagged it.
//Added by Terceran
private void OnPatrolHelicopterTakeDamage(PatrolHelicopter victimEntity, HitInfo hitInfo) {
   if (victimEntity == null || hitInfo == null) return;

   if (hitInfo.WeaponPrefab != null && patrolHeliHitInfo.WeaponPrefab != hitInfo.WeaponPrefab)
      patrolHeliHitInfo.WeaponPrefab = hitInfo.WeaponPrefab;

   if (hitInfo.Weapon != null && patrolHeliHitInfo.Weapon != hitInfo.Weapon)
      patrolHeliHitInfo.Weapon = hitInfo.Weapon;

   if (patrolHeliHitInfo.Initiator == null && hitInfo.Initiator != null)
      patrolHeliHitInfo.Initiator = hitInfo.Initiator;

   TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970,1,1);
   uint nowEpoch = (uint)timeSpan.TotalSeconds;

   //The Patrol Helicopter (Karen) hasn't been tagged in a couple of minutes.
   if (nowEpoch - patrolHeliTaggedEpoch >= 120)
      patrolHeliTaggedEpoch = 0;
   else
      return;

   if (hitInfo.Initiator != null)
   {

      patrolHeliTaggedEpoch = nowEpoch;

      var data = new DeathData
      {
         VictimEntity = victimEntity,
         KillerEntity = victimEntity.lastAttacker ?? hitInfo?.Initiator,
         VictimEntityType = GetCombatEntityType(victimEntity),
         KillerEntityType = GetCombatEntityType(victimEntity.lastAttacker),
         DamageType = victimEntity.lastDamage,
         HitInfo = patrolHeliHitInfo
      };

      //Comment out the below if statement if you do not want to report Patrol Helicopter tagging.
      if (hitInfo.Initiator?.ToPlayer().displayName != null)
      {
         patrolHeliHitInfo.Initiator = hitInfo.Initiator;

         string weaponName = GetCustomizedWeaponName(data);
         string message = "<color=#C4FF00>" + hitInfo.Initiator?.ToPlayer().displayName +
                          "</color> has tagged the <color=#C4FF00>Patrol Helicopter (Karen)</color> with their <color=#C4FF00>" +
         weaponName + "</color>. She's going to complain to the manager!";

         if (_configuration.ShowInChat)
         {
            foreach (var player in BasePlayer.activePlayerList)
            {
               if (_configuration.RequirePermission &&
                  !permission.UserHasPermission(player.UserIDString, CanSeePermission))
                  continue;

               if (_configuration.MessageRadius != -1 &&
                  player.Distance(data.VictimEntity) > _configuration.MessageRadius)
                  continue;

               Player.Reply(
                  player,
                  _configuration.ChatFormat.Replace("{message}", message),
                  ulong.Parse(_configuration.ChatIcon)
               );
            }
         }

         if (_configuration.ShowInConsole)
            Puts(StripRichText(message));
      }
   }
}

Next, add the two code blocks below to your OnEntityDeath method:

private void OnEntityDeath(BaseCombatEntity victimEntity, HitInfo hitInfo)

{
   // Ignore - there is no victim for some reason
   if (victimEntity == null)
      return;
 
   // Try to avoid error when entity was destroyed
   if (victimEntity.gameObject == null)
      return;
 
   var data = new DeathData
   {
      VictimEntity = victimEntity,
      KillerEntity = victimEntity.lastAttacker ?? hitInfo?.Initiator,
      VictimEntityType = GetCombatEntityType(victimEntity),
      KillerEntityType = GetCombatEntityType(victimEntity.lastAttacker),
      DamageType = victimEntity.lastDamage,
      HitInfo = hitInfo
   };
 
   //Pass along our previously collected damage information.
   //Added by Terceran
   if (victimEntity.GetType().Name == "PatrolHelicopter")
      data.HitInfo = patrolHeliHitInfo;
   // Handle inconsistencies/exceptions
   HandleInconsistencies(ref data);
 
#if DEBUG
   LogDebug("[DEATHNOTES DEBUG]");
   LogDebug(
      $"VictimEntity: {data.VictimEntity?.GetType().Name ?? "NULL"} / {data.VictimEntity?.ShortPrefabName ?? "NULL"} / {data.VictimEntity?.PrefabName ?? "NULL"}");
   LogDebug(
$"KillerEntity: {data.KillerEntity?.GetType().Name ?? "NULL"} / {data.KillerEntity?.ShortPrefabName ?? "NULL"} / {data.KillerEntity?.PrefabName ?? "NULL"}");
   LogDebug($"VictimEntityType: {data.VictimEntityType}");
   LogDebug($"KillerEntityType: {data.KillerEntityType}");
   LogDebug($"DamageType: {data.DamageType}");
   LogDebug($"Bodypart: {GetCustomizedBodypartName(data.HitInfo)}");
   LogDebug($"Weapon: {hitInfo?.WeaponPrefab?.ShortPrefabName ?? "NULL"}");
#endif
 
   // Change entity type for dwellers
   RepairEntityTypes(ref data);
 
   // Ignore deaths of other entities
   if (data.KillerEntityType == CombatEntityType.Other || data.VictimEntityType == CombatEntityType.Other)
      return;
 
   // Ignore deaths which don't involve players or the helicopter which usually does not track a player as killer
   if (data.VictimEntityType != CombatEntityType.Player && data.KillerEntityType != CombatEntityType.Player &&
      data.VictimEntityType != CombatEntityType.Helicopter)
   return;
 
   // Populate the variables in the message
   string message = PopulateMessageVariables(
      // Find the best matching death message for this death
      GetDeathMessage(data),
      data
   );
 
   if (message == null)
      return;
 
   object hookResult = Interface.Call("OnDeathNotice", data.ToDictionary(), message);
 
   if (hookResult?.Equals(false) ?? false)
      return;
 
   if (_configuration.ShowInChat)
   {
      foreach (var player in BasePlayer.activePlayerList)
      {
         if (_configuration.RequirePermission &&
            !permission.UserHasPermission(player.UserIDString, CanSeePermission))
            continue;
 
         if (_configuration.MessageRadius != -1 &&
            player.Distance(data.VictimEntity) > _configuration.MessageRadius)
           continue;
 
         Player.Reply(
            player,
           _configuration.ChatFormat.Replace("{message}", message),
           ulong.Parse(_configuration.ChatIcon)
         );
      }
   }
 
   if (_configuration.ShowInConsole)
   Puts(StripRichText(message));
   //The Patrol Helicopter has been destroyed, time to clean up after ourselves.
   //Added by Terceran
   if (victimEntity.GetType().Name == "PatrolHelicopter")
   {
      patrolHeliHitInfo.Initiator = null;
      patrolHeliHitInfo.WeaponPrefab = null;
      patrolHeliHitInfo.Weapon = null;
      patrolHeliTaggedEpoch = 0;
   }
}

That's it! To recap the issue, the Patrol Helicopter was erroneously omitted from the GetCombatEntityType method, so the Patrol Helicopter was never being classified correctly. Next, even once that was corrected, there is yet another issue where the information regarding the damage done to the Patrol Helicopter was missing. This included who was attacking it, with what weapon, etc. So, we needed to track that information as damage was being inflicted to the Patrol Helicopter and supply it to Death Notes once the Patrol Helicopter was destroyed. I certainly hope this analysis and fix is useful to everyone.

P.S. - I apologize for the poor code formatting. I'm apparently better at fixing bugs than I am at posting code.









Merged post

I made a few small corrections to the OnPatrolHelicopterTakeDamage method, please use this version instead of the one I previously posted:

//This method tracks Patrol Helicopter (Karen) damage and reports whoever tagged it.
//Added by Terceran
private void OnPatrolHelicopterTakeDamage(PatrolHelicopter victimEntity, HitInfo hitInfo) {
   if (victimEntity == null || hitInfo == null) return;

   if (hitInfo.WeaponPrefab != null && patrolHeliHitInfo.WeaponPrefab != hitInfo.WeaponPrefab)
      patrolHeliHitInfo.WeaponPrefab = hitInfo.WeaponPrefab;

   if (hitInfo.Weapon != null && patrolHeliHitInfo.Weapon != hitInfo.Weapon)
      patrolHeliHitInfo.Weapon = hitInfo.Weapon;

   if (patrolHeliHitInfo.Initiator == null && hitInfo.Initiator != null)
      patrolHeliHitInfo.Initiator = hitInfo.Initiator;

   TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970,1,1);
   uint nowEpoch = (uint)timeSpan.TotalSeconds;

   //The Patrol Helicopter (Karen) has been hit within a couple of minutes.
   if (nowEpoch - patrolHeliTaggedEpoch < 120)
   {
      patrolHeliTaggedEpoch = nowEpoch;
      return;
   }

   patrolHeliTaggedEpoch = nowEpoch;

   if (hitInfo.Initiator != null)
   {

      var data = new DeathData
      {
         VictimEntity = victimEntity,
         KillerEntity = victimEntity.lastAttacker ?? hitInfo?.Initiator,
         VictimEntityType = GetCombatEntityType(victimEntity),
         KillerEntityType = GetCombatEntityType(victimEntity.lastAttacker),
         DamageType = victimEntity.lastDamage,
         HitInfo = patrolHeliHitInfo
      };

      //Comment out the below if statement if you do not want to report Patrol Helicopter tagging.
      if (hitInfo.Initiator?.ToPlayer().displayName != null)
      {
         patrolHeliHitInfo.Initiator = hitInfo.Initiator;

         string weaponName = GetCustomizedWeaponName(data);
         string message = "<color=#C4FF00>" + hitInfo.Initiator?.ToPlayer().displayName +
                          "</color> has tagged the <color=#C4FF00>Patrol Helicopter (Karen)</color> with their <color=#C4FF00>" +
         weaponName + "</color>. She's going to complain to the manager!";

         object hookResult = Interface.Call("OnDeathNotice", data.ToDictionary(), message);

         if (hookResult?.Equals(false) ?? false)
            return;

         if (_configuration.ShowInChat)
         {
            foreach (var player in BasePlayer.activePlayerList)
            {
               if (_configuration.RequirePermission &&
                  !permission.UserHasPermission(player.UserIDString, CanSeePermission))
                  continue;

               if (_configuration.MessageRadius != -1 &&
                  player.Distance(data.VictimEntity) > _configuration.MessageRadius)
                  continue;

               Player.Reply(
                  player,
                  _configuration.ChatFormat.Replace("{message}", message),
                  ulong.Parse(_configuration.ChatIcon)
               );
            }
         }

         if (_configuration.ShowInConsole)
            Puts(StripRichText(message));
      }
   }
}​

I'm not in the topic about the issue, I just thought it was awesome you went to that trouble.

I haven't the chance to test that out yet, but I have applied it all. If I get the chance to test it out, I'll let you know how it goes.

6qTbv7hGBYxfSGN.jpg Terceran

Thanks man .. will test it on my server <3 the work



Merged post

Confirm works mucho gracias