private void calculateSupport()
        {
            foreach (Player player in log.getPlayerList())
            {
                Statistics.FinalSupport[] phaseSupport = new Statistics.FinalSupport[phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    Statistics.FinalSupport final = new Statistics.FinalSupport();

                    PhaseData phase = phases[phaseIndex];
                    long      start = phase.getStart() + log.getBossData().getFirstAware();
                    long      end   = phase.getEnd() + log.getBossData().getFirstAware();

                    // List<DamageLog> damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData());
                    int instid = player.getInstid();

                    int[] resArray     = player.getReses(log, phase.getStart(), phase.getEnd());
                    int[] cleanseArray = player.getCleanses(log, phase.getStart(), phase.getEnd());
                    final.resurrects       = resArray[0];
                    final.ressurrectTime   = resArray[1] / 1000f;
                    final.condiCleanse     = cleanseArray[0];
                    final.condiCleanseTime = cleanseArray[1] / 1000f;

                    phaseSupport[phaseIndex] = final;
                }
                statistics.support[player] = phaseSupport;
            }
        }
        private void calculateDefenses()
        {
            foreach (Player player in log.getPlayerList())
            {
                Statistics.FinalDefenses[] phaseDefense = new Statistics.FinalDefenses[phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    Statistics.FinalDefenses final = new Statistics.FinalDefenses();

                    PhaseData phase = phases[phaseIndex];
                    long      start = phase.getStart() + log.getBossData().getFirstAware();
                    long      end   = phase.getEnd() + log.getBossData().getFirstAware();

                    List <DamageLog> damageLogs = player.getDamageTakenLogs(log, phase.getStart(), phase.getEnd());

                    int instID = player.getInstid();



                    final.damageTaken    = damageLogs.Select(x => (long)x.getDamage()).Sum();
                    final.blockedCount   = 0;
                    final.invulnedCount  = 0;
                    final.damageInvulned = 0;
                    final.evadedCount    = 0;
                    final.damageBarrier  = 0;
                    foreach (DamageLog log in damageLogs.Where(x => x.getResult() == ParseEnum.Result.Block))
                    {
                        final.blockedCount++;
                    }
                    foreach (DamageLog log in damageLogs.Where(x => x.getResult() == ParseEnum.Result.Absorb))
                    {
                        final.invulnedCount++;
                        final.damageInvulned += log.getDamage();
                    }
                    foreach (DamageLog log in damageLogs.Where(x => x.getResult() == ParseEnum.Result.Evade))
                    {
                        final.evadedCount++;
                    }
                    foreach (DamageLog log in damageLogs.Where(x => x.isShields() == 1))
                    {
                        final.damageBarrier += log.getDamage();
                    }

                    phaseDefense[phaseIndex] = final;
                }
                statistics.defenses[player] = phaseDefense;
            }
        }
        private Dictionary <int, Statistics.FinalBoonUptime> getBoonsForList(List <Player> playerList, Player player, List <Boon> to_track, int phaseIndex)
        {
            PhaseData phase         = phases[phaseIndex];
            long      fightDuration = phase.getEnd() - phase.getStart();

            Dictionary <Player, BoonDistribution> boonDistributions = new Dictionary <Player, BoonDistribution>();

            foreach (Player p in playerList)
            {
                boonDistributions[p] = p.getBoonDistribution(log, phases, to_track, phaseIndex);
            }

            Dictionary <int, Statistics.FinalBoonUptime> final =
                new Dictionary <int, Statistics.FinalBoonUptime>();

            foreach (Boon boon in to_track)
            {
                long totalGeneration = 0;
                long totalOverstack  = 0;
                long totalUptime     = 0;

                foreach (BoonDistribution boons in boonDistributions.Values)
                {
                    if (boons.ContainsKey(boon.getID()))
                    {
                        totalGeneration += boons.getGeneration(boon.getID(), player.getInstid());
                        totalOverstack  += boons.getOverstack(boon.getID(), player.getInstid());
                        totalUptime     += boons.getUptime(boon.getID());
                    }
                }

                Statistics.FinalBoonUptime uptime = new Statistics.FinalBoonUptime();

                if (boon.getType() == Boon.BoonType.Duration)
                {
                    uptime.uptime     = Math.Round(100.0 * totalUptime / fightDuration / playerList.Count, 1);
                    uptime.generation = Math.Round(100.0f * totalGeneration / fightDuration / playerList.Count, 1);
                    uptime.overstack  = Math.Round(100.0f * totalOverstack / fightDuration / playerList.Count, 1);
                }
                else if (boon.getType() == Boon.BoonType.Intensity)
                {
                    uptime.uptime     = Math.Round((double)totalUptime / fightDuration / playerList.Count, 1);
                    uptime.generation = Math.Round((double)totalGeneration / fightDuration / playerList.Count, 1);
                    uptime.overstack  = Math.Round((double)totalOverstack / fightDuration / playerList.Count, 1);
                }

                uptime.boonType = boon.getType();

                final[boon.getID()] = uptime;
            }

            return(final);
        }
