Ejemplo n.º 1
0
        /// <summary>
        /// Merge data from another participant into this participant.
        /// </summary>
        public void Merge(FightParticipant p, int intervalOffset = 0, int timeOffset = 0)
        {
            OutboundMissCount   += p.OutboundMissCount;
            OutboundHitCount    += p.OutboundHitCount;
            OutboundHitSum      += p.OutboundHitSum;
            OutboundStrikeCount += p.OutboundStrikeCount;

            InboundMissCount  += p.InboundMissCount;
            InboundHitCount   += p.InboundHitCount;
            InboundHitSum     += p.InboundHitSum;
            InboundMeleeCount += p.InboundMeleeCount;
            InboundMeleeSum   += p.InboundMeleeSum;
            InboundRiposteSum += p.InboundRiposteSum;
            //InboundSpellCount += p.InboundSpellCount;
            //InboundSpellSum += p.InboundSpellSum;
            InboundStrikeCount += p.InboundStrikeCount;

            OutboundHealSum    += p.OutboundHealSum;
            InboundHealSum     += p.InboundHealSum;
            InboundFullHealSum += p.InboundFullHealSum;

            DeathCount += p.DeathCount;

            // merge intervals starting at 'intervalOffset' base
            for (var i = 0; i < p.DPS.Count; i++)
            {
                while (DPS.Count <= intervalOffset + i)
                {
                    DPS.Add(0);
                }
                DPS[intervalOffset + i] += p.DPS[i];
            }

            for (var i = 0; i < p.TankDPS.Count; i++)
            {
                while (TankDPS.Count <= intervalOffset + i)
                {
                    TankDPS.Add(0);
                }
                TankDPS[intervalOffset + i] += p.TankDPS[i];
            }

            for (var i = 0; i < p.HPS.Count; i++)
            {
                while (HPS.Count <= intervalOffset + i)
                {
                    HPS.Add(0);
                }
                HPS[intervalOffset + i] += p.HPS[i];
            }

            for (var i = 0; i < p.InboundHPS.Count; i++)
            {
                while (InboundHPS.Count <= intervalOffset + i)
                {
                    InboundHPS.Add(0);
                }
                InboundHPS[intervalOffset + i] += p.InboundHPS[i];
            }


            foreach (var at in p.AttackTypes)
            {
                var _at = AttackTypes.FirstOrDefault(x => x.Type == at.Type);
                if (_at == null)
                {
                    _at      = new FightHit();
                    _at.Type = at.Type;
                    AttackTypes.Add(_at);
                }
                _at.Merge(at);
            }

            foreach (var dt in p.DefenseTypes)
            {
                var _dt = DefenseTypes.FirstOrDefault(x => x.Type == dt.Type);
                if (_dt == null)
                {
                    _dt      = new FightMiss();
                    _dt.Type = dt.Type;
                    DefenseTypes.Add(_dt);
                }
                _dt.Merge(dt);
            }

            foreach (var h in p.Heals)
            {
                var _h = Heals.FirstOrDefault(x => x.Target == h.Target);
                if (_h == null)
                {
                    _h        = new FightHeal();
                    _h.Target = h.Target;
                    Heals.Add(_h);
                }
                _h.Merge(h);
            }

            foreach (var s in p.Spells)
            {
                var _s = Spells.FirstOrDefault(x => x.Name == s.Name && x.Type == s.Type);
                if (_s == null)
                {
                    _s      = new FightSpell();
                    _s.Type = s.Type;
                    _s.Name = s.Name;
                    //_s.Times =  // todo
                    Spells.Add(_s);
                }
                _s.Merge(s);
            }

            // disabled - merging buffs will create duplicates if fights overlap and include the same buff
            // it would be better to recreate buffs after merging
            p.Buffs.Clear();

            // >= 0 avoids any pre fight buffs
            //foreach (var b in p.Buffs.Where(x => x.Time >= 0))
            //{
            //    if (timeOffset == 0)
            //        Buffs.Add(b);
            //    else
            //        Buffs.Add(new FightBuff { Name = b.Name, Time = b.Time + timeOffset });
            //}
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Merges damage, heals and spells from a pet into this participant.
        /// Tanking is not merged.
        /// All data will be prefixed with "pet:" to distinguish it from the owner. e.g. "pet:slash" vs "slash"
        /// </summary>
        public void MergePet(FightParticipant pet)
        {
            foreach (var at in pet.AttackTypes)
            {
                at.Type = "pet:" + at.Type;
                //owner.AttackTypes.Add(hit);
                var match = AttackTypes.FirstOrDefault(x => x.Type == at.Type);
                if (match != null)
                {
                    match.Merge(at);
                }
                else
                {
                    AttackTypes.Add(at);
                }
            }

            foreach (var spell in pet.Spells.Where(x => x.Type == "hit"))
            {
                spell.Name = "pet:" + spell.Name;
                var match = Spells.FirstOrDefault(x => x.Type == spell.Type && x.Name == spell.Name);
                if (match != null)
                {
                    match.Merge(spell);
                }
                else
                {
                    Spells.Add(spell);
                }
            }

            OutboundHitCount  += pet.OutboundHitCount;
            OutboundHitSum    += pet.OutboundHitSum;
            OutboundMissCount += pet.OutboundMissCount;

            // merges DPS and HPS intervals (but not TankDPS or InboundHPS)
            for (var i = 0; i < pet.DPS.Count; i++)
            {
                while (DPS.Count <= i)
                {
                    DPS.Add(0);
                }
                DPS[i] += pet.DPS[i];
            }

            for (var i = 0; i < pet.HPS.Count; i++)
            {
                while (HPS.Count <= i)
                {
                    HPS.Add(0);
                }
                HPS[i] += pet.HPS[i];
            }

            // removing the pet has the downside of hiding pet tanking
            //Participants.Remove(pet);

            // clear the damage on the pet but keep it for tanking stats
            pet.OutboundHitCount  = 0;
            pet.OutboundHitSum    = 0;
            pet.OutboundMissCount = 0;
            pet.AttackTypes.Clear();
            //pet.Spells.Clear();
            pet.Spells.RemoveAll(x => x.Type == "hit"); // leave heals on pet so it shows on the healer list
            pet.DPS.Clear();
            pet.HPS.Clear();
        }
Ejemplo n.º 3
0
        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"
                        });
                    }
                }
            }
        }