/// <summary>
 /// [Extension method] Clone a damageKeywordPair by Value and damageKeywordDef. This should be enough
 /// to prevent any shallow copy issues. </summary>
 /// <param name="dkp">The damageKeywordPair to clone</param>
 /// <returns>A semi-fresh copy of the dkp</returns>
 public static DamageKeywordPair Clone(this DamageKeywordPair dkp)
 {
     return(new DamageKeywordPair()
     {
         Value = dkp.Value,
         DamageKeywordDef = dkp.DamageKeywordDef
     });
 }
 private static float SyncDamage(this WeaponDef weapon, DamageKeywordDef damageType, Func <float, float> handler)
 {
     lock ( weapon ) {
         if (weapon == null)
         {
             throw new ArgumentNullException(nameof(weapon));
         }
         if (damageType == null)
         {
             throw new ArgumentNullException(nameof(damageType));
         }
         var list = weapon.DamagePayload.DamageKeywords;
         var pair = list.FirstOrDefault(e => e.DamageKeywordDef == damageType);
         var orig = pair?.Value ?? 0;
         if (handler == null)
         {
             return(orig);
         }
         var value = handler(orig);
         if (value == orig)
         {
             return(orig);
         }
         object[] logArg = new object[] { weapon.name, damageType.name, orig, value };
         if (value > 0)
         {
             if (pair == null)
             {
                 ZyMod.ApiLog(TraceEventType.Start, "Adding {1} {3} to {0}", logArg);
                 list.Add(pair = new DamageKeywordPair {
                     DamageKeywordDef = damageType, Value = value
                 });
             }
             else
             {
                 ZyMod.ApiLog(TraceEventType.Start, "Update {0} {1} {2} to {3}", logArg);
                 pair.Value = value;
             }
         }
         else if (pair != null)
         {
             ZyMod.ApiLog(TraceEventType.Start, "Removing {1} {2} from {0}", logArg);
             list.Remove(pair);
         }
         return(orig);
     }
 }
 /// <summary>
 /// [Extension method] Compares this instance with a specified <seealso cref="DamageKeywordPair"/>
 /// object and indicates whether this instance precedes, follows, or appears in the same position
 /// in the sort order as the specified <seealso cref="DamageKeywordPair"/>.
 /// </summary>
 /// <param name="dkpB">The <seealso cref="DamageKeywordPair"/> to compare to this instance</param>
 /// <returns>-1 if A comes first, 1 if B comes first, 0 if they sort in the same place.</returns>
 public static int CompareTo(this DamageKeywordPair dkpA, DamageKeywordPair dkpB)
 {
     return(dkpA.DamageKeywordDef.CompareTo(dkpB.DamageKeywordDef));
 }