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; } }
private void doMechData() { List <int> mIDList = new List <int>(); foreach (Player p in p_list) { List <CombatItem> down = combat_data.getStates(p.getInstid(), ParseEnum.StateChange.ChangeDown, boss_data.getFirstAware(), boss_data.getLastAware()); foreach (CombatItem pnt in down) { mech_data.AddItem(new MechanicLog((long)((pnt.getTime() - boss_data.getFirstAware()) / 1000f), 0, "DOWN", 0, p, mech_data.GetPLoltyShape("DOWN"))); } List <CombatItem> dead = combat_data.getStates(p.getInstid(), ParseEnum.StateChange.ChangeDead, boss_data.getFirstAware(), boss_data.getLastAware()); foreach (CombatItem pnt in dead) { mech_data.AddItem(new MechanicLog((long)((pnt.getTime() - boss_data.getFirstAware()) / 1000f), 0, "DEAD", 0, p, mech_data.GetPLoltyShape("DEAD"))); } List <DamageLog> dls = p.getDamageTakenLogs(this, 0, boss_data.getAwareDuration()); //Player hit by skill 3 MechanicLog prevMech = null; foreach (DamageLog dLog in dls) { string name = skill_data.getName(dLog.getID()); if (dLog.getResult().IsHit()) { foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => x.GetMechType() == Mechanic.MechType.SkillOnPlayer)) { //Prevent multi hit attacks form multi registering if (prevMech != null) { if (dLog.getID() == prevMech.GetSkill() && mech.GetName() == prevMech.GetName() && (dLog.getTime() / 1000f) == prevMech.GetTime()) { break; } } if (dLog.getID() == mech.GetSkill()) { prevMech = new MechanicLog((long)(dLog.getTime() / 1000f), dLog.getID(), mech.GetName(), dLog.getDamage(), p, mech.GetPlotly()); mech_data.AddItem(prevMech); break; } } } } //Player gain buff 0,7 foreach (CombatItem c in combat_data.getCombatList().Where(x => x.isBuffremove() == ParseEnum.BuffRemove.None && x.isStateChange() == ParseEnum.StateChange.Normal)) { if (p.getInstid() == c.getDstInstid()) { if (c.isBuff() == 1 && c.getValue() > 0 && c.isBuffremove() == ParseEnum.BuffRemove.None && c.getResult().IsHit()) { String name = skill_data.getName(c.getSkillID()); //buff on player 0 foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => x.GetMechType() == Mechanic.MechType.PlayerBoon)) { if (c.getSkillID() == mech.GetSkill()) { //dst player mech_data.AddItem(new MechanicLog((long)((c.getTime() - boss_data.getFirstAware()) / 1000f), c.getSkillID(), mech.GetName(), c.getValue(), p, mech.GetPlotly())); break; } } //player on player 7 foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => x.GetMechType() == Mechanic.MechType.PlayerOnPlayer)) { if (c.getSkillID() == mech.GetSkill()) { //dst player mech_data.AddItem(new MechanicLog((long)((c.getTime() - boss_data.getFirstAware()) / 1000f), c.getSkillID(), mech.GetName(), c.getValue(), p, mech.GetPlotly())); //src player mech_data.AddItem(new MechanicLog((long)((c.getTime() - boss_data.getFirstAware()) / 1000f), c.getSkillID(), mech.GetName(), c.getValue(), p_list.FirstOrDefault(i => i.getInstid() == c.getSrcInstid()), mech.GetPlotly())); break; } } } } } } }
/// <summary> /// Parses all the data again and link related stuff to each other /// </summary> private void fillMissingData() { var agentsLookup = agent_data.getAllAgentsList().ToDictionary(a => a.getAgent()); bool golem_mode = isGolem(boss_data.getID()); // Set Agent instid, first_aware and last_aware var combat_list = combat_data.getCombatList(); foreach (CombatItem c in combat_list) { if (agentsLookup.TryGetValue(c.getSrcAgent(), out var a)) { if (a.getInstid() == 0 && (c.isStateChange() == ParseEnum.StateChange.Normal || (golem_mode && isGolem(a.getID()) && c.isStateChange() == ParseEnum.StateChange.MaxHealthUpdate))) { a.setInstid(c.getSrcInstid()); } if (a.getInstid() != 0) { if (a.getFirstAware() == 0) { a.setFirstAware(c.getTime()); a.setLastAware(c.getTime()); } else { a.setLastAware(c.getTime()); } } } } foreach (CombatItem c in combat_list) { if (c.getSrcMasterInstid() != 0) { var master = agent_data.getAllAgentsList().Find(x => x.getInstid() == c.getSrcMasterInstid() && x.getFirstAware() < c.getTime() && c.getTime() < x.getLastAware()); if (master != null) { if (agentsLookup.TryGetValue(c.getSrcAgent(), out var minion) && minion.getFirstAware() < c.getTime() && c.getTime() < minion.getLastAware()) { minion.setMasterAgent(master.getAgent()); } } } } agent_data.clean(); // Set Boss data agent, instid, first_aware, last_aware and name List <AgentItem> NPC_list = agent_data.getNPCAgentList(); HashSet <ulong> multiple_boss = new HashSet <ulong>(); foreach (AgentItem NPC in NPC_list) { if (NPC.getProf().EndsWith(boss_data.getID().ToString())) { if (boss_data.getAgent() == 0) { boss_data.setAgent(NPC.getAgent()); boss_data.setInstid(NPC.getInstid()); boss_data.setFirstAware(NPC.getFirstAware()); boss_data.setName(NPC.getName()); boss_data.setTough(NPC.getToughness()); } multiple_boss.Add(NPC.getAgent()); boss_data.setLastAware(NPC.getLastAware()); } } if (multiple_boss.Count > 1) { agent_data.cleanInstid(boss_data.getInstid()); } AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); boss = new Boss(bossAgent); List <Point> bossHealthOverTime = new List <Point>(); // a hack for buggy golem logs if (golem_mode) { ulong redirection = 0; foreach (AgentItem a in agent_data.getAllAgentsList()) { if (a.getID() == 19603) { redirection = a.getAgent(); } } if (redirection != 0) { foreach (CombatItem c in combat_list) { if (c.getDstAgent() == 0 && c.getDstInstid() == 0 && c.isStateChange() == ParseEnum.StateChange.Normal && c.getIFF() == ParseEnum.IFF.Foe && c.isActivation() == ParseEnum.Activation.None) { c.setDstAgent(bossAgent.getAgent()); c.setDstInstid(bossAgent.getInstid()); } } } } // Grab values threw combat data foreach (CombatItem c in combat_list) { if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange() == ParseEnum.StateChange.MaxHealthUpdate)//max health update { boss_data.setHealth((int)c.getDstAgent()); } switch (c.isStateChange()) { case ParseEnum.StateChange.PointOfView: if (log_data.getPOV() == "N/A") //Point of View { ulong pov_agent = c.getSrcAgent(); if (agentsLookup.TryGetValue(pov_agent, out var p)) { log_data.setPOV(p.getName()); } } break; case ParseEnum.StateChange.LogStart: log_data.setLogStart(c.getValue()); break; case ParseEnum.StateChange.LogEnd: log_data.setLogEnd(c.getValue()); break; case ParseEnum.StateChange.HealthUpdate: //set health update if (c.getSrcInstid() == boss_data.getInstid()) { bossHealthOverTime.Add(new Point((int)(c.getTime() - boss_data.getFirstAware()), (int)c.getDstAgent())); } break; } } // Dealing with second half of Xera | ((22611300 * 0.5) + (25560600 * 0.5) if (boss_data.getID() == 16246) { int xera_2_instid = 0; foreach (AgentItem NPC in NPC_list) { if (NPC.getProf().Contains("16286")) { bossHealthOverTime = new List <Point>();//reset boss health over time xera_2_instid = NPC.getInstid(); boss_data.setHealth(24085950); boss.addPhaseData(boss_data.getLastAware()); boss.addPhaseData(NPC.getFirstAware()); boss_data.setLastAware(NPC.getLastAware()); foreach (CombatItem c in combat_list) { if (c.getSrcInstid() == xera_2_instid) { c.setSrcInstid(boss_data.getInstid()); } if (c.getDstInstid() == xera_2_instid) { c.setDstInstid(boss_data.getInstid()); } //set health update if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange() == ParseEnum.StateChange.HealthUpdate) { bossHealthOverTime.Add(new Point((int)(c.getTime() - boss_data.getFirstAware()), (int)c.getDstAgent())); } } break; } } } //Dealing with Deimos split if (boss_data.getID() == 17154) { int deimos_2_instid = 0; foreach (AgentItem NPC in agent_data.getGadgetAgentList()) { if (NPC.getProf().Contains("08467") || NPC.getProf().Contains("08471")) { deimos_2_instid = NPC.getInstid(); long oldAware = boss_data.getLastAware(); if (NPC.getLastAware() < boss_data.getLastAware()) { // No split break; } boss.addPhaseData(NPC.getFirstAware() >= oldAware ? NPC.getFirstAware() : oldAware); boss_data.setLastAware(NPC.getLastAware()); //List<CombatItem> fuckyou = combat_list.Where(x => x.getDstInstid() == deimos_2_instid ).ToList().Sum(x); //int stop = 0; foreach (CombatItem c in combat_list) { if (c.getTime() > oldAware) { if (c.getSrcInstid() == deimos_2_instid) { c.setSrcInstid(boss_data.getInstid()); } if (c.getDstInstid() == deimos_2_instid) { c.setDstInstid(boss_data.getInstid()); } } } break; } } } boss_data.setHealthOverTime(bossHealthOverTime);//after xera in case of change // Re parse to see if the boss is dead and update last aware foreach (CombatItem c in combat_list) { //set boss dead if (c.isStateChange() == ParseEnum.StateChange.Reward)//got reward { log_data.setBossKill(true); boss_data.setLastAware(c.getTime()); break; } //set boss dead if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange() == ParseEnum.StateChange.ChangeDead && !log_data.getBosskill())//change dead { log_data.setBossKill(true); boss_data.setLastAware(c.getTime()); } } //players if (p_list.Count == 0) { //Fix Disconected players var playerAgentList = agent_data.getPlayerAgentList(); foreach (AgentItem playerAgent in playerAgentList) { List <CombatItem> lp = combat_data.getStates(playerAgent.getInstid(), ParseEnum.StateChange.Despawn, boss_data.getFirstAware(), boss_data.getLastAware()); Player player = new Player(playerAgent); bool skip = false; foreach (Player p in p_list) { if (p.getAccount() == player.getAccount())//is this a copy of original? { skip = true; } } if (skip) { continue; } if (lp.Count > 0) { //make all actions of other instances to original instid foreach (AgentItem extra in NPC_list) { if (extra.getAgent() == playerAgent.getAgent()) { var extra_login_Id = extra.getInstid(); foreach (CombatItem c in combat_list) { if (c.getSrcInstid() == extra_login_Id) { c.setSrcInstid(playerAgent.getInstid()); } if (c.getDstInstid() == extra_login_Id) { c.setDstInstid(playerAgent.getInstid()); } } break; } } player.SetDC(lp[0].getTime()); p_list.Add(player); } else//didnt dc { if (player.GetDC() == 0) { p_list.Add(player); } } } } // Sort p_list = p_list.OrderBy(a => a.getGroup()).ToList(); }