private void TrackHit(LogHitEvent hit) { var foe = Chars.GetFoe(hit.Source, hit.Target); if (foe == null) { //Console.WriteLine("*** " + hit); if (hit.Source != hit.Target) { PendingHits.Add(hit); } return; } if (hit.Source.EndsWith("'s corpse")) { if (hit.Target == foe) { // rename source to track damage from dead player hit = new LogHitEvent { Timestamp = hit.Timestamp, Type = hit.Type, Source = hit.Source.Substring(0, hit.Source.Length - 9), Target = hit.Target, Amount = hit.Amount, Mod = hit.Mod, Spell = hit.Spell }; } else { // do not track damage from a dead mob return; } } var f = GetOrAddFight(foe); if (f == null) { return; } f.AddHit(hit); //LastHit = hit; LastFight = f; }
/// <summary> /// Get tick offset from beginning of fight. This is used as the index for the damage/healing arrays. /// </summary> //private int GetTick(LogEvent e) //{ // var interval = (int)(e.Timestamp - StartedOn).TotalSeconds / 6; // // if the log is altered and entries are saved out of order then our intervals might be negative // if (interval < 0) // interval = 0; // return interval; //} public void AddHit(LogHitEvent hit) { var interval = GetTick(hit.Timestamp); // hit source may be null if caster dies if (hit.Source != null) { AddParticipant(hit.Source).AddHit(hit, interval); } AddParticipant(hit.Target).AddHit(hit, interval); // special counters for the mob/target only //if (hit.Source == Name) //{ // if (hit.Special != null && hit.Special.Contains("strikethrough")) // { // StrikeCount += 1; // } //} }
public void AddHit(LogHitEvent hit, int interval = -1) { if (FirstAction == null) { FirstAction = hit.Timestamp; } LastAction = hit.Timestamp; if (hit.Source == Name) { OutboundHitCount += 1; OutboundHitSum += hit.Amount; if (hit.Spell != null) { //OutboundSpellCount += 1; //OutboundSpellSum += hit.Amount; var spell = AddSpell(hit.Spell, "hit"); spell.HitCount += 1; spell.HitSum += hit.Amount; if (hit.Amount > spell.HitMax) { spell.HitMax = hit.Amount; } if (hit.Mod.HasFlag(LogEventMod.Critical)) { spell.CritCount += 1; spell.CritSum += hit.Amount; } if (hit.Mod.HasFlag(LogEventMod.Twincast)) { spell.TwinCount += 1; //spell.TwinSum += hit.Amount; } } else { //if (hit.Amount > OutboundMaxHit) //{ // OutboundMaxHit = hit.Amount; //} //OutboundMeleeCount += 1; //OutboundMeleeSum += hit.Amount; } var type = hit.Type; // alter the attack type on some special hits if (hit.Mod.HasFlag(LogEventMod.Finishing_Blow)) { type = "finishing"; } else if (hit.Mod.HasFlag(LogEventMod.Headshot)) { type = "headshot"; } else if (hit.Mod.HasFlag(LogEventMod.Assassinate)) { type = "assassinate"; } else if (hit.Mod.HasFlag(LogEventMod.Decapitate)) { type = "decapitate"; } else if (hit.Mod.HasFlag(LogEventMod.Slay_Undead)) { type = "slay"; } //else if (hit.Mod.HasFlag(LogEventMod.Special)) // type += ":special"; else if (hit.Mod.HasFlag(LogEventMod.Riposte)) { type = "riposte"; } var at = AddAttack(type); at.HitCount += 1; at.HitSum += hit.Amount; if (hit.Amount > at.HitMax) { at.HitMax = hit.Amount; } if (hit.Mod.HasFlag(LogEventMod.Critical)) { at.CritCount += 1; at.CritSum += hit.Amount; } if (hit.Mod.HasFlag(LogEventMod.Strikethrough)) { OutboundStrikeCount += 1; } if (interval >= 0) { while (DPS.Count <= interval) { DPS.Add(0); } DPS[interval] += hit.Amount; } } else if (hit.Target == Name) { InboundHitCount += 1; InboundHitSum += hit.Amount; if (hit.Spell != null) { //InboundSpellSum += hit.Amount; } else { InboundMeleeCount += 1; InboundMeleeSum += hit.Amount; if (interval >= 0) { while (TankDPS.Count <= interval) { TankDPS.Add(0); } TankDPS[interval] += hit.Amount; } //TankHits.TryGetValue(hit.Amount, out int count); //TankHits[hit.Amount] = count + 1; } if (hit.Mod.HasFlag(LogEventMod.Riposte)) { InboundRiposteSum += hit.Amount; } if (hit.Mod.HasFlag(LogEventMod.Strikethrough)) { InboundStrikeCount += 1; // strikethroughs are reported on hits and riposte, but other defenses do get not reported on a strikethrough // in order to properly count these defenses we should log a mystery defense that was never reported // i.e. for riposte the log will show this: // [Wed Jan 19 20:54:58 2022] A shadowbone tries to bash YOU, but YOU riposte!(Strikethrough) // [Wed Jan 19 20:54:58 2022] A shadowbone bashes YOU for 5625 points of damage. (Riposte Strikethrough) // but for dodge/parry/etc.. it will only show this: // [Wed Jan 19 20:54:58 2022] A shadowbone bashes YOU for 5625 points of damage. (Strikethrough) if (!hit.Mod.HasFlag(LogEventMod.Riposte)) { AddMiss(new LogMissEvent { Timestamp = hit.Timestamp, Source = hit.Source, Target = hit.Target, Type = "unknown" }); } } } }