internal void AddLootRecord(LootRecord record, double beginTime) { Helpers.AddAction(AllLootBlocks, record, beginTime); if (!record.IsCurrency && record.Quantity == 1 && AssignedLoot.Count > 0) { var found = AssignedLoot.FindLastIndex(item => item.Player == record.Player && item.Item == record.Item); if (found > -1) { AssignedLoot.RemoveAt(found); foreach (var block in AllLootBlocks.OrderByDescending(block => block.BeginTime)) { found = block.Actions.FindLastIndex(item => item is LootRecord loot && loot.Player == record.Player && loot.Item == record.Item); if (found > -1) { lock (block.Actions) { block.Actions.RemoveAt(found); } } } } } else if (!record.IsCurrency && record.Quantity == 0) { AssignedLoot.Add(record); } }
internal void AddResistRecord(ResistRecord record, double beginTime) { Helpers.AddAction(AllResistBlocks, record, beginTime); if (SpellsNameDB.TryGetValue(record.Spell, out SpellData spellData)) { UpdateNpcSpellResistStats(record.Defender, spellData.Resist, true); } }
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (LastFightProcessTime != processed.BeginTime) { DataManager.Instance.CheckExpireFights(processed.BeginTime); } if (IsValidAttack(processed.Record, out bool defender)) { if (!double.IsNaN(LastFightProcessTime)) { var seconds = processed.BeginTime - LastFightProcessTime; if (seconds >= GROUP_TIMEOUT) { CurrentGroupID++; } } string origTimeString = processed.OrigTimeString.Substring(4, 15); Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Attacker, processed.BeginTime); fight.Total += processed.Record.Total; fight.BeginDamageTime = double.IsNaN(fight.BeginDamageTime) ? processed.BeginTime : fight.BeginDamageTime; fight.LastDamageTime = processed.BeginTime; fight.DamageHits++; } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Defender, processed.BeginTime); fight.BeginTankingTime = double.IsNaN(fight.BeginTankingTime) ? processed.BeginTime : fight.BeginTankingTime; fight.LastTankingTime = processed.BeginTime; fight.TankHits++; } fight.LastTime = processed.BeginTime; LastFightProcessTime = processed.BeginTime; var ttl = fight.LastTime - fight.BeginTime + 1; fight.TooltipText = string.Format(CultureInfo.CurrentCulture, "#Hits To Players: {0}, #Hits From Players: {1}, Time Alive: {2}s", fight.TankHits, fight.DamageHits, ttl); DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight); if (defender) { EventsPlayerAttackProcessed?.Invoke(processed.Record, processed); } } }
internal void AddResistRecord(ResistRecord record, double beginTime) { Helpers.AddAction(AllResistBlocks, record, beginTime); if (SpellsNameDB.TryGetValue(record.Spell, out List <SpellData> spellList)) { if (spellList.Find(item => !item.IsBeneficial) is SpellData spellData) { UpdateNpcSpellResistStats(record.Defender, spellData.Resist, true); } } }
internal void AddSpellCast(SpellCast cast, double beginTime) { if (SpellsNameDB.ContainsKey(cast.Spell)) { Helpers.AddAction(AllSpellCastBlocks, cast, beginTime); AllUniqueSpellCasts[cast.Spell] = 1; if (SpellsToClass.TryGetValue(cast.Spell, out SpellClass theClass)) { PlayerManager.Instance.UpdatePlayerClassFromSpell(cast, theClass); } } }
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (IsValidAttack(processed.Record, processed.BeginTime, out bool defender)) { if (!double.IsNaN(LastUpdateTime)) { var seconds = processed.BeginTime - LastUpdateTime; if (seconds >= GROUP_TIMEOUT) { CurrentGroupID++; } } string origTimeString = processed.OrigTimeString.Substring(4, 15); Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); fight.Total += processed.Record.Total; } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); } fight.LastTime = processed.BeginTime; LastUpdateTime = processed.BeginTime; DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight); if (defender) { EventsPlayerAttackProcessed?.Invoke(processed.Record, processed); } } }
internal void AddHealRecord(HealRecord record, double beginTime) { record.Healer = PlayerManager.Instance.ReplacePlayer(record.Healer, record.Healed); record.Healed = PlayerManager.Instance.ReplacePlayer(record.Healed, record.Healer); Helpers.AddAction(AllHealBlocks, record, beginTime); }
internal void AddReceivedSpell(ReceivedSpell received, double beginTime) => Helpers.AddAction(AllReceivedSpellBlocks, received, beginTime);
internal void AddResistRecord(ResistRecord record, double beginTime) => Helpers.AddAction(AllResistBlocks, record, beginTime);
internal void AddMiscRecord(IAction action, double beginTime) => Helpers.AddAction(AllMiscBlocks, action, beginTime);
internal void AddLootRecord(LootRecord record, double beginTime) => Helpers.AddAction(AllLootBlocks, record, beginTime);
internal void AddDeathRecord(DeathRecord record, double beginTime) => Helpers.AddAction(AllDeathBlocks, record, beginTime);
private void HandleDamageProcessed(object sender, DamageProcessedEvent processed) { if (LastFightProcessTime != processed.BeginTime) { DataManager.Instance.CheckExpireFights(processed.BeginTime); ValidCombo.Clear(); if (processed.BeginTime - LastFightProcessTime > RECENTSPELLTIME) { RecentSpellCache.Clear(); } } // cache recent player spells to help determine who the caster was var isAttackerPlayer = PlayerManager.Instance.IsPetOrPlayer(processed.Record.Attacker) || processed.Record.Attacker == Labels.RS; if (isAttackerPlayer && (processed.Record.Type == Labels.DD || processed.Record.Type == Labels.DOT || processed.Record.Type == Labels.PROC)) { RecentSpellCache[processed.Record.SubType] = true; } string comboKey = processed.Record.Attacker + "=" + processed.Record.Defender; if (ValidCombo.TryGetValue(comboKey, out bool defender) || IsValidAttack(processed.Record, isAttackerPlayer, out defender)) { ValidCombo[comboKey] = defender; bool isNonTankingFight = false; string origTimeString = processed.OrigTimeString.Substring(4, 15); // fix for unknown spells having a good name to work from if (processed.Record.AttackerIsSpell && defender) { processed.Record.Attacker = Labels.UNK; } Fight fight = Get(processed.Record, processed.BeginTime, origTimeString, defender); if (defender) { Helpers.AddAction(fight.DamageBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Attacker, processed.BeginTime); fight.BeginDamageTime = double.IsNaN(fight.BeginDamageTime) ? processed.BeginTime : fight.BeginDamageTime; fight.LastDamageTime = processed.BeginTime; if (StatsUtil.IsHitType(processed.Record.Type)) { fight.DamageHits++; fight.Total += processed.Record.Total; isNonTankingFight = fight.DamageHits == 1; var attacker = processed.Record.AttackerOwner ?? processed.Record.Attacker; if (fight.PlayerTotals.TryGetValue(attacker, out FightTotalDamage total)) { total.Damage += (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total; total.DamageWithBane += processed.Record.Total; total.Name = processed.Record.Attacker; total.PetOwner = total.PetOwner ?? processed.Record.AttackerOwner; total.UpdateTime = processed.BeginTime; } else { fight.PlayerTotals[attacker] = new FightTotalDamage { Damage = (processed.Record.Type == Labels.BANE) ? 0 : processed.Record.Total, DamageWithBane = processed.Record.Total, Name = processed.Record.Attacker, PetOwner = processed.Record.AttackerOwner, UpdateTime = processed.BeginTime, BeginTime = processed.BeginTime }; } SpellDamageStats stats = null; var spellKey = processed.Record.Attacker + "++" + processed.Record.SubType; if (processed.Record.Type == Labels.DD) { if (!fight.DDDamage.TryGetValue(spellKey, out stats)) { stats = new SpellDamageStats { Caster = processed.Record.Attacker, Spell = processed.Record.SubType }; fight.DDDamage[spellKey] = stats; } } else if (processed.Record.Type == Labels.DOT) { if (!fight.DoTDamage.TryGetValue(spellKey, out stats)) { stats = new SpellDamageStats { Caster = processed.Record.Attacker, Spell = processed.Record.SubType }; fight.DoTDamage[spellKey] = stats; } } if (stats != null) { stats.Count += 1; stats.Max = Math.Max(processed.Record.Total, stats.Max); stats.Total += processed.Record.Total; } // only a pet can 'hit' with a Flurry since players only crush/slash/punch/pierce with main hand weapons if (processed.Record.AttackerOwner == null && processed.Record.Type == Labels.MELEE && processed.Record.SubType == "Hits" && LineModifiersParser.IsFlurry(processed.Record.ModifiersMask)) { PlayerManager.Instance.AddVerifiedPet(processed.Record.Attacker); } } } else { Helpers.AddAction(fight.TankingBlocks, processed.Record, processed.BeginTime); AddPlayerTime(fight, processed.Record, processed.Record.Defender, processed.BeginTime); fight.BeginTankingTime = double.IsNaN(fight.BeginTankingTime) ? processed.BeginTime : fight.BeginTankingTime; fight.LastTankingTime = processed.BeginTime; if (StatsUtil.IsHitType(processed.Record.Type)) { fight.TankHits++; } } fight.LastTime = processed.BeginTime; LastFightProcessTime = processed.BeginTime; var ttl = fight.LastTime - fight.BeginTime + 1; fight.TooltipText = string.Format(CultureInfo.CurrentCulture, "#Hits To Players: {0}, #Hits From Players: {1}, Time Alive: {2}s", fight.TankHits, fight.DamageHits, ttl); DataManager.Instance.UpdateIfNewFightMap(fight.CorrectMapKey, fight, isNonTankingFight); } }