示例#4
0
        public static List <Point> getDPSGraph(ParsedLog log, AbstractPlayer p, int phase_index, ushort dstid, GraphMode mode)
        {
            int asked_id = (phase_index + "_" + dstid + "_" + mode).GetHashCode();

            if (p.getDPSGraph(asked_id).Count > 0)
            {
                return(p.getDPSGraph(asked_id));
            }

            List <Point>     dmgList     = new List <Point>();
            List <Point>     dmgList10s  = new List <Point>();
            List <Point>     dmgList30s  = new List <Point>();
            PhaseData        phase       = log.getBoss().getPhases(log, settings.ParsePhases)[phase_index];
            List <DamageLog> damage_logs = p.getDamageLogs(dstid, log, phase.getStart(), phase.getEnd());
            // fill the graph, full precision
            List <double> dmgListFull = new List <double>();

            for (int i = 0; i <= phase.getDuration(); i++)
            {
                dmgListFull.Add(0.0);
            }
            int total_time   = 1;
            int total_damage = 0;

            foreach (DamageLog dl in damage_logs)
            {
                int time = (int)(dl.getTime() - phase.getStart());
                // fill
                for (; total_time < time; total_time++)
                {
                    dmgListFull[total_time] = total_damage;
                }
                total_damage           += dl.getDamage();
                dmgListFull[total_time] = total_damage;
            }
            // fill
            for (; total_time <= phase.getDuration(); total_time++)
            {
                dmgListFull[total_time] = total_damage;
            }
            dmgList.Add(new Point(0, 0));
            dmgList10s.Add(new Point(0, 0));
            dmgList30s.Add(new Point(0, 0));
            for (int i = 1; i <= phase.getDuration("s"); i++)
            {
                int limit_id = 0;
                dmgList.Add(new Point(i, (int)Math.Round((dmgListFull[1000 * i] - dmgListFull[1000 * limit_id]) / (i - limit_id))));
                if (settings.Show10s)
                {
                    limit_id = Math.Max(i - 10, 0);
                    dmgList10s.Add(new Point(i, (int)Math.Round((dmgListFull[1000 * i] - dmgListFull[1000 * limit_id]) / (i - limit_id))));
                }
                if (settings.Show30s)
                {
                    limit_id = Math.Max(i - 30, 0);
                    dmgList30s.Add(new Point(i, (int)Math.Round((dmgListFull[1000 * i] - dmgListFull[1000 * limit_id]) / (i - limit_id))));
                }
            }
            int id = (phase_index + "_" + dstid + "_" + GraphMode.Full).GetHashCode();

            p.addDPSGraph(id, dmgList);
            if (settings.Show10s)
            {
                id = (phase_index + "_" + dstid + "_" + GraphMode.s10).GetHashCode();
                p.addDPSGraph(id, dmgList10s);
            }
            if (settings.Show30s)
            {
                id = (phase_index + "_" + dstid + "_" + GraphMode.s30).GetHashCode();
                p.addDPSGraph(id, dmgList30s);
            }
            return(p.getDPSGraph(asked_id));
        }
        private Statistics.FinalDPS getFinalDPS(AbstractPlayer player, int phaseIndex)
        {
            Statistics.FinalDPS final = new Statistics.FinalDPS();

            PhaseData phase = phases[phaseIndex];

            double phaseDuration = (phase.getDuration()) / 1000.0;

            double damage = 0.0;
            double dps    = 0.0;

            // All DPS
            damage = player.getDamageLogs(0, log, phase.getStart(),
                                          phase.getEnd())
                     .Sum(x => x.getDamage());
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.allDps    = (int)dps;
            final.allDamage = (int)damage;

            // All Condi DPS
            damage = player.getDamageLogs(0, log, phase.getStart(),
                                          phase.getEnd())
                     .Where(x => x.isCondi() > 0).Sum(x => x.getDamage());
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.allCondiDps    = (int)dps;
            final.allCondiDamage = (int)damage;

            // All Power DPS
            damage = final.allDamage - damage;
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.allPowerDps    = (int)dps;
            final.allPowerDamage = (int)damage;

            // Boss DPS
            damage = player.getDamageLogs(log.getBossData().getInstid(), log,
                                          phase.getStart(), phase.getEnd()).Sum(x => x.getDamage());
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.bossDps    = (int)dps;
            final.bossDamage = (int)damage;


            // Boss Condi DPS
            damage = player.getDamageLogs(log.getBossData().getInstid(), log,
                                          phase.getStart(), phase.getEnd()).Where(x => x.isCondi() > 0).Sum(x => x.getDamage());
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.bossCondiDps    = (int)dps;
            final.bossCondiDamage = (int)dps;

            // Boss Power DPS
            damage = final.bossDamage - damage;
            if (phaseDuration > 0)
            {
                dps = damage / phaseDuration;
            }

            final.bossPowerDps    = (int)dps;
            final.bossPowerDamage = (int)damage;

            return(final);
        }
        private void calculateBoons()
        {
            // Player Boons
            foreach (Player player in log.getPlayerList())
            {
                List <Boon> boon_to_track = new List <Boon>();
                boon_to_track.AddRange(statistics.present_boons);
                boon_to_track.AddRange(statistics.present_offbuffs);
                boon_to_track.AddRange(statistics.present_defbuffs);
                boon_to_track.AddRange(statistics.present_personnal[player.getInstid()]);
                Dictionary <int, Statistics.FinalBoonUptime>[] phaseBoons = new Dictionary <int, Statistics.FinalBoonUptime> [phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    Dictionary <int, Statistics.FinalBoonUptime> final = new Dictionary <int, Statistics.FinalBoonUptime>();

                    PhaseData phase = phases[phaseIndex];

                    BoonDistribution selfBoons = player.getBoonDistribution(log, phases, boon_to_track, phaseIndex);

                    long fightDuration = phase.getEnd() - phase.getStart();
                    foreach (Boon boon in Boon.getAllBuffList())
                    {
                        Statistics.FinalBoonUptime uptime = new Statistics.FinalBoonUptime();

                        uptime.uptime     = 0;
                        uptime.generation = 0;
                        uptime.overstack  = 0;
                        if (selfBoons.ContainsKey(boon.getID()))
                        {
                            if (boon.getType() == Boon.BoonType.Duration)
                            {
                                uptime.uptime     = Math.Round(100.0 * selfBoons.getUptime(boon.getID()) / fightDuration, 1);
                                uptime.generation = Math.Round(100.0f * selfBoons.getGeneration(boon.getID(), player.getInstid()) / fightDuration, 1);
                                uptime.overstack  = Math.Round(100.0f * selfBoons.getOverstack(boon.getID(), player.getInstid()) / fightDuration, 1);
                            }
                            else if (boon.getType() == Boon.BoonType.Intensity)
                            {
                                uptime.uptime     = Math.Round((double)selfBoons.getUptime(boon.getID()) / fightDuration, 1);
                                uptime.generation = Math.Round((double)selfBoons.getGeneration(boon.getID(), player.getInstid()) / fightDuration, 1);
                                uptime.overstack  = Math.Round((double)selfBoons.getOverstack(boon.getID(), player.getInstid()) / fightDuration, 1);
                            }

                            uptime.boonType = boon.getType();
                        }
                        final[boon.getID()] = uptime;
                    }

                    phaseBoons[phaseIndex] = final;
                }
                statistics.selfBoons[player] = phaseBoons;
            }

            // Group Boons
            foreach (Player player in log.getPlayerList())
            {
                List <Boon> boon_to_track = new List <Boon>();
                boon_to_track.AddRange(statistics.present_boons);
                boon_to_track.AddRange(statistics.present_offbuffs);
                boon_to_track.AddRange(statistics.present_defbuffs);
                boon_to_track.AddRange(statistics.present_personnal[player.getInstid()]);
                List <Player> groupPlayers = new List <Player>();
                foreach (Player p in log.getPlayerList())
                {
                    if (p.getGroup() == player.getGroup())
                    {
                        groupPlayers.Add(p);
                    }
                }
                Dictionary <int, Statistics.FinalBoonUptime>[] phaseBoons = new Dictionary <int, Statistics.FinalBoonUptime> [phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    phaseBoons[phaseIndex] = getBoonsForList(groupPlayers, player, boon_to_track, phaseIndex);
                }
                statistics.groupBoons[player] = phaseBoons;
            }

            // Off Group Boons
            foreach (Player player in log.getPlayerList())
            {
                List <Boon> boon_to_track = new List <Boon>();
                boon_to_track.AddRange(statistics.present_boons);
                boon_to_track.AddRange(statistics.present_offbuffs);
                boon_to_track.AddRange(statistics.present_defbuffs);
                boon_to_track.AddRange(statistics.present_personnal[player.getInstid()]);
                List <Player> groupPlayers = new List <Player>();
                foreach (Player p in log.getPlayerList())
                {
                    if (p.getGroup() != player.getGroup())
                    {
                        groupPlayers.Add(p);
                    }
                }
                Dictionary <int, Statistics.FinalBoonUptime>[] phaseBoons = new Dictionary <int, Statistics.FinalBoonUptime> [phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    phaseBoons[phaseIndex] = getBoonsForList(groupPlayers, player, boon_to_track, phaseIndex);
                }
                statistics.offGroupBoons[player] = phaseBoons;
            }

            // Squad Boons
            foreach (Player player in log.getPlayerList())
            {
                List <Boon> boon_to_track = new List <Boon>();
                boon_to_track.AddRange(statistics.present_boons);
                boon_to_track.AddRange(statistics.present_offbuffs);
                boon_to_track.AddRange(statistics.present_defbuffs);
                boon_to_track.AddRange(statistics.present_personnal[player.getInstid()]);
                List <Player> groupPlayers = new List <Player>();
                foreach (Player p in log.getPlayerList())
                {
                    groupPlayers.Add(p);
                }
                Dictionary <int, Statistics.FinalBoonUptime>[] phaseBoons = new Dictionary <int, Statistics.FinalBoonUptime> [phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    phaseBoons[phaseIndex] = getBoonsForList(groupPlayers, player, boon_to_track, phaseIndex);
                }
                statistics.squadBoons[player] = phaseBoons;
            }
        }
        private void calculateStats()
        {
            foreach (Player player in log.getPlayerList())
            {
                Statistics.FinalStats[] phaseStats = new Statistics.FinalStats[phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    Statistics.FinalStats final = new Statistics.FinalStats();

                    PhaseData phase = phases[phaseIndex];
                    long      start = phase.getStart() + log.getBossData().getFirstAware();
                    long      end   = phase.getEnd() + log.getBossData().getFirstAware();

                    List <DamageLog> damageLogs     = player.getDamageLogs(0, log, phase.getStart(), phase.getEnd());
                    List <DamageLog> damageLogsBoss = player.getDamageLogs(log.getBoss().getInstid(), log, phase.getStart(), phase.getEnd());
                    List <CastLog>   castLogs       = player.getCastLogs(log, phase.getStart(), phase.getEnd());

                    int instid = player.getInstid();

                    final.powerLoopCount = 0;
                    final.criticalRate   = 0;
                    final.criticalDmg    = 0;
                    final.scholarRate    = 0;
                    final.scholarDmg     = 0;
                    final.movingRate     = 0;
                    final.flankingRate   = 0;
                    final.glanceRate     = 0;
                    final.missed         = 0;
                    final.interupts      = 0;
                    final.invulned       = 0;
                    final.wasted         = 0;
                    final.timeWasted     = 0;
                    final.saved          = 0;
                    final.timeSaved      = 0;

                    final.powerLoopCountBoss = 0;
                    final.criticalRateBoss   = 0;
                    final.criticalDmgBoss    = 0;
                    final.scholarRateBoss    = 0;
                    final.scholarDmgBoss     = 0;
                    final.movingRateBoss     = 0;
                    final.flankingRateBoss   = 0;
                    final.glanceRateBoss     = 0;
                    final.missedBoss         = 0;
                    final.interuptsBoss      = 0;
                    final.invulnedBoss       = 0;

                    foreach (DamageLog log in damageLogs)
                    {
                        if (log.isCondi() == 0)
                        {
                            if (log.getResult() == ParseEnum.Result.Crit)
                            {
                                final.criticalRate++;
                                final.criticalDmg += log.getDamage();
                            }

                            if (log.isNinety() > 0)
                            {
                                final.scholarRate++;
                                final.scholarDmg += (int)(log.getDamage() / 11.0); //regular+10% damage
                            }

                            final.movingRate   += log.isMoving();
                            final.flankingRate += log.isFlanking();

                            if (log.getResult() == ParseEnum.Result.Glance)
                            {
                                final.glanceRate++;
                            }

                            if (log.getResult() == ParseEnum.Result.Blind)
                            {
                                final.missed++;
                            }

                            if (log.getResult() == ParseEnum.Result.Interrupt)
                            {
                                final.interupts++;
                            }

                            if (log.getResult() == ParseEnum.Result.Absorb)
                            {
                                final.invulned++;
                            }
                            final.powerLoopCount++;
                        }
                    }
                    foreach (DamageLog log in damageLogsBoss)
                    {
                        if (log.isCondi() == 0)
                        {
                            if (log.getResult() == ParseEnum.Result.Crit)
                            {
                                final.criticalRateBoss++;
                                final.criticalDmgBoss += log.getDamage();
                            }

                            if (log.isNinety() > 0)
                            {
                                final.scholarRateBoss++;
                                final.scholarDmgBoss += (int)(log.getDamage() / 11.0); //regular+10% damage
                            }

                            final.movingRateBoss   += log.isMoving();
                            final.flankingRateBoss += log.isFlanking();

                            if (log.getResult() == ParseEnum.Result.Glance)
                            {
                                final.glanceRateBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Blind)
                            {
                                final.missedBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Interrupt)
                            {
                                final.interuptsBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Absorb)
                            {
                                final.invulnedBoss++;
                            }
                            final.powerLoopCountBoss++;
                        }
                    }
                    foreach (CastLog cl in castLogs)
                    {
                        if (cl.endActivation() == ParseEnum.Activation.CancelCancel)
                        {
                            final.wasted++;
                            final.timeWasted += cl.getActDur();
                        }
                        if (cl.endActivation() == ParseEnum.Activation.CancelFire)
                        {
                            final.saved++;
                            if (cl.getActDur() < cl.getExpDur())
                            {
                                final.timeSaved += cl.getExpDur() - cl.getActDur();
                            }
                        }
                    }

                    final.timeSaved  = final.timeSaved / 1000f;
                    final.timeWasted = final.timeWasted / 1000f;

                    final.totalDmg       = damageLogs.Sum(x => x.getDamage());
                    final.powerLoopCount = final.powerLoopCount == 0 ? 1 : final.powerLoopCount;

                    final.totalDmgBoss       = damageLogsBoss.Sum(x => x.getDamage());
                    final.powerLoopCountBoss = final.powerLoopCountBoss == 0 ? 1 : final.powerLoopCountBoss;

                    // Counts
                    CombatData combatData = log.getCombatData();
                    final.swapCount  = combatData.getStates(instid, ParseEnum.StateChange.WeaponSwap, start, end).Count();
                    final.downCount  = combatData.getStates(instid, ParseEnum.StateChange.ChangeDown, start, end).Count();
                    final.dodgeCount = combatData.getSkillCount(instid, 65001, start, end) + combatData.getBuffCount(instid, 40408, start, end); //dodge = 65001 mirage cloak =40408
                    final.ressCount  = combatData.getSkillCount(instid, 1066, start, end);                                                       //Res = 1066

                    // R.I.P
                    List <CombatItem> dead = combatData.getStates(instid, ParseEnum.StateChange.ChangeDead, start, end);
                    final.died = 0.0;
                    if (dead.Count() > 0)
                    {
                        final.died = dead[0].getTime() - start;
                    }

                    List <CombatItem> disconect = combatData.getStates(instid, ParseEnum.StateChange.Despawn, start, end);
                    final.dcd = 0.0;
                    if (disconect.Count() > 0)
                    {
                        final.dcd = disconect[0].getTime() - start;
                    }

                    phaseStats[phaseIndex] = final;
                }
                statistics.stats[player] = phaseStats;
            }
        }