From e75f87c6eaaa7e75ef4da0b427310a73c0c556ab Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 16:06:15 +0200 Subject: [PATCH 01/53] added phase data on the controller for testing purpose, can detect phases for sab, matt and gorseval, added some skill data, corrected some boon issues --- LuckParser/Controllers/Controller1.cs | 6 +++ LuckParser/Models/ParseModels/Boons/Boon.cs | 10 ++--- LuckParser/Models/ParseModels/Boss.cs | 49 +++++++++++++++++++-- LuckParser/Models/ParseModels/SkillData.cs | 6 ++- 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 8a38f3a62..7c94fe3fa 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -5418,6 +5418,12 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) CreatePlayerTab(sw,settingsSnap); } sw.Write(""); + sw.Write("
"); + for (int i = 1; i < phases.Count; i++) + { + sw.Write("

Phase " + i + " started at " + Math.Round(phases[i].start / 1000.0) + "s and ended at " + Math.Round(phases[i].end / 1000.0) + "s

"); + } + sw.Write("
"); sw.Write("

ARC:" + getLogData().getBuildVersion().ToString() + " | Bossid " + getBossData().getID().ToString() + "

"); sw.Write("

File recorded by: " + log_data.getPOV() + "

"); } diff --git a/LuckParser/Models/ParseModels/Boons/Boon.cs b/LuckParser/Models/ParseModels/Boons/Boon.cs index 1b0ab3721..ff8684ce2 100644 --- a/LuckParser/Models/ParseModels/Boons/Boon.cs +++ b/LuckParser/Models/ParseModels/Boons/Boon.cs @@ -278,15 +278,15 @@ private Boon(string name, int id, BoonSource source, string type, int capacity, new Boon("Gear Shield",5997, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff), //Transforms new Boon("Rampage", BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Photon Forge",43708, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + //new Boon("Photon Forge",43708, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), Never removed? //Traits new Boon("Laser's Edge",44414, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - //new Boon("Afterburner",42210, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff), What is this? - new Boon("Iron Blooded",49065, BoonSource.Engineer, "intensity", 25, BoonEnum.GraphOnlyBuff), + new Boon("Afterburner",42210, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Iron Blooded",49065, BoonSource.Engineer, "intensity", 25, BoonEnum.GraphOnlyBuff, RemoveType.Manual), new Boon("Streamlined Kits",18687, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), new Boon("Kinetic Charge",45781, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, "duration", 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), - new Boon("Heat Therapy",40694, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff), + new Boon("Heat Therapy",40694, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), new Boon("Overheat", 40397, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff), ///RANGER new Boon("Celestial Avatar", 31508, BoonSource.Ranger, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), @@ -504,7 +504,7 @@ public static bool removePermission(int boonid, int buffremove) case RemoveType.Cleanse: return buffremove == 1 || buffremove == 2; case RemoveType.Manual: - return buffremove == 3; + return buffremove == 3 || buffremove == 1; case RemoveType.All: return buffremove == 1 || buffremove == 2 || buffremove == 3; default: diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 7b5025a33..f2abd8632 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -63,16 +63,57 @@ private void setPhases(BossData bossData, List combatList, AgentData } break; case "Sabetha the Saboteur": - cls = getCastLogs(bossData, combatList, agentData).Where(x => x.getID() == 31372).ToList(); - foreach (CastLog cl in cls) + cls = getCastLogs(bossData, combatList, agentData); + for (int i = 0; i < cls.Count; i++) { - + CastLog cur = cls[i]; + if (cur.getID() == 31372) + { + end = cur.getTime(); + phases.Add(new PhaseData(start, end)); + for (int j = i; j < cls.Count; j++) + { + CastLog next = cls[j]; + if (next.getID() != 31372) + { + i = j; + break; + } else + { + start = next.getTime() + next.getActDur(); + } + } + } + } + break; + case "Matthias Gabrel": + CombatItem heat_wave = combatList.Find(x => x.getSkillID() == 34526); + List phase_starts = new List(); + if (heat_wave != null) + { + phase_starts.Add(heat_wave.getTime() - bossData.getFirstAware()); + CombatItem down_pour = combatList.Find(x => x.getSkillID() == 34554); + if (down_pour != null) + { + phase_starts.Add(down_pour.getTime() - bossData.getFirstAware()); + CastLog abo = getCastLogs(bossData, combatList, agentData).Find(x => x.getID() == 34427); + if (abo != null) + { + phase_starts.Add(abo.getTime()); + } + } + } + foreach (long t in phase_starts) + { + end = t; + phases.Add(new PhaseData(start, end)); + start = t; } break; default: return; } - if (phases.Last().end != fight_dur) + if (fight_dur - start > 5000 && start > 0) { phases.Add(new PhaseData(start, fight_dur)); } diff --git a/LuckParser/Models/ParseModels/SkillData.cs b/LuckParser/Models/ParseModels/SkillData.cs index 9a9ebea39..16974c99f 100644 --- a/LuckParser/Models/ParseModels/SkillData.cs +++ b/LuckParser/Models/ParseModels/SkillData.cs @@ -19,7 +19,11 @@ public class SkillData {31759,"Protective Shadow" }, {31466,"Ghastly Rampage (Begin)" }, // Sabetha - {31372, "Shadow Step" } + {31372, "Shadow Step" }, + // Matthias + { 34468, "Shield (Human)"}, + { 34427, "Abomination Transformation"}, + { 34510, "Shiled (Abomination)"} }; // Constructors From 9d5a9bac244860bb77fde0c5d9148e4277329f11 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 20:39:58 +0200 Subject: [PATCH 02/53] VG + sab phase detection done --- LuckParser/Controllers/Controller1.cs | 6 +-- LuckParser/Models/ParseModels/Boss.cs | 50 +++++++++++++++------- LuckParser/Models/ParseModels/SkillData.cs | 6 ++- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 7c94fe3fa..812eaa769 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -477,6 +477,8 @@ private void fillMissingData() boss_data.setLastAware(NPC.getLastAware()); } } + AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); + boss = new Boss(bossAgent); List bossHealthOverTime = new List(); // Grab values threw combat data @@ -674,8 +676,6 @@ private void fillMissingData() } } - AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); - boss = new Boss(bossAgent); // Sort p_list = p_list.OrderBy(a => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) setMechData(); @@ -5421,7 +5421,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) sw.Write("
"); for (int i = 1; i < phases.Count; i++) { - sw.Write("

Phase " + i + " started at " + Math.Round(phases[i].start / 1000.0) + "s and ended at " + Math.Round(phases[i].end / 1000.0) + "s

"); + sw.Write("

Phase " + i + " started at " + phases[i].start / 1000 + "s and ended at " + phases[i].end / 1000 + "s

"); } sw.Write("
"); sw.Write("

ARC:" + getLogData().getBuildVersion().ToString() + " | Bossid " + getBossData().getID().ToString() + "

"); diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index f2abd8632..44db72afd 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -53,6 +53,27 @@ private void setPhases(BossData bossData, List combatList, AgentData List cls; switch (name) { + case "Vale Guardian": + List invulsVG = combatList.Where(x => x.getSkillID() == 757 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); + for (int i = 0; i < invulsVG.Count; i++) + { + CombatItem c = invulsVG[i]; + if (c.isBuffremove().getID() == 0) + { + end = c.getTime() - bossData.getFirstAware(); + phases.Add(new PhaseData(start, end)); + if (i == invulsVG.Count - 1) + { + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); + } + } + else + { + start = c.getTime() - bossData.getFirstAware(); + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + } + } + break; case "Gorseval the Multifarious": cls = getCastLogs(bossData, combatList, agentData).Where(x => x.getID() == 31759).ToList(); foreach (CastLog cl in cls) @@ -63,27 +84,24 @@ private void setPhases(BossData bossData, List combatList, AgentData } break; case "Sabetha the Saboteur": - cls = getCastLogs(bossData, combatList, agentData); - for (int i = 0; i < cls.Count; i++) + List invulsSab = combatList.Where(x => x.getSkillID() == 757 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); + for (int i = 0; i < invulsSab.Count; i++) { - CastLog cur = cls[i]; - if (cur.getID() == 31372) + CombatItem c = invulsSab[i]; + if (c.isBuffremove().getID() == 0) { - end = cur.getTime(); + end = c.getTime() - bossData.getFirstAware(); phases.Add(new PhaseData(start, end)); - for (int j = i; j < cls.Count; j++) + if (i == invulsSab.Count - 1) { - CastLog next = cls[j]; - if (next.getID() != 31372) - { - i = j; - break; - } else - { - start = next.getTime() + next.getActDur(); - } + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); } } + else + { + start = c.getTime() - bossData.getFirstAware(); + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + } } break; case "Matthias Gabrel": @@ -113,7 +131,7 @@ private void setPhases(BossData bossData, List combatList, AgentData default: return; } - if (fight_dur - start > 5000 && start > 0) + if (fight_dur - start > 5000 && start > phases.Last().end) { phases.Add(new PhaseData(start, fight_dur)); } diff --git a/LuckParser/Models/ParseModels/SkillData.cs b/LuckParser/Models/ParseModels/SkillData.cs index 16974c99f..fa71c258d 100644 --- a/LuckParser/Models/ParseModels/SkillData.cs +++ b/LuckParser/Models/ParseModels/SkillData.cs @@ -23,7 +23,11 @@ public class SkillData // Matthias { 34468, "Shield (Human)"}, { 34427, "Abomination Transformation"}, - { 34510, "Shiled (Abomination)"} + { 34510, "Shield (Abomination)"}, + // Generic + {-5, "Phase out" }, + // Deimos + {-6, "Roleplay" } }; // Constructors From 1a281df8f102d4c04a5c4b2963e35c9d204a5df7 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 21:24:52 +0200 Subject: [PATCH 03/53] fixed a bug where avg boons calculation would hang up, added Deimos phase detection --- LuckParser/Controllers/Controller1.cs | 6 +++++- LuckParser/Models/ParseModels/Boss.cs | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 812eaa769..448d8423a 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -566,6 +566,7 @@ private void fillMissingData() // No split break; } + boss.addPhaseData(boss_data.getLastAware()); boss_data.setLastAware(NPC.getLastAware()); //List fuckyou = combat_list.Where(x => x.getDstInstid() == deimos_2_instid ).ToList().Sum(x); //int stop = 0; @@ -2350,7 +2351,10 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t double avg_boons = 0.0; foreach(Boon boon in list_to_use) { - avg_boons += boonPresence[boon.getID()]; + if (boonPresence.ContainsKey(boon.getID())) + { + avg_boons += boonPresence[boon.getID()]; + } } avg_boons /= fight_duration; sw.Write("" + player.getCharacter().ToString() + " "); diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 44db72afd..4abfeb443 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -26,7 +26,8 @@ public Boss(AgentItem agent) : base(agent) } - public List phases = new List(); + private List phases = new List(); + private List phaseData = new List(); public List getPhases(BossData bossData, List combatList, AgentData agentData) { @@ -37,9 +38,9 @@ public List getPhases(BossData bossData, List combatList, return phases; } - public void forcePhase(List phases) + public void addPhaseData(long data) { - this.phases = phases; + phaseData.Add(data); } // Private Methods @@ -128,8 +129,18 @@ private void setPhases(BossData bossData, List combatList, AgentData start = t; } break; + case "Deimos": + CombatItem invulDei = combatList.Find(x => x.getSkillID() == 762 && x.isBuff() == 1 && x.isBuffremove().getID() == 0 && x.getDstInstid() == getInstid()); + if (invulDei != null) + { + end = invulDei.getTime() - bossData.getFirstAware(); + phases.Add(new PhaseData(start, end)); + start = (phaseData.Count == 1 ? phaseData[0] : fight_dur) - bossData.getFirstAware(); + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -6, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + } + break; default: - return; + break; } if (fight_dur - start > 5000 && start > phases.Last().end) { From 19d6ff0e92b7fdf2d7a0f5622e60b32159ed0df7 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 22:37:18 +0200 Subject: [PATCH 04/53] added samarog phase detection. Missing Xera and KC --- LuckParser/Models/ParseModels/Boss.cs | 48 +++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 4abfeb443..c57c5b913 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -51,10 +51,10 @@ private void setPhases(BossData bossData, List combatList, AgentData string name = getCharacter(); long start = 0; long end = 0; - List cls; switch (name) { case "Vale Guardian": + // Invul check List invulsVG = combatList.Where(x => x.getSkillID() == 757 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); for (int i = 0; i < invulsVG.Count; i++) { @@ -76,8 +76,9 @@ private void setPhases(BossData bossData, List combatList, AgentData } break; case "Gorseval the Multifarious": - cls = getCastLogs(bossData, combatList, agentData).Where(x => x.getID() == 31759).ToList(); - foreach (CastLog cl in cls) + // Ghostly protection check + List clsG = getCastLogs(bossData, combatList, agentData).Where(x => x.getID() == 31759).ToList(); + foreach (CastLog cl in clsG) { end = cl.getTime(); phases.Add(new PhaseData(start, end)); @@ -85,6 +86,7 @@ private void setPhases(BossData bossData, List combatList, AgentData } break; case "Sabetha the Saboteur": + // Invul check List invulsSab = combatList.Where(x => x.getSkillID() == 757 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); for (int i = 0; i < invulsSab.Count; i++) { @@ -106,6 +108,7 @@ private void setPhases(BossData bossData, List combatList, AgentData } break; case "Matthias Gabrel": + // Special buff cast check CombatItem heat_wave = combatList.Find(x => x.getSkillID() == 34526); List phase_starts = new List(); if (heat_wave != null) @@ -129,7 +132,46 @@ private void setPhases(BossData bossData, List combatList, AgentData start = t; } break; + case "Samarog": + // Determined check + List invulsSam = combatList.Where(x => x.getSkillID() == 762 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); + // Samarog receives determined twice and its removed twice, filter it + List invulsSamFiltered = new List(); + foreach( CombatItem c in invulsSam) + { + if (invulsSamFiltered.Count > 0) + { + CombatItem last = invulsSamFiltered.Last(); + if (last.getTime() != c.getTime()) + { + invulsSamFiltered.Add(c); + } + } else + { + invulsSamFiltered.Add(c); + } + } + for (int i = 0; i < invulsSamFiltered.Count; i++) + { + CombatItem c = invulsSamFiltered[i]; + if (c.isBuffremove().getID() == 0) + { + end = c.getTime() - bossData.getFirstAware(); + phases.Add(new PhaseData(start, end)); + if (i == invulsSamFiltered.Count - 1) + { + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); + } + } + else + { + start = c.getTime() - bossData.getFirstAware(); + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + } + } + break; case "Deimos": + // Determined + additional data on inst change CombatItem invulDei = combatList.Find(x => x.getSkillID() == 762 && x.isBuff() == 1 && x.isBuffremove().getID() == 0 && x.getDstInstid() == getInstid()); if (invulDei != null) { From bc0d6308d99abd1585e06d38710a6296393ef52d Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 02:20:08 +0200 Subject: [PATCH 05/53] added data for Xera --- LuckParser/Controllers/Controller1.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 0506aaa25..3ad591561 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -530,6 +530,8 @@ private void fillMissingData() bossHealthOverTime = new List();//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) { @@ -574,7 +576,6 @@ private void fillMissingData() { if (c.getTime() > oldAware) { - int lol = c.isStateChange().getID(); if (c.getSrcInstid() == deimos_2_instid) { c.setSrcInstid(boss_data.getInstid()); From dc0a324e85934b3942799298dbb9cd94180b185d Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 02:20:58 +0200 Subject: [PATCH 06/53] added Xera phase detection, needs testing --- LuckParser/Models/ParseModels/Boss.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index c57c5b913..78d295ca2 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -132,6 +132,16 @@ private void setPhases(BossData bossData, List combatList, AgentData start = t; } break; + case "Xera": + // split happened + if (phaseData.Count == 2) + { + end = phaseData[0] - bossData.getFirstAware(); + phases.Add(new PhaseData(start, end)); + start = phaseData[1] - bossData.getFirstAware(); + getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + } + break; case "Samarog": // Determined check List invulsSam = combatList.Where(x => x.getSkillID() == 762 && getInstid() == x.getDstInstid() && x.isBuff() == 1).ToList(); From 59eab38e0f298da81f6fd3342d9a0da302230cc0 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 15:39:26 +0200 Subject: [PATCH 07/53] added friend foe distinction to remove permission --- LuckParser/Models/ParseModels/Boons/Boon.cs | 374 ++++++++++---------- LuckParser/Models/ParseModels/Player.cs | 2 +- 2 files changed, 189 insertions(+), 187 deletions(-) diff --git a/LuckParser/Models/ParseModels/Boons/Boon.cs b/LuckParser/Models/ParseModels/Boons/Boon.cs index 484e94a2f..353e9130d 100644 --- a/LuckParser/Models/ParseModels/Boons/Boon.cs +++ b/LuckParser/Models/ParseModels/Boons/Boon.cs @@ -10,7 +10,7 @@ public class Boon // Boon public enum BoonEnum { Condition, Boon, OffensiveBuffTable, DefensiveBuffTable, GraphOnlyBuff, Food, Utility}; public enum BoonSource { Mixed, Necromancer, Elementalist, Mesmer, Warrior, Revenant, Guardian, Thief, Ranger, Engineer, Item }; - public enum RemoveType { Cleanse, Manual, None, All}; + public enum RemoveType { CleanseFoe, CleanseFriend, ManualFriend, None, All}; public enum BoonType { Duration, Intensity}; private static BoonSource ProfToEnum(string prof) @@ -107,36 +107,36 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity private static List allBoons = new List { //Base boons - new Boon("Might", 740, BoonSource.Mixed, BoonType.Intensity, 25, BoonEnum.Boon, "https://wiki.guildwars2.com/images/7/7c/Might.png", RemoveType.Cleanse), - new Boon("Fury", 725, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/4/46/Fury.png", RemoveType.Cleanse),//or 3m and 30s - new Boon("Quickness", 1187, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/b/b4/Quickness.png", RemoveType.Cleanse), - new Boon("Alacrity", 30328, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/thumb/4/4c/Alacrity.png/20px-Alacrity.png", RemoveType.Cleanse), - new Boon("Protection", 717, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/6/6c/Protection.png", RemoveType.Cleanse), - new Boon("Regeneration", 718, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/5/53/Regeneration.png", RemoveType.Cleanse), - new Boon("Vigor", 726, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/f/f4/Vigor.png", RemoveType.Cleanse), + new Boon("Might", 740, BoonSource.Mixed, BoonType.Intensity, 25, BoonEnum.Boon, "https://wiki.guildwars2.com/images/7/7c/Might.png", RemoveType.CleanseFoe), + new Boon("Fury", 725, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/4/46/Fury.png", RemoveType.CleanseFoe),//or 3m and 30s + new Boon("Quickness", 1187, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/b/b4/Quickness.png", RemoveType.CleanseFoe), + new Boon("Alacrity", 30328, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/thumb/4/4c/Alacrity.png/20px-Alacrity.png", RemoveType.CleanseFoe), + new Boon("Protection", 717, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/6/6c/Protection.png", RemoveType.CleanseFoe), + new Boon("Regeneration", 718, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/5/53/Regeneration.png", RemoveType.CleanseFoe), + new Boon("Vigor", 726, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/f/f4/Vigor.png", RemoveType.CleanseFoe), new Boon("Aegis", 743, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/e/e5/Aegis.png", RemoveType.All), new Boon("Stability", 1122, BoonSource.Mixed, BoonType.Intensity, 25, BoonEnum.Boon, "https://wiki.guildwars2.com/images/a/ae/Stability.png", RemoveType.All), - new Boon("Swiftness", 719, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/a/af/Swiftness.png", RemoveType.Cleanse), - new Boon("Retaliation", 873, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/5/53/Retaliation.png", RemoveType.Cleanse), - new Boon("Resistance", 26980, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/thumb/e/e9/Resistance_40px.png/20px-Resistance_40px.png", RemoveType.Cleanse), + new Boon("Swiftness", 719, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Boon, "https://wiki.guildwars2.com/images/a/af/Swiftness.png", RemoveType.CleanseFoe), + new Boon("Retaliation", 873, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/5/53/Retaliation.png", RemoveType.CleanseFoe), + new Boon("Resistance", 26980, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Boon, "https://wiki.guildwars2.com/images/thumb/e/e9/Resistance_40px.png/20px-Resistance_40px.png", RemoveType.CleanseFoe), // Condis - new Boon("Bleeding", 736, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/33/Bleeding.png/20px-Bleeding.png", RemoveType.Cleanse), - new Boon("Burning", 737, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/4/45/Burning.png/20px-Burning.png", RemoveType.Cleanse), - new Boon("Confusion", 861, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/e/e6/Confusion.png/20px-Confusion.png", RemoveType.Cleanse), - new Boon("Poison", 723, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/0/05/Poison.png/20px-Poison.png", RemoveType.Cleanse), - new Boon("Torment", 19426, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/0/08/Torment.png/20px-Torment.png", RemoveType.Cleanse), - new Boon("Blind", 720, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/33/Blinded.png/20px-Blinded.png", RemoveType.Cleanse), - new Boon("Chilled", 722, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/a/a6/Chilled.png/20px-Chilled.png", RemoveType.Cleanse), - new Boon("Crippled", 721, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/fb/Crippled.png/20px-Crippled.png", RemoveType.Cleanse), - new Boon("Fear", 791, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/e/e6/Fear.png/20px-Fear.png", RemoveType.Cleanse), - new Boon("Immobile", 727, BoonSource.Mixed, BoonType.Duration, 3, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/32/Immobile.png/20px-Immobile.png", RemoveType.Cleanse), - new Boon("Slow", 26766, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/fb/Slow_40px.png/20px-Slow_40px.png", RemoveType.Cleanse), - new Boon("Weakness", 742, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/f9/Weakness.png/20px-Weakness.png", RemoveType.Cleanse), - new Boon("Taunt", 27705, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/c/cc/Taunt.png/20px-Taunt.png", RemoveType.Cleanse), - new Boon("Vulnerability", 738, BoonSource.Mixed, BoonType.Intensity, 25, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/a/af/Vulnerability.png/20px-Vulnerability.png", RemoveType.Cleanse), - new Boon("Retaliation", 873, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/5/53/Retaliation.png", RemoveType.Cleanse), + new Boon("Bleeding", 736, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/33/Bleeding.png/20px-Bleeding.png", RemoveType.CleanseFriend), + new Boon("Burning", 737, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/4/45/Burning.png/20px-Burning.png", RemoveType.CleanseFriend), + new Boon("Confusion", 861, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/e/e6/Confusion.png/20px-Confusion.png", RemoveType.CleanseFriend), + new Boon("Poison", 723, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/0/05/Poison.png/20px-Poison.png", RemoveType.CleanseFriend), + new Boon("Torment", 19426, BoonSource.Mixed, BoonType.Intensity, 1500, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/0/08/Torment.png/20px-Torment.png", RemoveType.CleanseFriend), + new Boon("Blind", 720, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/33/Blinded.png/20px-Blinded.png", RemoveType.CleanseFriend), + new Boon("Chilled", 722, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/a/a6/Chilled.png/20px-Chilled.png", RemoveType.CleanseFriend), + new Boon("Crippled", 721, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/fb/Crippled.png/20px-Crippled.png", RemoveType.CleanseFriend), + new Boon("Fear", 791, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/e/e6/Fear.png/20px-Fear.png", RemoveType.CleanseFriend), + new Boon("Immobile", 727, BoonSource.Mixed, BoonType.Duration, 3, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/3/32/Immobile.png/20px-Immobile.png", RemoveType.CleanseFriend), + new Boon("Slow", 26766, BoonSource.Mixed, BoonType.Duration, 9, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/fb/Slow_40px.png/20px-Slow_40px.png", RemoveType.CleanseFriend), + new Boon("Weakness", 742, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/f/f9/Weakness.png/20px-Weakness.png", RemoveType.CleanseFriend), + new Boon("Taunt", 27705, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/c/cc/Taunt.png/20px-Taunt.png", RemoveType.CleanseFriend), + new Boon("Vulnerability", 738, BoonSource.Mixed, BoonType.Intensity, 25, BoonEnum.Condition, "https://wiki.guildwars2.com/images/thumb/a/af/Vulnerability.png/20px-Vulnerability.png", RemoveType.CleanseFriend), + new Boon("Retaliation", 873, BoonSource.Mixed, BoonType.Duration, 5, BoonEnum.Condition, "https://wiki.guildwars2.com/images/5/53/Retaliation.png", RemoveType.CleanseFoe), // Generic - new Boon("Stealth", 13017, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Stealth", 13017, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Revealed", 890, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Superspeed", 5974, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/1/1a/Super_Speed.png"), //new Boon("Invulnerability", 801, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/e/eb/Determined.png"), @@ -149,39 +149,39 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Magnetic Aura", 5684, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Shocking Aura", 5577, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //race - new Boon("Take Root", 12459, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Become the Bear",12426, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Become the Raven",12405, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Become the Snow Leopard",12400, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Become the Wolf",12393, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Avatar of Melandru", 12368, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Power Suit",12326, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Reaper of Grenth", 12366, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Charrzooka",43503, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Take Root", 12459, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Become the Bear",12426, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Become the Raven",12405, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Become the Snow Leopard",12400, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Become the Wolf",12393, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Avatar of Melandru", 12368, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Power Suit",12326, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Reaper of Grenth", 12366, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Charrzooka",43503, BoonSource.Mixed, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), ///REVENANT //skills - new Boon("Crystal Hibernation", 28262, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Vengeful Hammers", 27273, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Crystal Hibernation", 28262, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Vengeful Hammers", 27273, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Rite of the Great Dwarf", 26596, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/6/69/Rite_of_the_Great_Dwarf.png"), - new Boon("Embrace the Darkness", 28001, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Enchanted Daggers", 28557, BoonSource.Revenant, BoonType.Intensity, 6, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Impossible Odds", 27581, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Embrace the Darkness", 28001, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Enchanted Daggers", 28557, BoonSource.Revenant, BoonType.Intensity, 6, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Impossible Odds", 27581, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //facets - new Boon("Facet of Light",27336, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Infuse Light",27737, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/6/60/Infuse_Light.png", RemoveType.Manual), - new Boon("Facet of Darkness",28036, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, RemoveType.Manual), - new Boon("Facet of Elements",28243, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, RemoveType.Manual), - new Boon("Facet of Strength",27376, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, RemoveType.Manual), - new Boon("Facet of Chaos",27983, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, RemoveType.Manual), - new Boon("Facet of Nature",29275, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Naturalistic Resonance", 29379, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/e/e9/Facet_of_Nature.png", RemoveType.Manual), + new Boon("Facet of Light",27336, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Infuse Light",27737, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/6/60/Infuse_Light.png", RemoveType.ManualFriend), + new Boon("Facet of Darkness",28036, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, RemoveType.ManualFriend), + new Boon("Facet of Elements",28243, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, RemoveType.ManualFriend), + new Boon("Facet of Strength",27376, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, RemoveType.ManualFriend), + new Boon("Facet of Chaos",27983, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, RemoveType.ManualFriend), + new Boon("Facet of Nature",29275, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Naturalistic Resonance", 29379, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/e/e9/Facet_of_Nature.png", RemoveType.ManualFriend), //legends - new Boon("Legendary Centaur Stance",27972, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Legendary Dragon Stance",27732, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Legendary Dwarf Stance",27205, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Legendary Demon Stance",27928, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Legendary Assassin Stance",27890, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Legendary Renegade Stance",44272, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Legendary Centaur Stance",27972, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Legendary Dragon Stance",27732, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Legendary Dwarf Stance",27205, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Legendary Demon Stance",27928, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Legendary Assassin Stance",27890, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Legendary Renegade Stance",44272, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //summons new Boon("Breakrazor's Bastion",44682, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/a/a7/Breakrazor%27s_Bastion.png"), new Boon("Razorclaw's Rage",41016, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/7/73/Razorclaw%27s_Rage.png"), @@ -192,24 +192,24 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity //new Boon("Expose Defenses", 48894, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Invoking Harmony",29025, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //new Boon("Selfless Amplification",30509, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Hardening Persistence",28957, BoonSource.Revenant, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Soothing Bastion",34136, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Hardening Persistence",28957, BoonSource.Revenant, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Soothing Bastion",34136, BoonSource.Revenant, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Kalla's Fervor",42883, BoonSource.Revenant, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff), new Boon("Improved Kalla's Fervor",45614, BoonSource.Revenant, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff), ///WARRIOR //skills - new Boon("Riposte",14434, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Riposte",14434, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Flames of War", 31708, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Blood Reckoning", 29466 , BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Rock Guard", 34256 , BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Sight beyond Sight",40616, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //signets - new Boon("Healing Signet",786, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Dolyak Signet",14458, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Fury",14459, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Might",14444, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Stamina",14478, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Rage",14496, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Healing Signet",786, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Dolyak Signet",14458, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Fury",14459, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Might",14444, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Stamina",14478, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Rage",14496, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //banners new Boon("Banner of Strength", 14417, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/e/e1/Banner_of_Strength.png/33px-Banner_of_Strength.png"), new Boon("Banner of Discipline", 14449, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/5/5f/Banner_of_Discipline.png/33px-Banner_of_Discipline.png"), @@ -221,7 +221,7 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Enduring Pain",787, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Balanced Stance",34778, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Defiant Stance",21816, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Rampage",14484, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Rampage",14484, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Empower Allies", 14222, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/4/4c/Empower_Allies.png/20px-Empower_Allies.png"), new Boon("Peak Performance",46853, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), @@ -229,74 +229,74 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Health Gain per Adrenaline bar Spent", BoonSource.Warrior, BoonType.Intensity, 3, BoonEnum.GraphOnlyBuff), new Boon("Rousing Resilience",24383, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Always Angry",34099, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Full Counter",43949, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Full Counter",43949, BoonSource.Warrior, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Attacker's Insight",41963, BoonSource.Warrior, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff), /// GUARDIAN //skills - new Boon("Zealot's Flame", 9103, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Zealot's Flame", 9103, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Purging Flames",21672, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/2/28/Purging_Flames.png"), new Boon("Litany of Wrath",21665, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Renewed Focus",9255, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Ashes of the Just",41957, BoonSource.Guardian, BoonType.Intensity, 25, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/6/6d/Epilogue-_Ashes_of_the_Just.png", RemoveType.Manual), + new Boon("Renewed Focus",9255, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Ashes of the Just",41957, BoonSource.Guardian, BoonType.Intensity, 25, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/6/6d/Epilogue-_Ashes_of_the_Just.png", RemoveType.ManualFriend), new Boon("Eternal Oasis",44871, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/5/5f/Epilogue-_Eternal_Oasis.png"), new Boon("Unbroken Lines",43194, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/d/d8/Epilogue-_Unbroken_Lines.png"), //signets - new Boon("Signet of Resolve",9220, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Bane Signet",9092, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Judgment",9156, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Mercy",9162, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Wrath",9100, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Courage",29633, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of Resolve",9220, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Bane Signet",9092, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Judgment",9156, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Mercy",9162, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Wrath",9100, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Courage",29633, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //virtues - new Boon("Virtue of Justice", 9114, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Spears of Justice", 29632, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Virtue of Courage", 9113, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Shield of Courage", 29523, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Virtue of Resolve", 9119, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Wings of Resolve", 30308, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Tome of Justice",40530, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Tome of Courage",43508,BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Tome of Resolve",46298, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Virtue of Justice", 9114, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Spears of Justice", 29632, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Virtue of Courage", 9113, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Shield of Courage", 29523, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Virtue of Resolve", 9119, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Wings of Resolve", 30308, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Tome of Justice",40530, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Tome of Courage",43508,BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Tome of Resolve",46298, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Strength in Numbers",13796, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/7/7b/Strength_in_Numbers.png"), new Boon("Invigorated Bulwark",30207, BoonSource.Guardian, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff), new Boon("Battle Presence", 17046, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/2/27/Battle_Presence.png"), //new Boon("Force of Will",29485, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff),//not sure if intensity - new Boon("Quickfire",45123, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Quickfire",45123, BoonSource.Guardian, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), ///ENGINEER //skills new Boon("Static Shield",6055, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Absorb",6056, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("A.E.D.",21660, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("A.E.D.",21660, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Elixir S",5863, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Elixir X", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Elixir X", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Utility Goggles",5864, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Slick Shoes",5833, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Watchful Eye", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Watchful Eye", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Cooling Vapor",46444, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Photon Wall Deployed",46094, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Spectrum Shield",43066, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Photon Wall Deployed",46094, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Spectrum Shield",43066, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Gear Shield",5997, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //Transforms - new Boon("Rampage", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Photon Forge",43708, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Rampage", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Photon Forge",43708, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //Traits - new Boon("Laser's Edge",44414, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Afterburner",42210, BoonSource.Engineer, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Iron Blooded",49065, BoonSource.Engineer, BoonType.Intensity, 25, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Streamlined Kits",18687, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Kinetic Charge",45781, BoonSource.Engineer, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Laser's Edge",44414, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Afterburner",42210, BoonSource.Engineer, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Iron Blooded",49065, BoonSource.Engineer, BoonType.Intensity, 25, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Streamlined Kits",18687, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Kinetic Charge",45781, BoonSource.Engineer, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), - new Boon("Heat Therapy",40694, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Heat Therapy",40694, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Overheat", 40397, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), ///RANGER - new Boon("Celestial Avatar", 31508, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Counterattack",14509, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Celestial Avatar", 31508, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Counterattack",14509, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //signets - new Boon("Signet of Renewal",41147, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Stone",12627, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of the Hunt",12626, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of the Wild",12636, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of Renewal",41147, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Stone",12627, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of the Hunt",12626, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of the Wild",12636, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //spirits // new Boon("Water Spirit", 50386, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/0/06/Water_Spirit.png/33px-Water_Spirit.png"), new Boon("Frost Spirit", 12544, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/c/c6/Frost_Spirit.png/33px-Frost_Spirit.png"), @@ -314,8 +314,8 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Call of the Wild",36781, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Strength of the pack!",12554, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Sick 'Em!",33902, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Sharpening Stones",12536, BoonSource.Ranger, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Ancestral Grace", 31584, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Sharpening Stones",12536, BoonSource.Ranger, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Ancestral Grace", 31584, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Glyph of Empowerment", 31803, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/thumb/f/f0/Glyph_of_Empowerment.png/33px-Glyph_of_Empowerment.png"), new Boon("Dolyak Stance",41815, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/7/71/Dolyak_Stance.png"), new Boon("Griffon Stance",46280, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/9/98/Griffon_Stance.png"), @@ -323,44 +323,44 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Vulture Stance",44651, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/8/8f/Vulture_Stance.png"), new Boon("Bear Stance",40045, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/f/f0/Bear_Stance.png"), new Boon("One Wolf Pack",44139, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/3/3b/One_Wolf_Pack.png"), - new Boon("Sharpen Spines",43266, BoonSource.Ranger, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Sharpen Spines",43266, BoonSource.Ranger, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Spotter", 14055, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/b0/Spotter.png"), - new Boon("Opening Strike",13988, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Quick Draw",29703, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Opening Strike",13988, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Quick Draw",29703, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Light on your feet",30673, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Natural Mender",30449, BoonSource.Ranger, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff), new Boon("Lingering Light",32248, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Deadly",44932, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Ferocious",41720, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Supportive",40069, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Versatile",44693, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Stout",40272, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Deadly",44932, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Ferocious",41720, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Supportive",40069, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Versatile",44693, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Stout",40272, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Unstoppable Union",44439, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Twice as Vicious",45600, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), ///THIEF //signets - new Boon("Signet of Malice",13049, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Assassin's Signet (Passive)",13047, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Assassin's Signet (Active)",44597, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Infiltrator's Signet",13063, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Agility",13061, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Shadows",13059, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of Malice",13049, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Assassin's Signet (Passive)",13047, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Assassin's Signet (Active)",44597, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Infiltrator's Signet",13063, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Agility",13061, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Shadows",13059, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //venoms - new Boon("Skelk Venom",-1, BoonSource.Thief, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/75/Skelk_Venom.png", RemoveType.Manual), - new Boon("Ice Drake Venom",13095, BoonSource.Thief, BoonType.Intensity, 4, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/7b/Ice_Drake_Venom.png", RemoveType.Manual), - new Boon("Devourer Venom", 13094, BoonSource.Thief, BoonType.Intensity, 2, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/4/4d/Devourer_Venom.png", RemoveType.Manual), - new Boon("Skale Venom", 13036, BoonSource.Thief, BoonType.Intensity, 4, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/1/14/Skale_Venom.png", RemoveType.Manual), - new Boon("Spider Venom",13036, BoonSource.Thief, BoonType.Intensity, 6, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/3/39/Spider_Venom.png", RemoveType.Manual), - new Boon("Basilisk Venom", 13133, BoonSource.Thief, BoonType.Intensity, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/3/3a/Basilisk_Venom.png", RemoveType.Manual), + new Boon("Skelk Venom",-1, BoonSource.Thief, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/75/Skelk_Venom.png", RemoveType.ManualFriend), + new Boon("Ice Drake Venom",13095, BoonSource.Thief, BoonType.Intensity, 4, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/7b/Ice_Drake_Venom.png", RemoveType.ManualFriend), + new Boon("Devourer Venom", 13094, BoonSource.Thief, BoonType.Intensity, 2, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/4/4d/Devourer_Venom.png", RemoveType.ManualFriend), + new Boon("Skale Venom", 13036, BoonSource.Thief, BoonType.Intensity, 4, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/1/14/Skale_Venom.png", RemoveType.ManualFriend), + new Boon("Spider Venom",13036, BoonSource.Thief, BoonType.Intensity, 6, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/3/39/Spider_Venom.png", RemoveType.ManualFriend), + new Boon("Basilisk Venom", 13133, BoonSource.Thief, BoonType.Intensity, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/3/3a/Basilisk_Venom.png", RemoveType.ManualFriend), //physical - new Boon("Palm Strike",30423, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Pulmonary Impact",30510, BoonSource.Thief, BoonType.Intensity, 2, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Palm Strike",30423, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Pulmonary Impact",30510, BoonSource.Thief, BoonType.Intensity, 2, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //weapon - new Boon("Infiltration",13135, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Infiltration",13135, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //transforms - new Boon("Dagger Storm",13134, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Kneeling",42869, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Dagger Storm",13134, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Kneeling",42869, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits //new Boon("Deadeyes's Gaze",46333, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //new Boon("Maleficent Seven",43606, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), @@ -372,21 +372,21 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Bounding Dodger", 33162, BoonSource.Thief, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), ///MESMER //signets - new Boon("Signet of the Ether", 21751, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Domination",10231, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Illusions",10246, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Inspiration",10235, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Midnight",10233, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Humility",30739, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of the Ether", 21751, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Domination",10231, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Illusions",10246, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Inspiration",10235, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Midnight",10233, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Humility",30739, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //skills new Boon("Distortion",10243, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Blur", 10335 , BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Blur", 10335 , BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Mirror",10357, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Echo",29664, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Illusion of Life", BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Echo",29664, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Illusion of Life", BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //new Boon("Time Block",30134, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), What is this? - new Boon("Time Echo",29582, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Time Anchored",30136, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Time Echo",29582, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Time Anchored",30136, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Fencer's Finesse", 30426 , BoonSource.Mesmer, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff), new Boon("Illusionary Defense",49099, BoonSource.Mesmer, BoonType.Intensity, 5, BoonEnum.GraphOnlyBuff), @@ -395,64 +395,64 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Mirage Cloak",40408, BoonSource.Mesmer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), ///NECROMANCER //forms - new Boon("Lich Form",10631, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Death Shroud", 790, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Reaper's Shroud", 29446, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Lich Form",10631, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Death Shroud", 790, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Reaper's Shroud", 29446, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //signets - new Boon("Signet of Vampirism",21761, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Plague Signet",10630, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Spite",10621, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of the Locust",10614, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Undeath",10610, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of Vampirism",21761, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Plague Signet",10630, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Spite",10621, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of the Locust",10614, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Undeath",10610, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //skills - new Boon("Spectral Walk",15083, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Infusing Terror", 30129, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Spectral Walk",15083, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Infusing Terror", 30129, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Corrupter's Defense",30845, BoonSource.Necromancer, BoonType.Intensity, 10, BoonEnum.GraphOnlyBuff), new Boon("Vampiric Aura", 30285, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/d/da/Vampiric_Presence.png"), new Boon("Last Rites",29726, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/1/1a/Last_Rites_%28effect%29.png"), - new Boon("Sadistic Searing",43626, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Sadistic Searing",43626, BoonSource.Necromancer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), ///ELEMENTALIST //signets - new Boon("Signet of Restoration",739, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Air",5590, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Earth",5592, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Fire",5544, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Signet of Water",5591, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Signet of Restoration",739, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Air",5590, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Earth",5592, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Fire",5544, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Signet of Water",5591, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //attunments - new Boon("Fire Attunement", 5585, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Water Attunement", 5586, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Air Attunement", 5575, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Earth Attunement", 5580, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Fire Attunement", 5585, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Water Attunement", 5586, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Air Attunement", 5575, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Earth Attunement", 5580, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //forms new Boon("Mist Form",5543, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Ride the Lightning",5588, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Ride the Lightning",5588, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Vapor Form",5620, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Tornado",5534, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Whirlpool", BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Tornado",5534, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Whirlpool", BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //conjures - new Boon("Conjure Earth Shield", 15788, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/7/7a/Conjure_Earth_Shield.png", RemoveType.Manual), - new Boon("Conjure Flame Axe", 15789, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/a/a1/Conjure_Flame_Axe.png", RemoveType.Manual), - new Boon("Conjure Frost Bow", 15790, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/c/c3/Conjure_Frost_Bow.png", RemoveType.Manual), - new Boon("Conjure Lightning Hammer", 15791, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/1/1f/Conjure_Lightning_Hammer.png", RemoveType.Manual), - new Boon("Conjure Fiery Greatsword", 15792, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/e/e2/Conjure_Fiery_Greatsword.png", RemoveType.Manual), + new Boon("Conjure Earth Shield", 15788, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/7/7a/Conjure_Earth_Shield.png", RemoveType.ManualFriend), + new Boon("Conjure Flame Axe", 15789, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/a/a1/Conjure_Flame_Axe.png", RemoveType.ManualFriend), + new Boon("Conjure Frost Bow", 15790, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/c/c3/Conjure_Frost_Bow.png", RemoveType.ManualFriend), + new Boon("Conjure Lightning Hammer", 15791, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/1/1f/Conjure_Lightning_Hammer.png", RemoveType.ManualFriend), + new Boon("Conjure Fiery Greatsword", 15792, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/e/e2/Conjure_Fiery_Greatsword.png", RemoveType.ManualFriend), //skills - new Boon("Arcane Power",5582, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/72/Arcane_Power.png", RemoveType.Manual), - new Boon("Arcane Shield",5640, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Renewal of Fire",5764, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Glyph of Elemental Power (Fire)",5739, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Glyph of Elemental Power (Water)",5741, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Glyph of Elemental Power (Air)",5740, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Glyph of Elemental Power (Earth)",5742, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Rebound",31337, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/0/03/%22Rebound%21%22.png", RemoveType.Manual), - new Boon("Rock Barrier",34633, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual),//750? + new Boon("Arcane Power",5582, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, "https://wiki.guildwars2.com/images/7/72/Arcane_Power.png", RemoveType.ManualFriend), + new Boon("Arcane Shield",5640, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Renewal of Fire",5764, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Glyph of Elemental Power (Fire)",5739, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Glyph of Elemental Power (Water)",5741, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Glyph of Elemental Power (Air)",5740, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Glyph of Elemental Power (Earth)",5742, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), + new Boon("Rebound",31337, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/0/03/%22Rebound%21%22.png", RemoveType.ManualFriend), + new Boon("Rock Barrier",34633, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend),//750? new Boon("Magnetic Wave",15794, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), - new Boon("Obsidian Flesh",5667, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Obsidian Flesh",5667, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //traits new Boon("Harmonious Conduit",31353, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Fresh Air",31353, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Soothing Mist", 5587, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.DefensiveBuffTable, "https://wiki.guildwars2.com/images/f/f7/Soothing_Mist.png"), - new Boon("Lesser Arcane Shield",25579, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Lesser Arcane Shield",25579, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Weaver's Prowess",42061, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), new Boon("Elements of Rage",42416, BoonSource.Elementalist, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), /// FOODS @@ -491,7 +491,7 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity }; - public static bool removePermission(int boonid, int buffremove) + public static bool removePermission(int boonid, int buffremove, int iff) { if (buffremove == 0) { @@ -502,10 +502,12 @@ public static bool removePermission(int boonid, int buffremove) { switch (toCheck.remove_type) { - case RemoveType.Cleanse: - return buffremove == 1 || buffremove == 2; - case RemoveType.Manual: - return buffremove == 3 || buffremove == 1; + case RemoveType.CleanseFriend: + return iff != 1 && (buffremove == 1 || buffremove == 2); + case RemoveType.CleanseFoe: + return iff != 0 && (buffremove == 1 || buffremove == 2); + case RemoveType.ManualFriend: + return iff != 1 && (buffremove == 3 || buffremove == 1); case RemoveType.All: return buffremove == 1 || buffremove == 2 || buffremove == 3; default: diff --git a/LuckParser/Models/ParseModels/Player.cs b/LuckParser/Models/ParseModels/Player.cs index a5cf9f5e9..63cb02251 100644 --- a/LuckParser/Models/ParseModels/Player.cs +++ b/LuckParser/Models/ParseModels/Player.cs @@ -689,7 +689,7 @@ private BoonMap getBoonMap(BossData bossData, SkillData skillData, List Date: Sun, 10 Jun 2018 16:11:44 +0200 Subject: [PATCH 08/53] changed weps icons so that they have the same color palet --- LuckParser/Controllers/Controller1.cs | 41 +++++++++++++------------ LuckParser/Models/ParseModels/Player.cs | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 04a1a9533..f6367cf4d 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1808,6 +1808,7 @@ private void PrintWeapons(StreamWriter sw, Player p) AgentData a_data = getAgentData(); //print weapon sets string[] wep = p.getWeaponsArray(s_data,c_data,b_data,a_data); + sw.Write("
"); if (wep[0] != null) { sw.Write("\"""); @@ -1832,7 +1833,7 @@ private void PrintWeapons(StreamWriter sw, Player p) } else { - sw.Write("/"); + sw.Write(" / "); } if (wep[2] != null) @@ -1855,6 +1856,7 @@ private void PrintWeapons(StreamWriter sw, Player p) //sw.Write("\"Unknown\""); } sw.Write("
"); + sw.Write("
"); } bool[] SnapSettings; @@ -1915,8 +1917,9 @@ private void CreateCompTable(StreamWriter sw) { sw.Write(""); { sw.Write("\"""); + sw.Write(build); PrintWeapons(sw,gPlay); - sw.Write(build + "
" + charName); + sw.Write(charName); } sw.Write(""); } @@ -6041,37 +6044,37 @@ public string GetLink(string name) case "Question": return "https://wiki.guildwars2.com/images/thumb/d/de/Sword_slot.png/40px-Sword_slot.png"; case "Sword": - return "https://wiki.guildwars2.com/images/6/61/Sword_Proficiency.png"; + return "https://wiki.guildwars2.com/images/0/07/Crimson_Antique_Blade.png"; case "Axe": - return "https://wiki.guildwars2.com/images/a/a2/Axe_Proficiency.png"; + return "https://wiki.guildwars2.com/images/d/d4/Crimson_Antique_Reaver.png"; case "Dagger": - return "https://wiki.guildwars2.com/images/c/c9/Dagger_Proficiency.png"; + return "https://wiki.guildwars2.com/images/6/65/Crimson_Antique_Razor.png"; case "Mace": - return "https://wiki.guildwars2.com/images/3/37/Mace_Smash.png"; + return "https://wiki.guildwars2.com/images/6/6d/Crimson_Antique_Flanged_Mace.png"; case "Pistol": - return "https://wiki.guildwars2.com/images/7/7a/Phantasmal_Duelist.png"; - case "Sceptor": - return "https://wiki.guildwars2.com/images/2/22/Water_Trident.png"; + return "https://wiki.guildwars2.com/images/4/46/Crimson_Antique_Revolver.png"; + case "Scepter": + return "https://wiki.guildwars2.com/images/e/e2/Crimson_Antique_Wand.png"; case "Focus": - return "https://wiki.guildwars2.com/images/7/79/Focus_Mastery.png"; + return "https://wiki.guildwars2.com/images/8/87/Crimson_Antique_Artifact.png"; case "Shield": - return "https://wiki.guildwars2.com/images/c/c6/Shield_Proficiency.png"; + return "https://wiki.guildwars2.com/images/b/b0/Crimson_Antique_Bastion.png"; case "Torch": - return "https://wiki.guildwars2.com/images/1/11/Torch_Proficiency.png"; + return "https://wiki.guildwars2.com/images/7/76/Crimson_Antique_Brazier.png"; case "Warhorn": - return "https://wiki.guildwars2.com/images/b/b8/Warhorn_Proficiency.png"; + return "https://wiki.guildwars2.com/images/1/1c/Crimson_Antique_Herald.png"; case "Greatsword": - return "https://wiki.guildwars2.com/images/8/8b/Greatsword_Proficiency.png"; + return "https://wiki.guildwars2.com/images/5/50/Crimson_Antique_Claymore.png"; case "Hammer": - return "https://wiki.guildwars2.com/images/5/5f/Hammer_Proficiency.png"; + return "https://wiki.guildwars2.com/images/3/38/Crimson_Antique_Warhammer.png"; case "Longbow": - return "https://wiki.guildwars2.com/images/5/53/Longbow_Proficiency.png"; + return "https://wiki.guildwars2.com/images/f/f0/Crimson_Antique_Greatbow.png"; case "Shortbow": - return "https://wiki.guildwars2.com/images/e/e7/Short_Bow_Proficiency_%28renegade%29.png"; + return "https://wiki.guildwars2.com/images/1/17/Crimson_Antique_Short_Bow.png"; case "Rifle": - return "https://wiki.guildwars2.com/images/5/5d/Rifle_Proficiency_%28deadeye%29.png"; + return "https://wiki.guildwars2.com/images/1/19/Crimson_Antique_Musket.png"; case "Staff": - return "https://wiki.guildwars2.com/images/7/78/Staff_Proficiency.png"; + return "https://wiki.guildwars2.com/images/5/5f/Crimson_Antique_Spire.png"; case "Vale Guardian-icon": return "https://wiki.guildwars2.com/images/f/fb/Mini_Vale_Guardian.png"; case "Gorseval the Multifarious-icon": diff --git a/LuckParser/Models/ParseModels/Player.cs b/LuckParser/Models/ParseModels/Player.cs index 63cb02251..7ea582854 100644 --- a/LuckParser/Models/ParseModels/Player.cs +++ b/LuckParser/Models/ParseModels/Player.cs @@ -366,7 +366,7 @@ private void EstimateWeapons(SkillData s_data, CombatData c_data, BossData b_dat //} continue; }//OffHand - if (apiskill.weapon_type == "Axe" || apiskill.weapon_type == "Dagger" || apiskill.weapon_type == "Mace" || apiskill.weapon_type == "Pistol" || apiskill.weapon_type == "Sword" || apiskill.weapon_type == "Sceptor") + if (apiskill.weapon_type == "Axe" || apiskill.weapon_type == "Dagger" || apiskill.weapon_type == "Mace" || apiskill.weapon_type == "Pistol" || apiskill.weapon_type == "Sword" || apiskill.weapon_type == "Scepter") { if (apiskill.slot == "Weapon_1" || apiskill.slot == "Weapon_2" || apiskill.slot == "Weapon_3") { From fb32fb80a6a84754f2a336fd4d93e9ebb30974ad Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 16:06:15 +0200 Subject: [PATCH 09/53] added phase data on the controller for testing purpose, can detect phases for sab, matt and gorseval, added some skill data, corrected some boon issues --- LuckParser/Models/ParseModels/Boons/Boon.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/LuckParser/Models/ParseModels/Boons/Boon.cs b/LuckParser/Models/ParseModels/Boons/Boon.cs index 353e9130d..c8e52774e 100644 --- a/LuckParser/Models/ParseModels/Boons/Boon.cs +++ b/LuckParser/Models/ParseModels/Boons/Boon.cs @@ -278,6 +278,7 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Spectrum Shield",43066, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Gear Shield",5997, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //Transforms +<<<<<<< HEAD new Boon("Rampage", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Photon Forge",43708, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //Traits @@ -289,6 +290,19 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), new Boon("Heat Therapy",40694, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Overheat", 40397, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), +======= + new Boon("Rampage", BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + //new Boon("Photon Forge",43708, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), Never removed? + //Traits + new Boon("Laser's Edge",44414, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Afterburner",42210, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Iron Blooded",49065, BoonSource.Engineer, "intensity", 25, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Streamlined Kits",18687, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Kinetic Charge",45781, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, "duration", 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), + new Boon("Heat Therapy",40694, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), + new Boon("Overheat", 40397, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff), +>>>>>>> added phase data on the controller for testing purpose, can detect phases for sab, matt and gorseval, added some skill data, corrected some boon issues ///RANGER new Boon("Celestial Avatar", 31508, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Counterattack",14509, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), From 16ad7464ac16e97c6f863dc03cd0077807cf1880 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sat, 9 Jun 2018 21:24:52 +0200 Subject: [PATCH 10/53] fixed a bug where avg boons calculation would hang up, added Deimos phase detection --- LuckParser/Controllers/Controller1.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index f6367cf4d..d15edc8de 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -2416,6 +2416,13 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t { avg_boons += boonPresence[boon.getID()]; } +<<<<<<< HEAD +======= +<<<<<<< HEAD + +======= +>>>>>>> fixed a bug where avg boons calculation would hang up, added Deimos phase detection +>>>>>>> fixed a bug where avg boons calculation would hang up, added Deimos phase detection } avg_boons /= fight_duration; sw.Write("" + player.getCharacter().ToString() + " "); From 822afe314a9496f28e788cf9be935427e5e4d881 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 16:20:06 +0200 Subject: [PATCH 11/53] merge errors --- LuckParser/Controllers/Controller1.cs | 7 ------- LuckParser/Models/ParseModels/Boons/Boon.cs | 14 -------------- 2 files changed, 21 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index d15edc8de..f6367cf4d 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -2416,13 +2416,6 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t { avg_boons += boonPresence[boon.getID()]; } -<<<<<<< HEAD -======= -<<<<<<< HEAD - -======= ->>>>>>> fixed a bug where avg boons calculation would hang up, added Deimos phase detection ->>>>>>> fixed a bug where avg boons calculation would hang up, added Deimos phase detection } avg_boons /= fight_duration; sw.Write("" + player.getCharacter().ToString() + " "); diff --git a/LuckParser/Models/ParseModels/Boons/Boon.cs b/LuckParser/Models/ParseModels/Boons/Boon.cs index c8e52774e..353e9130d 100644 --- a/LuckParser/Models/ParseModels/Boons/Boon.cs +++ b/LuckParser/Models/ParseModels/Boons/Boon.cs @@ -278,7 +278,6 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Spectrum Shield",43066, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Gear Shield",5997, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), //Transforms -<<<<<<< HEAD new Boon("Rampage", BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Photon Forge",43708, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), //Traits @@ -290,19 +289,6 @@ private Boon(string name, int id, BoonSource source, BoonType type, int capacity new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), new Boon("Heat Therapy",40694, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Overheat", 40397, BoonSource.Engineer, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff), -======= - new Boon("Rampage", BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - //new Boon("Photon Forge",43708, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), Never removed? - //Traits - new Boon("Laser's Edge",44414, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Afterburner",42210, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Iron Blooded",49065, BoonSource.Engineer, "intensity", 25, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Streamlined Kits",18687, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Kinetic Charge",45781, BoonSource.Engineer, "intensity", 5, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Pinpoint Distribution", 38333, BoonSource.Engineer, "duration", 1, BoonEnum.OffensiveBuffTable, "https://wiki.guildwars2.com/images/b/bf/Pinpoint_Distribution.png"), - new Boon("Heat Therapy",40694, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff, RemoveType.Manual), - new Boon("Overheat", 40397, BoonSource.Engineer, "duration", 1, BoonEnum.GraphOnlyBuff), ->>>>>>> added phase data on the controller for testing purpose, can detect phases for sab, matt and gorseval, added some skill data, corrected some boon issues ///RANGER new Boon("Celestial Avatar", 31508, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), new Boon("Counterattack",14509, BoonSource.Ranger, BoonType.Duration, 1, BoonEnum.GraphOnlyBuff, RemoveType.ManualFriend), From 87dbe89c5e6111a6529aa29921595f460f8996f6 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 16:24:08 +0200 Subject: [PATCH 12/53] fixed a reg on matthias phase detection --- LuckParser/Models/ParseModels/Boss.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 78d295ca2..19415ed57 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -194,7 +194,7 @@ private void setPhases(BossData bossData, List combatList, AgentData default: break; } - if (fight_dur - start > 5000 && start > phases.Last().end) + if (fight_dur - start > 5000 && start >= phases.Last().end) { phases.Add(new PhaseData(start, fight_dur)); } From 870e24afbcf6650e17e3747e25a3abd699d9f407 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Sun, 10 Jun 2018 21:56:30 +0200 Subject: [PATCH 13/53] all stats, mechanics, simple rota, damage dist tables , rota under player graph ok, boons and dps graphs missing --- LuckParser/Controllers/Controller1.cs | 1073 ++++++++++--------- LuckParser/Models/ParseModels/Boss.cs | 2 +- LuckParser/Models/ParseModels/CombatData.cs | 16 +- LuckParser/Models/ParseModels/Player.cs | 76 +- 4 files changed, 597 insertions(+), 570 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 88d303490..5a69c952f 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -622,7 +622,7 @@ private void fillMissingData() foreach (AgentItem playerAgent in playerAgentList) { - List lp = combat_data.getStates(playerAgent.getInstid(), "DESPAWN"); + List lp = combat_data.getStates(playerAgent.getInstid(), "DESPAWN", boss_data.getFirstAware(), boss_data.getLastAware()); Player player = new Player(playerAgent); bool skip = false; foreach (Player p in p_list) @@ -664,7 +664,7 @@ private void fillMissingData() } } - player.SetDC(lp[0].X); + player.SetDC(lp[0].getTime()); p_list.Add(player); } else//didnt dc @@ -737,7 +737,7 @@ private void setPresentBoons(bool[] SnapSettings) { } } } - private String getFinalDPS(Player p) + private String getFinalDPS(Player p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); @@ -754,14 +754,14 @@ private String getFinalDPS(Player p) int totalAllcondi_damage = 0; int totalAllphys_dps = 0; int totalAllphys_damage = 0; - double fight_duration = (b_data.getLastAware() - b_data.getFirstAware()) / 1000.0; - + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + double fight_duration = (phase.end - phase.start) / 1000.0; double damage = 0.0; double dps = 0.0; // All DPS - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); if (fight_duration > 0) { dps = damage / fight_duration; @@ -769,7 +769,7 @@ private String getFinalDPS(Player p) totalAll_dps = (int)dps; totalAll_damage = (int)damage; //Allcondi - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0 && x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage()); if (fight_duration > 0) { dps = damage / fight_duration; @@ -786,7 +786,7 @@ private String getFinalDPS(Player p) totalAllphys_damage = (int)damage; // boss DPS - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); if (fight_duration > 0) { dps = damage / fight_duration; @@ -794,7 +794,7 @@ private String getFinalDPS(Player p) totalboss_dps = (int)dps; totalboss_damage = (int)damage; //bosscondi - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0 && x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage()); if (fight_duration > 0) { dps = damage / fight_duration; @@ -813,13 +813,16 @@ private String getFinalDPS(Player p) return totalAll_dps.ToString() + "|" + totalAll_damage.ToString() + "|" + totalAllphys_dps.ToString() + "|" + totalAllphys_damage.ToString() + "|" + totalAllcondi_dps.ToString() + "|" + totalAllcondi_damage.ToString() + "|" + totalboss_dps.ToString() + "|" + totalboss_damage.ToString() + "|" + totalbossphys_dps.ToString() + "|" + totalbossphys_damage.ToString() + "|" + totalbosscondi_dps.ToString() + "|" + totalbosscondi_damage.ToString(); } - private String[] getFinalStats(Player p) + private String[] getFinalStats(Player p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); String[] statsArray; - List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()); - List cast_logs = p.getCastLogs( b_data, c_data.getCombatList(), getAgentData()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List cast_logs = p.getCastLogs( b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); int instid = p.getInstid(); // Rates @@ -827,7 +830,7 @@ private String[] getFinalStats(Player p) int critical_rate = 0; int scholar_rate = 0; int scholar_dmg = 0; - int totaldamage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Sum(x => x.getDamage()); + int totaldamage = damage_logs.Sum(x => x.getDamage()); int moving_rate = 0; int flanking_rate = 0; @@ -911,54 +914,67 @@ private String[] getFinalStats(Player p) power_loop_count = (power_loop_count == 0) ? 1 : power_loop_count; // Counts - int swap = c_data.getStates(instid, "WEAPON_SWAP").Count(); - int down = c_data.getStates(instid, "CHANGE_DOWN").Count(); - int dodge = c_data.getSkillCount(instid, 65001) + c_data.getBuffCount(instid, 40408);//dodge = 65001 mirage cloak =40408 - int ress = c_data.getSkillCount(instid, 1066); //Res = 1066 + int swap = c_data.getStates(instid, "WEAPON_SWAP", start, end).Count(); + int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); + int dodge = c_data.getSkillCount(instid, 65001, start, end) + c_data.getBuffCount(instid, 40408, start, end);//dodge = 65001 mirage cloak =40408 + int ress = c_data.getSkillCount(instid, 1066, start, end); //Res = 1066 // R.I.P - List dead = c_data.getStates(instid, "CHANGE_DEAD"); + List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); double died = 0.0; if (dead.Count() > 0) { - died = dead[0].X - b_data.getFirstAware(); + died = dead[0].getTime() - start; } - List disconect = c_data.getStates(instid, "DESPAWN"); + List disconect = c_data.getStates(instid, "DESPAWN", start, end); double dcd = 0.0; if (disconect.Count() > 0) { - dcd = disconect[0].X - b_data.getFirstAware(); + dcd = disconect[0].getTime() - start; } - statsArray = new string[] { power_loop_count.ToString(), critical_rate.ToString(), scholar_rate.ToString(), moving_rate.ToString(), - flanking_rate.ToString(), swap.ToString(),down.ToString(),dodge.ToString(),ress.ToString(),died.ToString("0.00"), - glance_rate.ToString(),missed.ToString(),interupts.ToString(),invulned.ToString(),(time_wasted/1000f).ToString(),wasted.ToString(),avgBoons.ToString(),(time_saved/1000f).ToString(),saved.ToString(), - scholar_dmg.ToString(),totaldamage.ToString(),dcd.ToString("0.00"), + statsArray = new string[] { power_loop_count.ToString(), + critical_rate.ToString(), + scholar_rate.ToString(), + moving_rate.ToString(), + flanking_rate.ToString(), + swap.ToString(), + down.ToString(), + dodge.ToString(), + ress.ToString(), + died.ToString("0.00"), + glance_rate.ToString(), + missed.ToString(), + interupts.ToString(), + invulned.ToString(), + (time_wasted/1000f).ToString(), + wasted.ToString(), + avgBoons.ToString(), + (time_saved/1000f).ToString(), + saved.ToString(), + scholar_dmg.ToString(), + totaldamage.ToString(), + dcd.ToString("0.00"), }; return statsArray; } - private string getDamagetaken(Player p) - { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - int instid = p.getInstid(); - int damagetaken = p.getDamagetaken(b_data, c_data.getCombatList(), getAgentData(),getMechData()).Sum(); - return damagetaken.ToString(); - } - private string[] getFinalDefenses(Player p) + private string[] getFinalDefenses(Player p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); - List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(),getMechData()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(),getMechData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); int instid = p.getInstid(); - int damagetaken = p.getDamagetaken(b_data, c_data.getCombatList(), getAgentData(),getMechData()).Sum(); + int damagetaken = damage_logs.Select(x => x.getDamage()).Sum(); int blocked = 0; //int dmgblocked = 0; int invulned = 0; int dmginvulned = 0; - int dodge = c_data.getSkillCount(instid, 65001);//dodge = 65001 - dodge += c_data.getBuffCount(instid, 40408);//mirage cloak add + int dodge = c_data.getSkillCount(instid, 65001, start, end);//dodge = 65001 + dodge += c_data.getBuffCount(instid, 40408, start, end);//mirage cloak add int evades = 0; //int dmgevaded = 0; int dmgBarriar = 0; @@ -982,25 +998,35 @@ private string[] getFinalDefenses(Player p) dmgBarriar += log.getDamage(); } - int down = c_data.getStates(instid, "CHANGE_DOWN").Count(); + int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); // R.I.P - List dead = c_data.getStates(instid, "CHANGE_DEAD"); + List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); double died = 0.0; if (dead.Count() > 0) { - died = dead[0].X - b_data.getFirstAware(); + died = dead[0].getTime()- start; } String[] statsArray = new string[] { damagetaken.ToString(), - blocked.ToString(),"0"/*dmgblocked.ToString()*/,invulned.ToString(),dmginvulned.ToString(), - dodge.ToString(),evades.ToString(),"0"/*dmgevaded.ToString()*/, - down.ToString(),died.ToString("0.00"),dmgBarriar.ToString()}; + blocked.ToString(), + "0"/*dmgblocked.ToString()*/, + invulned.ToString(), + dmginvulned.ToString(), + dodge.ToString(), + evades.ToString(), + "0"/*dmgevaded.ToString()*/, + down.ToString(), + died.ToString("0.00"), + dmgBarriar.ToString()}; return statsArray; } //(currently not correct) - private string[] getFinalSupport(Player p) + private string[] getFinalSupport(Player p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); // List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData()); int instid = p.getInstid(); int resurrects = 0; @@ -1008,8 +1034,8 @@ private string[] getFinalSupport(Player p) int condiCleanse = 0; double condiCleansetime = 0.0; - int[] resArray = p.getReses(b_data, c_data.getCombatList(), getAgentData()); - int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), getAgentData()); + int[] resArray = p.getReses(b_data, c_data.getCombatList(), getAgentData(), start, end); + int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), getAgentData(), start, end); resurrects = resArray[0]; restime = resArray[1]; condiCleanse = cleanseArray[0]; @@ -1132,14 +1158,14 @@ private void setMechData() { foreach (Player p in p_list) { - List down = c_data.getStates(p.getInstid(), "CHANGE_DOWN"); - foreach (Point pnt in down) { - mech_data.AddItem(new MechanicLog((long)((pnt.X - boss_data.getFirstAware()) / 1000f), 0, "DOWN", 0, p, mech_data.GetPLoltyShape("DOWN"))); + List down = c_data.getStates(p.getInstid(), "CHANGE_DOWN", 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 dead = c_data.getStates(p.getInstid(), "CHANGE_DEAD"); - foreach (Point pnt in dead) + List dead = c_data.getStates(p.getInstid(), "CHANGE_DEAD", boss_data.getFirstAware(), boss_data.getLastAware()); + foreach (CombatItem pnt in dead) { - mech_data.AddItem(new MechanicLog((long)((pnt.X - boss_data.getFirstAware()) / 1000f), 0, "DEAD", 0, p, mech_data.GetPLoltyShape("DEAD"))); + mech_data.AddItem(new MechanicLog((long)((pnt.getTime() - boss_data.getFirstAware()) / 1000f), 0, "DEAD", 0, p, mech_data.GetPLoltyShape("DEAD"))); } List dls = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data); //Player hit by skill 3 @@ -1215,73 +1241,60 @@ private void setMechData() { /// /// The player /// - private List getBossDPSGraph(Player p) { + private List getBossDPSGraph(Player p, int phase_index) + { List bossdmgList = new List(); - if (p.getBossDPSGraph().Count == 0) + BossData b_data = getBossData(); + CombatData c_data = getCombatData(); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + List damage_logs_boss = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + int totaldmg = 0; + + int timeGraphed = (int)phase.start; + foreach (DamageLog log in damage_logs_boss) { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - // bossdmgList.Add(new int[] {1, 0 }); - // List damage_logs_all = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()); - List damage_logs_boss = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()); - int totaldmg = 0; + totaldmg += log.getDamage(); - int timeGraphed = 0; - foreach (DamageLog log in damage_logs_boss) + long time = log.getTime(); + if (time > 1000) { - totaldmg += log.getDamage(); - - long time = log.getTime(); - if (time > 1000) + //to reduce processing time only graph 1 point per sec + if (Math.Floor(time / 1000f) > timeGraphed) { - //to reduce processing time only graph 1 point per sec - if (Math.Floor(time / 1000f) > timeGraphed) + if ((Math.Floor(time / 1000f) - timeGraphed) < 2) { - - if ((Math.Floor(time / 1000f) - timeGraphed) < 2) + timeGraphed = (int)Math.Floor(time / 1000f); + bossdmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); + } + else + { + int gap = (int)Math.Floor(time / 1000f) - timeGraphed; + bool startOfFight = true; + if (bossdmgList.Count > 0) { - timeGraphed = (int)Math.Floor(time / 1000f); - bossdmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); + startOfFight = false; } - else + + for (int itr = 0; itr < gap - 1; itr++) { - int gap = (int)Math.Floor(time / 1000f) - timeGraphed; - bool startOfFight = true; - if (bossdmgList.Count > 0) + timeGraphed++; + if (!startOfFight) { - startOfFight = false; + bossdmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); } - - for (int itr = 0; itr < gap - 1; itr++) - { - timeGraphed++; - if (!startOfFight) - { - bossdmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); - } - else - {//hasnt hit boss yet gap - bossdmgList.Add(new int[] { timeGraphed, 0 }); - } - + else + {//hasnt hit boss yet gap + bossdmgList.Add(new int[] { timeGraphed, 0 }); } - } + } } - - } - } - p.setBossDPSGraph(bossdmgList); } - else { - bossdmgList = p.getBossDPSGraph(); - } - return bossdmgList; } /// @@ -1289,16 +1302,15 @@ private List getBossDPSGraph(Player p) { /// /// The player /// - private List getTotalDPSGraph(Player p) + private List getTotalDPSGraph(Player p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; List totaldmgList = new List(); - // totaldmgList.Add(new int[] { 1, 0 }); - List damage_logs_all = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()); - //List damage_logs_boss = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()); + List damage_logs_all = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); int totaldmg = 0; - int timeGraphed = 0; + int timeGraphed = (int) phase.start; foreach (DamageLog log in damage_logs_all) { totaldmg += log.getDamage(); @@ -1345,10 +1357,10 @@ private List getTotalDPSGraph(Player p) /// Creates the dps graph /// /// Stream writer - private void CreateDPSGraph(StreamWriter sw) + private void CreateDPSGraph(StreamWriter sw, int phase_index) { //Generate DPS graph - sw.Write("
"); + sw.Write("
"); sw.Write(" "); } private void GetRoles() @@ -1936,10 +1948,11 @@ private void CreateCompTable(StreamWriter sw) { /// /// Stream writer /// Duration of the fight - private void CreateDPSTable(StreamWriter sw,double fight_duration) { + private void CreateDPSTable(StreamWriter sw, int phase_index) { //generate dps table - sw.Write(""); - sw.Write(""); + PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -1966,8 +1979,8 @@ private void CreateDPSTable(StreamWriter sw,double fight_duration) { sw.Write(""); foreach (Player player in p_list) { - string[] dmg = getFinalDPS(player).Split('|'); - string[] stats = getFinalStats(player); + string[] dmg = getFinalDPS(player, phase_index).Split('|'); + string[] stats = getFinalStats(player, phase_index); //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), dmg[0], dmg[1], dmg[2], dmg[3], dmg[4], dmg[5], dmg[6], dmg[7], dmg[8], dmg[9], dmg[10], dmg[11] }); sw.Write(""); @@ -1986,7 +1999,7 @@ private void CreateDPSTable(StreamWriter sw,double fight_duration) { sw.Write(""); sw.Write(""); TimeSpan timedead = TimeSpan.FromMilliseconds(Double.Parse(stats[9])); - + long fight_duration = (phase.end - phase.start)/1000; if (timedead > TimeSpan.Zero) { sw.Write(""); @@ -2051,10 +2064,11 @@ private void CreateDPSTable(StreamWriter sw,double fight_duration) { /// /// Stream writer /// Duration of the fight - private void CreateDMGStatsTable(StreamWriter sw,double fight_duration) { + private void CreateDMGStatsTable(StreamWriter sw, int phase_index) { //generate dmgstats table - sw.Write(""); - sw.Write("
" + "" + dmg[4] + "" + "" + stats[6] + "" + "" + timedead.Minutes + " m " + timedead.Seconds + " s" + "
"); + PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2085,7 +2099,7 @@ private void CreateDMGStatsTable(StreamWriter sw,double fight_duration) { { foreach (Player player in p_list) { - string[] stats = getFinalStats(player); + string[] stats = getFinalStats(player, phase_index); TimeSpan timedead = TimeSpan.FromMilliseconds(Double.Parse(stats[9]));//dead //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[0], stats[1], stats[2], stats[3], stats[4], stats[10], stats[11], stats[12], stats[13], stats[5], stats[6] }); @@ -2107,6 +2121,7 @@ private void CreateDMGStatsTable(StreamWriter sw,double fight_duration) { sw.Write("");//timesaved sw.Write("");//w swaps sw.Write("");//downs + long fight_duration = (phase.end - phase.start) / 1000; if (timedead > TimeSpan.Zero) { sw.Write(""); @@ -2180,10 +2195,11 @@ private void CreateDMGStatsTable(StreamWriter sw,double fight_duration) { /// /// Stream writer /// Duration of the fight - private void CreateDefTable(StreamWriter sw, double fight_duration) { + private void CreateDefTable(StreamWriter sw, int phase_index) { //generate Tankstats table - sw.Write(""); - sw.Write("
" + "" + stats[17] + "" + "" + stats[5] + "" + stats[6] + "" + "" + timedead.Minutes + " m " + timedead.Seconds + " s" + "
"); + PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2210,7 +2226,7 @@ private void CreateDefTable(StreamWriter sw, double fight_duration) { { foreach (Player player in p_list) { - string[] stats = getFinalDefenses(player); + string[] stats = getFinalDefenses(player, phase_index); TimeSpan timedead = TimeSpan.FromMilliseconds(Double.Parse(stats[9]));//dead //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[0], stats[10], stats[1], stats[3], stats[6], stats[5], stats[8] }); @@ -2226,6 +2242,7 @@ private void CreateDefTable(StreamWriter sw, double fight_duration) { sw.Write("");// evades sw.Write("");//dodges sw.Write("");//downs + long fight_duration = (phase.end - phase.start)/1000; if (timedead > TimeSpan.Zero) { sw.Write(""); @@ -2290,10 +2307,10 @@ private void CreateDefTable(StreamWriter sw, double fight_duration) { /// /// Stream writer /// Duration of the fight - private void CreateSupTable(StreamWriter sw, double fight_duration) { + private void CreateSupTable(StreamWriter sw, int phase_index) { //generate suppstats table - sw.Write(""); - sw.Write("
" + stats[6] + "" + stats[5] + "" + stats[8] + "" + "" + timedead.Minutes + " m " + timedead.Seconds + " s" + "
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2314,7 +2331,7 @@ private void CreateSupTable(StreamWriter sw, double fight_duration) { { foreach (Player player in p_list) { - string[] stats = getFinalSupport(player); + string[] stats = getFinalSupport(player, phase_index); //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[3], stats[2], stats[1], stats[0] }); sw.Write(""); @@ -2368,12 +2385,12 @@ private void CreateSupTable(StreamWriter sw, double fight_duration) { /// Stream writer /// Boon list to use /// id of the table - private void CreateUptimeTable(StreamWriter sw, List list_to_use, string table_id) + private void CreateUptimeTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { //Generate Boon table------------------------------------------------------------------------------------------------ - sw.Write(""); + sw.Write(""); List> footList = new List>(); - sw.Write("
"); + sw.Write("
"); { sw.Write(""); { @@ -2507,10 +2524,10 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t /// Stream writer /// Boon list to use /// id of the table - private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string table_id) + private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { //Generate BoonGenSelf table - sw.Write(""); - sw.Write("
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2567,10 +2584,10 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string /// Stream writer /// Boon list to use /// id of the table - private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string table_id) + private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { //Generate BoonGenGroup table - sw.Write(""); - sw.Write("
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2632,10 +2649,10 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string /// Stream writer /// Boon list to use /// id of the table - private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, string table_id) + private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { //Generate BoonGenOGroup table - sw.Write(""); - sw.Write("
"); + sw.Write(""); + sw.Write("
"); { sw.Write(" "); foreach (Boon boon in list_to_use) @@ -2685,10 +2702,10 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin /// Stream writer /// Boon list to use /// id of the table - private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string table_id) { + private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { //Generate BoonGenSquad table - sw.Write(""); - sw.Write("
SubName
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -2745,48 +2762,52 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string /// /// Stream writer /// Settings to use - private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) + private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_index) { //generate Player list Graphs foreach (Player p in p_list) { CombatData c_data = getCombatData(); BossData b_data = getBossData(); - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where( x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); - bool died = p.getDeath(getCombatData().getCombatList()) > 0; + bool died = p.getDeath(getCombatData().getCombatList(), start, end) > 0; string charname = p.getCharacter(); - sw.Write("
"); + string pid = p.getInstid() + "_" + phase_index; + sw.Write("
"); { sw.Write("

" + charname + "\""" + "

"); sw.Write(""); sw.Write("
"); { - sw.Write("
"); + sw.Write("
"); { - List consume = p.getConsumablesList(b_data,s_data, c_data.getCombatList()); + List consume = p.getConsumablesList(b_data, s_data, c_data.getCombatList(), phase.start, phase.end); List initial = consume.Where(x => x[1] == 0).ToList(); List refreshed = consume.Where(x => x[1] > 0).ToList(); if (initial.Count() > 0) @@ -2851,7 +2872,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) } sw.Write("

"); } - sw.Write("
"); + sw.Write("
"); sw.Write(" "); sw.Write(""); sw.Write("
"); { - sw.Write("
"); + sw.Write("
"); { - CreateDMGDistTable(sw, p, false); + CreateDMGDistTable(sw, p, false, phase_index); } sw.Write("
"); - sw.Write("
"); + sw.Write("
"); { - CreateDMGDistTable(sw, p, true); + CreateDMGDistTable(sw, p, true, phase_index); } sw.Write("
"); } @@ -3306,8 +3327,8 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) sw.Write("
"); foreach (AgentItem agent in p.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) { - string id = p.getInstid() + "_" + agent.getInstid(); - sw.Write("
"); + string id = pid + "_" + agent.getInstid(); + sw.Write("
"); { sw.Write("
    "); { @@ -3319,12 +3340,12 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) { sw.Write("
    "); { - CreateDMGDistTable(sw, p, agent, false); + CreateDMGDistTable(sw, p, agent, false, phase_index); } sw.Write("
    "); sw.Write("
    "); { - CreateDMGDistTable(sw, p, agent, true); + CreateDMGDistTable(sw, p, agent, true, phase_index); } sw.Write("
    "); } @@ -3334,28 +3355,28 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) } if (SnapSettings[10]) { - sw.Write("
    "); + sw.Write("
    "); { int simpleRotSize = 20; if (settingsSnap[12]) { simpleRotSize = 30; } - CreateSimpleRotationTab(sw, p,simpleRotSize); + CreateSimpleRotationTab(sw, p,simpleRotSize, phase_index); } sw.Write("
    "); } if (died) { - sw.Write("
    "); + sw.Write("
    "); { - CreateDeathRecap(sw, p); + CreateDeathRecap(sw, p, phase_index); } sw.Write("
    "); } - sw.Write("
    "); + sw.Write("
    "); { - CreateDMGTakenDistTable(sw, p); + CreateDMGTakenDistTable(sw, p, phase_index); } sw.Write("
    "); } @@ -3371,14 +3392,15 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap) /// Stream writer /// The player /// Size of the images - private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize) { + private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize, int phase_index) { if (SnapSettings[6])//Display rotation { SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); CombatData c_data = getCombatData(); BossData b_data = getBossData(); - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); GW2APISkill autoSkill = null; int autosCount = 0; foreach (CastLog cl in casting) @@ -3464,7 +3486,7 @@ private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize) /// /// Stream writer /// The player - private void CreateDeathRecap(StreamWriter sw, Player p) + private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) { CombatData c_data = getCombatData(); BossData b_data = getBossData(); @@ -3472,19 +3494,22 @@ private void CreateDeathRecap(StreamWriter sw, Player p) List damageLogs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(), getMechData()); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); - List down = getCombatData().getStates(p.getInstid(), "CHANGE_DOWN"); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List down = getCombatData().getStates(p.getInstid(), "CHANGE_DOWN", start, end); if (down.Count > 0) { - List ups = getCombatData().getStates(p.getInstid(), "CHANGE_UP"); + List ups = getCombatData().getStates(p.getInstid(), "CHANGE_UP", start, end); down = down.GetRange(ups.Count(), down.Count()-ups.Count()); } - List dead = getCombatData().getStates(p.getInstid(), "CHANGE_DEAD"); + List dead = getCombatData().getStates(p.getInstid(), "CHANGE_DEAD", start, end); List damageToDown = new List(); - List damageToKill = new List(); ; + List damageToKill = new List(); if (down.Count > 0) {//went to down state before death - damageToDown = damageLogs.Where(x => x.getTime() < down.Last().X - b_data.getFirstAware() && x.getDamage() > 0).ToList(); - damageToKill = damageLogs.Where(x => x.getTime() > down.Last().X - b_data.getFirstAware() && x.getTime() < dead.Last().X - b_data.getFirstAware() && x.getDamage() > 0).ToList(); + damageToDown = damageLogs.Where(x => x.getTime() < down.Last().getTime() - start && x.getDamage() > 0).ToList(); + damageToKill = damageLogs.Where(x => x.getTime() > down.Last().getTime() - start && x.getTime() < dead.Last().getTime() - start && x.getDamage() > 0).ToList(); //Filter last 30k dmg taken int totaldmg = 0; for (int i = damageToDown.Count() - 1; i > 0; i--) @@ -3511,7 +3536,7 @@ private void CreateDeathRecap(StreamWriter sw, Player p) } else { - damageToKill = damageLogs.Where(x => x.getTime() < dead.Last().X && x.getDamage() > 0).ToList(); + damageToKill = damageLogs.Where(x => x.getTime() < dead.Last().getTime() && x.getDamage() > 0).ToList(); //Filter last 30k dmg taken int totaldmg = 0; for (int i = damageToKill.Count() - 1; i > 0; i--) @@ -3525,8 +3550,8 @@ private void CreateDeathRecap(StreamWriter sw, Player p) } sw.Write("

    Player was insta killed by a mechanic, fall damage or by /gg

    "); } - - sw.Write("
    "); + string pid = p.getInstid() + "_" + phase_index; + sw.Write("
    "); sw.Write(""); @@ -3635,20 +3660,21 @@ private void CreateDeathRecap(StreamWriter sw, Player p) /// /// Stream writer /// The player - private void CreateDMGDistTable(StreamWriter sw, Player p, bool toBoss) + private void CreateDMGDistTable(StreamWriter sw, Player p, bool toBoss, int phase_index) { CombatData c_data = getCombatData(); BossData b_data = getBossData(); - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()); - List damageLogs = p.getJustPlayerDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData()); - int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p).Split('|')[7]) : Int32.Parse(getFinalDPS(p).Split('|')[1]); - int finalTotalDamage = damageLogs.Sum(x => x.getDamage()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where( x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List damageLogs = p.getJustPlayerDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); + int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) { string contribution = String.Format("{0:0.00}", 100.0 * finalTotalDamage / totalDamage); sw.Write("
    " + p.getCharacter() + " did " + contribution + "% of its own total " + (toBoss ? "boss " : "") + "dps
    "); } - string tabid = p.getInstid() + (toBoss ? "_boss" : ""); + string tabid = p.getInstid() +"_"+ phase_index + (toBoss ? "_boss" : ""); sw.Write(""); sw.Write("
"); { @@ -4027,14 +4053,15 @@ private void CreateDMGDistTable(StreamWriter sw, Player p, bool toBoss) /// Player, master of the minion /// Damage logs to use /// The minion - private void CreateDMGDistTable(StreamWriter sw, Player p, AgentItem agent, bool toBoss) + private void CreateDMGDistTable(StreamWriter sw, Player p, AgentItem agent, bool toBoss, int phase_index) { - int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p).Split('|')[7]) : Int32.Parse(getFinalDPS(p).Split('|')[1]); - string tabid = p.getInstid() + "_" + agent.getInstid() + (toBoss ? "_boss" : ""); + int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); + string tabid = p.getInstid() +"_"+phase_index + "_" + agent.getInstid() + (toBoss ? "_boss" : ""); CombatData c_data = getCombatData(); BossData b_data = getBossData(); - List damageLogs = p.getMinionsDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData())[agent]; - int finalTotalDamage = damageLogs.Sum(x => x.getDamage()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; + List damageLogs = p.getMinionsDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData())[agent].Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) { string contribution = String.Format("{0:0.00}", 100.0 * finalTotalDamage / totalDamage); @@ -4230,7 +4257,7 @@ private void CreateDMGDistTable(StreamWriter sw, Player p, AgentItem agent, bool /// /// Stream writer /// The player - private void CreateDMGTakenDistTable(StreamWriter sw, Player p) + private void CreateDMGTakenDistTable(StreamWriter sw, Player p, int phase_index) { CombatData c_data = getCombatData(); BossData b_data = getBossData(); @@ -4238,8 +4265,9 @@ private void CreateDMGTakenDistTable(StreamWriter sw, Player p) SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); int finalTotalDamage = damageLogs.Sum(x => x.getDamage()); - sw.Write(""); - sw.Write("
"); + string pid = p.getInstid() + "_" + phase_index; + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -4374,28 +4402,33 @@ private void CreateDMGTakenDistTable(StreamWriter sw, Player p) /// Creates the mechanics table of the fight /// /// Stream writer - private void CreateMechanicTable(StreamWriter sw) { - List presMech = new List(); + private void CreateMechanicTable(StreamWriter sw, int phase_index) { + Dictionary> presMech = new Dictionary>(); + PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; foreach (Mechanic item in mech_data.GetMechList(boss_data.getID())) { if (mech_data.GetMDataLogs().FirstOrDefault(x => x.GetSkill() == item.GetSkill()) != null) { - presMech.Add(item); + if (!presMech.ContainsKey(item.GetAltName())) + { + presMech[item.GetAltName()] = new List(); + } + presMech[item.GetAltName()].Add(item); } } if (presMech.Count() > 0) { - sw.Write(""); - sw.Write("
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { sw.Write(""); { sw.Write(""); - foreach (string mechalt in presMech.Select(x => x.GetAltName()).Distinct().ToList()) + foreach (string mechalt in presMech.Keys) { - sw.Write(""); + sw.Write(""); } } sw.Write(""); @@ -4409,13 +4442,13 @@ private void CreateMechanicTable(StreamWriter sw) { sw.Write(""); { sw.Write(""); - foreach (string mechalt in presMech.Select(x => x.GetAltName()).Distinct().ToList()) + foreach (List mechs in presMech.Values) { int count = 0; - foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => mechalt == x.GetAltName())) + foreach (Mechanic mech in mechs) { - List test = mech_data.GetMDataLogs().Where(x => x.GetSkill() == mech.GetSkill() && x.GetPlayer() == p).ToList(); - count += mech_data.GetMDataLogs().Where(x => x.GetSkill() == mech.GetSkill() && x.GetPlayer() == p).Count(); + List test = mech_data.GetMDataLogs().Where(x => x.GetSkill() == mech.GetSkill() && x.GetPlayer() == p && x.GetTime() >= phase.start / 1000 && x.GetTime() < phase.end / 1000).ToList(); + count += test.Count(); } sw.Write(""); } @@ -4553,11 +4586,11 @@ private void CreateSkillList(StreamWriter sw) { /// /// Stream writer /// The boss - private void CreateCondiUptimeTable(StreamWriter sw,Player boss) + private void CreateCondiUptimeTable(StreamWriter sw,Player boss, int phase_index) { //Generate Boon table------------------------------------------------------------------------------------------------ - sw.Write(""); - sw.Write("
Player x.GetAltName() == mechalt).GetName() + "\">" + mechalt + "" + mechalt + "
" + p.getCharacter() + "" + count + "
"); + sw.Write(""); + sw.Write("
"); { sw.Write(""); { @@ -4593,7 +4626,7 @@ private void CreateCondiUptimeTable(StreamWriter sw,Player boss) /// Creates the boss summary tab /// /// Stream writer - private void CreateBossSummary(StreamWriter sw) + private void CreateBossSummary(StreamWriter sw, int phase_index) { //generate Player list Graphs CombatData c_data = getCombatData(); @@ -4602,22 +4635,23 @@ private void CreateBossSummary(StreamWriter sw) SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); string charname = boss.getCharacter(); + string pid = boss.getInstid() + "_" + phase_index; sw.Write("

" + charname + "

"); sw.Write(""); //condi stats tab - sw.Write("
"); + sw.Write("
"); { - CreateCondiUptimeTable(sw, boss); - sw.Write("
"); + CreateCondiUptimeTable(sw, boss, phase_index); + sw.Write("
"); sw.Write(" "); - CreateDMGDistTable(sw, boss, false); + CreateDMGDistTable(sw, boss, false, phase_index); sw.Write("
"); foreach (AgentItem agent in boss.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) { - sw.Write("
"); + sw.Write("
"); { - CreateDMGDistTable(sw, boss, agent, false); + CreateDMGDistTable(sw, boss, agent, false, phase_index); } sw.Write("
"); } @@ -4989,34 +5023,34 @@ private void CreateBossSummary(StreamWriter sw) /// To define /// /// Stream writer - private void CreateEstimateTabs(StreamWriter sw) + private void CreateEstimateTabs(StreamWriter sw, int phase_index) { sw.Write(""); sw.Write("
"); { - sw.Write("
"); + sw.Write("
"); { //Use cards } sw.Write("
"); - sw.Write("
"); + sw.Write("
"); { } sw.Write("
"); - sw.Write("
"); + sw.Write("
"); { } sw.Write("
"); @@ -5072,15 +5106,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) } string bossname = FilterStringChars(b_data.getName()); setPresentBoons(settingsSnap); - List phases = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData()); - string Html_playerDropdown = ""; - foreach (Player p in p_list) - { - - string charname = p.getCharacter(); - Html_playerDropdown += "" + charname + - "\""" + ""; - } + List phases = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData()); // HTML STARTS sw.Write(""); { @@ -5184,303 +5210,338 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) } sw.Write("
"); } + sw.Write("
"); //if (p_list.Count() == 1)//Create condensed version of log //{ // CreateSoloHTML(sw,settingsSnap); // return; //} - sw.Write("
"); - sw.Write("
    "); + if (phases.Count > 1) { - sw.Write("
  • " + - "Stats" + - "
  • " + - - "
  • " + - "Damage Graph" + - "
  • " + - "
  • " + - "Boons" + - "
  • " + - - - "
  • " + - "Mechanics" + - "
  • " + - "
  • " + - "Player" + - "
    " + - Html_playerDropdown + - "
    " + - "
  • "); - if (settingsSnap[9]) - { - sw.Write("
  • " + - "Boss" + - "
  • "); - } - if (settingsSnap[8]) - { - sw.Write("
  • " + - "Event List" + - "
  • "); - } - if (settingsSnap[13]) + sw.Write("
      "); { - sw.Write("
    • " + - "Estimates" + - "
    • "); + for (int i = 0; i < phases.Count; i++) + { + string active = (i > 0 ? "" : "active"); + string name = i > 0 ? "Phase " + i : "Full Fight"; + sw.Write("
    • " + + "" + name + "" + + "
    • "); + } } + sw.Write("
    "); } - sw.Write("
"); - sw.Write("
"); + sw.Write("
"); { - sw.Write("
"); + for (int i = 0; i < phases.Count; i++) { - //Stats Tab - sw.Write("

Stats

"); - - sw.Write(""); - sw.Write("
"); + string active = (i > 0 ? "" : "show active"); + + + sw.Write("
"); { - sw.Write("
"); - { - // DPS table - CreateDPSTable(sw, fight_duration); - } - sw.Write("
"); - sw.Write("
"); - { - // HTML_dmgstats - CreateDMGStatsTable(sw, fight_duration); - } - sw.Write("
"); - sw.Write("
"); + string Html_playerDropdown = ""; + foreach (Player p in p_list) { - // def stats - CreateDefTable(sw, fight_duration); + string charname = p.getCharacter(); + Html_playerDropdown += "" + charname + + "\""" + ""; } - sw.Write("
"); - sw.Write("
"); + sw.Write("
    "); { - // HTML_supstats - CreateSupTable(sw, fight_duration); + sw.Write("
  • " + + "Stats" + + "
  • " + + + "
  • " + + "Damage Graph" + + "
  • " + + "
  • " + + "Boons" + + "
  • " + + "
  • " + + "Mechanics" + + "
  • " + + "
  • " + + "Player" + + "
    " + + Html_playerDropdown + + "
    " + + "
  • "); + if (settingsSnap[9]) + { + sw.Write("
  • " + + "Boss" + + "
  • "); + } + if (settingsSnap[8]) + { + sw.Write("
  • " + + "Event List" + + "
  • "); + } + if (settingsSnap[13]) + { + sw.Write("
  • " + + "Estimates" + + "
  • "); + } } - sw.Write("
"); - } - sw.Write("
"); - - } - sw.Write("
"); - - sw.Write("
"); - { - //Html_dpsGraph - CreateDPSGraph(sw); - } - sw.Write("
"); - //Boon Stats - sw.Write("
"); - { - //Boons Tab - sw.Write("

Boons

"); - - sw.Write(""); - sw.Write("
"); - { - sw.Write("
"); + sw.Write(""); + sw.Write("
"); { - sw.Write(""); - sw.Write("
"); + sw.Write("
"); { - sw.Write("
"); - { - sw.Write("

Boon Uptime

"); - // Html_boons - CreateUptimeTable(sw, present_boons, "boons_table"); - } - sw.Write("
"); - sw.Write("
"); - { - //Html_boonGenSelf - sw.Write("

Boons generated by a character for themselves

"); - CreateGenSelfTable(sw, present_boons, "boongenself_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Boons generated by a character for their sub group

"); - // Html_boonGenGroup - CreateGenGroupTable(sw, present_boons, "boongengroup_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Boons generated by a character for any subgroup that is not their own

"); - // Html_boonGenOGroup - CreateGenOGroupTable(sw, present_boons, "boongenogroup_table"); - } - sw.Write("
"); - sw.Write("
"); + //Stats Tab + sw.Write("

Stats

"); + + sw.Write(""); + sw.Write("
"); { - sw.Write("

Boons generated by a character for the entire squad

"); - // Html_boonGenSquad - CreateGenSquadTable(sw, present_boons, "boongensquad_table"); + sw.Write("
"); + { + // DPS table + CreateDPSTable(sw, i); + } + sw.Write("
"); + sw.Write("
"); + { + // HTML_dmgstats + CreateDMGStatsTable(sw, i); + } + sw.Write("
"); + sw.Write("
"); + { + // def stats + CreateDefTable(sw, i); + } + sw.Write("
"); + sw.Write("
"); + { + // HTML_supstats + CreateSupTable(sw, i); + } + sw.Write("
"); } sw.Write("
"); + } sw.Write("
"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write(""); - sw.Write("
"); + + sw.Write("
"); { - //Offensive Buffs stats - sw.Write("
"); - { - sw.Write("

Offensive Buffs Uptime

"); - CreateUptimeTable(sw, present_offbuffs, "offensive_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Offensive Buffs generated by a character for themselves

"); - CreateGenSelfTable(sw, present_offbuffs, "offensivegenself_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Offensive Buffs generated by a character for their sub group

"); - CreateGenGroupTable(sw, present_offbuffs, "offensivegengroup_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Offensive Buffs generated by a character for any subgroup that is not their own

"); - CreateGenOGroupTable(sw, present_offbuffs, "offensivegenogroup_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Offensive Buffs generated by a character for the entire squad

"); - CreateGenSquadTable(sw, present_offbuffs, "offensivegensquad_table"); - } - sw.Write("
"); + //Html_dpsGraph + CreateDPSGraph(sw, i); } sw.Write("
"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write(""); - sw.Write("
"); + //Boon Stats + sw.Write("
"); { - //Defensive Buffs stats - sw.Write("
"); + //Boons Tab + sw.Write("

Boons

"); + + sw.Write(""); + sw.Write("
"); { - sw.Write("

Defensive Buffs Uptime

"); - CreateUptimeTable(sw, present_defbuffs, "defensive_table"); - } - sw.Write("
"); - sw.Write("
"); - { - sw.Write("

Defensive Buffs generated by a character for themselves

"); - CreateGenSelfTable(sw, present_defbuffs, "defensivegenself_table"); + sw.Write("
"); + { + sw.Write(""); + sw.Write("
"); + { + sw.Write("
"); + { + sw.Write("

Boon Uptime

"); + // Html_boons + CreateUptimeTable(sw, present_boons, "boons_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + //Html_boonGenSelf + sw.Write("

Boons generated by a character for themselves

"); + CreateGenSelfTable(sw, present_boons, "boongenself_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Boons generated by a character for their sub group

"); + // Html_boonGenGroup + CreateGenGroupTable(sw, present_boons, "boongengroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Boons generated by a character for any subgroup that is not their own

"); + // Html_boonGenOGroup + CreateGenOGroupTable(sw, present_boons, "boongenogroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Boons generated by a character for the entire squad

"); + // Html_boonGenSquad + CreateGenSquadTable(sw, present_boons, "boongensquad_table", i); + } + sw.Write("
"); + } + sw.Write("
"); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write(""); + sw.Write("
"); + { + //Offensive Buffs stats + sw.Write("
"); + { + sw.Write("

Offensive Buffs Uptime

"); + CreateUptimeTable(sw, present_offbuffs, "offensive_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Offensive Buffs generated by a character for themselves

"); + CreateGenSelfTable(sw, present_offbuffs, "offensivegenself_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Offensive Buffs generated by a character for their sub group

"); + CreateGenGroupTable(sw, present_offbuffs, "offensivegengroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Offensive Buffs generated by a character for any subgroup that is not their own

"); + CreateGenOGroupTable(sw, present_offbuffs, "offensivegenogroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Offensive Buffs generated by a character for the entire squad

"); + CreateGenSquadTable(sw, present_offbuffs, "offensivegensquad_table", i); + } + sw.Write("
"); + } + sw.Write("
"); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write(""); + sw.Write("
"); + { + //Defensive Buffs stats + sw.Write("
"); + { + sw.Write("

Defensive Buffs Uptime

"); + CreateUptimeTable(sw, present_defbuffs, "defensive_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Defensive Buffs generated by a character for themselves

"); + CreateGenSelfTable(sw, present_defbuffs, "defensivegenself_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Defensive Buffs generated by a character for their sub group

"); + CreateGenGroupTable(sw, present_defbuffs, "defensivegengroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Defensive Buffs generated by a character for any subgroup that is not their own

"); + CreateGenOGroupTable(sw, present_defbuffs, "defensivegenogroup_table", i); + } + sw.Write("
"); + sw.Write("
"); + { + sw.Write("

Defensive Buffs generated by a character for the entire squad

"); + CreateGenSquadTable(sw, present_defbuffs, "defensivegensquad_table", i); + } + sw.Write("
"); + } + sw.Write("
"); + } + sw.Write("
"); } sw.Write("
"); - sw.Write("
"); + } + sw.Write("
"); + //mechanics + sw.Write("
"); + { + sw.Write("

Mechanics

"); + CreateMechanicTable(sw, i); + } + sw.Write("
"); + //boss summary + if (settingsSnap[9]) + { + sw.Write("
"); { - sw.Write("

Defensive Buffs generated by a character for their sub group

"); - CreateGenGroupTable(sw, present_defbuffs, "defensivegengroup_table"); + CreateBossSummary(sw, i); } sw.Write("
"); - sw.Write("
"); + } + //event list + if (settingsSnap[8] && i == 0) + { + sw.Write("
"); { - sw.Write("

Defensive Buffs generated by a character for any subgroup that is not their own

"); - CreateGenOGroupTable(sw, present_defbuffs, "defensivegenogroup_table"); + sw.Write("

List of all events.

"); + // CreateEventList(sw); + CreateSkillList(sw); } sw.Write("
"); - sw.Write("
"); + } + //boss summary + if (settingsSnap[13]) + { + sw.Write("
"); { - sw.Write("

Defensive Buffs generated by a character for the entire squad

"); - CreateGenSquadTable(sw, present_defbuffs, "defensivegensquad_table"); + CreateEstimateTabs(sw, i); } sw.Write("
"); } - sw.Write("
"); + //Html_playertabs + CreatePlayerTab(sw, settingsSnap, i); } sw.Write("
"); } sw.Write("
"); + } - sw.Write("
"); - //mechanics - sw.Write("
"); - { - sw.Write("

Mechanics

"); - CreateMechanicTable(sw); - } - sw.Write("
"); - //boss summary - if (settingsSnap[9]) - { - sw.Write("
"); - { - CreateBossSummary(sw); - } - sw.Write("
"); - } - //event list - if (settingsSnap[8]) - { - sw.Write("
"); - { - sw.Write("

List of all events.

"); - // CreateEventList(sw); - CreateSkillList(sw); - } - sw.Write("
"); - } - //boss summary - if (settingsSnap[13]) - { - sw.Write("
"); - { - CreateEstimateTabs(sw); - } - sw.Write("
"); - } - //Html_playertabs - CreatePlayerTab(sw,settingsSnap); } sw.Write("
"); sw.Write("
"); @@ -5513,10 +5574,10 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); - CreateDPSTable(sw, fight_duration); - CreateDMGStatsTable(sw, fight_duration); - CreateDefTable(sw, fight_duration); - CreateSupTable(sw, fight_duration); + CreateDPSTable(sw, 0); + CreateDMGStatsTable(sw, 0); + CreateDefTable(sw, 0); + CreateSupTable(sw, 0); // CreateDPSGraph(sw); sw.Write("
"); sw.Write(""); sw.Write("
"); From db1237a93e4b3ed7a846b4b63a7a0c4582aaa36e Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 01:51:17 +0200 Subject: [PATCH 16/53] some cleanup --- LuckParser/Controllers/Controller1.cs | 139 ++--- LuckParser/LuckParser.csproj | 1 + .../Models/ParseModels/AbstractPlayer.cs | 492 +++++++++++++++++ LuckParser/Models/ParseModels/Boss.cs | 23 +- LuckParser/Models/ParseModels/BossData.cs | 5 + LuckParser/Models/ParseModels/Player.cs | 495 +----------------- 6 files changed, 577 insertions(+), 578 deletions(-) create mode 100644 LuckParser/Models/ParseModels/AbstractPlayer.cs diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 20f79d2d4..f358e6e0a 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -737,7 +737,7 @@ private void setPresentBoons(bool[] SnapSettings) { } } } - private String getFinalDPS(Player p, int phase_index) + private String getFinalDPS(AbstractPlayer p, int phase_index) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); @@ -761,7 +761,7 @@ private String getFinalDPS(Player p, int phase_index) double dps = 0.0; // All DPS - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); if (fight_duration > 0) { dps = damage / fight_duration; @@ -769,7 +769,7 @@ private String getFinalDPS(Player p, int phase_index) totalAll_dps = (int)dps; totalAll_damage = (int)damage; //Allcondi - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0 && x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage()); + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); if (fight_duration > 0) { dps = damage / fight_duration; @@ -786,7 +786,7 @@ private String getFinalDPS(Player p, int phase_index) totalAllphys_damage = (int)damage; // boss DPS - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); if (fight_duration > 0) { dps = damage / fight_duration; @@ -794,7 +794,7 @@ private String getFinalDPS(Player p, int phase_index) totalboss_dps = (int)dps; totalboss_damage = (int)damage; //bosscondi - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.isCondi() > 0 && x.getTime() >= phase.start && x.getTime() < phase.end).Sum(x => x.getDamage()); + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); if (fight_duration > 0) { dps = damage / fight_duration; @@ -821,8 +821,8 @@ private String[] getFinalStats(Player p, int phase_index) PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; long start = phase.start + b_data.getFirstAware(); long end = phase.end + b_data.getFirstAware(); - List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); - List cast_logs = p.getCastLogs( b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + List cast_logs = p.getCastLogs( b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); int instid = p.getInstid(); // Rates @@ -965,7 +965,7 @@ private string[] getFinalDefenses(Player p, int phase_index) PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; long start = phase.start + b_data.getFirstAware(); long end = phase.end + b_data.getFirstAware(); - List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(),getMechData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(),getMechData(), phase.start, phase.end); int instid = p.getInstid(); int damagetaken = damage_logs.Select(x => x.getDamage()).Sum(); @@ -1034,8 +1034,8 @@ private string[] getFinalSupport(Player p, int phase_index) int condiCleanse = 0; double condiCleansetime = 0.0; - int[] resArray = p.getReses(b_data, c_data.getCombatList(), getAgentData(), start, end); - int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), getAgentData(), start, end); + int[] resArray = p.getReses(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); resurrects = resArray[0]; restime = resArray[1]; condiCleanse = cleanseArray[0]; @@ -1123,7 +1123,7 @@ private Dictionary getfinalboons(Player p, List trgetPlayer } return rates; } - private Dictionary getfinalcondis(Player p) + private Dictionary getfinalcondis(AbstractPlayer p) { BossData b_data = getBossData(); CombatData c_data = getCombatData(); @@ -1167,7 +1167,7 @@ private void setMechData() { { mech_data.AddItem(new MechanicLog((long)((pnt.getTime() - boss_data.getFirstAware()) / 1000f), 0, "DEAD", 0, p, mech_data.GetPLoltyShape("DEAD"))); } - List dls = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data); + List dls = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data, 0, boss_data.getAwareDuration()); //Player hit by skill 3 MechanicLog prevMech = null; foreach (DamageLog dLog in dls) @@ -1235,23 +1235,18 @@ private void setMechData() { } //Generate HTML--------------------------------------------------------------------------------------------------------------------------------------------------------- - //Methods that make it easier to create Javascript graphs - /// - /// Gets the points for the boss dps graph for a given player - /// - /// The player - /// - private List getBossDPSGraph(Player p, int phase_index) + //Methods that make it easier to create Javascript graphs + private List getDPSGraph(AbstractPlayer p, int phase_index, ushort dstid) { - List bossdmgList = new List(); + List dmgList = new List(); BossData b_data = getBossData(); CombatData c_data = getCombatData(); PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List damage_logs_boss = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List damage_logs = p.getDamageLogs(dstid, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); int totaldmg = 0; int timeGraphed = (int)phase.start; - foreach (DamageLog log in damage_logs_boss) + foreach (DamageLog log in damage_logs) { totaldmg += log.getDamage(); @@ -1267,13 +1262,13 @@ private List getBossDPSGraph(Player p, int phase_index) if ((Math.Floor(time / 1000f) - timeGraphed) < 2) { timeGraphed = (int)Math.Floor(time / 1000f); - bossdmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); + dmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); } else { int gap = (int)Math.Floor(time / 1000f) - timeGraphed; bool startOfFight = true; - if (bossdmgList.Count > 0) + if (dmgList.Count > 0) { startOfFight = false; } @@ -1283,11 +1278,11 @@ private List getBossDPSGraph(Player p, int phase_index) timeGraphed++; if (!startOfFight) { - bossdmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); + dmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); } else {//hasnt hit boss yet gap - bossdmgList.Add(new int[] { timeGraphed, 0 }); + dmgList.Add(new int[] { timeGraphed, 0 }); } } @@ -1295,63 +1290,25 @@ private List getBossDPSGraph(Player p, int phase_index) } } } - return bossdmgList; + return dmgList; + } + /// + /// Gets the points for the boss dps graph for a given player + /// + /// The player + /// + private List getBossDPSGraph(AbstractPlayer p, int phase_index) + { + return getDPSGraph(p, phase_index, getBossData().getInstid()); } /// /// Gets the points for the total dps graph for a given player /// /// The player /// - private List getTotalDPSGraph(Player p, int phase_index) + private List getTotalDPSGraph(AbstractPlayer p, int phase_index) { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List totaldmgList = new List(); - List damage_logs_all = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); - int totaldmg = 0; - int timeGraphed = (int) phase.start; - foreach (DamageLog log in damage_logs_all) - { - totaldmg += log.getDamage(); - long time = log.getTime(); - if (time > 1000) - { - - // to reduce processing time only graph 1 point per sec - if (Math.Floor(time / 1000f) > timeGraphed) - { - if ((Math.Floor(time / 1000f) - timeGraphed) < 2) - { - timeGraphed = (int)Math.Floor(time / 1000f); - totaldmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); - } - else - { - int gap = (int)Math.Floor(time / 1000f) - timeGraphed; - bool startOfFight = true; - if (totaldmgList.Count > 0) - { - startOfFight = false; - } - for (int itr = 0; itr < gap - 1; itr++) - { - timeGraphed++; - // totaldmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); - if (!startOfFight) - { - totaldmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); - } - else - {//hasnt hit boss yet gap - totaldmgList.Add(new int[] { timeGraphed, 0 }); - } - } - } - } - } - } - return totaldmgList; + return getDPSGraph(p, phase_index, 0); } /// /// Creates the dps graph @@ -2774,9 +2731,9 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind //generate Player list Graphs foreach (Player p in p_list) { - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where( x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); - - bool died = p.getDeath(getCombatData().getCombatList(), start, end) > 0; + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + + bool died = p.getDeath(b_data, c_data.getCombatList(), phase.start, phase.end) > 0; string charname = p.getCharacter(); string pid = p.getInstid() + "_" + phase_index; sw.Write("
"); @@ -2808,7 +2765,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind { sw.Write("
"); { - List consume = p.getConsumablesList(b_data, s_data, c_data.getCombatList(), start, end); + List consume = p.getConsumablesList(b_data, s_data, c_data.getCombatList(), phase.start, phase.end); List initial = consume.Where(x => x[1] == 0).ToList(); List refreshed = consume.Where(x => x[1] > 0).ToList(); if (initial.Count() > 0) @@ -3401,7 +3358,7 @@ private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize, CombatData c_data = getCombatData(); BossData b_data = getBossData(); PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); GW2APISkill autoSkill = null; int autosCount = 0; foreach (CastLog cl in casting) @@ -3492,10 +3449,10 @@ private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) CombatData c_data = getCombatData(); BossData b_data = getBossData(); AgentData a_data = getAgentData(); - List damageLogs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(), getMechData()); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + List damageLogs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(), getMechData(), phase.start, phase.end); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; long start = phase.start + b_data.getFirstAware(); long end = phase.end + b_data.getFirstAware(); List down = getCombatData().getStates(p.getInstid(), "CHANGE_DOWN", start, end); @@ -3661,13 +3618,13 @@ private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) ///
/// Stream writer /// The player - private void CreateDMGDistTable(StreamWriter sw, Player p, bool toBoss, int phase_index) + private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, int phase_index) { CombatData c_data = getCombatData(); BossData b_data = getBossData(); PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where( x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); - List damageLogs = p.getJustPlayerDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + List damageLogs = p.getJustPlayerDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) @@ -4054,7 +4011,7 @@ private void CreateDMGDistTable(StreamWriter sw, Player p, bool toBoss, int phas /// Player, master of the minion /// Damage logs to use /// The minion - private void CreateDMGDistTable(StreamWriter sw, Player p, AgentItem agent, bool toBoss, int phase_index) + private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, AgentItem agent, bool toBoss, int phase_index) { int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); string tabid = p.getInstid() +"_"+phase_index + "_" + agent.getInstid() + (toBoss ? "_boss" : ""); @@ -4263,7 +4220,7 @@ private void CreateDMGTakenDistTable(StreamWriter sw, Player p, int phase_index) CombatData c_data = getCombatData(); BossData b_data = getBossData(); PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List damageLogs = p.getDamageTakenLogs( b_data, c_data.getCombatList(), getAgentData(),getMechData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List damageLogs = p.getDamageTakenLogs( b_data, c_data.getCombatList(), getAgentData(),getMechData(), phase.start, phase.end); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; @@ -4588,7 +4545,7 @@ private void CreateSkillList(StreamWriter sw) { /// /// Stream writer /// The boss - private void CreateCondiUptimeTable(StreamWriter sw,Player boss, int phase_index) + private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) { //Generate Boon table------------------------------------------------------------------------------------------------ sw.Write(""); @@ -4634,7 +4591,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) CombatData c_data = getCombatData(); BossData b_data = getBossData(); PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = boss.getCastLogs(b_data, c_data.getCombatList(), getAgentData()).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + List casting = boss.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); string charname = boss.getCharacter(); @@ -5573,7 +5530,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) CombatData c_data = getCombatData(); - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData()); + List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), 0, b_data.getAwareDuration()); SkillData s_data = getSkillData(); List s_list = s_data.getSkillList(); diff --git a/LuckParser/LuckParser.csproj b/LuckParser/LuckParser.csproj index c5620d4f5..27e58b93e 100644 --- a/LuckParser/LuckParser.csproj +++ b/LuckParser/LuckParser.csproj @@ -84,6 +84,7 @@ Form1.cs + diff --git a/LuckParser/Models/ParseModels/AbstractPlayer.cs b/LuckParser/Models/ParseModels/AbstractPlayer.cs new file mode 100644 index 000000000..1678afb81 --- /dev/null +++ b/LuckParser/Models/ParseModels/AbstractPlayer.cs @@ -0,0 +1,492 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; + +namespace LuckParser.Models.ParseModels +{ + public abstract class AbstractPlayer + { + protected ushort instid; + private String character; + // Boons + private BoonDistribution boon_distribution = new BoonDistribution(); + private Dictionary boon_presence = new Dictionary(); + private Dictionary boon_points = new Dictionary(); + // DPS + protected List damage_logs = new List(); + private List damage_logsFiltered = new List(); + // Minions + private List combatMinionIDList = new List(); + private Dictionary> minion_damage_logs = new Dictionary>(); + private Dictionary> minion_damage_logsFiltered = new Dictionary>(); + // Taken damage + protected List damageTaken_logs = new List(); + // Casts + protected List cast_logs = new List(); + // Constructor + public AbstractPlayer(AgentItem agent) + { + String[] name = agent.getName().Split('\0'); + character = name[0]; + instid = agent.getInstid(); + } + // Getters + public ushort getInstid() + { + return instid; + } + public string getCharacter() + { + return character; + } + public long getDeath(BossData bossData, List combatList, long start, long end) + { + long offset = bossData.getFirstAware(); + CombatItem dead = combatList.FirstOrDefault(x => x.getSrcInstid() == instid && x.isStateChange().getEnum() == "CHANGE_DEAD" && x.getTime() >= start + offset && x.getTime() < end + offset); + if (dead != null && dead.getTime() > 0) + { + return dead.getTime(); + } + return 0; + } + public List getDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, long start, long end)//isntid = 0 gets all logs if specefied sets and returns filterd logs + { + if (damage_logs.Count == 0) + { + setDamageLogs(bossData, combatList, agentData); + } + + + if (damage_logsFiltered.Count == 0) + { + setFilteredLogs(bossData, combatList, agentData); + } + if (instidFilter == 0) + { + return damage_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + } + else + { + return damage_logsFiltered.Where( x => x.getTime() >= start && x.getTime() < end).ToList(); + } + } + public List getDamageTakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data, long start, long end) + { + if (damageTaken_logs.Count == 0) + { + setDamagetakenLogs(bossData, combatList, agentData, m_data); + } + return damageTaken_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + } + public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList) + { + if (boon_distribution.Count == 0) + { + setBoonDistribution(bossData, skillData, combatList); + } + return boon_distribution; + } + public Dictionary getBoonGraphs(BossData bossData, SkillData skillData, List combatList) + { + if (boon_distribution.Count == 0) + { + setBoonDistribution(bossData, skillData, combatList); + } + return boon_points; + } + public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList) + { + if (boon_distribution.Count == 0) + { + setBoonDistribution(bossData, skillData, combatList); + } + return boon_presence; + } + public List getCastLogs(BossData bossData, List combatList, AgentData agentData, long start, long end) + { + if (cast_logs.Count == 0) + { + setCastLogs(bossData, combatList, agentData); + } + return cast_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + + } + public Dictionary> getMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData) + { + if (minion_damage_logs.Count == 0) + { + // make sure the keys matches + foreach (AgentItem agent in minion_damage_logsFiltered.Keys) + { + minion_damage_logs[agent] = new List(); + } + setMinionsDamageLogs(0, bossData, combatList, agentData, minion_damage_logs); + } + + if (minion_damage_logsFiltered.Count == 0) + { + // make sure the keys matches + foreach (AgentItem agent in minion_damage_logs.Keys) + { + minion_damage_logsFiltered[agent] = new List(); + } + setMinionsDamageLogs(bossData.getInstid(), bossData, combatList, agentData, minion_damage_logsFiltered); + } + if (instidFilter == 0) + { + return minion_damage_logs; + } + else + { + return minion_damage_logsFiltered; + } + } + public List getJustPlayerDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, long start, long end) + { + List minionList = getCombatMinionList(bossData, combatList, agentData); + return getDamageLogs(instidFilter, bossData, combatList, agentData, start, end).Where(x => !minionList.Contains(x.getInstidt())).ToList(); + } + // privates + protected void addDamageLog(long time, ushort instid, CombatItem c, List toFill) + { + LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); + if (instid == c.getDstInstid() && c.getIFF().getEnum() == "FOE") + { + if (state.getEnum() == "NORMAL" && c.isBuffremove().getID() == 0) + { + if (c.isBuff() == 1 && c.getBuffDmg() != 0)//condi + { + toFill.Add(new DamageLogCondition(time, c)); + } + else if (c.isBuff() == 0 && c.getValue() != 0)//power + { + toFill.Add(new DamageLogPower(time, c)); + } + else if (c.getResult().getID() == 5 || c.getResult().getID() == 6 || c.getResult().getID() == 7) + {//Hits that where blinded, invulned, interupts + toFill.Add(new DamageLogPower(time, c)); + } + } + } + } + // Setters + protected abstract void setDamageLogs(BossData bossData, List combatList, AgentData agentData); + protected void setDamageTakenLog(long time, ushort instid, CombatItem c) + { + LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); + if (instid == c.getSrcInstid()) + { + if (state.getID() == 0) + { + if (c.isBuff() == 1 && c.getBuffDmg() != 0) + { + //inco,ing condi dmg not working or just not present? + // damagetaken.Add(c.getBuffDmg()); + damageTaken_logs.Add(new DamageLogCondition(time, c)); + } + else if (c.isBuff() == 0 && c.getValue() != 0) + { + damageTaken_logs.Add(new DamageLogPower(time, c)); + + } + else if (c.isBuff() == 0 && c.getValue() == 0) + { + damageTaken_logs.Add(new DamageLogPower(time, c)); + } + } + } + } + private void setFilteredLogs(BossData bossData, List combatList, AgentData agentData) + { + long time_start = bossData.getFirstAware(); + foreach (CombatItem c in combatList) + { + if (instid == c.getSrcInstid() || instid == c.getSrcMasterInstid())//selecting player + { + long time = c.getTime() - time_start; + addDamageLog(time, bossData.getInstid(), c, damage_logsFiltered); + } + } + } + private void setBoonDistribution(BossData bossData, SkillData skillData, List combatList) + { + BoonMap to_use = getBoonMap(bossData, skillData, combatList, true); + List boon_to_use = Boon.getAllBuffList(); + boon_to_use.AddRange(Boon.getCondiBoonList()); + long dur = bossData.getLastAware() - bossData.getFirstAware(); + int fight_duration = (int)(dur) / 1000; + // Init boon presence points + BoonsGraphModel boon_presence_points = new BoonsGraphModel("Number of Boons"); + for (int i = 0; i < fight_duration; i++) + { + boon_presence_points.getBoonChart().Add(new Point(i, 0)); + } + foreach (Boon boon in boon_to_use) + { + int boonid = boon.getID(); + if (to_use.ContainsKey(boonid)) + { + List logs = to_use[boonid]; + if (logs.Count == 0) + { + continue; + } + if (boon_distribution.ContainsKey(boonid)) + { + continue; + } + boon_distribution[boonid] = new Dictionary(); + BoonSimulator simulator = boon.getSimulator(); + simulator.simulate(logs, dur); + long death = getDeath(bossData, combatList, 0, dur); + if (death > 0) + { + simulator.trim(death - bossData.getFirstAware()); + } + else + { + simulator.trim(dur); + } + List simulation = simulator.getSimulationResult(); + foreach (BoonSimulationItem simul in simulation) + { + if (!boon_presence.ContainsKey(boonid)) + { + boon_presence[boonid] = simul.getItemDuration(); + } + else + { + boon_presence[boonid] += simul.getItemDuration(); + } + foreach (ushort src in simul.getSrc()) + { + if (!boon_distribution[boonid].ContainsKey(src)) + { + boon_distribution[boonid][src] = new OverAndValue(simul.getDuration(src), simul.getOverstack(src)); + } + else + { + OverAndValue toModify = boon_distribution[boonid][src]; + toModify.value += simul.getDuration(src); + toModify.overstack += simul.getOverstack(src); + boon_distribution[boonid][src] = toModify; + } + } + } + int prev = 0; + // full precision + List toFill = new List(); + List toFillPresence = new List(); + foreach (BoonSimulationItem simul in simulation) + { + int start = (int)simul.getStart(); + int end = (int)simul.getEnd(); + // fill + if (toFill.Count < start) + { + for (int i = prev; i < start; i++) + { + toFill.Add(new Point(i, 0)); + toFillPresence.Add(new Point(i, 0)); + } + } + for (int i = start; i < end; i++) + { + toFill.Add(new Point(i, simul.getStack(i))); + toFillPresence.Add(new Point(i, simul.getItemDuration() > 0 ? 1 : 0)); + } + prev = end; + } + // fill + for (int i = prev; i < dur; i++) + { + toFill.Add(new Point(i, 0)); + toFillPresence.Add(new Point(i, 0)); + } + // reduce precision to seconds + List reducedPrecision = new List(); + List boonPresence = boon_presence_points.getBoonChart(); + for (int i = 0; i < fight_duration; i++) + { + reducedPrecision.Add(new Point(i, toFill[1000 * i].Y)); + if (Boon.getBoonList().Select(x => x.getID()).Contains(boonid)) + boonPresence[i] = new Point(i, boonPresence[i].Y + toFillPresence[1000 * i].Y); + } + boon_points[boonid] = new BoonsGraphModel(boon.getName(), reducedPrecision); + } + } + boon_points[-2] = boon_presence_points; + } + private void setCastLogs(BossData bossData, List combatList, AgentData agentData) + { + long time_start = bossData.getFirstAware(); + CastLog curCastLog = null; + + foreach (CombatItem c in combatList) + { + LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); + if (state.getID() == 0) + { + if (instid == c.getSrcInstid())//selecting player as caster + { + if (c.isActivation().getID() > 0) + { + if (c.isActivation().getID() < 3) + { + long time = c.getTime() - time_start; + curCastLog = new CastLog(time, c.getSkillID(), c.getValue(), c.isActivation()); + } + else + { + if (curCastLog != null) + { + if (curCastLog.getID() == c.getSkillID()) + { + curCastLog = new CastLog(curCastLog.getTime(), curCastLog.getID(), curCastLog.getExpDur(), curCastLog.startActivation(), c.getValue(), c.isActivation()); + cast_logs.Add(curCastLog); + curCastLog = null; + } + } + } + } + } + } + else if (state.getID() == 11) + {//Weapon swap + if (instid == c.getSrcInstid())//selecting player as caster + { + if ((int)c.getDstAgent() == 4 || (int)c.getDstAgent() == 5) + { + long time = c.getTime() - time_start; + curCastLog = new CastLog(time, -2, (int)c.getDstAgent(), c.isActivation()); + cast_logs.Add(curCastLog); + curCastLog = null; + } + } + } + } + } + private void setMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, Dictionary> toFill) + { + List minionList = getCombatMinionList(bossData, combatList, agentData); + foreach (int petid in minionList) + { + AgentItem agent = agentData.getNPCAgentList().FirstOrDefault(x => x.getInstid() == petid); + if (agent != null) + { + List damageLogs = getDamageLogs(instidFilter, bossData, combatList, agentData, 0, bossData.getAwareDuration()).Where(x => x.getSrcAgent() == agent.getAgent()).ToList(); + if (damageLogs.Count == 0) + { + continue; + } + AgentItem key = toFill.Keys.ToList().FirstOrDefault(x => x.getName() == agent.getName()); + if (key == null) + { + toFill[agent] = damageLogs; + } + else + { + toFill[key].AddRange(damageLogs); + } + } + } + } + protected abstract void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data); + // private getters + private BoonMap getBoonMap(BossData bossData, SkillData skillData, List combatList, bool add_condi) + { + BoonMap boon_map = new BoonMap(); + boon_map.add(Boon.getAllBuffList()); + // This only happens for bosses + if (add_condi) + { + boon_map.add(Boon.getCondiBoonList()); + } + // Fill in Boon Map + long time_start = bossData.getFirstAware(); + long fight_duration = bossData.getLastAware() - time_start; + + foreach (CombatItem c in combatList) + { + if (c.isBuff() != 1 || !boon_map.ContainsKey(c.getSkillID())) + { + continue; + } + long time = c.getTime() - time_start; + ushort dst = c.isBuffremove().getID() == 0 ? c.getDstInstid() : c.getSrcInstid(); + if (instid == dst && time >= 0 && time <= fight_duration) + { + ushort src = c.getSrcMasterInstid() > 0 ? c.getSrcMasterInstid() : c.getSrcInstid(); + if (c.isBuffremove().getID() == 0) + { + boon_map[c.getSkillID()].Add(new BoonLog(time, src, c.getValue(), 0)); + } + else if (Boon.removePermission(c.getSkillID(), c.isBuffremove().getID(), c.getIFF().getID())) + { + if (c.isBuffremove().getID() == 1)//All + { + List loglist = boon_map[c.getSkillID()]; + for (int cnt = loglist.Count() - 1; cnt >= 0; cnt--) + { + BoonLog curBL = loglist[cnt]; + if (curBL.getTime() + curBL.getValue() > time) + { + long subtract = (curBL.getTime() + curBL.getValue()) - time; + loglist[cnt].addValue(-subtract); + // add removed as overstack + loglist[cnt].addOverstack((ushort)subtract); + } + } + + } + else if (c.isBuffremove().getID() == 2)//Single + { + List loglist = boon_map[c.getSkillID()]; + int cnt = loglist.Count() - 1; + BoonLog curBL = loglist[cnt]; + if (curBL.getTime() + curBL.getValue() > time) + { + long subtract = (curBL.getTime() + curBL.getValue()) - time; + loglist[cnt].addValue(-subtract); + // add removed as overstack + loglist[cnt].addOverstack((ushort)subtract); + } + } + else if (c.isBuffremove().getID() == 3)//Manuel + { + List loglist = boon_map[c.getSkillID()]; + for (int cnt = loglist.Count() - 1; cnt >= 0; cnt--) + { + BoonLog curBL = loglist[cnt]; + long ctime = curBL.getTime() + curBL.getValue(); + if (ctime > time) + { + long subtract = (curBL.getTime() + curBL.getValue()) - time; + loglist[cnt].addValue(-subtract); + // add removed as overstack + loglist[cnt].addOverstack((ushort)subtract); + break; + } + } + + } + } + + } + } + return boon_map; + } + private List getCombatMinionList(BossData bossData, List combatList, AgentData agentData) + { + if (combatMinionIDList.Count == 0) + { + combatMinionIDList = combatList.Where(x => x.getSrcMasterInstid() == instid && ((x.getValue() != 0 && x.isBuff() == 0) || (x.isBuff() == 1 && x.getBuffDmg() != 0))).Select(x => x.getSrcInstid()).Distinct().ToList(); + } + return combatMinionIDList; + } + + } +} diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 0b426ce2a..5525149a4 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -5,7 +5,7 @@ namespace LuckParser.Models.ParseModels { - public class Boss : Player + public class Boss : AbstractPlayer { public struct PhaseData @@ -51,6 +51,7 @@ private void setPhases(BossData bossData, List combatList, AgentData string name = getCharacter(); long start = 0; long end = 0; + getCastLogs(bossData, combatList, agentData, 0, fight_dur); switch (name) { case "Vale Guardian": @@ -65,19 +66,19 @@ private void setPhases(BossData bossData, List combatList, AgentData phases.Add(new PhaseData(start, end)); if (i == invulsVG.Count - 1) { - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); } } else { start = c.getTime() - bossData.getFirstAware(); - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } } break; case "Gorseval the Multifarious": // Ghostly protection check - List clsG = getCastLogs(bossData, combatList, agentData).Where(x => x.getID() == 31759).ToList(); + List clsG = cast_logs.Where(x => x.getID() == 31759).ToList(); foreach (CastLog cl in clsG) { end = cl.getTime(); @@ -97,13 +98,13 @@ private void setPhases(BossData bossData, List combatList, AgentData phases.Add(new PhaseData(start, end)); if (i == invulsSab.Count - 1) { - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); } } else { start = c.getTime() - bossData.getFirstAware(); - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } } break; @@ -118,7 +119,7 @@ private void setPhases(BossData bossData, List combatList, AgentData if (down_pour != null) { phase_starts.Add(down_pour.getTime() - bossData.getFirstAware()); - CastLog abo = getCastLogs(bossData, combatList, agentData).Find(x => x.getID() == 34427); + CastLog abo = cast_logs.Find(x => x.getID() == 34427); if (abo != null) { phase_starts.Add(abo.getTime()); @@ -139,7 +140,7 @@ private void setPhases(BossData bossData, List combatList, AgentData end = phaseData[0] - bossData.getFirstAware(); phases.Add(new PhaseData(start, end)); start = phaseData[1] - bossData.getFirstAware(); - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } break; case "Samarog": @@ -170,13 +171,13 @@ private void setPhases(BossData bossData, List combatList, AgentData phases.Add(new PhaseData(start, end)); if (i == invulsSamFiltered.Count - 1) { - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(fight_dur - end), new ParseEnums.Activation(0), (int)(fight_dur - end), new ParseEnums.Activation(0))); } } else { start = c.getTime() - bossData.getFirstAware(); - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -5, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } } break; @@ -188,7 +189,7 @@ private void setPhases(BossData bossData, List combatList, AgentData end = invulDei.getTime() - bossData.getFirstAware(); phases.Add(new PhaseData(start, end)); start = (phaseData.Count == 1 ? phaseData[0] : fight_dur) - bossData.getFirstAware(); - getCastLogs(bossData, combatList, agentData).Add(new CastLog(end, -6, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); + cast_logs.Add(new CastLog(end, -6, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } break; default: diff --git a/LuckParser/Models/ParseModels/BossData.cs b/LuckParser/Models/ParseModels/BossData.cs index 1f2489c09..550dd85af 100644 --- a/LuckParser/Models/ParseModels/BossData.cs +++ b/LuckParser/Models/ParseModels/BossData.cs @@ -107,6 +107,11 @@ public long getLastAware() return last_aware; } + public long getAwareDuration() + { + return last_aware - first_aware; + } + public ushort getID() { return id; diff --git a/LuckParser/Models/ParseModels/Player.cs b/LuckParser/Models/ParseModels/Player.cs index 374237ec6..54a7375bb 100644 --- a/LuckParser/Models/ParseModels/Player.cs +++ b/LuckParser/Models/ParseModels/Player.cs @@ -1,17 +1,14 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.Linq; using System.Web; namespace LuckParser.Models.ParseModels { - public class Player + public class Player : AbstractPlayer { // Fields - protected ushort instid; private String account; - private String character; private String group; private String prof; private int toughness; @@ -19,54 +16,28 @@ public class Player private int condition; private long dcd = 0;//time in ms the player dcd - // DPS - protected List damage_logs = new List(); - private List damage_logsFiltered = new List(); - // Minions - private List combatMinionIDList = new List(); - private Dictionary> minion_damage_logs = new Dictionary>(); - private Dictionary> minion_damage_logsFiltered = new Dictionary>(); - // Taken damage - protected List damageTaken_logs = new List(); - // Boons - private BoonDistribution boon_distribution = new BoonDistribution(); - private Dictionary boon_presence = new Dictionary(); - private Dictionary boon_points = new Dictionary(); private List consumeList = new List(); - // Casts - private List cast_logs = new List(); //weaponslist private string[] weapons_array; // Constructors - public Player(AgentItem agent) + public Player(AgentItem agent) : base(agent) { - this.instid = agent.getInstid(); String[] name = agent.getName().Split('\0'); - this.character = name[0]; - this.account = name[1]; - this.group = name[2]; - this.prof = agent.getProf(); - this.toughness = agent.getToughness(); - this.healing = agent.getHealing(); - this.condition = agent.getCondition(); + account = name[1]; + group = name[2]; + prof = agent.getProf(); + toughness = agent.getToughness(); + healing = agent.getHealing(); + condition = agent.getCondition(); } // Getters - public ushort getInstid() - { - return instid; - } public string getAccount() { return account; } - - public string getCharacter() - { - return character; - } - + public string getGroup() { return group; @@ -91,61 +62,11 @@ public int getCondition() { return condition; } - - public List getDamageLogs(int instidFilter,BossData bossData, List combatList, AgentData agentData)//isntid = 0 gets all logs if specefied sets and returns filterd logs - { - if (damage_logs.Count == 0) - { - setDamageLogs(bossData, combatList,agentData); - } - - - if(damage_logsFiltered.Count == 0) { - setFilteredLogs(bossData, combatList, agentData); - } - if (instidFilter == 0) - { - return damage_logs; - }else { - return damage_logsFiltered; - } - } - public List getDamageTakenLogs(BossData bossData, List combatList, AgentData agentData,MechanicData m_data) - { - if (damageTaken_logs.Count == 0) - { - setDamagetakenLogs(bossData, combatList, agentData,m_data); - } - return damageTaken_logs; - } - public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList) - { - if (boon_distribution.Count == 0) - { - setBoonDistribution(bossData, skillData, combatList); - } - return boon_distribution; - } - public Dictionary getBoonGraphs(BossData bossData, SkillData skillData, List combatList) - { - if (boon_distribution.Count == 0) - { - setBoonDistribution(bossData, skillData, combatList); - } - return boon_points; - } - public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList) - { - if (boon_distribution.Count == 0) - { - setBoonDistribution(bossData, skillData, combatList); - } - return boon_presence; - } + // Public methods public int[] getCleanses(BossData bossData, List combatList, AgentData agentData, long start, long end) { long time_start = bossData.getFirstAware(); int[] cleanse = { 0, 0 }; - foreach (CombatItem c in combatList.Where(x=>x.isStateChange().getID() == 0 && x.isBuff() == 1 && x.getTime() >= start && x.getTime() < end)) + foreach (CombatItem c in combatList.Where(x=>x.isStateChange().getID() == 0 && x.isBuff() == 1 && x.getTime() >= (start + time_start) && x.getTime() < (end + time_start))) { if (c.isActivation().getID() == 0) { @@ -170,9 +91,9 @@ public int[] getCleanses(BossData bossData, List combatList, AgentDa } public int[] getReses(BossData bossData, List combatList, AgentData agentData, long start, long end) { - long time_start = bossData.getFirstAware(); + List cls = getCastLogs(bossData, combatList, agentData, start, end); int[] reses = { 0, 0 }; - foreach (CastLog log in cast_logs.Where(x => x.getTime() >= start - time_start && x.getTime() < end - time_start)) { + foreach (CastLog log in cls) { if (log.getID() == 1066) { reses[0]++; @@ -181,50 +102,6 @@ public int[] getReses(BossData bossData, List combatList, AgentData } return reses; } - public List getCastLogs(BossData bossData, List combatList, AgentData agentData) - { - if (cast_logs.Count == 0) - { - setCastLogs(bossData, combatList, agentData); - } - return cast_logs; - - } - public Dictionary> getMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData) - { - if (minion_damage_logs.Count == 0) - { - // make sure the keys matches - foreach (AgentItem agent in minion_damage_logsFiltered.Keys) - { - minion_damage_logs[agent] = new List(); - } - setMinionsDamageLogs(0, bossData, combatList, agentData, minion_damage_logs); - } - - if (minion_damage_logsFiltered.Count == 0) - { - // make sure the keys matches - foreach (AgentItem agent in minion_damage_logs.Keys) - { - minion_damage_logsFiltered[agent] = new List(); - } - setMinionsDamageLogs(bossData.getInstid(), bossData, combatList, agentData, minion_damage_logsFiltered); - } - if (instidFilter == 0) - { - return minion_damage_logs; - } - else - { - return minion_damage_logsFiltered; - } - } - public List getJustPlayerDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData) - { - List minionList = getCombatMinionList(bossData, combatList, agentData); - return getDamageLogs(instidFilter, bossData, combatList, agentData).Where(x => !minionList.Contains(x.getInstidt())).ToList(); - } public string[] getWeaponsArray(SkillData s_data, CombatData c_data, BossData b_data, AgentData a_data) { if (weapons_array == null) @@ -233,7 +110,7 @@ public string[] getWeaponsArray(SkillData s_data, CombatData c_data, BossData b_ } return weapons_array; } - // Public methods + public long GetDC() { return dcd; @@ -242,15 +119,6 @@ public void SetDC(long value) { dcd = value; } - public long getDeath(List combatList, long start, long end) - { - CombatItem dead = combatList.FirstOrDefault( x => x.getSrcInstid() == instid && x.isStateChange().getEnum() == "CHANGE_DEAD" && x.getTime() >= start && x.getTime() < end); - if (dead != null && dead.getTime() > 0) - { - return dead.getTime(); - } - return 0; - } public List getConsumablesList(BossData bossData, SkillData skillData, List combatList, long start, long end) { if (consumeList.Count() == 0) @@ -264,7 +132,7 @@ private void EstimateWeapons(SkillData s_data, CombatData c_data, BossData b_dat { string[] weapons = new string[4];//first 2 for first set next 2 for second set List s_list = s_data.getSkillList(); - List casting = getCastLogs(b_data, c_data.getCombatList(), a_data); + List casting = getCastLogs(b_data, c_data.getCombatList(), a_data, 0, b_data.getAwareDuration()); int swapped = 0;//4 for first set and 5 for next foreach (CastLog cl in casting) { @@ -404,29 +272,7 @@ private void EstimateWeapons(SkillData s_data, CombatData c_data, BossData b_dat } weapons_array = weapons; } - protected void addDamageLog(long time, ushort instid, CombatItem c, List toFill) - { - LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); - if (instid == c.getDstInstid() && c.getIFF().getEnum() == "FOE") - { - if (state.getEnum() == "NORMAL" && c.isBuffremove().getID() == 0) - { - if (c.isBuff() == 1 && c.getBuffDmg() != 0)//condi - { - toFill.Add(new DamageLogCondition(time, c)); - } - else if (c.isBuff() == 0 && c.getValue() != 0)//power - { - toFill.Add(new DamageLogPower(time, c)); - } - else if (c.getResult().getID() == 5 || c.getResult().getID() == 6 || c.getResult().getID() == 7) - {//Hits that where blinded, invulned, interupts - toFill.Add(new DamageLogPower(time, c)); - } - } - } - } - protected virtual void setDamageLogs(BossData bossData, List combatList, AgentData agentData) + protected override void setDamageLogs(BossData bossData, List combatList, AgentData agentData) { long time_start = bossData.getFirstAware(); foreach (CombatItem c in combatList) @@ -442,45 +288,8 @@ protected virtual void setDamageLogs(BossData bossData, List combatL } } - } - private void setFilteredLogs(BossData bossData, List combatList, AgentData agentData) - { - long time_start = bossData.getFirstAware(); - foreach (CombatItem c in combatList) - { - if (instid == c.getSrcInstid() || instid == c.getSrcMasterInstid())//selecting player - { - long time = c.getTime() - time_start; - addDamageLog(time, bossData.getInstid(), c, damage_logsFiltered); - } - } - } - protected void setDamageTakenLog(long time, ushort instid, CombatItem c) - { - LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); - if (instid == c.getSrcInstid()) - { - if (state.getID() == 0) - { - if (c.isBuff() == 1 && c.getBuffDmg() != 0) - { - //inco,ing condi dmg not working or just not present? - // damagetaken.Add(c.getBuffDmg()); - damageTaken_logs.Add(new DamageLogCondition(time, c)); - } - else if (c.isBuff() == 0 && c.getValue() != 0) - { - damageTaken_logs.Add(new DamageLogPower(time, c)); - - } - else if (c.isBuff() == 0 && c.getValue() == 0) - { - damageTaken_logs.Add(new DamageLogPower(time, c)); - } - } - } - } - protected virtual void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData,MechanicData m_data) { + } + protected override void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData,MechanicData m_data) { long time_start = bossData.getFirstAware(); foreach (CombatItem c in combatList) { if (instid == c.getDstInstid()) {//selecting player as target @@ -521,273 +330,7 @@ private void setConsumablesList(BossData bossData, SkillData skillData, List combatList) - { - BoonMap to_use = getBoonMap(bossData,skillData,combatList, true); - List boon_to_use = Boon.getAllBuffList(); - boon_to_use.AddRange(Boon.getCondiBoonList()); - long dur = bossData.getLastAware() - bossData.getFirstAware(); - int fight_duration = (int)(dur) / 1000; - // Init boon presence points - BoonsGraphModel boon_presence_points = new BoonsGraphModel("Number of Boons"); - for (int i = 0; i < fight_duration; i++) - { - boon_presence_points.getBoonChart().Add(new Point(i, 0)); - } - foreach (Boon boon in boon_to_use) - { - int boonid = boon.getID(); - if (to_use.ContainsKey(boonid)) - { - List logs = to_use[boonid]; - if (logs.Count == 0) - { - continue; - } - if (boon_distribution.ContainsKey(boonid)) { - continue; - } - boon_distribution[boonid] = new Dictionary(); - BoonSimulator simulator = boon.getSimulator(); - simulator.simulate(logs, dur); - long death = getDeath(combatList, bossData.getFirstAware(), bossData.getLastAware()); - if (death > 0) - { - simulator.trim(death - bossData.getFirstAware()); - } else - { - simulator.trim(dur); - } - List simulation = simulator.getSimulationResult(); - foreach (BoonSimulationItem simul in simulation) - { - if (!boon_presence.ContainsKey(boonid)) - { - boon_presence[boonid] = simul.getItemDuration(); - } else - { - boon_presence[boonid] += simul.getItemDuration(); - } - foreach (ushort src in simul.getSrc()) - { - if (!boon_distribution[boonid].ContainsKey(src)) - { - boon_distribution[boonid][src] = new OverAndValue(simul.getDuration(src), simul.getOverstack(src)); - } - else - { - OverAndValue toModify = boon_distribution[boonid][src]; - toModify.value += simul.getDuration(src); - toModify.overstack += simul.getOverstack(src); - boon_distribution[boonid][src] = toModify; - } - } - } - int prev = 0; - // full precision - List toFill = new List(); - List toFillPresence = new List(); - foreach (BoonSimulationItem simul in simulation) - { - int start = (int)simul.getStart(); - int end = (int)simul.getEnd(); - // fill - if (toFill.Count < start) - { - for (int i = prev; i < start; i++) - { - toFill.Add(new Point(i, 0)); - toFillPresence.Add(new Point(i, 0)); - } - } - for (int i = start; i < end; i++) - { - toFill.Add(new Point(i, simul.getStack(i))); - toFillPresence.Add(new Point(i, simul.getItemDuration() > 0 ? 1 : 0)); - } - prev = end; - } - // fill - for (int i = prev; i < dur; i++) - { - toFill.Add(new Point(i, 0)); - toFillPresence.Add(new Point(i, 0)); - } - // reduce precision to seconds - List reducedPrecision = new List(); - List boonPresence = boon_presence_points.getBoonChart(); - for (int i = 0; i < fight_duration; i++) - { - reducedPrecision.Add(new Point(i, toFill[1000 * i].Y)); - if (Boon.getBoonList().Select(x => x.getID()).Contains(boonid)) - boonPresence[i] = new Point(i, boonPresence[i].Y + toFillPresence[1000 * i].Y); - } - boon_points[boonid] = new BoonsGraphModel(boon.getName(), reducedPrecision); - } - } - boon_points[-2] = boon_presence_points; - } - private BoonMap getBoonMap(BossData bossData, SkillData skillData, List combatList, bool add_condi) - { - BoonMap boon_map = new BoonMap(); - boon_map.add(Boon.getAllBuffList()); - // This only happens for bosses - if (add_condi) - { - boon_map.add(Boon.getCondiBoonList()); - } - // Fill in Boon Map - long time_start = bossData.getFirstAware(); - long fight_duration = bossData.getLastAware() - time_start; - - foreach (CombatItem c in combatList) - { - if (c.isBuff() != 1 || !boon_map.ContainsKey(c.getSkillID())) - { - continue; - } - long time = c.getTime() - time_start; - ushort dst = c.isBuffremove().getID() == 0 ? c.getDstInstid() : c.getSrcInstid(); - if (instid == dst && time >= 0 && time <= fight_duration) - { - ushort src = c.getSrcMasterInstid() > 0 ? c.getSrcMasterInstid() : c.getSrcInstid(); - if (c.isBuffremove().getID() == 0) - { - boon_map[c.getSkillID()].Add(new BoonLog(time, src, c.getValue(), 0)); - } - else if (Boon.removePermission(c.getSkillID(), c.isBuffremove().getID(), c.getIFF().getID())) - { - if (c.isBuffremove().getID() == 1)//All - { - List loglist = boon_map[c.getSkillID()]; - for (int cnt = loglist.Count() - 1; cnt >= 0; cnt--) - { - BoonLog curBL = loglist[cnt]; - if (curBL.getTime() + curBL.getValue() > time) - { - long subtract = (curBL.getTime() + curBL.getValue()) - time; - loglist[cnt].addValue(-subtract); - // add removed as overstack - loglist[cnt].addOverstack((ushort)subtract); - } - } - - } - else if (c.isBuffremove().getID() == 2)//Single - { - List loglist = boon_map[c.getSkillID()]; - int cnt = loglist.Count() - 1; - BoonLog curBL = loglist[cnt]; - if (curBL.getTime() + curBL.getValue() > time) - { - long subtract = (curBL.getTime() + curBL.getValue()) - time; - loglist[cnt].addValue(-subtract); - // add removed as overstack - loglist[cnt].addOverstack((ushort)subtract); - } - } - else if (c.isBuffremove().getID() == 3)//Manuel - { - List loglist = boon_map[c.getSkillID()]; - for (int cnt = loglist.Count() - 1; cnt >= 0; cnt--) - { - BoonLog curBL = loglist[cnt]; - long ctime = curBL.getTime() + curBL.getValue(); - if (ctime > time) - { - long subtract = (curBL.getTime() + curBL.getValue()) - time; - loglist[cnt].addValue(-subtract); - // add removed as overstack - loglist[cnt].addOverstack((ushort)subtract); - break; - } - } - - } - } - - } - } - return boon_map; - } - private void setCastLogs(BossData bossData, List combatList, AgentData agentData) { - long time_start = bossData.getFirstAware(); - CastLog curCastLog = null; - - foreach (CombatItem c in combatList) - { - LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); - if (state.getID() == 0) - { - if (instid == c.getSrcInstid())//selecting player as caster - { - if (c.isActivation().getID() > 0) - { - if (c.isActivation().getID() < 3) - { - long time = c.getTime() - time_start; - curCastLog = new CastLog(time, c.getSkillID(), c.getValue(), c.isActivation()); - } - else { - if (curCastLog != null) - { - if (curCastLog.getID() == c.getSkillID()) - { - curCastLog = new CastLog(curCastLog.getTime(), curCastLog.getID(), curCastLog.getExpDur(), curCastLog.startActivation(), c.getValue(), c.isActivation()); - cast_logs.Add(curCastLog); - curCastLog = null; - } - } - } - } - } - } else if (state.getID() == 11) {//Weapon swap - if (instid == c.getSrcInstid())//selecting player as caster - { - if ((int)c.getDstAgent() == 4 || (int)c.getDstAgent() == 5) - { - long time = c.getTime() - time_start; - curCastLog = new CastLog(time, -2, (int)c.getDstAgent(), c.isActivation()); - cast_logs.Add(curCastLog); - curCastLog = null; - } - } - } - } - } - private List getCombatMinionList(BossData bossData, List combatList, AgentData agentData) - { - if (combatMinionIDList.Count == 0) - { - combatMinionIDList = combatList.Where(x => x.getSrcMasterInstid() == instid && ((x.getValue() != 0 && x.isBuff() == 0) || (x.isBuff() == 1 && x.getBuffDmg() != 0))).Select(x => x.getSrcInstid()).Distinct().ToList(); - } - return combatMinionIDList; - } - private void setMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, Dictionary> toFill) - { - List minionList = getCombatMinionList(bossData, combatList, agentData); - foreach (int petid in minionList) - { - AgentItem agent = agentData.getNPCAgentList().FirstOrDefault(x => x.getInstid() == petid); - if (agent != null) - { - List damageLogs = getDamageLogs(instidFilter, bossData, combatList, agentData).Where(x => x.getSrcAgent() == agent.getAgent()).ToList(); - if (damageLogs.Count == 0) - { - continue; - } - AgentItem key = toFill.Keys.ToList().FirstOrDefault(x => x.getName() == agent.getName()); - if (key == null) - { - toFill[agent] = damageLogs; - } - else - { - toFill[key].AddRange(damageLogs); - } - } - } - } + } } From 31741774a4c0282074e09a806318b3dd357f75de Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 13:37:06 +0200 Subject: [PATCH 17/53] some refacto start --- LuckParser/Controllers/Controller1.cs | 554 +------------------------ LuckParser/Controllers/ParseHelper.cs | 564 ++++++++++++++++++++++++++ 2 files changed, 567 insertions(+), 551 deletions(-) create mode 100644 LuckParser/Controllers/ParseHelper.cs diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index f358e6e0a..1b133dc2f 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -34,90 +34,7 @@ private static byte[] StreamToBytes(Stream input) // Private Methods //for pulling from binary - private MemoryStream stream = new MemoryStream(); - private void safeSkip(long bytes_to_skip) - { - - while (bytes_to_skip > 0) - { - int dummyByte = stream.ReadByte(); - long bytes_actually_skipped = 1; - if (bytes_actually_skipped > 0) - { - bytes_to_skip -= bytes_actually_skipped; - } - else if (bytes_actually_skipped == 0) - { - if (stream.ReadByte() == -1) - { - break; - } - else - { - bytes_to_skip--; - } - } - } - - return; - } - private int getbyte() - { - byte byt = Convert.ToByte(stream.ReadByte()); - // stream.Position++; - - return byt; - } - private ushort getShort() - { - byte[] bytes = new byte[2]; - for (int b = 0; b < bytes.Length; b++) - { - bytes[b] = Convert.ToByte(stream.ReadByte()); - //stream.Position++; - } - // return Short.toUnsignedInt(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort()); - return BitConverter.ToUInt16(bytes, 0); - } - private int getInt() - { - byte[] bytes = new byte[4]; - for (int b = 0; b < bytes.Length; b++) - { - bytes[b] = Convert.ToByte(stream.ReadByte()); - // stream.Position++; - } - //return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); - return BitConverter.ToInt32(bytes, 0); - } - private long getLong() - { - byte[] bytes = new byte[8]; - for (int b = 0; b < bytes.Length; b++) - { - bytes[b] = Convert.ToByte(stream.ReadByte()); - // stream.Position++; - } - - // return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong(); - return BitConverter.ToInt64(bytes, 0); - } - private String getString(int length) - { - byte[] bytes = new byte[length]; - for (int b = 0; b < bytes.Length; b++) - { - bytes[b] = Convert.ToByte(stream.ReadByte()); - // stream.Position++; - } - - string s = new String(System.Text.Encoding.UTF8.GetString(bytes).ToCharArray()).TrimEnd(); - if (s != null) - { - return s; - } - return "UNKNOWN"; - } + private static String FilterStringChars(string str) { string filtered = ""; @@ -176,6 +93,7 @@ public MechanicData getMechData() { /// public bool ParseLog(string evtc) { + MemoryStream stream = new MemoryStream(); //used to stream from a database, probably could use better stream now using(var client = new WebClient()) using(var origstream = client.OpenRead(evtc)) @@ -216,473 +134,7 @@ public bool ParseLog(string evtc) /// /// Parses boss related data /// - private void parseBossData() - { - // 12 bytes: arc build version - String build_version = getString(12); - this.log_data = new LogData(build_version); - - // 1 byte: skip - safeSkip(1); - - // 2 bytes: boss instance ID - ushort instid = getShort(); - - // 1 byte: position - safeSkip(1); - - //Save - // TempData["Debug"] = build_version +" "+ instid.ToString() ; - this.boss_data = new BossData(instid); - } - /// - /// Parses agent related data - /// - private void parseAgentData() - { - // 4 bytes: player count - int player_count = getInt(); - - // 96 bytes: each player - for (int i = 0; i < player_count; i++) - { - // 8 bytes: agent - long agent = getLong(); - - // 4 bytes: profession - int prof = getInt(); - - // 4 bytes: is_elite - int is_elite = getInt(); - - // 4 bytes: toughness - int toughness = getInt(); - - // 4 bytes: healing - int healing = getInt(); - - // 4 bytes: condition - int condition = getInt(); - - // 68 bytes: name - String name = getString(68); - //Save - Agent a = new Agent(agent, name, prof, is_elite); - if (a != null) - { - // NPC - if (a.getProf(this.log_data.getBuildVersion(),APIContrioller) == "NPC") - { - agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + prof.ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof))); - } - // Gadget - else if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "GDG") - { - agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + (prof & 0x0000ffff).ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof & 0x0000ffff))); - } - // Player - else - { - agent_data.addItem(a, new AgentItem(agent, name, a.getProf(this.log_data.getBuildVersion(), APIContrioller), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); - } - } - // Unknown - else - { - agent_data.addItem(a, new AgentItem(agent, name, prof.ToString(), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); - } - } - - } - /// - /// Parses skill related data - /// - private void parseSkillData() - { - GW2APIController apiController = new GW2APIController(); - // 4 bytes: player count - int skill_count = getInt(); - //TempData["Debug"] += "Skill Count:" + skill_count.ToString(); - // 68 bytes: each skill - for (int i = 0; i < skill_count; i++) - { - // 4 bytes: skill ID - int skill_id = getInt(); - - // 64 bytes: name - String name = getString(64); - String nameTrim = name.Replace("\0", ""); - int n; - bool isNumeric = int.TryParse(nameTrim, out n);//check to see if name was id - if (n == skill_id && skill_id != 0) - { - //was it a known boon? - foreach (Boon b in Boon.getBoonList()) - { - if (skill_id == b.getID()) - { - nameTrim = b.getName(); - } - } - } - //Save - - SkillItem skill = new SkillItem(skill_id, nameTrim); - - skill.SetGW2APISkill(apiController); - skill_data.addItem(skill); - } - } - /// - /// Parses combat related data - /// - private void parseCombatList() - { - // 64 bytes: each combat - while (stream.Length - stream.Position >= 64) - { - // 8 bytes: time - long time = getLong(); - - // 8 bytes: src_agent - long src_agent = getLong(); - - // 8 bytes: dst_agent - long dst_agent = getLong(); - - // 4 bytes: value - int value = getInt(); - - // 4 bytes: buff_dmg - int buff_dmg = getInt(); - - // 2 bytes: overstack_value - ushort overstack_value = getShort(); - - // 2 bytes: skill_id - ushort skill_id = getShort(); - - // 2 bytes: src_instid - ushort src_instid = getShort(); - - // 2 bytes: dst_instid - ushort dst_instid = getShort(); - - // 2 bytes: src_master_instid - ushort src_master_instid = getShort(); - - // 9 bytes: garbage - safeSkip(9); - - // 1 byte: iff - //IFF iff = IFF.getEnum(f.read()); - IFF iff = new IFF(Convert.ToByte(stream.ReadByte())); //Convert.ToByte(stream.ReadByte()); - - // 1 byte: buff - ushort buff = (ushort)stream.ReadByte(); - - // 1 byte: result - //Result result = Result.getEnum(f.read()); - Result result = new Result(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_activation - //Activation is_activation = Activation.getEnum(f.read()); - Activation is_activation = new Activation(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_buffremove - //BuffRemove is_buffremove = BuffRemove.getEnum(f.read()); - BuffRemove is_buffremoved = new BuffRemove(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_ninety - ushort is_ninety = (ushort)stream.ReadByte(); - - // 1 byte: is_fifty - ushort is_fifty = (ushort)stream.ReadByte(); - - // 1 byte: is_moving - ushort is_moving = (ushort)stream.ReadByte(); - - // 1 byte: is_statechange - //StateChange is_statechange = StateChange.getEnum(f.read()); - StateChange is_statechange = new StateChange(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_flanking - ushort is_flanking = (ushort)stream.ReadByte(); - - // 1 byte: is_flanking - ushort is_shields = (ushort)stream.ReadByte(); - // 2 bytes: garbage - safeSkip(2); - - //save - // Add combat - combat_data.addItem(new CombatItem(time, src_agent, dst_agent, value, buff_dmg, overstack_value, skill_id, - src_instid, dst_instid, src_master_instid, iff, buff, result, is_activation, is_buffremoved, - is_ninety, is_fifty, is_moving, is_statechange, is_flanking,is_shields)); - } - } - /// - /// Parses all the data again and link related stuff to each other - /// - private void fillMissingData() - { - // Set Agent instid, first_aware and last_aware - List player_list = agent_data.getPlayerAgentList(); - List agent_list = agent_data.getAllAgentsList(); - List combat_list = combat_data.getCombatList(); - foreach (AgentItem a in agent_list) - { - bool assigned_first = false; - foreach (CombatItem c in combat_list) - { - if (a.getAgent() == c.getSrcAgent() && c.getSrcInstid() != 0) - { - if (!assigned_first) - { - a.setInstid(c.getSrcInstid()); - a.setFirstAware(c.getTime()); - assigned_first = true; - } - a.setLastAware(c.getTime()); - } - else if (a.getAgent() == c.getDstAgent() && c.getDstInstid() != 0) - { - if (!assigned_first) - { - a.setInstid(c.getDstInstid()); - a.setFirstAware(c.getTime()); - assigned_first = true; - } - a.setLastAware(c.getTime()); - } - - } - } - - - // Set Boss data agent, instid, first_aware, last_aware and name - List NPC_list = agent_data.getNPCAgentList(); - 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()); - } - boss_data.setLastAware(NPC.getLastAware()); - } - } - AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); - boss = new Boss(bossAgent); - List bossHealthOverTime = new List(); - - // Grab values threw combat data - foreach (CombatItem c in combat_list) - { - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 12)//max health update - { - boss_data.setHealth((int)c.getDstAgent()); - - } - if (c.isStateChange().getID() == 13 && log_data.getPOV() == "N/A")//Point of View - { - long pov_agent = c.getSrcAgent(); - foreach (AgentItem p in player_list) - { - if (pov_agent == p.getAgent()) - { - log_data.setPOV(p.getName()); - } - } - - } - else if (c.isStateChange().getID() == 9)//Log start - { - log_data.setLogStart(c.getValue()); - } - else if (c.isStateChange().getID() == 10)//log end - { - log_data.setLogEnd(c.getValue()); - - } - //set health update - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 8) - { - bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); - } - - } - - - // 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();//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().getID() == 8) - { - bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); - } - } - break; - } - } - } - //Dealing with Deimos split - if (boss_data.getID() == 17154) - { - int deimos_2_instid = 0; - foreach (AgentItem NPC in NPC_list) - { - if (NPC.getProf().Contains("57069")) - { - deimos_2_instid = NPC.getInstid(); - long oldAware = boss_data.getLastAware(); - if (NPC.getLastAware() < boss_data.getLastAware()) - { - // No split - break; - } - boss.addPhaseData(boss_data.getLastAware()); - boss_data.setLastAware(NPC.getLastAware()); - //List 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().getEnum() == "REWARD")//got reward - { - log_data.setBossKill(true); - boss_data.setLastAware(c.getTime()); - break; - } - //set boss dead - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 4 && !log_data.getBosskill())//change dead - { - log_data.setBossKill(true); - boss_data.setLastAware(c.getTime()); - } - - } - - //players - if (p_list.Count == 0) - { - - //Fix Disconected players - List playerAgentList = getAgentData().getPlayerAgentList(); - - foreach (AgentItem playerAgent in playerAgentList) - { - List lp = combat_data.getStates(playerAgent.getInstid(), "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 isntances to original instid - int extra_login_Id = 0; - foreach (AgentItem extra in NPC_list) - { - if (extra.getAgent() == playerAgent.getAgent()) - { - - 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 => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) - setMechData(); - } - + //Statistics-------------------------------------------------------------------------------------------------------------------------------------------------------- private List present_boons = new List();//Used only for Boon tables private List present_offbuffs = new List();//Used only for Off Buff tables diff --git a/LuckParser/Controllers/ParseHelper.cs b/LuckParser/Controllers/ParseHelper.cs new file mode 100644 index 000000000..3e0cf25b0 --- /dev/null +++ b/LuckParser/Controllers/ParseHelper.cs @@ -0,0 +1,564 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LuckParser.Controllers +{ + class ParseHelper + { + private void safeSkip(long bytes_to_skip) + { + + while (bytes_to_skip > 0) + { + int dummyByte = stream.ReadByte(); + long bytes_actually_skipped = 1; + if (bytes_actually_skipped > 0) + { + bytes_to_skip -= bytes_actually_skipped; + } + else if (bytes_actually_skipped == 0) + { + if (stream.ReadByte() == -1) + { + break; + } + else + { + bytes_to_skip--; + } + } + } + + return; + } + private int getbyte() + { + byte byt = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + + return byt; + } + private ushort getShort() + { + byte[] bytes = new byte[2]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + //stream.Position++; + } + // return Short.toUnsignedInt(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort()); + return BitConverter.ToUInt16(bytes, 0); + } + private int getInt() + { + byte[] bytes = new byte[4]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + } + //return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); + return BitConverter.ToInt32(bytes, 0); + } + private long getLong() + { + byte[] bytes = new byte[8]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + } + + // return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong(); + return BitConverter.ToInt64(bytes, 0); + } + private String getString(int length) + { + byte[] bytes = new byte[length]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + } + + string s = new String(System.Text.Encoding.UTF8.GetString(bytes).ToCharArray()).TrimEnd(); + if (s != null) + { + return s; + } + return "UNKNOWN"; + } + } + + private void parseBossData() + { + // 12 bytes: arc build version + String build_version = getString(12); + this.log_data = new LogData(build_version); + + // 1 byte: skip + safeSkip(1); + + // 2 bytes: boss instance ID + ushort instid = getShort(); + + // 1 byte: position + safeSkip(1); + + //Save + // TempData["Debug"] = build_version +" "+ instid.ToString() ; + this.boss_data = new BossData(instid); + } + /// + /// Parses agent related data + /// + private void parseAgentData() + { + // 4 bytes: player count + int player_count = getInt(); + + // 96 bytes: each player + for (int i = 0; i < player_count; i++) + { + // 8 bytes: agent + long agent = getLong(); + + // 4 bytes: profession + int prof = getInt(); + + // 4 bytes: is_elite + int is_elite = getInt(); + + // 4 bytes: toughness + int toughness = getInt(); + + // 4 bytes: healing + int healing = getInt(); + + // 4 bytes: condition + int condition = getInt(); + + // 68 bytes: name + String name = getString(68); + //Save + Agent a = new Agent(agent, name, prof, is_elite); + if (a != null) + { + // NPC + if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "NPC") + { + agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + prof.ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof))); + } + // Gadget + else if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "GDG") + { + agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + (prof & 0x0000ffff).ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof & 0x0000ffff))); + } + // Player + else + { + agent_data.addItem(a, new AgentItem(agent, name, a.getProf(this.log_data.getBuildVersion(), APIContrioller), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); + } + } + // Unknown + else + { + agent_data.addItem(a, new AgentItem(agent, name, prof.ToString(), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); + } + } + + } + /// + /// Parses skill related data + /// + private void parseSkillData() + { + GW2APIController apiController = new GW2APIController(); + // 4 bytes: player count + int skill_count = getInt(); + //TempData["Debug"] += "Skill Count:" + skill_count.ToString(); + // 68 bytes: each skill + for (int i = 0; i < skill_count; i++) + { + // 4 bytes: skill ID + int skill_id = getInt(); + + // 64 bytes: name + String name = getString(64); + String nameTrim = name.Replace("\0", ""); + int n; + bool isNumeric = int.TryParse(nameTrim, out n);//check to see if name was id + if (n == skill_id && skill_id != 0) + { + //was it a known boon? + foreach (Boon b in Boon.getBoonList()) + { + if (skill_id == b.getID()) + { + nameTrim = b.getName(); + } + } + } + //Save + + SkillItem skill = new SkillItem(skill_id, nameTrim); + + skill.SetGW2APISkill(apiController); + skill_data.addItem(skill); + } + } + /// + /// Parses combat related data + /// + private void parseCombatList() + { + // 64 bytes: each combat + while (stream.Length - stream.Position >= 64) + { + // 8 bytes: time + long time = getLong(); + + // 8 bytes: src_agent + long src_agent = getLong(); + + // 8 bytes: dst_agent + long dst_agent = getLong(); + + // 4 bytes: value + int value = getInt(); + + // 4 bytes: buff_dmg + int buff_dmg = getInt(); + + // 2 bytes: overstack_value + ushort overstack_value = getShort(); + + // 2 bytes: skill_id + ushort skill_id = getShort(); + + // 2 bytes: src_instid + ushort src_instid = getShort(); + + // 2 bytes: dst_instid + ushort dst_instid = getShort(); + + // 2 bytes: src_master_instid + ushort src_master_instid = getShort(); + + // 9 bytes: garbage + safeSkip(9); + + // 1 byte: iff + //IFF iff = IFF.getEnum(f.read()); + IFF iff = new IFF(Convert.ToByte(stream.ReadByte())); //Convert.ToByte(stream.ReadByte()); + + // 1 byte: buff + ushort buff = (ushort)stream.ReadByte(); + + // 1 byte: result + //Result result = Result.getEnum(f.read()); + Result result = new Result(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_activation + //Activation is_activation = Activation.getEnum(f.read()); + Activation is_activation = new Activation(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_buffremove + //BuffRemove is_buffremove = BuffRemove.getEnum(f.read()); + BuffRemove is_buffremoved = new BuffRemove(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_ninety + ushort is_ninety = (ushort)stream.ReadByte(); + + // 1 byte: is_fifty + ushort is_fifty = (ushort)stream.ReadByte(); + + // 1 byte: is_moving + ushort is_moving = (ushort)stream.ReadByte(); + + // 1 byte: is_statechange + //StateChange is_statechange = StateChange.getEnum(f.read()); + StateChange is_statechange = new StateChange(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_flanking + ushort is_flanking = (ushort)stream.ReadByte(); + + // 1 byte: is_flanking + ushort is_shields = (ushort)stream.ReadByte(); + // 2 bytes: garbage + safeSkip(2); + + //save + // Add combat + combat_data.addItem(new CombatItem(time, src_agent, dst_agent, value, buff_dmg, overstack_value, skill_id, + src_instid, dst_instid, src_master_instid, iff, buff, result, is_activation, is_buffremoved, + is_ninety, is_fifty, is_moving, is_statechange, is_flanking, is_shields)); + } + } + /// + /// Parses all the data again and link related stuff to each other + /// + private void fillMissingData() + { + // Set Agent instid, first_aware and last_aware + List player_list = agent_data.getPlayerAgentList(); + List agent_list = agent_data.getAllAgentsList(); + List combat_list = combat_data.getCombatList(); + foreach (AgentItem a in agent_list) + { + bool assigned_first = false; + foreach (CombatItem c in combat_list) + { + if (a.getAgent() == c.getSrcAgent() && c.getSrcInstid() != 0) + { + if (!assigned_first) + { + a.setInstid(c.getSrcInstid()); + a.setFirstAware(c.getTime()); + assigned_first = true; + } + a.setLastAware(c.getTime()); + } + else if (a.getAgent() == c.getDstAgent() && c.getDstInstid() != 0) + { + if (!assigned_first) + { + a.setInstid(c.getDstInstid()); + a.setFirstAware(c.getTime()); + assigned_first = true; + } + a.setLastAware(c.getTime()); + } + + } + } + + + // Set Boss data agent, instid, first_aware, last_aware and name + List NPC_list = agent_data.getNPCAgentList(); + 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()); + } + boss_data.setLastAware(NPC.getLastAware()); + } + } + AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); + boss = new Boss(bossAgent); + List bossHealthOverTime = new List(); + + // Grab values threw combat data + foreach (CombatItem c in combat_list) + { + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 12)//max health update + { + boss_data.setHealth((int)c.getDstAgent()); + + } + if (c.isStateChange().getID() == 13 && log_data.getPOV() == "N/A")//Point of View + { + long pov_agent = c.getSrcAgent(); + foreach (AgentItem p in player_list) + { + if (pov_agent == p.getAgent()) + { + log_data.setPOV(p.getName()); + } + } + + } + else if (c.isStateChange().getID() == 9)//Log start + { + log_data.setLogStart(c.getValue()); + } + else if (c.isStateChange().getID() == 10)//log end + { + log_data.setLogEnd(c.getValue()); + + } + //set health update + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 8) + { + bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); + } + + } + + + // 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();//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().getID() == 8) + { + bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); + } + } + break; + } + } + } + //Dealing with Deimos split + if (boss_data.getID() == 17154) + { + int deimos_2_instid = 0; + foreach (AgentItem NPC in NPC_list) + { + if (NPC.getProf().Contains("57069")) + { + deimos_2_instid = NPC.getInstid(); + long oldAware = boss_data.getLastAware(); + if (NPC.getLastAware() < boss_data.getLastAware()) + { + // No split + break; + } + boss.addPhaseData(boss_data.getLastAware()); + boss_data.setLastAware(NPC.getLastAware()); + //List 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().getEnum() == "REWARD")//got reward + { + log_data.setBossKill(true); + boss_data.setLastAware(c.getTime()); + break; + } + //set boss dead + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 4 && !log_data.getBosskill())//change dead + { + log_data.setBossKill(true); + boss_data.setLastAware(c.getTime()); + } + + } + + //players + if (p_list.Count == 0) + { + + //Fix Disconected players + List playerAgentList = getAgentData().getPlayerAgentList(); + + foreach (AgentItem playerAgent in playerAgentList) + { + List lp = combat_data.getStates(playerAgent.getInstid(), "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 isntances to original instid + int extra_login_Id = 0; + foreach (AgentItem extra in NPC_list) + { + if (extra.getAgent() == playerAgent.getAgent()) + { + + 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 => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) + setMechData(); + } + +} From 03cb5130031e653fcbc30c7ac1fc78fbc9b5ff8e Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 19:24:55 +0200 Subject: [PATCH 18/53] some more refacto --- LuckParser/Controllers/Controller1.cs | 1201 ++++++++++++------------- LuckParser/Controllers/HTMLHelper.cs | 490 ++++++++++ LuckParser/Controllers/ParseHelper.cs | 487 +--------- LuckParser/LuckParser.csproj | 2 + 4 files changed, 1055 insertions(+), 1125 deletions(-) create mode 100644 LuckParser/Controllers/HTMLHelper.cs diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 1b133dc2f..e775b91cd 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -17,24 +17,7 @@ namespace LuckParser.Controllers { public class Controller1 { - private static byte[] StreamToBytes(Stream input) - { - byte[] buffer = new byte[16 * 1024]; - using (MemoryStream ms = new MemoryStream()) - { - int read; - while ((read = input.Read(buffer, 0, buffer.Length)) > 0) - { - ms.Write(buffer, 0, read); - } - return ms.ToArray(); - } - } - private GW2APIController APIContrioller = new GW2APIController(); - - // Private Methods - //for pulling from binary - + private GW2APIController APIContrioller = new GW2APIController(); private static String FilterStringChars(string str) { string filtered = ""; @@ -68,23 +51,8 @@ public BossData getBossData() { return boss_data; } - public AgentData getAgentData() - { - return agent_data; - } - public SkillData getSkillData() - { - return skill_data; - } - public CombatData getCombatData() - { - return combat_data; - } - public MechanicData getMechData() { - return mech_data; - } - + //Main Parse method------------------------------------------------------------------------------------------------------------------------------------------------ /// /// Parses the given log @@ -118,11 +86,11 @@ public bool ParseLog(string evtc) } stream.Position = 0; - parseBossData(); - parseAgentData(); - parseSkillData(); - parseCombatList(); - fillMissingData(); + parseBossData(stream); + parseAgentData(stream); + parseSkillData(stream); + parseCombatList(stream); + fillMissingData(stream); stream.Close(); } @@ -134,487 +102,538 @@ public bool ParseLog(string evtc) /// /// Parses boss related data /// - - //Statistics-------------------------------------------------------------------------------------------------------------------------------------------------------- - private List present_boons = new List();//Used only for Boon tables - private List present_offbuffs = new List();//Used only for Off Buff tables - private List present_defbuffs = new List();//Used only for Def Buff tables - private Dictionary> present_personnal = new Dictionary>();//Used only for personnal + private void parseBossData(MemoryStream stream) + { + // 12 bytes: arc build version + String build_version = ParseHelper.getString(stream, 12); + this.log_data = new LogData(build_version); + + // 1 byte: skip + ParseHelper.safeSkip(stream, 1); + + // 2 bytes: boss instance ID + ushort instid = ParseHelper.getShort(stream); + + // 1 byte: position + ParseHelper.safeSkip(stream, 1); + + //Save + // TempData["Debug"] = build_version +" "+ instid.ToString() ; + this.boss_data = new BossData(instid); + } /// - /// Checks the combat data and gets buffs that were present during the fight + /// Parses agent related data /// - /// Settings to use - private void setPresentBoons(bool[] SnapSettings) { - List s_list = getSkillData().getSkillList(); - if (SnapSettings[3]) - {//Main boons - foreach (Boon boon in Boon.getBoonList()) + private void parseAgentData(MemoryStream stream) + { + // 4 bytes: player count + int player_count = ParseHelper.getInt(stream); + + // 96 bytes: each player + for (int i = 0; i < player_count; i++) + { + // 8 bytes: agent + long agent = ParseHelper.getLong(stream); + + // 4 bytes: profession + int prof = ParseHelper.getInt(stream); + + // 4 bytes: is_elite + int is_elite = ParseHelper.getInt(stream); + + // 4 bytes: toughness + int toughness = ParseHelper.getInt(stream); + + // 4 bytes: healing + int healing = ParseHelper.getInt(stream); + + // 4 bytes: condition + int condition = ParseHelper.getInt(stream); + + // 68 bytes: name + String name = ParseHelper.getString(stream, 68); + //Save + Agent a = new Agent(agent, name, prof, is_elite); + if (a != null) { - if (s_list.Exists(x => x.getID() == boon.getID())) + // NPC + if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "NPC") { - present_boons.Add(boon); + agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + prof.ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof))); } - } - } - if (SnapSettings[4]) - {//Important Class specefic boons - foreach (Boon boon in Boon.getOffensiveTableList()) - { - if (s_list.Exists(x => x.getID() == boon.getID())) + // Gadget + else if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "GDG") { - present_offbuffs.Add(boon); + agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + (prof & 0x0000ffff).ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof & 0x0000ffff))); } - } - foreach (Boon boon in Boon.getDefensiveTableList()) - { - if (s_list.Exists(x => x.getID() == boon.getID())) + // Player + else { - present_defbuffs.Add(boon); + agent_data.addItem(a, new AgentItem(agent, name, a.getProf(this.log_data.getBuildVersion(), APIContrioller), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); } } + // Unknown + else + { + agent_data.addItem(a, new AgentItem(agent, name, prof.ToString(), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); + } } - if (SnapSettings[5]) - {//All class specefic boons - List c_data = getCombatData().getCombatList(); - foreach (Player p in p_list) + + } + /// + /// Parses skill related data + /// + private void parseSkillData(MemoryStream stream) + { + GW2APIController apiController = new GW2APIController(); + // 4 bytes: player count + int skill_count = ParseHelper.getInt(stream); + //TempData["Debug"] += "Skill Count:" + skill_count.ToString(); + // 68 bytes: each skill + for (int i = 0; i < skill_count; i++) + { + // 4 bytes: skill ID + int skill_id = ParseHelper.getInt(stream); + + // 64 bytes: name + String name = ParseHelper.getString(stream, 64); + String nameTrim = name.Replace("\0", ""); + int n; + bool isNumeric = int.TryParse(nameTrim, out n);//check to see if name was id + if (n == skill_id && skill_id != 0) { - present_personnal[p.getInstid()] = new List(); - foreach (Boon boon in Boon.getRemainingBuffsList(p.getProf())) + //was it a known boon? + foreach (Boon b in Boon.getBoonList()) { - if (c_data.Exists(x => x.getSkillID() == boon.getID() && x.getDstInstid() == p.getInstid())) + if (skill_id == b.getID()) { - present_personnal[p.getInstid()].Add(boon); + nameTrim = b.getName(); } } } - } + //Save + + SkillItem skill = new SkillItem(skill_id, nameTrim); + + skill.SetGW2APISkill(apiController); + skill_data.addItem(skill); + } } - private String getFinalDPS(AbstractPlayer p, int phase_index) + /// + /// Parses combat related data + /// + private void parseCombatList(MemoryStream stream) { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - - int totalboss_dps = 0; - int totalboss_damage = 0; - int totalbosscondi_dps = 0; - int totalbosscondi_damage = 0; - int totalbossphys_dps = 0; - int totalbossphys_damage = 0; - int totalAll_dps = 0; - int totalAll_damage = 0; - int totalAllcondi_dps = 0; - int totalAllcondi_damage = 0; - int totalAllphys_dps = 0; - int totalAllphys_damage = 0; - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - double fight_duration = (phase.end - phase.start) / 1000.0; - - double damage = 0.0; - double dps = 0.0; - // All DPS - - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); - if (fight_duration > 0) - { - dps = damage / fight_duration; - } - totalAll_dps = (int)dps; - totalAll_damage = (int)damage; - //Allcondi - damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); - if (fight_duration > 0) - { - dps = damage / fight_duration; - } - totalAllcondi_dps = (int)dps; - totalAllcondi_damage = (int)damage; - //All Power - damage = totalAll_damage - damage; - if (fight_duration > 0) + // 64 bytes: each combat + while (stream.Length - stream.Position >= 64) { - dps = damage / fight_duration; - } - totalAllphys_dps = (int)dps; - totalAllphys_damage = (int)damage; + // 8 bytes: time + long time = ParseHelper.getLong(stream); - // boss DPS - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); - if (fight_duration > 0) - { - dps = damage / fight_duration; - } - totalboss_dps = (int)dps; - totalboss_damage = (int)damage; - //bosscondi - damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); - if (fight_duration > 0) - { - dps = damage / fight_duration; - } - totalbosscondi_dps = (int)dps; - totalbosscondi_damage = (int)damage; - //boss Power - damage = totalboss_damage - damage; - if (fight_duration > 0) - { - dps = damage / fight_duration; + // 8 bytes: src_agent + long src_agent = ParseHelper.getLong(stream); + + // 8 bytes: dst_agent + long dst_agent = ParseHelper.getLong(stream); + + // 4 bytes: value + int value = ParseHelper.getInt(stream); + + // 4 bytes: buff_dmg + int buff_dmg = ParseHelper.getInt(stream); + + // 2 bytes: overstack_value + ushort overstack_value = ParseHelper.getShort(stream); + + // 2 bytes: skill_id + ushort skill_id = ParseHelper.getShort(stream); + + // 2 bytes: src_instid + ushort src_instid = ParseHelper.getShort(stream); + + // 2 bytes: dst_instid + ushort dst_instid = ParseHelper.getShort(stream); + + // 2 bytes: src_master_instid + ushort src_master_instid = ParseHelper.getShort(stream); + + // 9 bytes: garbage + ParseHelper.safeSkip(stream, 9); + + // 1 byte: iff + //IFF iff = IFF.getEnum(f.read()); + IFF iff = new IFF(Convert.ToByte(stream.ReadByte())); //Convert.ToByte(stream.ReadByte()); + + // 1 byte: buff + ushort buff = (ushort)stream.ReadByte(); + + // 1 byte: result + //Result result = Result.getEnum(f.read()); + Result result = new Result(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_activation + //Activation is_activation = Activation.getEnum(f.read()); + Activation is_activation = new Activation(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_buffremove + //BuffRemove is_buffremove = BuffRemove.getEnum(f.read()); + BuffRemove is_buffremoved = new BuffRemove(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_ninety + ushort is_ninety = (ushort)stream.ReadByte(); + + // 1 byte: is_fifty + ushort is_fifty = (ushort)stream.ReadByte(); + + // 1 byte: is_moving + ushort is_moving = (ushort)stream.ReadByte(); + + // 1 byte: is_statechange + //StateChange is_statechange = StateChange.getEnum(f.read()); + StateChange is_statechange = new StateChange(Convert.ToByte(stream.ReadByte())); + + // 1 byte: is_flanking + ushort is_flanking = (ushort)stream.ReadByte(); + + // 1 byte: is_flanking + ushort is_shields = (ushort)stream.ReadByte(); + // 2 bytes: garbage + ParseHelper.safeSkip(stream, 2); + + //save + // Add combat + combat_data.addItem(new CombatItem(time, src_agent, dst_agent, value, buff_dmg, overstack_value, skill_id, + src_instid, dst_instid, src_master_instid, iff, buff, result, is_activation, is_buffremoved, + is_ninety, is_fifty, is_moving, is_statechange, is_flanking, is_shields)); } - totalbossphys_dps = (int)dps; - totalbossphys_damage = (int)damage; - //Placeholders for further calc - return totalAll_dps.ToString() + "|" + totalAll_damage.ToString() + "|" + totalAllphys_dps.ToString() + "|" + totalAllphys_damage.ToString() + "|" + totalAllcondi_dps.ToString() + "|" + totalAllcondi_damage.ToString() + "|" - + totalboss_dps.ToString() + "|" + totalboss_damage.ToString() + "|" + totalbossphys_dps.ToString() + "|" + totalbossphys_damage.ToString() + "|" + totalbosscondi_dps.ToString() + "|" + totalbosscondi_damage.ToString(); } - private String[] getFinalStats(Player p, int phase_index) + /// + /// Parses all the data again and link related stuff to each other + /// + private void fillMissingData(MemoryStream stream) { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - String[] statsArray; - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - long start = phase.start + b_data.getFirstAware(); - long end = phase.end + b_data.getFirstAware(); - List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - List cast_logs = p.getCastLogs( b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - int instid = p.getInstid(); - - // Rates - int power_loop_count = 0; - int critical_rate = 0; - int scholar_rate = 0; - int scholar_dmg = 0; - int totaldamage = damage_logs.Sum(x => x.getDamage()); - - int moving_rate = 0; - int flanking_rate = 0; - //glancerate - int glance_rate = 0; - //missed - int missed = 0; - //interupted - int interupts = 0; - //times enemy invulned - int invulned = 0; - - //timeswasted - int wasted = 0; - double time_wasted = 0; - //Time saved - int saved = 0; - double time_saved = 0; - //avgboons - double avgBoons = 0.0; - - foreach (DamageLog log in damage_logs) + // Set Agent instid, first_aware and last_aware + List player_list = agent_data.getPlayerAgentList(); + List agent_list = agent_data.getAllAgentsList(); + List combat_list = combat_data.getCombatList(); + foreach (AgentItem a in agent_list) { - if (log.isCondi() == 0) + bool assigned_first = false; + foreach (CombatItem c in combat_list) { - if (log.getResult().getEnum() == "CRIT") - { - critical_rate++; - } - if (log.isNinety()>0) { - scholar_rate++; - - scholar_dmg += (int)(log.getDamage() / 11.0); //regular+10% damage - } - //scholar_rate += log.isNinety(); - moving_rate += log.isMoving(); - flanking_rate += log.isFlanking(); - if (log.getResult().getEnum() == "GLANCE") - { - glance_rate++; - } - if (log.getResult().getEnum() == "BLIND") - { - missed++; - } - if (log.getResult().getEnum() == "INTERRUPT") + if (a.getAgent() == c.getSrcAgent() && c.getSrcInstid() != 0) { - interupts++; + if (!assigned_first) + { + a.setInstid(c.getSrcInstid()); + a.setFirstAware(c.getTime()); + assigned_first = true; + } + a.setLastAware(c.getTime()); } - if (log.getResult().getEnum() == "ABSORB") + else if (a.getAgent() == c.getDstAgent() && c.getDstInstid() != 0) { - invulned++; + if (!assigned_first) + { + a.setInstid(c.getDstInstid()); + a.setFirstAware(c.getTime()); + assigned_first = true; + } + a.setLastAware(c.getTime()); } - //if (log.isActivation().getEnum() == "CANCEL_FIRE" || log.isActivation().getEnum() == "CANCEL_CANCEL") - //{ - // wasted++; - // time_wasted += log.getDamage(); - //} - power_loop_count++; + } } - foreach (CastLog cl in cast_logs) { - if (cl.endActivation() != null) + + + // Set Boss data agent, instid, first_aware, last_aware and name + List NPC_list = agent_data.getNPCAgentList(); + foreach (AgentItem NPC in NPC_list) + { + if (NPC.getProf().EndsWith(boss_data.getID().ToString())) { - if (cl.endActivation().getID() == 4) + if (boss_data.getAgent() == 0) { - wasted++; - time_wasted += cl.getActDur(); + 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()); } - if (cl.endActivation().getID() == 3) + boss_data.setLastAware(NPC.getLastAware()); + } + } + AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); + boss = new Boss(bossAgent); + List bossHealthOverTime = new List(); + + // Grab values threw combat data + foreach (CombatItem c in combat_list) + { + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 12)//max health update + { + boss_data.setHealth((int)c.getDstAgent()); + + } + if (c.isStateChange().getID() == 13 && log_data.getPOV() == "N/A")//Point of View + { + long pov_agent = c.getSrcAgent(); + foreach (AgentItem p in player_list) { - saved++; - if (cl.getActDur() < cl.getExpDur()) + if (pov_agent == p.getAgent()) { - time_saved += cl.getExpDur() - cl.getActDur(); + log_data.setPOV(p.getName()); } } + + } + else if (c.isStateChange().getID() == 9)//Log start + { + log_data.setLogStart(c.getValue()); } + else if (c.isStateChange().getID() == 10)//log end + { + log_data.setLogEnd(c.getValue()); + + } + //set health update + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 8) + { + bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); + } + } - power_loop_count = (power_loop_count == 0) ? 1 : power_loop_count; - // Counts - int swap = c_data.getStates(instid, "WEAPON_SWAP", start, end).Count(); - int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); - int dodge = c_data.getSkillCount(instid, 65001, start, end) + c_data.getBuffCount(instid, 40408, start, end);//dodge = 65001 mirage cloak =40408 - int ress = c_data.getSkillCount(instid, 1066, start, end); //Res = 1066 + // Dealing with second half of Xera | ((22611300 * 0.5) + (25560600 * 0.5) - // R.I.P - List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); - - double died = 0.0; - if (dead.Count() > 0) - { - died = dead[0].getTime() - start; - } - List disconect = c_data.getStates(instid, "DESPAWN", start, end); - double dcd = 0.0; - if (disconect.Count() > 0) - { - dcd = disconect[0].getTime() - start; - } - statsArray = new string[] { power_loop_count.ToString(), - critical_rate.ToString(), - scholar_rate.ToString(), - moving_rate.ToString(), - flanking_rate.ToString(), - swap.ToString(), - down.ToString(), - dodge.ToString(), - ress.ToString(), - died.ToString("0.00"), - glance_rate.ToString(), - missed.ToString(), - interupts.ToString(), - invulned.ToString(), - (time_wasted/1000f).ToString(), - wasted.ToString(), - avgBoons.ToString(), - (time_saved/1000f).ToString(), - saved.ToString(), - scholar_dmg.ToString(), - totaldamage.ToString(), - dcd.ToString("0.00"), - }; - return statsArray; - } - private string[] getFinalDefenses(Player p, int phase_index) - { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - long start = phase.start + b_data.getFirstAware(); - long end = phase.end + b_data.getFirstAware(); - List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(),getMechData(), phase.start, phase.end); - int instid = p.getInstid(); - - int damagetaken = damage_logs.Select(x => x.getDamage()).Sum(); - int blocked = 0; - //int dmgblocked = 0; - int invulned = 0; - int dmginvulned = 0; - int dodge = c_data.getSkillCount(instid, 65001, start, end);//dodge = 65001 - dodge += c_data.getBuffCount(instid, 40408, start, end);//mirage cloak add - int evades = 0; - //int dmgevaded = 0; - int dmgBarriar = 0; - foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "BLOCK")) - { - blocked++; - //dmgblocked += log.getDamage(); - } - foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "ABSORB")) + if (boss_data.getID() == 16246) { - invulned++; - dmginvulned += log.getDamage(); - } - foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "EVADE")) - { - evades++; - // dmgevaded += log.getDamage(); + int xera_2_instid = 0; + foreach (AgentItem NPC in NPC_list) + { + if (NPC.getProf().Contains("16286")) + { + bossHealthOverTime = new List();//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().getID() == 8) + { + bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); + } + } + break; + } + } } - foreach (DamageLog log in damage_logs.Where(x => x.isShields() == 1)) + //Dealing with Deimos split + if (boss_data.getID() == 17154) { + int deimos_2_instid = 0; + foreach (AgentItem NPC in NPC_list) + { + if (NPC.getProf().Contains("57069")) + { + deimos_2_instid = NPC.getInstid(); + long oldAware = boss_data.getLastAware(); + if (NPC.getLastAware() < boss_data.getLastAware()) + { + // No split + break; + } + boss.addPhaseData(boss_data.getLastAware()); + boss_data.setLastAware(NPC.getLastAware()); + //List 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()); - dmgBarriar += log.getDamage(); + } + if (c.getDstInstid() == deimos_2_instid) + { + c.setDstInstid(boss_data.getInstid()); + } + } + + } + break; + } + } } - int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); - // R.I.P - List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); - double died = 0.0; - if (dead.Count() > 0) + 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) { - died = dead[0].getTime()- start; + //set boss dead + if (c.isStateChange().getEnum() == "REWARD")//got reward + { + log_data.setBossKill(true); + boss_data.setLastAware(c.getTime()); + break; + } + //set boss dead + if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 4 && !log_data.getBosskill())//change dead + { + log_data.setBossKill(true); + boss_data.setLastAware(c.getTime()); + } + } - String[] statsArray = new string[] { damagetaken.ToString(), - blocked.ToString(), - "0"/*dmgblocked.ToString()*/, - invulned.ToString(), - dmginvulned.ToString(), - dodge.ToString(), - evades.ToString(), - "0"/*dmgevaded.ToString()*/, - down.ToString(), - died.ToString("0.00"), - dmgBarriar.ToString()}; - return statsArray; - } - //(currently not correct) - private string[] getFinalSupport(Player p, int phase_index) - { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - long start = phase.start + b_data.getFirstAware(); - long end = phase.end + b_data.getFirstAware(); - // List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData()); - int instid = p.getInstid(); - int resurrects = 0; - double restime = 0.0; - int condiCleanse = 0; - double condiCleansetime = 0.0; - - int[] resArray = p.getReses(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - resurrects = resArray[0]; - restime = resArray[1]; - condiCleanse = cleanseArray[0]; - condiCleansetime = cleanseArray[1]; - - - String[] statsArray = new string[] { resurrects.ToString(), (restime/1000f).ToString(), condiCleanse.ToString(), (condiCleansetime/1000f).ToString() }; - return statsArray; - } - private Dictionary getfinalboons(Player p) - { - BossData b_data = getBossData(); - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, getSkillData(), getCombatData().getCombatList()); - Dictionary rates = new Dictionary(); - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); - foreach (Boon boon in Boon.getAllBuffList()) + + //players + if (p_list.Count == 0) { - string rate = "0"; - if (boon_distrib.ContainsKey(boon.getID())) + + //Fix Disconected players + List playerAgentList = agent_data.getPlayerAgentList(); + + foreach (AgentItem playerAgent in playerAgentList) { - if (boon.getType() == Boon.BoonType.Duration) + List lp = combat_data.getStates(playerAgent.getInstid(), "DESPAWN", boss_data.getFirstAware(), boss_data.getLastAware()); + Player player = new Player(playerAgent); + bool skip = false; + foreach (Player p in p_list) { - rate = Math.Round(100.0 * boon_distrib.getUptime(boon.getID()) / fight_duration, 1) + "%"; + if (p.getAccount() == player.getAccount())//is this a copy of original? + { + skip = true; + } + } + if (skip) + { + continue; } - else if (boon.getType() == Boon.BoonType.Intensity) + if (lp.Count > 0) { - rate = Math.Round((double)boon_distrib.getUptime(boon.getID()) / fight_duration, 1).ToString(); + //make all actions of other isntances to original instid + int extra_login_Id = 0; + foreach (AgentItem extra in NPC_list) + { + if (extra.getAgent() == playerAgent.getAgent()) + { + + 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); + } + } } - rates[boon.getID()] = rate; + } - return rates; + // Sort + p_list = p_list.OrderBy(a => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) + setMechData(); } - private Dictionary getfinalboons(Player p, List trgetPlayers) - { - if (trgetPlayers.Count() == 0) - { - return getfinalboons(p); - } - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - SkillData s_data = getSkillData(); - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); - Dictionary boon_logsDist = new Dictionary(); - foreach (Player player in trgetPlayers) - { - boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList()); - } - Dictionary rates = new Dictionary(); - foreach (Boon boon in Boon.getAllBuffList()) - { - string rate = "0"; - long total = 0; - long totaloverstack = 0; - foreach (Player player in trgetPlayers) + + + //Statistics-------------------------------------------------------------------------------------------------------------------------------------------------------- + private List present_boons = new List();//Used only for Boon tables + private List present_offbuffs = new List();//Used only for Off Buff tables + private List present_defbuffs = new List();//Used only for Def Buff tables + private Dictionary> present_personnal = new Dictionary>();//Used only for personnal + /// + /// Checks the combat data and gets buffs that were present during the fight + /// + /// Settings to use + private void setPresentBoons(bool[] SnapSettings) { + List s_list = skill_data.getSkillList(); + if (SnapSettings[3]) + {//Main boons + foreach (Boon boon in Boon.getBoonList()) { - BoonDistribution boon_dist = boon_logsDist[player]; - if (boon_dist.ContainsKey(boon.getID())) + if (s_list.Exists(x => x.getID() == boon.getID())) { - total += boon_dist.getGeneration(boon.getID(), p.getInstid()); - totaloverstack += boon_dist.getOverstack(boon.getID(), p.getInstid()); + present_boons.Add(boon); } } - totaloverstack += total; - if (total > 0) + } + if (SnapSettings[4]) + {//Important Class specefic boons + foreach (Boon boon in Boon.getOffensiveTableList()) { - if (boon.getType() == Boon.BoonType.Duration) + if (s_list.Exists(x => x.getID() == boon.getID())) { - rate = "" - + Math.Round(100.0 * total / fight_duration / trgetPlayers.Count, 1) - + "%"; + present_offbuffs.Add(boon); } - else if (boon.getType() == Boon.BoonType.Intensity) + } + foreach (Boon boon in Boon.getDefensiveTableList()) + { + if (s_list.Exists(x => x.getID() == boon.getID())) { - rate = "" - + Math.Round((double)total / fight_duration / trgetPlayers.Count, 1).ToString() - + ""; + present_defbuffs.Add(boon); } - } - rates[boon.getID()] = rate; } - return rates; - } - private Dictionary getfinalcondis(AbstractPlayer p) - { - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - SkillData s_data = getSkillData(); - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList()); - Dictionary rates = new Dictionary(); - foreach (Boon boon in Boon.getCondiBoonList()) - { - rates[boon.getID()] = "0"; - if (boon_distrib.ContainsKey(boon.getID())) + if (SnapSettings[5]) + {//All class specefic boons + List c_list = combat_data.getCombatList(); + foreach (Player p in p_list) { - string rate = "0"; - if (boon.getType() == Boon.BoonType.Duration) - { - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); - rate = Math.Round(100.0 * boon_distrib.getUptime(boon.getID()) / fight_duration, 1) + "%"; - } - else if (boon.getType() == Boon.BoonType.Intensity) + present_personnal[p.getInstid()] = new List(); + foreach (Boon boon in Boon.getRemainingBuffsList(p.getProf())) { - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); - rate = Math.Round((double)boon_distrib.getUptime(boon.getID()) / fight_duration, 1).ToString(); + if (c_list.Exists(x => x.getSkillID() == boon.getID() && x.getDstInstid() == p.getInstid())) + { + present_personnal[p.getInstid()].Add(boon); + } } - - rates[boon.getID()] = rate; } - } - return rates; + } } private void setMechData() { List mIDList = new List(); - CombatData c_data = getCombatData(); foreach (Player p in p_list) { - - List down = c_data.getStates(p.getInstid(), "CHANGE_DOWN", boss_data.getFirstAware(), boss_data.getLastAware()); + List down = combat_data.getStates(p.getInstid(), "CHANGE_DOWN", 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 dead = c_data.getStates(p.getInstid(), "CHANGE_DEAD", boss_data.getFirstAware(), boss_data.getLastAware()); + List dead = combat_data.getStates(p.getInstid(), "CHANGE_DEAD", 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"))); @@ -627,7 +646,7 @@ private void setMechData() { string name = skill_data.getName(dLog.getID()); if (dLog.getResult().getID() < 3 ) { - foreach (Mechanic mech in getMechData().GetMechList(boss_data.getID()).Where(x=>x.GetMechType() == 3)) + foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x=>x.GetMechType() == 3)) { //Prevent multi hit attacks form multi registering if (prevMech != null) @@ -658,7 +677,7 @@ private void setMechData() { { String name = skill_data.getName(c.getSkillID()); //buff on player 0 - foreach (Mechanic mech in getMechData().GetMechList(boss_data.getID()).Where(x => x.GetMechType() == 0)) + foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => x.GetMechType() == 0)) { if (c.getSkillID() == mech.GetSkill()) { @@ -668,7 +687,7 @@ private void setMechData() { } } //player on player 7 - foreach (Mechanic mech in getMechData().GetMechList(boss_data.getID()).Where(x => x.GetMechType() == 7)) + foreach (Mechanic mech in mech_data.GetMechList(boss_data.getID()).Where(x => x.GetMechType() == 7)) { if (c.getSkillID() == mech.GetSkill()) { @@ -688,81 +707,7 @@ private void setMechData() { } //Generate HTML--------------------------------------------------------------------------------------------------------------------------------------------------------- //Methods that make it easier to create Javascript graphs - private List getDPSGraph(AbstractPlayer p, int phase_index, ushort dstid) - { - List dmgList = new List(); - BossData b_data = getBossData(); - CombatData c_data = getCombatData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List damage_logs = p.getDamageLogs(dstid, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end).Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); - int totaldmg = 0; - - int timeGraphed = (int)phase.start; - foreach (DamageLog log in damage_logs) - { - - totaldmg += log.getDamage(); - - long time = log.getTime(); - if (time > 1000) - { - - //to reduce processing time only graph 1 point per sec - if (Math.Floor(time / 1000f) > timeGraphed) - { - - if ((Math.Floor(time / 1000f) - timeGraphed) < 2) - { - timeGraphed = (int)Math.Floor(time / 1000f); - dmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); - } - else - { - int gap = (int)Math.Floor(time / 1000f) - timeGraphed; - bool startOfFight = true; - if (dmgList.Count > 0) - { - startOfFight = false; - } - - for (int itr = 0; itr < gap - 1; itr++) - { - timeGraphed++; - if (!startOfFight) - { - dmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); - } - else - {//hasnt hit boss yet gap - dmgList.Add(new int[] { timeGraphed, 0 }); - } - - } - } - } - } - } - return dmgList; - } - /// - /// Gets the points for the boss dps graph for a given player - /// - /// The player - /// - private List getBossDPSGraph(AbstractPlayer p, int phase_index) - { - return getDPSGraph(p, phase_index, getBossData().getInstid()); - } - /// - /// Gets the points for the total dps graph for a given player - /// - /// The player - /// - private List getTotalDPSGraph(AbstractPlayer p, int phase_index) - { - return getDPSGraph(p, phase_index, 0); - } - /// + /// /// Creates the dps graph /// /// Stream writer @@ -778,7 +723,7 @@ private void CreateDPSGraph(StreamWriter sw, int phase_index) foreach (Player p in p_list) { //Adding dps axis - List playerbossdpsgraphdata = new List(getBossDPSGraph(p, phase_index)); + List playerbossdpsgraphdata = new List(HTMLHelper.getBossDPSGraph(boss_data, combat_data, agent_data,p, boss, phase_index)); if (totalDpsAllPlayers.Count == 0) { //totalDpsAllPlayers = new List(playerbossdpsgraphdata); @@ -846,7 +791,7 @@ private void CreateDPSGraph(StreamWriter sw, int phase_index) {//Turns display on or off sw.Write("{"); //Adding dps axis - List playertotaldpsgraphdata = getTotalDPSGraph(p,phase_index); + List playertotaldpsgraphdata = HTMLHelper.getTotalDPSGraph(boss_data, combat_data, agent_data,p,boss,phase_index); sw.Write("y: ["); pbdgdCount = 0; foreach (int[] dp in playertotaldpsgraphdata) @@ -958,7 +903,7 @@ private void CreateDPSGraph(StreamWriter sw, int phase_index) int mechcount = 0; foreach (MechanicLog ml in filterdList) { - int[] check = getBossDPSGraph(ml.GetPlayer(), phase_index).FirstOrDefault(x => x[0] == ml.GetTime()); + int[] check = HTMLHelper.getBossDPSGraph(boss_data, combat_data, agent_data,ml.GetPlayer(), boss, phase_index).FirstOrDefault(x => x[0] == ml.GetTime()); if (mechcount == filterdList.Count - 1) { if (check != null) @@ -1048,7 +993,7 @@ private void CreateDPSGraph(StreamWriter sw, int phase_index) sw.Write("y: ["); foreach (MechanicLog ml in DnDList) { - int[] check = getBossDPSGraph(ml.GetPlayer(), phase_index).FirstOrDefault(x => x[0] == ml.GetTime()); + int[] check = HTMLHelper.getBossDPSGraph(boss_data, combat_data, agent_data, ml.GetPlayer(),boss, phase_index).FirstOrDefault(x => x[0] == ml.GetTime()); if (mcount == DnDList.Count - 1) { if (check != null) @@ -1105,7 +1050,7 @@ private void CreateDPSGraph(StreamWriter sw, int phase_index) sw.Write("visible:'legendonly',"); } sw.Write("type:'scatter'," + - "marker:{" + getMechData().GetPLoltyShape(state) + "size: 15" + "}," + + "marker:{" + mech_data.GetPLoltyShape(state) + "size: 15" + "}," + "text:["); foreach (MechanicLog ml in DnDList) { @@ -1223,12 +1168,8 @@ private void GetRoles() } private void PrintWeapons(StreamWriter sw, Player p) { - SkillData s_data = getSkillData(); - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - AgentData a_data = getAgentData(); //print weapon sets - string[] wep = p.getWeaponsArray(s_data,c_data,b_data,a_data); + string[] wep = p.getWeaponsArray(skill_data,combat_data,boss_data,agent_data); sw.Write("
"); if (wep[0] != null) { @@ -1359,7 +1300,7 @@ private void CreateCompTable(StreamWriter sw) { /// Duration of the fight private void CreateDPSTable(StreamWriter sw, int phase_index) { //generate dps table - PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; sw.Write(""); sw.Write("
"); { @@ -1388,8 +1329,8 @@ private void CreateDPSTable(StreamWriter sw, int phase_index) { sw.Write(""); foreach (Player player in p_list) { - string[] dmg = getFinalDPS(player, phase_index).Split('|'); - string[] stats = getFinalStats(player, phase_index); + string[] dmg = HTMLHelper.getFinalDPS(boss_data,combat_data, agent_data,player,boss, phase_index).Split('|'); + string[] stats = HTMLHelper.getFinalStats(boss_data, combat_data, agent_data,player,boss, phase_index); //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), dmg[0], dmg[1], dmg[2], dmg[3], dmg[4], dmg[5], dmg[6], dmg[7], dmg[8], dmg[9], dmg[10], dmg[11] }); sw.Write(""); @@ -1475,7 +1416,7 @@ private void CreateDPSTable(StreamWriter sw, int phase_index) { /// Duration of the fight private void CreateDMGStatsTable(StreamWriter sw, int phase_index) { //generate dmgstats table - PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; sw.Write(""); sw.Write("
"); { @@ -1508,7 +1449,7 @@ private void CreateDMGStatsTable(StreamWriter sw, int phase_index) { { foreach (Player player in p_list) { - string[] stats = getFinalStats(player, phase_index); + string[] stats = HTMLHelper.getFinalStats(boss_data,combat_data,agent_data,player,boss, phase_index); TimeSpan timedead = TimeSpan.FromMilliseconds(Double.Parse(stats[9]));//dead //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[0], stats[1], stats[2], stats[3], stats[4], stats[10], stats[11], stats[12], stats[13], stats[5], stats[6] }); @@ -1606,7 +1547,7 @@ private void CreateDMGStatsTable(StreamWriter sw, int phase_index) { /// Duration of the fight private void CreateDefTable(StreamWriter sw, int phase_index) { //generate Tankstats table - PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; sw.Write(""); sw.Write("
"); { @@ -1635,7 +1576,7 @@ private void CreateDefTable(StreamWriter sw, int phase_index) { { foreach (Player player in p_list) { - string[] stats = getFinalDefenses(player, phase_index); + string[] stats = HTMLHelper.getFinalDefenses(boss_data,combat_data,agent_data,mech_data,player,boss, phase_index); TimeSpan timedead = TimeSpan.FromMilliseconds(Double.Parse(stats[9]));//dead //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[0], stats[10], stats[1], stats[3], stats[6], stats[5], stats[8] }); @@ -1740,7 +1681,7 @@ private void CreateSupTable(StreamWriter sw, int phase_index) { { foreach (Player player in p_list) { - string[] stats = getFinalSupport(player, phase_index); + string[] stats = HTMLHelper.getFinalSupport(boss_data,combat_data,agent_data,player, boss,phase_index); //gather data for footer footerList.Add(new string[] { player.getGroup().ToString(), stats[3], stats[2], stats[1], stats[0] }); sw.Write(""); @@ -1822,7 +1763,7 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t { foreach (Player player in p_list) { - Dictionary boonArray = getfinalboons(player); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player); List boonArrayToList = new List(); boonArrayToList.Add(player.getGroup()); int count = 0; @@ -1833,8 +1774,8 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t sw.Write(""); if (boonTable) { - long fight_duration = getBossData().getLastAware() - getBossData().getFirstAware(); - Dictionary boonPresence = player.getBoonPresence(getBossData(), getSkillData(), getCombatData().getCombatList()); + long fight_duration = boss_data.getLastAware() - boss_data.getFirstAware(); + Dictionary boonPresence = player.getBoonPresence(boss_data, skill_data, combat_data.getCombatList()); double avg_boons = 0.0; foreach(Boon boon in list_to_use) { @@ -1961,7 +1902,7 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string { List playerID = new List(); playerID.Add(player); - Dictionary boonArray = getfinalboons(player, playerID); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerID); sw.Write(""); { sw.Write(""); @@ -2024,7 +1965,7 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string if (p.getGroup() == player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = getfinalboons(player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); playerIDS.Clear(); sw.Write(""); { @@ -2079,7 +2020,7 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin if (p.getGroup() != player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = getfinalboons(player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); playerIDS.Clear(); sw.Write(""); { @@ -2140,7 +2081,7 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string } foreach (Player player in p_list) { - Dictionary boonArray = getfinalboons(player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); sw.Write(""); { sw.Write(""); @@ -2173,19 +2114,16 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string /// Settings to use private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_index) { - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - long start = phase.start + b_data.getFirstAware(); - long end = phase.end + b_data.getFirstAware(); - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + long start = phase.start + boss_data.getFirstAware(); + long end = phase.end + boss_data.getFirstAware(); + List s_list = skill_data.getSkillList(); //generate Player list Graphs foreach (Player p in p_list) { - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + List casting = p.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.start, phase.end); - bool died = p.getDeath(b_data, c_data.getCombatList(), phase.start, phase.end) > 0; + bool died = p.getDeath(boss_data, combat_data.getCombatList(), phase.start, phase.end) > 0; string charname = p.getCharacter(); string pid = p.getInstid() + "_" + phase_index; sw.Write("
"); @@ -2205,7 +2143,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind } //foreach pet loop here - foreach (AgentItem agent in p.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) + foreach (AgentItem agent in p.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) { sw.Write("
  • " + agent.getName() + "
  • "); } @@ -2217,7 +2155,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind { sw.Write("
    "); { - List consume = p.getConsumablesList(b_data, s_data, c_data.getCombatList(), phase.start, phase.end); + List consume = p.getConsumablesList(boss_data, skill_data, combat_data.getCombatList(), phase.start, phase.end); List initial = consume.Where(x => x[1] == 0).ToList(); List refreshed = consume.Where(x => x[1] > 0).ToList(); if (initial.Count() > 0) @@ -2301,7 +2239,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind } if (skill == null) { - skillName = s_data.getName(cl.getID()); + skillName = skill_data.getName(cl.getID()); } else { @@ -2420,7 +2358,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind { parseBoonsList.AddRange(present_personnal[p.getInstid()]); } - Dictionary boonGraphData = p.getBoonGraphs(getBossData(), getSkillData(), getCombatData().getCombatList()); + Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList()); foreach (int boonid in boonGraphData.Keys.Reverse()) { if (parseBoonsList.FirstOrDefault(x => x.getID() == boonid) != null || boonid == -2) @@ -2428,7 +2366,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind sw.Write("{"); { BoonsGraphModel bgm = boonGraphData[boonid]; - List bChart = bgm.getBoonChart().Where(x => x.X >= phase.start / 1000 && x.X < phase.end / 1000).ToList(); + List bChart = bgm.getBoonChart().Where(x => x.X >= phase.start / 1000 && x.X <= phase.end / 1000).ToList(); int bChartCount = 0; sw.Write("y: ["); { @@ -2493,7 +2431,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind if (SnapSettings[2]) {//show boss dps plot //Adding dps axis - List playerbossdpsgraphdata = getBossDPSGraph(p, phase_index); + List playerbossdpsgraphdata = HTMLHelper.getBossDPSGraph(boss_data,combat_data,agent_data,p, boss,phase_index); int pbdgCount = 0; sw.Write("{"); { @@ -2557,7 +2495,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind {//show total dps plot sw.Write("{"); { //Adding dps axis - List playertotaldpsgraphdata = getTotalDPSGraph(p, phase_index); + List playertotaldpsgraphdata = HTMLHelper.getTotalDPSGraph(boss_data,combat_data,agent_data,p,boss, phase_index); int ptdgCount = 0; sw.Write("y: ["); { @@ -2735,7 +2673,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind sw.Write("
    "); } sw.Write("
    "); - foreach (AgentItem agent in p.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) + foreach (AgentItem agent in p.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) { string id = pid + "_" + agent.getInstid(); sw.Write("
    "); @@ -2805,18 +2743,14 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize, int phase_index) { if (SnapSettings[6])//Display rotation { - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List casting = p.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.start, phase.end); GW2APISkill autoSkill = null; int autosCount = 0; foreach (CastLog cl in casting) { GW2APISkill apiskill = null; - SkillItem skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()); + SkillItem skill = skill_data.getSkillList().FirstOrDefault(x => x.getID() == cl.getID()); if (skill != null) { apiskill = skill.GetGW2APISkill(); @@ -2898,22 +2832,18 @@ private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize, /// The player private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) { - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - AgentData a_data = getAgentData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; - List damageLogs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData(), getMechData(), phase.start, phase.end); - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); - long start = phase.start + b_data.getFirstAware(); - long end = phase.end + b_data.getFirstAware(); - List down = getCombatData().getStates(p.getInstid(), "CHANGE_DOWN", start, end); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List damageLogs = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data, phase.start, phase.end); + List s_list = skill_data.getSkillList(); + long start = phase.start + boss_data.getFirstAware(); + long end = phase.end + boss_data.getFirstAware(); + List down = combat_data.getStates(p.getInstid(), "CHANGE_DOWN", start, end); if (down.Count > 0) { - List ups = getCombatData().getStates(p.getInstid(), "CHANGE_UP", start, end); + List ups = combat_data.getStates(p.getInstid(), "CHANGE_UP", start, end); down = down.GetRange(ups.Count(), down.Count()-ups.Count()); } - List dead = getCombatData().getStates(p.getInstid(), "CHANGE_DEAD", start, end); + List dead = combat_data.getStates(p.getInstid(), "CHANGE_DEAD", start, end); List damageToDown = new List(); List damageToKill = new List(); if (down.Count > 0) @@ -3039,14 +2969,14 @@ private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) { for (int d = 0; d < damageToDown.Count(); d++) { - sw.Write("'" + a_data.GetAgentWInst(damageToDown[d].getInstidt()).getName().Replace("\0", "").Replace("\'", "\\'") + "
    "+ - s_data.getName( damageToDown[d].getID()).Replace("\'", "\\'") + " hit you for "+damageToDown[d].getDamage() + "',"); + sw.Write("'" + agent_data.GetAgentWInst(damageToDown[d].getInstidt()).getName().Replace("\0", "").Replace("\'", "\\'") + "
    "+ + skill_data.getName( damageToDown[d].getID()).Replace("\'", "\\'") + " hit you for "+damageToDown[d].getDamage() + "',"); } } for (int d = 0; d < damageToKill.Count(); d++) { - sw.Write("'" + a_data.GetAgentWInst(damageToKill[d].getInstidt()).getName().Replace("\0","").Replace("\'", "\\'") + "
    " + - "hit you with "+ s_data.getName(damageToKill[d].getID()).Replace("\'", "\\'") + " for " + damageToKill[d].getDamage() + "'"); + sw.Write("'" + agent_data.GetAgentWInst(damageToKill[d].getInstidt()).getName().Replace("\0","").Replace("\'", "\\'") + "
    " + + "hit you with "+ skill_data.getName(damageToKill[d].getID()).Replace("\'", "\\'") + " for " + damageToKill[d].getDamage() + "'"); if (d != damageToKill.Count() - 1) { @@ -3072,12 +3002,11 @@ private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) /// The player private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, int phase_index) { - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - List damageLogs = p.getJustPlayerDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List casting = p.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.start, phase.end); + List damageLogs = p.getJustPlayerDamageLogs(toBoss ? boss_data.getInstid() : 0, boss_data, combat_data.getCombatList(), agent_data, phase.start, phase.end); + string finalDPSdata = HTMLHelper.getFinalDPS(boss_data, combat_data, agent_data, p, boss, phase_index); + int totalDamage = toBoss ? Int32.Parse(finalDPSdata.Split('|')[7]) : Int32.Parse(finalDPSdata.Split('|')[1]); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) { @@ -3088,8 +3017,7 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, sw.Write(""); sw.Write("
    " + "\""" + "
    " + player.getGroup().ToString() + "
    " + player.getGroup().ToString() + "
    "); { - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); + List s_list = skill_data.getSkillList(); sw.Write(""); { sw.Write(""); @@ -3465,12 +3393,11 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, /// The minion private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, AgentItem agent, bool toBoss, int phase_index) { - int totalDamage = toBoss ? Int32.Parse(getFinalDPS(p, phase_index).Split('|')[7]) : Int32.Parse(getFinalDPS(p, phase_index).Split('|')[1]); + string finalDPSdata = HTMLHelper.getFinalDPS(boss_data, combat_data, agent_data, p, boss, phase_index); + int totalDamage = toBoss ? Int32.Parse(finalDPSdata.Split('|')[7]) : Int32.Parse(finalDPSdata.Split('|')[1]); string tabid = p.getInstid() +"_"+phase_index + "_" + agent.getInstid() + (toBoss ? "_boss" : ""); - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List damageLogs = p.getMinionsDamageLogs(toBoss ? b_data.getInstid() : 0, b_data, c_data.getCombatList(), getAgentData())[agent].Where(x => x.getTime() >= phase.start && x.getTime() < phase.end).ToList(); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List damageLogs = p.getMinionsDamageLogs(toBoss ? boss_data.getInstid() : 0, boss_data, combat_data.getCombatList(), agent_data)[agent].Where(x => x.getTime() >= phase.start && x.getTime() <= phase.end).ToList(); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) { @@ -3480,7 +3407,7 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, AgentItem age sw.Write(""); sw.Write("
    "); { - SkillData s_data = getSkillData(); + SkillData s_data = skill_data; List s_list = s_data.getSkillList(); sw.Write(""); { @@ -3669,12 +3596,9 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, AgentItem age /// The player private void CreateDMGTakenDistTable(StreamWriter sw, Player p, int phase_index) { - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List damageLogs = p.getDamageTakenLogs( b_data, c_data.getCombatList(), getAgentData(),getMechData(), phase.start, phase.end); - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List damageLogs = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data,mech_data, phase.start, phase.end); + List s_list = skill_data.getSkillList(); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; string pid = p.getInstid() + "_" + phase_index; sw.Write(""); @@ -3815,7 +3739,7 @@ private void CreateDMGTakenDistTable(StreamWriter sw, Player p, int phase_index) /// Stream writer private void CreateMechanicTable(StreamWriter sw, int phase_index) { Dictionary> presMech = new Dictionary>(); - PhaseData phase = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData())[phase_index]; + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; foreach (Mechanic item in mech_data.GetMechList(boss_data.getID())) { if (mech_data.GetMDataLogs().FirstOrDefault(x => x.GetSkill() == item.GetSkill()) != null) @@ -3858,7 +3782,7 @@ private void CreateMechanicTable(StreamWriter sw, int phase_index) { int count = 0; foreach (Mechanic mech in mechs) { - List test = mech_data.GetMDataLogs().Where(x => x.GetSkill() == mech.GetSkill() && x.GetPlayer() == p && x.GetTime() >= phase.start / 1000 && x.GetTime() < phase.end / 1000).ToList(); + List test = mech_data.GetMDataLogs().Where(x => x.GetSkill() == mech.GetSkill() && x.GetPlayer() == p && x.GetTime() >= phase.start / 1000 && x.GetTime() <= phase.end / 1000).ToList(); count += test.Count(); } sw.Write(""); @@ -3982,8 +3906,7 @@ private void CreateEventList(StreamWriter sw) { private void CreateSkillList(StreamWriter sw) { sw.Write("
      "); { - SkillData s_data = getSkillData(); - foreach (SkillItem skill in s_data.getSkillList()) + foreach (SkillItem skill in skill_data.getSkillList()) { sw.Write("
    • " + skill.getID() + " : " + skill.getName() + @@ -4021,7 +3944,7 @@ private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) sw.Write("
    "); { sw.Write(""); - Dictionary boonArray = getfinalcondis(boss); + Dictionary boonArray = HTMLHelper.getfinalcondis(boss_data,combat_data,skill_data,boss); foreach (Boon boon in Boon.getCondiBoonList()) { sw.Write(""); @@ -4040,12 +3963,9 @@ private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) private void CreateBossSummary(StreamWriter sw, int phase_index) { //generate Player list Graphs - CombatData c_data = getCombatData(); - BossData b_data = getBossData(); - PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), getAgentData())[phase_index]; - List casting = boss.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), phase.start, phase.end); - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); + PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List casting = boss.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.start, phase.end); + List s_list = skill_data.getSkillList(); string charname = boss.getCharacter(); string pid = boss.getInstid() + "_" + phase_index; sw.Write("

    " + charname + "

    "); @@ -4053,7 +3973,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) { sw.Write("
  • " + boss.getCharacter() + "
  • "); //foreach pet loop here - foreach (AgentItem agent in boss.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) + foreach (AgentItem agent in boss.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) { sw.Write("
  • " + agent.getName() + "
  • "); } @@ -4082,7 +4002,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) } if (skill == null) { - skillName = s_data.getName(cl.getID()); + skillName = skill_data.getName(cl.getID()); } else { @@ -4197,7 +4117,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) parseBoonsList.AddRange(Boon.getCondiBoonList()); //Every buffs and boons parseBoonsList.AddRange(Boon.getAllBuffList()); - Dictionary boonGraphData = boss.getBoonGraphs(getBossData(), getSkillData(),getCombatData().getCombatList()); + Dictionary boonGraphData = boss.getBoonGraphs(boss_data, skill_data,combat_data.getCombatList()); foreach (int boonid in boonGraphData.Keys.Reverse()) { if (parseBoonsList.FirstOrDefault(x => x.getID() == boonid) != null) @@ -4206,7 +4126,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) { BoonsGraphModel bgm = boonGraphData[boonid]; - List bChart = bgm.getBoonChart().Where(x => x.X >= phase.start / 1000 && x.X < phase.end/1000).ToList(); + List bChart = bgm.getBoonChart().Where(x => x.X >= phase.start / 1000 && x.X <= phase.end/1000).ToList(); int bChartCount = 0; sw.Write("y: ["); { @@ -4272,7 +4192,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) {//show total dps plot sw.Write("{"); //Adding dps axis - List playertotaldpsgraphdata = getTotalDPSGraph(boss, phase_index); + List playertotaldpsgraphdata = HTMLHelper.getTotalDPSGraph(boss_data,combat_data,agent_data,boss,boss, phase_index); sw.Write("y: ["); int ptdgCount = 0; foreach (int[] dp in playertotaldpsgraphdata) @@ -4420,7 +4340,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) sw.Write(" "); CreateDMGDistTable(sw, boss, false, phase_index); sw.Write(""); - foreach (AgentItem agent in boss.getMinionsDamageLogs(0, b_data, c_data.getCombatList(), getAgentData()).Keys) + foreach (AgentItem agent in boss.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) { sw.Write("
    "); { @@ -4508,17 +4428,16 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { SnapSettings = settingsSnap; - BossData b_data = getBossData(); - double fight_duration = (b_data.getLastAware() - b_data.getFirstAware()) / 1000.0; + double fight_duration = (boss_data.getAwareDuration()) / 1000.0; TimeSpan duration = TimeSpan.FromSeconds(fight_duration); string durationString = duration.ToString("mm") + "m " + duration.ToString("ss") + "s"; if (duration.ToString("hh") != "00") { durationString = duration.ToString("hh") + "h " + durationString; } - string bossname = FilterStringChars(b_data.getName()); + string bossname = FilterStringChars(boss_data.getName()); setPresentBoons(settingsSnap); - List phases = boss.getPhases(getBossData(), getCombatData().getCombatList(), getAgentData()); + List phases = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data); // HTML STARTS sw.Write(""); { @@ -4567,7 +4486,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { sw.Write("
    "); { - sw.Write(""); + sw.Write(""); } sw.Write("
    "); sw.Write("
    "); @@ -4576,7 +4495,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { if (log_data.getBosskill()) { - string tp = getBossData().getHealth().ToString() + " Health"; + string tp = boss_data.getHealth().ToString() + " Health"; sw.Write("
    "); } else @@ -4586,15 +4505,15 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { finalPercent = 100.0 - boss_data.getHealthOverTime()[boss_data.getHealthOverTime().Count - 1][1] * 0.01; } - string tp = Math.Round(getBossData().getHealth() * finalPercent / 100.0) + " Health"; + string tp = Math.Round(boss_data.getHealth() * finalPercent / 100.0) + " Health"; sw.Write("
    "); - tp = Math.Round(getBossData().getHealth() * (100.0-finalPercent) / 100.0) + " Health"; + tp = Math.Round(boss_data.getHealth() * (100.0-finalPercent) / 100.0) + " Health"; sw.Write("
    "); } } sw.Write("
    "); - sw.Write("

    " + getBossData().getHealth().ToString() + " Health

    "); + sw.Write("

    " + boss_data.getHealth().ToString() + " Health

    "); if (log_data.getBosskill()) { sw.Write("

    Result: Success

    "); @@ -4962,7 +4881,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) sw.Write("

    Phase " + i + " started at " + phases[i].start / 1000 + "s and ended at " + phases[i].end / 1000 + "s

    "); } sw.Write("
    "); - sw.Write("

    ARC:" + getLogData().getBuildVersion().ToString() + " | Bossid " + getBossData().getID().ToString() + "

    "); + sw.Write("

    ARC:" + log_data.getBuildVersion().ToString() + " | Bossid " + boss_data.getID().ToString() + "

    "); sw.Write("

    File recorded by: " + log_data.getPOV() + "

    "); } sw.Write(""); @@ -4976,15 +4895,10 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) } public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) { - BossData b_data = getBossData(); - double fight_duration = (b_data.getLastAware() - b_data.getFirstAware()) / 1000.0; - Player p = p_list[0]; - - CombatData c_data = getCombatData(); - - List casting = p.getCastLogs(b_data, c_data.getCombatList(), getAgentData(), 0, b_data.getAwareDuration()); - SkillData s_data = getSkillData(); - List s_list = s_data.getSkillList(); + double fight_duration = (boss_data.getAwareDuration()) / 1000.0; + Player p = p_list[0]; + List casting = p.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, 0, boss_data.getAwareDuration()); + List s_list = skill_data.getSkillList(); CreateDPSTable(sw, 0); CreateDMGStatsTable(sw, 0); @@ -5010,7 +4924,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) } if (skill == null) { - skillName = s_data.getName(cl.getID()); + skillName = skill_data.getName(cl.getID()); } else { @@ -5129,7 +5043,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) { parseBoonsList.AddRange(present_personnal[p.getInstid()]); } - Dictionary boonGraphData = p.getBoonGraphs(getBossData(), getSkillData(), getCombatData().getCombatList()); + Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList()); foreach (int boonid in boonGraphData.Keys.Reverse()) { if (parseBoonsList.FirstOrDefault(x => x.getID() == boonid) != null) @@ -5202,7 +5116,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) if (SnapSettings[2]) {//show boss dps plot //Adding dps axis - List playerbossdpsgraphdata = getBossDPSGraph(p, 0); + List playerbossdpsgraphdata = HTMLHelper.getBossDPSGraph(boss_data,combat_data,agent_data,p,boss, 0); int pbdgCount = 0; sw.Write("{"); { @@ -5266,7 +5180,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) {//show total dps plot sw.Write("{"); { //Adding dps axis - List playertotaldpsgraphdata = getTotalDPSGraph(p,0); + List playertotaldpsgraphdata = HTMLHelper.getTotalDPSGraph(boss_data,combat_data,agent_data,p, boss,0); int ptdgCount = 0; sw.Write("y: ["); { @@ -5446,8 +5360,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) //Creating CSV--------------------------------------------------------------------------------- public void CreateCSV(StreamWriter sw,String delimiter) { - BossData b_data = getBossData(); - double fight_duration = (b_data.getLastAware() - b_data.getFirstAware()) / 1000.0; + double fight_duration = (boss_data.getAwareDuration()) / 1000.0; TimeSpan duration = TimeSpan.FromSeconds(fight_duration); String durationString = duration.ToString("mm") +":" + duration.ToString("ss") ; @@ -5472,7 +5385,7 @@ public void CreateCSV(StreamWriter sw,String delimiter) int[] teamStats= { 0,0,0}; foreach (Player p in p_list) { - string[] finaldps = getFinalDPS(p, 0).Split('|'); + string[] finaldps = HTMLHelper.getFinalDPS(boss_data,combat_data,agent_data,p,boss, 0).Split('|'); teamStats[0] += Int32.Parse(finaldps[6]); teamStats[1] += Int32.Parse(finaldps[0]); teamStats[2] += (Int32.Parse(finaldps[0]) - Int32.Parse(finaldps[6])); @@ -5480,7 +5393,7 @@ public void CreateCSV(StreamWriter sw,String delimiter) foreach (Player p in p_list) { - string[] finaldps = getFinalDPS(p, 0).Split('|'); + string[] finaldps = HTMLHelper.getFinalDPS(boss_data, combat_data, agent_data, p, boss, 0).Split('|'); sw.Write(p.getGroup() + delimiter + // group p.getProf() + delimiter + // class p.getCharacter() + delimiter + // character @@ -5490,7 +5403,7 @@ public void CreateCSV(StreamWriter sw,String delimiter) finaldps[10] + delimiter + // condi finaldps[0] + delimiter); // all dps - Dictionary boonArray = getfinalboons(p); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,p); sw.Write(boonArray[1187] + delimiter + // Quickness boonArray[30328] + delimiter + // Alacrity boonArray[740] + delimiter); // Might diff --git a/LuckParser/Controllers/HTMLHelper.cs b/LuckParser/Controllers/HTMLHelper.cs new file mode 100644 index 000000000..41c6b3680 --- /dev/null +++ b/LuckParser/Controllers/HTMLHelper.cs @@ -0,0 +1,490 @@ +using LuckParser.Models.ParseModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static LuckParser.Models.ParseModels.Boss; + +namespace LuckParser.Controllers +{ + class HTMLHelper + { + + public static string getFinalDPS(BossData b_data, CombatData c_data, AgentData a_data, AbstractPlayer p, Boss boss, int phase_index) + { + int totalboss_dps = 0; + int totalboss_damage = 0; + int totalbosscondi_dps = 0; + int totalbosscondi_damage = 0; + int totalbossphys_dps = 0; + int totalbossphys_damage = 0; + int totalAll_dps = 0; + int totalAll_damage = 0; + int totalAllcondi_dps = 0; + int totalAllcondi_damage = 0; + int totalAllphys_dps = 0; + int totalAllphys_damage = 0; + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + double fight_duration = (phase.end - phase.start) / 1000.0; + + double damage = 0.0; + double dps = 0.0; + // All DPS + + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), a_data, phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalAll_dps = (int)dps; + totalAll_damage = (int)damage; + //Allcondi + damage = p.getDamageLogs(0, b_data, c_data.getCombatList(), a_data, phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalAllcondi_dps = (int)dps; + totalAllcondi_damage = (int)damage; + //All Power + damage = totalAll_damage - damage; + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalAllphys_dps = (int)dps; + totalAllphys_damage = (int)damage; + + // boss DPS + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), a_data, phase.start, phase.end).Sum(x => x.getDamage());//p.getDamageLogs(b_data, c_data.getCombatList()).stream().mapToDouble(DamageLog::getDamage).sum(); + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalboss_dps = (int)dps; + totalboss_damage = (int)damage; + //bosscondi + damage = p.getDamageLogs(b_data.getInstid(), b_data, c_data.getCombatList(), a_data, phase.start, phase.end).Where(x => x.isCondi() > 0).Sum(x => x.getDamage()); + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalbosscondi_dps = (int)dps; + totalbosscondi_damage = (int)damage; + //boss Power + damage = totalboss_damage - damage; + if (fight_duration > 0) + { + dps = damage / fight_duration; + } + totalbossphys_dps = (int)dps; + totalbossphys_damage = (int)damage; + //Placeholders for further calc + return totalAll_dps.ToString() + "|" + totalAll_damage.ToString() + "|" + totalAllphys_dps.ToString() + "|" + totalAllphys_damage.ToString() + "|" + totalAllcondi_dps.ToString() + "|" + totalAllcondi_damage.ToString() + "|" + + totalboss_dps.ToString() + "|" + totalboss_damage.ToString() + "|" + totalbossphys_dps.ToString() + "|" + totalbossphys_damage.ToString() + "|" + totalbosscondi_dps.ToString() + "|" + totalbosscondi_damage.ToString(); + } + public static string[] getFinalStats(BossData b_data, CombatData c_data, AgentData a_data, Player p, Boss boss, int phase_index) + { + String[] statsArray; + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List damage_logs = p.getDamageLogs(0, b_data, c_data.getCombatList(), a_data, phase.start, phase.end); + List cast_logs = p.getCastLogs(b_data, c_data.getCombatList(), a_data, phase.start, phase.end); + int instid = p.getInstid(); + + // Rates + int power_loop_count = 0; + int critical_rate = 0; + int scholar_rate = 0; + int scholar_dmg = 0; + int totaldamage = damage_logs.Sum(x => x.getDamage()); + + int moving_rate = 0; + int flanking_rate = 0; + //glancerate + int glance_rate = 0; + //missed + int missed = 0; + //interupted + int interupts = 0; + //times enemy invulned + int invulned = 0; + + //timeswasted + int wasted = 0; + double time_wasted = 0; + //Time saved + int saved = 0; + double time_saved = 0; + //avgboons + double avgBoons = 0.0; + + foreach (DamageLog log in damage_logs) + { + if (log.isCondi() == 0) + { + if (log.getResult().getEnum() == "CRIT") + { + critical_rate++; + } + if (log.isNinety() > 0) + { + scholar_rate++; + + scholar_dmg += (int)(log.getDamage() / 11.0); //regular+10% damage + } + //scholar_rate += log.isNinety(); + moving_rate += log.isMoving(); + flanking_rate += log.isFlanking(); + if (log.getResult().getEnum() == "GLANCE") + { + glance_rate++; + } + if (log.getResult().getEnum() == "BLIND") + { + missed++; + } + if (log.getResult().getEnum() == "INTERRUPT") + { + interupts++; + } + if (log.getResult().getEnum() == "ABSORB") + { + invulned++; + } + //if (log.isActivation().getEnum() == "CANCEL_FIRE" || log.isActivation().getEnum() == "CANCEL_CANCEL") + //{ + // wasted++; + // time_wasted += log.getDamage(); + //} + power_loop_count++; + } + } + foreach (CastLog cl in cast_logs) + { + if (cl.endActivation() != null) + { + if (cl.endActivation().getID() == 4) + { + wasted++; + time_wasted += cl.getActDur(); + } + if (cl.endActivation().getID() == 3) + { + saved++; + if (cl.getActDur() < cl.getExpDur()) + { + time_saved += cl.getExpDur() - cl.getActDur(); + } + } + } + } + + power_loop_count = (power_loop_count == 0) ? 1 : power_loop_count; + + // Counts + int swap = c_data.getStates(instid, "WEAPON_SWAP", start, end).Count(); + int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); + int dodge = c_data.getSkillCount(instid, 65001, start, end) + c_data.getBuffCount(instid, 40408, start, end);//dodge = 65001 mirage cloak =40408 + int ress = c_data.getSkillCount(instid, 1066, start, end); //Res = 1066 + + // R.I.P + List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); + + double died = 0.0; + if (dead.Count() > 0) + { + died = dead[0].getTime() - start; + } + List disconect = c_data.getStates(instid, "DESPAWN", start, end); + double dcd = 0.0; + if (disconect.Count() > 0) + { + dcd = disconect[0].getTime() - start; + } + statsArray = new string[] { power_loop_count.ToString(), + critical_rate.ToString(), + scholar_rate.ToString(), + moving_rate.ToString(), + flanking_rate.ToString(), + swap.ToString(), + down.ToString(), + dodge.ToString(), + ress.ToString(), + died.ToString("0.00"), + glance_rate.ToString(), + missed.ToString(), + interupts.ToString(), + invulned.ToString(), + (time_wasted/1000f).ToString(), + wasted.ToString(), + avgBoons.ToString(), + (time_saved/1000f).ToString(), + saved.ToString(), + scholar_dmg.ToString(), + totaldamage.ToString(), + dcd.ToString("0.00"), + }; + return statsArray; + } + public static string[] getFinalDefenses(BossData b_data, CombatData c_data, AgentData a_data, MechanicData m_data, Player p, Boss boss, int phase_index) + { + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), a_data, m_data, phase.start, phase.end); + int instid = p.getInstid(); + + int damagetaken = damage_logs.Select(x => x.getDamage()).Sum(); + int blocked = 0; + //int dmgblocked = 0; + int invulned = 0; + int dmginvulned = 0; + int dodge = c_data.getSkillCount(instid, 65001, start, end);//dodge = 65001 + dodge += c_data.getBuffCount(instid, 40408, start, end);//mirage cloak add + int evades = 0; + //int dmgevaded = 0; + int dmgBarriar = 0; + foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "BLOCK")) + { + blocked++; + //dmgblocked += log.getDamage(); + } + foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "ABSORB")) + { + invulned++; + dmginvulned += log.getDamage(); + } + foreach (DamageLog log in damage_logs.Where(x => x.getResult().getEnum() == "EVADE")) + { + evades++; + // dmgevaded += log.getDamage(); + } + foreach (DamageLog log in damage_logs.Where(x => x.isShields() == 1)) + { + + dmgBarriar += log.getDamage(); + } + int down = c_data.getStates(instid, "CHANGE_DOWN", start, end).Count(); + // R.I.P + List dead = c_data.getStates(instid, "CHANGE_DEAD", start, end); + double died = 0.0; + if (dead.Count() > 0) + { + died = dead[0].getTime() - start; + } + String[] statsArray = new string[] { damagetaken.ToString(), + blocked.ToString(), + "0"/*dmgblocked.ToString()*/, + invulned.ToString(), + dmginvulned.ToString(), + dodge.ToString(), + evades.ToString(), + "0"/*dmgevaded.ToString()*/, + down.ToString(), + died.ToString("0.00"), + dmgBarriar.ToString()}; + return statsArray; + } + //(currently not correct) + public static string[] getFinalSupport(BossData b_data, CombatData c_data, AgentData a_data, Player p, Boss boss, int phase_index) + { + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + long start = phase.start + b_data.getFirstAware(); + long end = phase.end + b_data.getFirstAware(); + // List damage_logs = p.getDamageTakenLogs(b_data, c_data.getCombatList(), getAgentData()); + int instid = p.getInstid(); + int resurrects = 0; + double restime = 0.0; + int condiCleanse = 0; + double condiCleansetime = 0.0; + + int[] resArray = p.getReses(b_data, c_data.getCombatList(), a_data, phase.start, phase.end); + int[] cleanseArray = p.getCleanses(b_data, c_data.getCombatList(), a_data, phase.start, phase.end); + resurrects = resArray[0]; + restime = resArray[1]; + condiCleanse = cleanseArray[0]; + condiCleansetime = cleanseArray[1]; + + + String[] statsArray = new string[] { resurrects.ToString(), (restime / 1000f).ToString(), condiCleanse.ToString(), (condiCleansetime / 1000f).ToString() }; + return statsArray; + } + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, Player p) + { + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + Dictionary rates = new Dictionary(); + long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + foreach (Boon boon in Boon.getAllBuffList()) + { + string rate = "0"; + if (boon_distrib.ContainsKey(boon.getID())) + { + if (boon.getType() == Boon.BoonType.Duration) + { + rate = Math.Round(100.0 * boon_distrib.getUptime(boon.getID()) / fight_duration, 1) + "%"; + } + else if (boon.getType() == Boon.BoonType.Intensity) + { + rate = Math.Round((double)boon_distrib.getUptime(boon.getID()) / fight_duration, 1).ToString(); + } + + } + rates[boon.getID()] = rate; + } + return rates; + } + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, Player p, List trgetPlayers) + { + if (trgetPlayers.Count() == 0) + { + return getfinalboons(b_data, c_data, s_data, p); + } + long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + Dictionary boon_logsDist = new Dictionary(); + foreach (Player player in trgetPlayers) + { + boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + } + Dictionary rates = new Dictionary(); + foreach (Boon boon in Boon.getAllBuffList()) + { + string rate = "0"; + long total = 0; + long totaloverstack = 0; + foreach (Player player in trgetPlayers) + { + BoonDistribution boon_dist = boon_logsDist[player]; + if (boon_dist.ContainsKey(boon.getID())) + { + total += boon_dist.getGeneration(boon.getID(), p.getInstid()); + totaloverstack += boon_dist.getOverstack(boon.getID(), p.getInstid()); + } + } + totaloverstack += total; + if (total > 0) + { + if (boon.getType() == Boon.BoonType.Duration) + { + rate = "" + + Math.Round(100.0 * total / fight_duration / trgetPlayers.Count, 1) + + "%"; + } + else if (boon.getType() == Boon.BoonType.Intensity) + { + rate = "" + + Math.Round((double)total / fight_duration / trgetPlayers.Count, 1).ToString() + + ""; + } + + } + rates[boon.getID()] = rate; + } + return rates; + } + public static Dictionary getfinalcondis(BossData b_data, CombatData c_data, SkillData s_data, AbstractPlayer p) + { + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + Dictionary rates = new Dictionary(); + foreach (Boon boon in Boon.getCondiBoonList()) + { + rates[boon.getID()] = "0"; + if (boon_distrib.ContainsKey(boon.getID())) + { + string rate = "0"; + if (boon.getType() == Boon.BoonType.Duration) + { + long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + rate = Math.Round(100.0 * boon_distrib.getUptime(boon.getID()) / fight_duration, 1) + "%"; + } + else if (boon.getType() == Boon.BoonType.Intensity) + { + long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + rate = Math.Round((double)boon_distrib.getUptime(boon.getID()) / fight_duration, 1).ToString(); + } + + rates[boon.getID()] = rate; + } + } + return rates; + } + + public static List getDPSGraph(BossData b_data, CombatData c_data, AgentData a_data, AbstractPlayer p, Boss boss, int phase_index, ushort dstid) + { + List dmgList = new List(); + PhaseData phase = boss.getPhases(b_data, c_data.getCombatList(), a_data)[phase_index]; + List damage_logs = p.getDamageLogs(dstid, b_data, c_data.getCombatList(), a_data, phase.start, phase.end).Where(x => x.getTime() >= phase.start && x.getTime() <= phase.end).ToList(); + int totaldmg = 0; + + int timeGraphed = (int)phase.start; + foreach (DamageLog log in damage_logs) + { + + totaldmg += log.getDamage(); + + long time = log.getTime(); + if (time > 1000) + { + + //to reduce processing time only graph 1 point per sec + if (Math.Floor(time / 1000f) > timeGraphed) + { + + if ((Math.Floor(time / 1000f) - timeGraphed) < 2) + { + timeGraphed = (int)Math.Floor(time / 1000f); + dmgList.Add(new int[] { (int)time / 1000, (int)(totaldmg / (time / 1000f)) }); + } + else + { + int gap = (int)Math.Floor(time / 1000f) - timeGraphed; + bool startOfFight = true; + if (dmgList.Count > 0) + { + startOfFight = false; + } + + for (int itr = 0; itr < gap - 1; itr++) + { + timeGraphed++; + if (!startOfFight) + { + dmgList.Add(new int[] { timeGraphed, (int)(totaldmg / (float)timeGraphed) }); + } + else + {//hasnt hit boss yet gap + dmgList.Add(new int[] { timeGraphed, 0 }); + } + + } + } + } + } + } + return dmgList; + } + /// + /// Gets the points for the boss dps graph for a given player + /// + /// The player + /// + public static List getBossDPSGraph(BossData b_data, CombatData c_data, AgentData a_data, AbstractPlayer p, Boss boss, int phase_index) + { + return getDPSGraph(b_data, c_data, a_data, p, boss, phase_index, b_data.getInstid()); + } + /// + /// Gets the points for the total dps graph for a given player + /// + /// The player + /// + public static List getTotalDPSGraph(BossData b_data, CombatData c_data, AgentData a_data, AbstractPlayer p, Boss boss, int phase_index) + { + return getDPSGraph(b_data, c_data, a_data, p, boss, phase_index, 0); + } + + } +} diff --git a/LuckParser/Controllers/ParseHelper.cs b/LuckParser/Controllers/ParseHelper.cs index 3e0cf25b0..40ab39540 100644 --- a/LuckParser/Controllers/ParseHelper.cs +++ b/LuckParser/Controllers/ParseHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,7 +9,7 @@ namespace LuckParser.Controllers { class ParseHelper { - private void safeSkip(long bytes_to_skip) + public static void safeSkip(MemoryStream stream,long bytes_to_skip) { while (bytes_to_skip > 0) @@ -34,14 +35,7 @@ private void safeSkip(long bytes_to_skip) return; } - private int getbyte() - { - byte byt = Convert.ToByte(stream.ReadByte()); - // stream.Position++; - - return byt; - } - private ushort getShort() + public static ushort getShort(MemoryStream stream) { byte[] bytes = new byte[2]; for (int b = 0; b < bytes.Length; b++) @@ -52,7 +46,7 @@ private ushort getShort() // return Short.toUnsignedInt(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort()); return BitConverter.ToUInt16(bytes, 0); } - private int getInt() + public static int getInt(MemoryStream stream) { byte[] bytes = new byte[4]; for (int b = 0; b < bytes.Length; b++) @@ -63,7 +57,7 @@ private int getInt() //return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); return BitConverter.ToInt32(bytes, 0); } - private long getLong() + public static long getLong(MemoryStream stream) { byte[] bytes = new byte[8]; for (int b = 0; b < bytes.Length; b++) @@ -75,7 +69,7 @@ private long getLong() // return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong(); return BitConverter.ToInt64(bytes, 0); } - private String getString(int length) + public static string getString(MemoryStream stream, int length) { byte[] bytes = new byte[length]; for (int b = 0; b < bytes.Length; b++) @@ -92,473 +86,4 @@ private String getString(int length) return "UNKNOWN"; } } - - private void parseBossData() - { - // 12 bytes: arc build version - String build_version = getString(12); - this.log_data = new LogData(build_version); - - // 1 byte: skip - safeSkip(1); - - // 2 bytes: boss instance ID - ushort instid = getShort(); - - // 1 byte: position - safeSkip(1); - - //Save - // TempData["Debug"] = build_version +" "+ instid.ToString() ; - this.boss_data = new BossData(instid); - } - /// - /// Parses agent related data - /// - private void parseAgentData() - { - // 4 bytes: player count - int player_count = getInt(); - - // 96 bytes: each player - for (int i = 0; i < player_count; i++) - { - // 8 bytes: agent - long agent = getLong(); - - // 4 bytes: profession - int prof = getInt(); - - // 4 bytes: is_elite - int is_elite = getInt(); - - // 4 bytes: toughness - int toughness = getInt(); - - // 4 bytes: healing - int healing = getInt(); - - // 4 bytes: condition - int condition = getInt(); - - // 68 bytes: name - String name = getString(68); - //Save - Agent a = new Agent(agent, name, prof, is_elite); - if (a != null) - { - // NPC - if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "NPC") - { - agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + prof.ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof))); - } - // Gadget - else if (a.getProf(this.log_data.getBuildVersion(), APIContrioller) == "GDG") - { - agent_data.addItem(a, new AgentItem(agent, name, a.getName() + ":" + (prof & 0x0000ffff).ToString().PadLeft(5, '0')), this.log_data.getBuildVersion(), APIContrioller);//a.getName() + ":" + String.format("%05d", prof & 0x0000ffff))); - } - // Player - else - { - agent_data.addItem(a, new AgentItem(agent, name, a.getProf(this.log_data.getBuildVersion(), APIContrioller), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); - } - } - // Unknown - else - { - agent_data.addItem(a, new AgentItem(agent, name, prof.ToString(), toughness, healing, condition), this.log_data.getBuildVersion(), APIContrioller); - } - } - - } - /// - /// Parses skill related data - /// - private void parseSkillData() - { - GW2APIController apiController = new GW2APIController(); - // 4 bytes: player count - int skill_count = getInt(); - //TempData["Debug"] += "Skill Count:" + skill_count.ToString(); - // 68 bytes: each skill - for (int i = 0; i < skill_count; i++) - { - // 4 bytes: skill ID - int skill_id = getInt(); - - // 64 bytes: name - String name = getString(64); - String nameTrim = name.Replace("\0", ""); - int n; - bool isNumeric = int.TryParse(nameTrim, out n);//check to see if name was id - if (n == skill_id && skill_id != 0) - { - //was it a known boon? - foreach (Boon b in Boon.getBoonList()) - { - if (skill_id == b.getID()) - { - nameTrim = b.getName(); - } - } - } - //Save - - SkillItem skill = new SkillItem(skill_id, nameTrim); - - skill.SetGW2APISkill(apiController); - skill_data.addItem(skill); - } - } - /// - /// Parses combat related data - /// - private void parseCombatList() - { - // 64 bytes: each combat - while (stream.Length - stream.Position >= 64) - { - // 8 bytes: time - long time = getLong(); - - // 8 bytes: src_agent - long src_agent = getLong(); - - // 8 bytes: dst_agent - long dst_agent = getLong(); - - // 4 bytes: value - int value = getInt(); - - // 4 bytes: buff_dmg - int buff_dmg = getInt(); - - // 2 bytes: overstack_value - ushort overstack_value = getShort(); - - // 2 bytes: skill_id - ushort skill_id = getShort(); - - // 2 bytes: src_instid - ushort src_instid = getShort(); - - // 2 bytes: dst_instid - ushort dst_instid = getShort(); - - // 2 bytes: src_master_instid - ushort src_master_instid = getShort(); - - // 9 bytes: garbage - safeSkip(9); - - // 1 byte: iff - //IFF iff = IFF.getEnum(f.read()); - IFF iff = new IFF(Convert.ToByte(stream.ReadByte())); //Convert.ToByte(stream.ReadByte()); - - // 1 byte: buff - ushort buff = (ushort)stream.ReadByte(); - - // 1 byte: result - //Result result = Result.getEnum(f.read()); - Result result = new Result(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_activation - //Activation is_activation = Activation.getEnum(f.read()); - Activation is_activation = new Activation(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_buffremove - //BuffRemove is_buffremove = BuffRemove.getEnum(f.read()); - BuffRemove is_buffremoved = new BuffRemove(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_ninety - ushort is_ninety = (ushort)stream.ReadByte(); - - // 1 byte: is_fifty - ushort is_fifty = (ushort)stream.ReadByte(); - - // 1 byte: is_moving - ushort is_moving = (ushort)stream.ReadByte(); - - // 1 byte: is_statechange - //StateChange is_statechange = StateChange.getEnum(f.read()); - StateChange is_statechange = new StateChange(Convert.ToByte(stream.ReadByte())); - - // 1 byte: is_flanking - ushort is_flanking = (ushort)stream.ReadByte(); - - // 1 byte: is_flanking - ushort is_shields = (ushort)stream.ReadByte(); - // 2 bytes: garbage - safeSkip(2); - - //save - // Add combat - combat_data.addItem(new CombatItem(time, src_agent, dst_agent, value, buff_dmg, overstack_value, skill_id, - src_instid, dst_instid, src_master_instid, iff, buff, result, is_activation, is_buffremoved, - is_ninety, is_fifty, is_moving, is_statechange, is_flanking, is_shields)); - } - } - /// - /// Parses all the data again and link related stuff to each other - /// - private void fillMissingData() - { - // Set Agent instid, first_aware and last_aware - List player_list = agent_data.getPlayerAgentList(); - List agent_list = agent_data.getAllAgentsList(); - List combat_list = combat_data.getCombatList(); - foreach (AgentItem a in agent_list) - { - bool assigned_first = false; - foreach (CombatItem c in combat_list) - { - if (a.getAgent() == c.getSrcAgent() && c.getSrcInstid() != 0) - { - if (!assigned_first) - { - a.setInstid(c.getSrcInstid()); - a.setFirstAware(c.getTime()); - assigned_first = true; - } - a.setLastAware(c.getTime()); - } - else if (a.getAgent() == c.getDstAgent() && c.getDstInstid() != 0) - { - if (!assigned_first) - { - a.setInstid(c.getDstInstid()); - a.setFirstAware(c.getTime()); - assigned_first = true; - } - a.setLastAware(c.getTime()); - } - - } - } - - - // Set Boss data agent, instid, first_aware, last_aware and name - List NPC_list = agent_data.getNPCAgentList(); - 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()); - } - boss_data.setLastAware(NPC.getLastAware()); - } - } - AgentItem bossAgent = agent_data.GetAgent(boss_data.getAgent()); - boss = new Boss(bossAgent); - List bossHealthOverTime = new List(); - - // Grab values threw combat data - foreach (CombatItem c in combat_list) - { - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 12)//max health update - { - boss_data.setHealth((int)c.getDstAgent()); - - } - if (c.isStateChange().getID() == 13 && log_data.getPOV() == "N/A")//Point of View - { - long pov_agent = c.getSrcAgent(); - foreach (AgentItem p in player_list) - { - if (pov_agent == p.getAgent()) - { - log_data.setPOV(p.getName()); - } - } - - } - else if (c.isStateChange().getID() == 9)//Log start - { - log_data.setLogStart(c.getValue()); - } - else if (c.isStateChange().getID() == 10)//log end - { - log_data.setLogEnd(c.getValue()); - - } - //set health update - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 8) - { - bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); - } - - } - - - // 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();//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().getID() == 8) - { - bossHealthOverTime.Add(new long[] { c.getTime() - boss_data.getFirstAware(), c.getDstAgent() }); - } - } - break; - } - } - } - //Dealing with Deimos split - if (boss_data.getID() == 17154) - { - int deimos_2_instid = 0; - foreach (AgentItem NPC in NPC_list) - { - if (NPC.getProf().Contains("57069")) - { - deimos_2_instid = NPC.getInstid(); - long oldAware = boss_data.getLastAware(); - if (NPC.getLastAware() < boss_data.getLastAware()) - { - // No split - break; - } - boss.addPhaseData(boss_data.getLastAware()); - boss_data.setLastAware(NPC.getLastAware()); - //List 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().getEnum() == "REWARD")//got reward - { - log_data.setBossKill(true); - boss_data.setLastAware(c.getTime()); - break; - } - //set boss dead - if (c.getSrcInstid() == boss_data.getInstid() && c.isStateChange().getID() == 4 && !log_data.getBosskill())//change dead - { - log_data.setBossKill(true); - boss_data.setLastAware(c.getTime()); - } - - } - - //players - if (p_list.Count == 0) - { - - //Fix Disconected players - List playerAgentList = getAgentData().getPlayerAgentList(); - - foreach (AgentItem playerAgent in playerAgentList) - { - List lp = combat_data.getStates(playerAgent.getInstid(), "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 isntances to original instid - int extra_login_Id = 0; - foreach (AgentItem extra in NPC_list) - { - if (extra.getAgent() == playerAgent.getAgent()) - { - - 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 => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) - setMechData(); - } - } diff --git a/LuckParser/LuckParser.csproj b/LuckParser/LuckParser.csproj index 27e58b93e..cc0ce23b6 100644 --- a/LuckParser/LuckParser.csproj +++ b/LuckParser/LuckParser.csproj @@ -78,6 +78,8 @@ + + Form From fc20e50546c63b6d710c4ecd8cda4d67f93d2bbc Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 19:25:08 +0200 Subject: [PATCH 19/53] fixed a bug where the last point on the boon graph was missing --- .../Models/ParseModels/AbstractPlayer.cs | 45 +++++++------------ LuckParser/Models/ParseModels/CombatData.cs | 6 +-- LuckParser/Models/ParseModels/Player.cs | 4 +- 3 files changed, 22 insertions(+), 33 deletions(-) diff --git a/LuckParser/Models/ParseModels/AbstractPlayer.cs b/LuckParser/Models/ParseModels/AbstractPlayer.cs index 1678afb81..b82957218 100644 --- a/LuckParser/Models/ParseModels/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/AbstractPlayer.cs @@ -45,7 +45,7 @@ public string getCharacter() public long getDeath(BossData bossData, List combatList, long start, long end) { long offset = bossData.getFirstAware(); - CombatItem dead = combatList.FirstOrDefault(x => x.getSrcInstid() == instid && x.isStateChange().getEnum() == "CHANGE_DEAD" && x.getTime() >= start + offset && x.getTime() < end + offset); + CombatItem dead = combatList.FirstOrDefault(x => x.getSrcInstid() == instid && x.isStateChange().getEnum() == "CHANGE_DEAD" && x.getTime() >= start + offset && x.getTime() <= end + offset); if (dead != null && dead.getTime() > 0) { return dead.getTime(); @@ -66,11 +66,11 @@ public long getDeath(BossData bossData, List combatList, long start, } if (instidFilter == 0) { - return damage_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + return damage_logs.Where(x => x.getTime() >= start && x.getTime() <= end).ToList(); } else { - return damage_logsFiltered.Where( x => x.getTime() >= start && x.getTime() < end).ToList(); + return damage_logsFiltered.Where( x => x.getTime() >= start && x.getTime() <= end).ToList(); } } public List getDamageTakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data, long start, long end) @@ -79,7 +79,7 @@ public List getDamageTakenLogs(BossData bossData, List co { setDamagetakenLogs(bossData, combatList, agentData, m_data); } - return damageTaken_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + return damageTaken_logs.Where(x => x.getTime() >= start && x.getTime() <= end).ToList(); } public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList) { @@ -111,7 +111,7 @@ public List getCastLogs(BossData bossData, List combatList, { setCastLogs(bossData, combatList, agentData); } - return cast_logs.Where(x => x.getTime() >= start && x.getTime() < end).ToList(); + return cast_logs.Where(x => x.getTime() >= start && x.getTime() <= end).ToList(); } public Dictionary> getMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData) @@ -220,7 +220,7 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List toFill = new List(); + List toFill = new List(); List toFillPresence = new List(); + for (int i = 0; i < dur + 1; i++) + { + toFill.Add(new Point(i, 0)); + toFillPresence.Add(new Point(i, 0)); + } foreach (BoonSimulationItem simul in simulation) { int start = (int)simul.getStart(); int end = (int)simul.getEnd(); - // fill - if (toFill.Count < start) - { - for (int i = prev; i < start; i++) - { - toFill.Add(new Point(i, 0)); - toFillPresence.Add(new Point(i, 0)); - } - } - for (int i = start; i < end; i++) + + for (int i = start; i <= end; i++) { - toFill.Add(new Point(i, simul.getStack(i))); - toFillPresence.Add(new Point(i, simul.getItemDuration() > 0 ? 1 : 0)); + toFill[i] = new Point(i, simul.getStack(i)); + toFillPresence[i] = new Point(i, simul.getItemDuration() > 0 ? 1 : 0); } - prev = end; - } - // fill - for (int i = prev; i < dur; i++) - { - toFill.Add(new Point(i, 0)); - toFillPresence.Add(new Point(i, 0)); } // reduce precision to seconds List reducedPrecision = new List(); List boonPresence = boon_presence_points.getBoonChart(); - for (int i = 0; i < fight_duration; i++) + for (int i = 0; i <= fight_duration; i++) { reducedPrecision.Add(new Point(i, toFill[1000 * i].Y)); if (Boon.getBoonList().Select(x => x.getID()).Contains(boonid)) diff --git a/LuckParser/Models/ParseModels/CombatData.cs b/LuckParser/Models/ParseModels/CombatData.cs index 85c20052c..f4f7cba9c 100644 --- a/LuckParser/Models/ParseModels/CombatData.cs +++ b/LuckParser/Models/ParseModels/CombatData.cs @@ -26,7 +26,7 @@ public void addItem(CombatItem item) public List getStates(int src_instid, String change, long start, long end) { List states = new List(); - foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() < end)) + foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() <= end)) { if (c.getSrcInstid() == src_instid && c.isStateChange().getEnum() == change) { @@ -39,7 +39,7 @@ public List getStates(int src_instid, String change, long start, lon public int getSkillCount(int src_instid, int skill_id, long start, long end) { int count = 0; - foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() < end)) + foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() <= end)) { if (c.getSrcInstid() == src_instid && c.getSkillID() == skill_id) { @@ -52,7 +52,7 @@ public int getSkillCount(int src_instid, int skill_id, long start, long end) public int getBuffCount(int src_instid, int skill_id, long start, long end) { int count = 0; - foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() < end)) + foreach (CombatItem c in combat_list.Where(x => x.getTime() >= start && x.getTime() <= end)) { if (c.getSrcInstid() == src_instid && c.getSkillID() == skill_id) { diff --git a/LuckParser/Models/ParseModels/Player.cs b/LuckParser/Models/ParseModels/Player.cs index 54a7375bb..a29f0f497 100644 --- a/LuckParser/Models/ParseModels/Player.cs +++ b/LuckParser/Models/ParseModels/Player.cs @@ -66,7 +66,7 @@ public int getCondition() public int[] getCleanses(BossData bossData, List combatList, AgentData agentData, long start, long end) { long time_start = bossData.getFirstAware(); int[] cleanse = { 0, 0 }; - foreach (CombatItem c in combatList.Where(x=>x.isStateChange().getID() == 0 && x.isBuff() == 1 && x.getTime() >= (start + time_start) && x.getTime() < (end + time_start))) + foreach (CombatItem c in combatList.Where(x=>x.isStateChange().getID() == 0 && x.isBuff() == 1 && x.getTime() >= (start + time_start) && x.getTime() <= (end + time_start))) { if (c.isActivation().getID() == 0) { @@ -125,7 +125,7 @@ public List getConsumablesList(BossData bossData, SkillData skillData, Li { setConsumablesList( bossData, skillData, combatList); } - return consumeList.Where(x => x.getTime() >= start && x.getTime() < end).Select( x => new int[] { x.getSkillID(), (int)x.getTime() }).ToList() ; + return consumeList.Where(x => x.getTime() >= start && x.getTime() <= end).Select( x => new int[] { x.getSkillID(), (int)x.getTime() }).ToList() ; } // Private Methods private void EstimateWeapons(SkillData s_data, CombatData c_data, BossData b_data, AgentData a_data) From d548eeaac6593169d59f62bb023fe972c390c40d Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 19:46:09 +0200 Subject: [PATCH 20/53] some bugfixes --- LuckParser/Controllers/Controller1.cs | 2 +- LuckParser/Models/ParseModels/Boss.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index e775b91cd..9aa782132 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -2275,7 +2275,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind sw.Write( - "x: ['" + dur + "']," + + "x: ['" + Math.Min(dur, (phase.end - cl.getTime() / 1000f)) + "']," + "base:'" + (cl.getTime() - phase.start) / 1000f + "'," + "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api "orientation:'h'," + diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index 5525149a4..d42818730 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -130,7 +130,8 @@ private void setPhases(BossData bossData, List combatList, AgentData { end = t; phases.Add(new PhaseData(start, end)); - start = t; + // make sure stuff from the precedent phase mix witch each other + start = t+1; } break; case "Xera": From 5e82f66211fe5332108fa1d5460b6c6177f3bd92 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 19:57:02 +0200 Subject: [PATCH 21/53] fixed a bug in boss casting graph for phases --- LuckParser/Controllers/Controller1.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 9aa782132..ab98afb53 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -2275,7 +2275,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind sw.Write( - "x: ['" + Math.Min(dur, (phase.end - cl.getTime() / 1000f)) + "']," + + "x: ['" + Math.Min(dur, (phase.end - cl.getTime()) / 1000f) + "']," + "base:'" + (cl.getTime() - phase.start) / 1000f + "'," + "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api "orientation:'h'," + @@ -4035,10 +4035,9 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) { sw.Write("y: ['1.5'],"); - - + sw.Write( - "x: ['" + dur + "']," + + "x: ['" + Math.Min(dur, (phase.end - cl.getTime()) / 1000f) + "']," + "base:'" + (cl.getTime() - phase.start)/ 1000f + "'," + "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api "orientation:'h'," + From 783d1fa22bea173b2aaa935d7901a7cde7370522 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 20:30:16 +0200 Subject: [PATCH 22/53] some more refacto (rotation under graph and boon gen tables) --- LuckParser/Controllers/Controller1.cs | 719 +------------------------- LuckParser/Controllers/HTMLHelper.cs | 236 ++++++++- 2 files changed, 253 insertions(+), 702 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index ab98afb53..fd4550d96 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1742,21 +1742,7 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t List> footList = new List>(); sw.Write("
    " + count + "
    " + boss.getCharacter().ToString() + "" + boonArray[boon.getID()] + "
    "); { - sw.Write(""); - { - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - sw.Write(""); - } - } - sw.Write(" "); - } - sw.Write(""); + HTMLHelper.writeBoonTableHeader(sw, list_to_use); HashSet intensityBoon = new HashSet(); bool boonTable = list_to_use.Select(x => x.getID()).Contains(740); sw.Write(""); @@ -1879,23 +1865,7 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string sw.Write(""); sw.Write("
    SubName" + "\""" + "
    "); { - sw.Write(""); - { - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - sw.Write(""); - } - } - - sw.Write(""); - } - - sw.Write(""); + HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write(""); { foreach (Player player in p_list) @@ -1903,24 +1873,7 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string List playerID = new List(); playerID.Add(player); Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerID); - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - if (boonArray.ContainsKey(boon.getID())) - { - sw.Write(""); - } - else - { - sw.Write(""); - } - } - } - sw.Write(""); + HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray, GetLink(player.getProf().ToString())); } } sw.Write(""); @@ -1939,22 +1892,7 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string sw.Write(""); sw.Write("
    SubName" + "\""" + "
    " + player.getGroup().ToString() + "" + "\""" + "" + player.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + 0 + "
    "); { - sw.Write(""); - { - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - sw.Write(""); - } - } - - sw.Write(""); - } - sw.Write(""); + HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write(""); { List playerIDS = new List(); @@ -1966,27 +1904,7 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string playerIDS.Add(p); } Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); - playerIDS.Clear(); - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - - - foreach (Boon boon in list_to_use) - { - if (boonArray.ContainsKey(boon.getID())) - { - sw.Write(""); - } - else - { - sw.Write(""); - } - } - } - sw.Write(""); + HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray, GetLink(player.getProf().ToString())); } } sw.Write(""); @@ -2004,12 +1922,7 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin sw.Write(""); sw.Write("
    SubName" + "\""" + "
    " + player.getGroup().ToString() + "" + "\""" + "" + player.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + 0 + "
    "); { - sw.Write(" "); - foreach (Boon boon in list_to_use) - { - sw.Write(""); - } - sw.Write(" "); + HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write(""); { List playerIDS = new List(); @@ -2021,25 +1934,7 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin playerIDS.Add(p); } Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); - playerIDS.Clear(); - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - if (boonArray.ContainsKey(boon.getID())) - { - sw.Write(""); - } - else - { - sw.Write(""); - } - } - } - sw.Write(""); + HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray, GetLink(player.getProf().ToString())); } } sw.Write(""); @@ -2057,21 +1952,7 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string sw.Write(""); sw.Write("
    SubName" + "\""" + "
    " + player.getGroup().ToString() + "" + "\""" + "" + player.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + 0 + "
    "); { - sw.Write(""); - { - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - sw.Write(""); - } - } - sw.Write(""); - } - sw.Write(""); + HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write(""); { List playerIDS = new List(); @@ -2082,25 +1963,7 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string foreach (Player player in p_list) { Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); - sw.Write(""); - { - sw.Write(""); - sw.Write(""); - sw.Write(""); - foreach (Boon boon in list_to_use) - { - if (boonArray.ContainsKey(boon.getID())) - { - sw.Write(""); - } - else - { - sw.Write(""); - } - } - } - - sw.Write(""); + HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray, GetLink(player.getProf().ToString())); } } sw.Write(""); @@ -2227,125 +2090,9 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind { if (SnapSettings[6])//Display rotation { - foreach (CastLog cl in casting) { - - string skillName = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill == null) - { - skillName = skill_data.getName(cl.getID()); - } - else - { - skillName = skill.name; - } - float dur = 0.0f; - if (skillName == "Dodge") - { - dur = 0.5f; - } - else if (cl.getID() == -2) - {//wepswap - skillName = "Weapon Swap"; - dur = 0.1f; - } - else if (skillName == "Resurrect") - { - dur = cl.getActDur() / 1000f; - } - else if (skillName == "Bandage") - { - dur = cl.getActDur() / 1000f; - } - else - { - dur = cl.getActDur() / 1000f; - } - skillName = skillName.Replace("\"", ""); - sw.Write("{"); - { - - sw.Write("y: ['1.5'],"); - - - sw.Write( - "x: ['" + Math.Min(dur, (phase.end - cl.getTime()) / 1000f) + "']," + - "base:'" + (cl.getTime() - phase.start) / 1000f + "'," + - "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api - "orientation:'h'," + - "mode: 'markers'," + - "type: 'bar',"); - if (skill != null) - { - if (skill.slot == "Weapon_1") - { - sw.Write("width:'0.5',"); - } - else - { - sw.Write("width:'1',"); - } - - } - else - { - sw.Write("width:'1',"); - } - sw.Write("hoverinfo: 'name'," + - "hoverlabel:{namelength:'-1'},"); - sw.Write("marker: {"); - { - if (cl.endActivation() != null) - { - if (cl.endActivation().getID() == 3) - { - sw.Write("color: 'rgb(40,40,220)',"); - } - else if (cl.endActivation().getID() == 4) - { - sw.Write("color: 'rgb(220,40,40)',"); - } - else if (cl.endActivation().getID() == 5) - { - sw.Write("color: 'rgb(40,220,40)',"); - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - sw.Write("width: '5',"); - sw.Write("line:{"); - { - if (cl.startActivation() != null) - { - if (cl.startActivation().getID() == 1) - { - sw.Write("color: 'rgb(20,20,20)',"); - } - else if (cl.startActivation().getID() == 2) - { - sw.Write("color: 'rgb(220,40,220)',"); - } - } - sw.Write("width: '1'"); - } - sw.Write("}"); - } - sw.Write("},"); - sw.Write("showlegend: false"); - } - sw.Write(" },"); + HTMLHelper.writeCastingItem(sw, cl, skill_data, phase.start, phase.end); } } if (present_boons.Count() > 0) @@ -2569,76 +2316,8 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind int castCount = 0; foreach (CastLog cl in casting) { - string skillIcon = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill != null && cl.getID() != -2) - { - if (skill.slot != "Weapon_1") - { - skillIcon = skill.icon; - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + (cl.getTime() - phase.start) / 1000f + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - } - else - { - string skillName = ""; - - if (cl.getID() == -2) - { //wepswap - skillName = "Weapon Swap"; - // skillIcon = "https://wiki.guildwars2.com/images/archive/c/ce/20140606174035%21Weapon_Swap_Button.png"; - } - else - { - skillName = skill_data.getName(cl.getID()); - } - - - if (skillName == "Dodge") - { - // skillIcon = "https://wiki.guildwars2.com/images/c/cc/Dodge_Instructor.png"; - } - else if (skillName == "Resurrect") - { - //skillIcon = "https://wiki.guildwars2.com/images/archive/d/dd/20120611120554%21Downed.png"; - } - else if (skillName == "Bandage") - { - // skillIcon = "https://wiki.guildwars2.com/images/0/0c/Bandage.png"; - } - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + (cl.getTime() - phase.start) / 1000f + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - if (castCount == casting.Count - 1) - { - } - else - { - sw.Write(","); - } + HTMLHelper.writeCastingItemIcon(sw, cl, skill_data, phase.start, castCount == casting.Count - 1); + castCount++; } } } @@ -3993,121 +3672,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) foreach (CastLog cl in casting) { - - string skillName = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill == null) - { - skillName = skill_data.getName(cl.getID()); - } - else - { - skillName = skill.name; - } - float dur = 0.0f; - if (skillName == "Dodge") - { - dur = 0.5f; - } - else if (cl.getID() == -2) - {//wepswap - skillName = "Weapon Swap"; - dur = 0.1f; - } - else if (skillName == "Resurrect") - { - dur = cl.getActDur() / 1000f; - } - else if (skillName == "Bandage") - { - dur = cl.getActDur() / 1000f; - } - else - { - dur = cl.getActDur() / 1000f; - } - skillName = skillName.Replace("\"", ""); - sw.Write("{"); - { - - sw.Write("y: ['1.5'],"); - - sw.Write( - "x: ['" + Math.Min(dur, (phase.end - cl.getTime()) / 1000f) + "']," + - "base:'" + (cl.getTime() - phase.start)/ 1000f + "'," + - "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api - "orientation:'h'," + - "mode: 'markers'," + - "type: 'bar',"); - if (skill != null) - { - if (skill.slot == "Weapon_1") - { - sw.Write("width:'0.5',"); - } - else - { - sw.Write("width:'1',"); - } - - } - else - { - sw.Write("width:'1',"); - } - sw.Write("hoverinfo: 'name'," + - "hoverlabel:{namelength:'-1'},"); - sw.Write("marker: {"); - { - if (cl.endActivation() != null) - { - if (cl.endActivation().getID() == 3) - { - sw.Write("color: 'rgb(40,40,220)',"); - } - else if (cl.endActivation().getID() == 4) - { - sw.Write("color: 'rgb(220,40,40)',"); - } - else if (cl.endActivation().getID() == 5) - { - sw.Write("color: 'rgb(40,220,40)',"); - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - sw.Write("width: '5',"); - sw.Write("line:{"); - { - if (cl.startActivation() != null) - { - if (cl.startActivation().getID() == 1) - { - sw.Write("color: 'rgb(20,20,20)',"); - } - else if (cl.startActivation().getID() == 2) - { - sw.Write("color: 'rgb(220,40,220)',"); - } - } - sw.Write("width: '1'"); - } - sw.Write("}"); - } - sw.Write("},"); - sw.Write("showlegend: false"); - } - sw.Write(" },"); + HTMLHelper.writeCastingItem(sw, cl, skill_data, phase.start, phase.end); } } //============================================ @@ -4258,73 +3823,8 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) int castCount = 0; foreach (CastLog cl in casting) { - string skillIcon = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill != null && cl.getID() != -2) - { - if (skill.slot != "Weapon_1") - { - skillIcon = skill.icon; - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + (cl.getTime() - phase.start) / 1000f + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - } - else - { - string skillName = ""; - if (cl.getID() == -2) - { //wepswap - skillName = "Weapon Swap"; - // skillIcon = "https://wiki.guildwars2.com/images/archive/c/ce/20140606174035%21Weapon_Swap_Button.png"; - } - else - { - skillName = skill_data.getName(cl.getID()); - } - if (skillName == "Dodge") - { - // skillIcon = "https://wiki.guildwars2.com/images/c/cc/Dodge_Instructor.png"; - } - else if (skillName == "Resurrect") - { - //skillIcon = "https://wiki.guildwars2.com/images/archive/d/dd/20120611120554%21Downed.png"; - } - else if (skillName == "Bandage") - { - // skillIcon = "https://wiki.guildwars2.com/images/0/0c/Bandage.png"; - } - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + (cl.getTime() - phase.start) / 1000f + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - if (castCount == casting.Count - 1) - { - } - else - { - sw.Write(","); - } + HTMLHelper.writeCastingItemIcon(sw, cl, skill_data, phase.start, castCount == casting.Count - 1); + castCount++; } } } @@ -4914,122 +4414,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) foreach (CastLog cl in casting) { - - string skillName = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill == null) - { - skillName = skill_data.getName(cl.getID()); - } - else - { - skillName = skill.name; - } - float dur = 0.0f; - if (skillName == "Dodge") - { - dur = 0.5f; - } - else if (cl.getID() == -2) - {//wepswap - skillName = "Weapon Swap"; - dur = 0.1f; - } - else if (skillName == "Resurrect") - { - dur = cl.getActDur() / 1000f; - } - else if (skillName == "Bandage") - { - dur = cl.getActDur() / 1000f; - } - else - { - dur = cl.getActDur() / 1000f; - } - skillName = skillName.Replace("\"", ""); - sw.Write("{"); - { - - sw.Write("y: ['1.5'],"); - - - sw.Write( - "x: ['" + dur + "']," + - "base:'" + cl.getTime() / 1000f + "'," + - "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api - "orientation:'h'," + - "mode: 'markers'," + - "type: 'bar',"); - if (skill != null) - { - if (skill.slot == "Weapon_1") - { - sw.Write("width:'0.5',"); - } - else - { - sw.Write("width:'1',"); - } - - } - else - { - sw.Write("width:'1',"); - } - sw.Write("hoverinfo: 'name'," + - "hoverlabel:{namelength:'-1'},"); - sw.Write("marker: {"); - { - if (cl.endActivation() != null) - { - if (cl.endActivation().getID() == 3) - { - sw.Write("color: 'rgb(40,40,220)',"); - } - else if (cl.endActivation().getID() == 4) - { - sw.Write("color: 'rgb(220,40,40)',"); - } - else if (cl.endActivation().getID() == 5) - { - sw.Write("color: 'rgb(40,220,40)',"); - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - } - else - { - sw.Write("color: 'rgb(220,220,0)',"); - } - sw.Write("width: '5',"); - sw.Write("line:{"); - { - if (cl.startActivation() != null) - { - if (cl.startActivation().getID() == 1) - { - sw.Write("color: 'rgb(20,20,20)',"); - } - else if (cl.startActivation().getID() == 2) - { - sw.Write("color: 'rgb(220,40,220)',"); - } - } - sw.Write("width: '1'"); - } - sw.Write("}"); - } - sw.Write("},"); - sw.Write("showlegend: false"); - } - sw.Write(" },"); + HTMLHelper.writeCastingItem(sw, cl, skill_data, 0, boss_data.getAwareDuration()); } } if (present_boons.Count() > 0) @@ -5253,76 +4638,8 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) int castCount = 0; foreach (CastLog cl in casting) { - string skillIcon = ""; - GW2APISkill skill = null; - if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) - { - skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); - } - if (skill != null && cl.getID() != -2) - { - if (skill.slot != "Weapon_1") - { - skillIcon = skill.icon; - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + (cl.getTime() / 1000f) + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - } - else - { - string skillName = ""; - - if (cl.getID() == -2) - { //wepswap - skillName = "Weapon Swap"; - // skillIcon = "https://wiki.guildwars2.com/images/archive/c/ce/20140606174035%21Weapon_Swap_Button.png"; - } - else - { - skillName = skill_data.getName(cl.getID()); - } - - - if (skillName == "Dodge") - { - // skillIcon = "https://wiki.guildwars2.com/images/c/cc/Dodge_Instructor.png"; - } - else if (skillName == "Resurrect") - { - //skillIcon = "https://wiki.guildwars2.com/images/archive/d/dd/20120611120554%21Downed.png"; - } - else if (skillName == "Bandage") - { - // skillIcon = "https://wiki.guildwars2.com/images/0/0c/Bandage.png"; - } - sw.Write("{" + - "source: '" + skillIcon + "'," + - "xref: 'x'," + - "yref: 'y'," + - "x: " + cl.getTime() / 1000f + "," + - "y: 0," + - "sizex: 1.1," + - "sizey: 1.1," + - "xanchor: 'left'," + - "yanchor: 'bottom'" + - "}"); - } - if (castCount == casting.Count - 1) - { - } - else - { - sw.Write(","); - } + HTMLHelper.writeCastingItemIcon(sw, cl, skill_data, 0, castCount == casting.Count - 1); + castCount++; } } } diff --git a/LuckParser/Controllers/HTMLHelper.cs b/LuckParser/Controllers/HTMLHelper.cs index 41c6b3680..c75f30268 100644 --- a/LuckParser/Controllers/HTMLHelper.cs +++ b/LuckParser/Controllers/HTMLHelper.cs @@ -1,6 +1,8 @@ -using LuckParser.Models.ParseModels; +using LuckParser.Models; +using LuckParser.Models.ParseModels; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -486,5 +488,237 @@ public static List getTotalDPSGraph(BossData b_data, CombatData c_data, A return getDPSGraph(b_data, c_data, a_data, p, boss, phase_index, 0); } + public static void writeCastingItem(StreamWriter sw, CastLog cl, SkillData skill_data, long start, long end) + { + string skillName = ""; + GW2APISkill skill = null; + List s_list = skill_data.getSkillList(); + if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) + { + skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); + } + if (skill == null) + { + skillName = skill_data.getName(cl.getID()); + } + else + { + skillName = skill.name; + } + float dur = 0.0f; + if (skillName == "Dodge") + { + dur = 0.5f; + } + else if (cl.getID() == -2) + {//wepswap + skillName = "Weapon Swap"; + dur = 0.1f; + } + else if (skillName == "Resurrect") + { + dur = cl.getActDur() / 1000f; + } + else if (skillName == "Bandage") + { + dur = cl.getActDur() / 1000f; + } + else + { + dur = cl.getActDur() / 1000f; + } + skillName = skillName.Replace("\"", ""); + sw.Write("{"); + { + + sw.Write("y: ['1.5'],"); + + sw.Write( + "x: ['" + Math.Min(dur, (end - cl.getTime()) / 1000f) + "']," + + "base:'" + (cl.getTime() - start) / 1000f + "'," + + "name: \"" + skillName + " " + dur + "s\"," +//get name should be handled by api + "orientation:'h'," + + "mode: 'markers'," + + "type: 'bar',"); + if (skill != null) + { + if (skill.slot == "Weapon_1") + { + sw.Write("width:'0.5',"); + } + else + { + sw.Write("width:'1',"); + } + + } + else + { + sw.Write("width:'1',"); + } + sw.Write("hoverinfo: 'name'," + + "hoverlabel:{namelength:'-1'},"); + sw.Write("marker: {"); + { + if (cl.endActivation() != null) + { + if (cl.endActivation().getID() == 3) + { + sw.Write("color: 'rgb(40,40,220)',"); + } + else if (cl.endActivation().getID() == 4) + { + sw.Write("color: 'rgb(220,40,40)',"); + } + else if (cl.endActivation().getID() == 5) + { + sw.Write("color: 'rgb(40,220,40)',"); + } + else + { + sw.Write("color: 'rgb(220,220,0)',"); + } + } + else + { + sw.Write("color: 'rgb(220,220,0)',"); + } + sw.Write("width: '5',"); + sw.Write("line:{"); + { + if (cl.startActivation() != null) + { + if (cl.startActivation().getID() == 1) + { + sw.Write("color: 'rgb(20,20,20)',"); + } + else if (cl.startActivation().getID() == 2) + { + sw.Write("color: 'rgb(220,40,220)',"); + } + } + sw.Write("width: '1'"); + } + sw.Write("}"); + } + sw.Write("},"); + sw.Write("showlegend: false"); + } + sw.Write(" },"); + } + + public static void writeCastingItemIcon(StreamWriter sw, CastLog cl, SkillData skill_data, long start, bool last ) + { + string skillIcon = ""; + GW2APISkill skill = null; + List s_list = skill_data.getSkillList(); + if (s_list.FirstOrDefault(x => x.getID() == cl.getID()) != null) + { + skill = s_list.FirstOrDefault(x => x.getID() == cl.getID()).GetGW2APISkill(); + } + if (skill != null && cl.getID() != -2) + { + if (skill.slot != "Weapon_1") + { + skillIcon = skill.icon; + sw.Write("{" + + "source: '" + skillIcon + "'," + + "xref: 'x'," + + "yref: 'y'," + + "x: " + (cl.getTime() - start) / 1000f + "," + + "y: 0," + + "sizex: 1.1," + + "sizey: 1.1," + + "xanchor: 'left'," + + "yanchor: 'bottom'" + + "}"); + } + } + else + { + string skillName = ""; + + if (cl.getID() == -2) + { //wepswap + skillName = "Weapon Swap"; + // skillIcon = "https://wiki.guildwars2.com/images/archive/c/ce/20140606174035%21Weapon_Swap_Button.png"; + } + else + { + skillName = skill_data.getName(cl.getID()); + } + + + if (skillName == "Dodge") + { + // skillIcon = "https://wiki.guildwars2.com/images/c/cc/Dodge_Instructor.png"; + } + else if (skillName == "Resurrect") + { + //skillIcon = "https://wiki.guildwars2.com/images/archive/d/dd/20120611120554%21Downed.png"; + } + else if (skillName == "Bandage") + { + // skillIcon = "https://wiki.guildwars2.com/images/0/0c/Bandage.png"; + } + sw.Write("{" + + "source: '" + skillIcon + "'," + + "xref: 'x'," + + "yref: 'y'," + + "x: " + (cl.getTime() - start) / 1000f + "," + + "y: 0," + + "sizex: 1.1," + + "sizey: 1.1," + + "xanchor: 'left'," + + "yanchor: 'bottom'" + + "}"); + } + if (!last) + { + sw.Write(","); + } + } + + public static void writeBoonTableHeader(StreamWriter sw, List list_to_use) + { + sw.Write(""); + { + sw.Write(""); + { + sw.Write(""); + sw.Write(""); + sw.Write(""); + foreach (Boon boon in list_to_use) + { + sw.Write(""); + } + } + sw.Write(" "); + } + sw.Write(""); + + } + + public static void writeBoonGenTableBody(StreamWriter sw, Player player, List list_to_use, Dictionary boonArray, string prof_icon) + { + sw.Write(""); + { + sw.Write(""); + sw.Write(""); + sw.Write(""); + foreach (Boon boon in list_to_use) + { + if (boonArray.ContainsKey(boon.getID())) + { + sw.Write(""); + } + else + { + sw.Write(""); + } + } + } + sw.Write(""); + } } } From f695248e647f42a2a6282671d8960d35cbe849bc Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 23:12:02 +0200 Subject: [PATCH 23/53] phase detection for dhuum --- LuckParser/Models/ParseModels/Boss.cs | 21 ++++++++++++++++++++- LuckParser/Models/ParseModels/SkillData.cs | 4 +++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Boss.cs index d42818730..395851743 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Boss.cs @@ -46,7 +46,7 @@ public void addPhaseData(long data) // Private Methods private void setPhases(BossData bossData, List combatList, AgentData agentData) { - long fight_dur = bossData.getLastAware() - bossData.getFirstAware(); + long fight_dur = bossData.getAwareDuration(); phases.Add(new PhaseData(0, fight_dur)); string name = getCharacter(); long start = 0; @@ -193,6 +193,25 @@ private void setPhases(BossData bossData, List combatList, AgentData cast_logs.Add(new CastLog(end, -6, (int)(start - end), new ParseEnums.Activation(0), (int)(start - end), new ParseEnums.Activation(0))); } break; + case "Dhuum": + if (fight_dur > 120000) + { + end = 120000; + phases.Add(new PhaseData(start, end)); + start = end + 1; + CastLog shield = cast_logs.Find(x => x.getID() == 47396); + if (shield != null) + { + end = shield.getTime(); + phases.Add(new PhaseData(start, end)); + start = shield.getTime() + shield.getActDur(); + if (start < fight_dur - 5000) + { + phases.Add(new PhaseData(start, fight_dur)); + } + } + } + break; default: break; } diff --git a/LuckParser/Models/ParseModels/SkillData.cs b/LuckParser/Models/ParseModels/SkillData.cs index fa71c258d..0f1dfc2c5 100644 --- a/LuckParser/Models/ParseModels/SkillData.cs +++ b/LuckParser/Models/ParseModels/SkillData.cs @@ -27,7 +27,9 @@ public class SkillData // Generic {-5, "Phase out" }, // Deimos - {-6, "Roleplay" } + {-6, "Roleplay" }, + // Dhuum + {47396, "Major Soul Split" } }; // Constructors From e4d58ea6b473d6e0b3993562c7d626f0de4187b5 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Mon, 11 Jun 2018 23:13:11 +0200 Subject: [PATCH 24/53] death recap only on full fight, damagedist table refactoring --- LuckParser/Controllers/Controller1.cs | 421 ++------------------------ LuckParser/Controllers/HTMLHelper.cs | 218 ++++++++++++- 2 files changed, 249 insertions(+), 390 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index fd4550d96..7d03b65d5 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1356,7 +1356,7 @@ private void CreateDPSTable(StreamWriter sw, int phase_index) { } else { - sw.Write(""); + sw.Write(""); } } sw.Write(""); @@ -2393,11 +2393,11 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind } sw.Write(""); } - if (died) + if (died && phase_index == 0) { sw.Write("
    "); { - CreateDeathRecap(sw, p, phase_index); + CreateDeathRecap(sw, p); } sw.Write("
    "); } @@ -2509,13 +2509,12 @@ private void CreateSimpleRotationTab(StreamWriter sw,Player p,int simpleRotSize, /// /// Stream writer /// The player - private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) + private void CreateDeathRecap(StreamWriter sw, Player p) { - PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; - List damageLogs = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data, phase.start, phase.end); + List damageLogs = p.getDamageTakenLogs(boss_data, combat_data.getCombatList(), agent_data, mech_data, 0, boss_data.getAwareDuration()); List s_list = skill_data.getSkillList(); - long start = phase.start + boss_data.getFirstAware(); - long end = phase.end + boss_data.getFirstAware(); + long start = boss_data.getFirstAware(); + long end = boss_data.getLastAware(); List down = combat_data.getStates(p.getInstid(), "CHANGE_DOWN", start, end); if (down.Count > 0) { @@ -2569,7 +2568,7 @@ private void CreateDeathRecap(StreamWriter sw, Player p, int phase_index) } sw.Write("

    Player was insta killed by a mechanic, fall damage or by /gg

    "); } - string pid = p.getInstid() + "_" + phase_index; + string pid = p.getInstid().ToString(); sw.Write("
    "); sw.Write(""); } + + private void CreateDMGDistTableBody(StreamWriter sw, bool toBoss, List casting, List damageLogs, int finalTotalDamage) + { + HashSet usedIDs = new HashSet(); + List s_list = skill_data.getSkillList(); + HTMLHelper.writeDamageDistTableCondi(sw, usedIDs, damageLogs, finalTotalDamage); + foreach (int id in damageLogs.Where(x => !usedIDs.Contains(x.getID())).Select(x => x.getID()).Distinct().ToList()) + { + SkillItem skill = s_list.FirstOrDefault(x => x.getID() == id); + List list_to_use = damageLogs.Where(x => x.getID() == id).ToList(); + usedIDs.Add(id); + if (skill != null && list_to_use.Count > 0) + { + List clList = casting.Where(x => x.getID() == id).ToList(); + int casts = clList.Count(); + double timeswasted = 0; + int countwasted = 0; + double timessaved = 0; + int countsaved = 0; + foreach (CastLog cl in clList) + { + if (cl.getExpDur() < cl.getActDur()) + { + countsaved++; + timessaved += ((double)(cl.getExpDur() - cl.getActDur()) / 1000f); + } + else if (cl.getExpDur() > cl.getActDur()) + { + countwasted++; + timeswasted += ((double)(cl.getActDur()) / 1000f); + } + } + HTMLHelper.writeDamageDistTableSkill(sw, skill, list_to_use, finalTotalDamage, casts, timeswasted, timessaved); + } + } + // non damaging stuff + if (!toBoss) + { + foreach (int id in casting.Where(x => !usedIDs.Contains(x.getID())).Select(x => x.getID()).Distinct()) + { + SkillItem skill = s_list.FirstOrDefault(x => x.getID() == id); + if (skill != null) + { + List clList = casting.Where(x => x.getID() == id).ToList(); + int casts = clList.Count(); + double timeswasted = 0; + int countwasted = 0; + double timessaved = 0; + int countsaved = 0; + foreach (CastLog cl in clList) + { + if (cl.getExpDur() < cl.getActDur()) + { + countsaved++; + timessaved += ((double)(cl.getExpDur() - cl.getActDur()) / 1000f); + } + else if (cl.getExpDur() > cl.getActDur()) + { + countwasted++; + timeswasted += ((double)(cl.getActDur()) / 1000f); + } + } + HTMLHelper.writeDamageDistTableSkill(sw, skill, new List(), finalTotalDamage, casts, timeswasted, timessaved); + } + } + } + } /// /// Creates the damage distribution table for a given player /// /// Stream writer /// The player - private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, int phase_index) + private void CreateDMGDistTable(StreamWriter sw, AbstractMasterPlayer p, bool toBoss, int phase_index) { PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; List casting = p.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.getStart(), phase.getEnd()); @@ -2471,73 +2538,10 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, sw.Write(""); sw.Write("
    SubName" + "\""" + "
    " + player.getGroup().ToString() + "" + "\""" + "" + player.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + 0 + "
    SubName" + "\""" + "
    " + player.getGroup().ToString() + "" + "\""" + "" + player.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + 0 + "
    " + " 0" + " " + " 0" + "
    "); { - List s_list = skill_data.getSkillList(); HTMLHelper.writeDamageDistTableHeader(sw); sw.Write(""); { - HashSet usedIDs = new HashSet(); - HTMLHelper.writeDamageDistTableCondi(sw,usedIDs, damageLogs, finalTotalDamage); - foreach (int id in damageLogs.Where(x => !usedIDs.Contains(x.getID())).Select(x => x.getID()).Distinct().ToList()) - { - SkillItem skill = s_list.FirstOrDefault(x => x.getID() == id); - List list_to_use = damageLogs.Where(x => x.getID() == id).ToList(); - usedIDs.Add(id); - if (skill != null && list_to_use.Count > 0) - { - List clList = casting.Where(x => x.getID() == id).ToList(); - int casts = clList.Count(); - double timeswasted = 0; - int countwasted = 0; - double timessaved = 0; - int countsaved = 0; - foreach (CastLog cl in clList) - { - if (cl.getExpDur() < cl.getActDur()) - { - countsaved++; - timessaved += ((double)(cl.getExpDur() - cl.getActDur()) / 1000f); - } - else if (cl.getExpDur() > cl.getActDur()) - { - countwasted++; - timeswasted += ((double)(cl.getActDur()) / 1000f); - } - } - HTMLHelper.writeDamageDistTableSkill(sw, skill, list_to_use, finalTotalDamage, casts, timeswasted, timessaved); - } - } - // non damaging stuff - if (!toBoss) - { - foreach (int id in casting.Where(x => !usedIDs.Contains(x.getID())).Select(x => x.getID()).Distinct()) - { - SkillItem skill = s_list.FirstOrDefault(x => x.getID() == id); - if (skill != null) - { - List clList = casting.Where(x => x.getID() == id).ToList(); - int casts = clList.Count(); - double timeswasted = 0; - int countwasted = 0; - double timessaved = 0; - int countsaved = 0; - foreach (CastLog cl in clList) - { - if (cl.getExpDur() < cl.getActDur()) - { - countsaved++; - timessaved += ((double)(cl.getExpDur() - cl.getActDur()) / 1000f); - } - else if (cl.getExpDur() > cl.getActDur()) - { - countwasted++; - timeswasted += ((double)(cl.getActDur()) / 1000f); - } - } - HTMLHelper.writeDamageDistTableSkill(sw, skill, new List(), finalTotalDamage, casts, timeswasted, timessaved); - } - } - } - + CreateDMGDistTableBody(sw, toBoss, casting, damageLogs, finalTotalDamage); } sw.Write(""); HTMLHelper.writeDamageDistTableFoot(sw, finalTotalDamage); @@ -2551,37 +2555,27 @@ private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, bool toBoss, /// Player, master of the minion /// Damage logs to use /// The minion - private void CreateDMGDistTable(StreamWriter sw, AbstractPlayer p, AgentItem agent, bool toBoss, int phase_index) + private void CreateDMGDistTable(StreamWriter sw, AbstractMasterPlayer p, Minions minions, bool toBoss, int phase_index) { string finalDPSdata = HTMLHelper.getFinalDPS(boss_data, combat_data, agent_data, p, boss, phase_index); int totalDamage = toBoss ? Int32.Parse(finalDPSdata.Split('|')[7]) : Int32.Parse(finalDPSdata.Split('|')[1]); - string tabid = p.getInstid() +"_"+phase_index + "_" + agent.getInstid() + (toBoss ? "_boss" : ""); + string tabid = p.getInstid() +"_"+phase_index + "_" + minions.getInstid() + (toBoss ? "_boss" : ""); PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; - List damageLogs = p.getMinionsDamageLogs(toBoss ? boss_data.getInstid() : 0, boss_data, combat_data.getCombatList(), agent_data)[agent].Where(x => x.getTime() >= phase.getStart() && x.getTime() <= phase.getEnd()).ToList(); + List casting = minions.getCastLogs(boss_data, combat_data.getCombatList(), agent_data, phase.getStart(), phase.getEnd()); + List damageLogs = minions.getDamageLogs(toBoss ? boss_data.getInstid() : 0, boss_data, combat_data.getCombatList(), agent_data, phase.getStart(), phase.getEnd()); int finalTotalDamage = damageLogs.Count > 0 ? damageLogs.Sum(x => x.getDamage()) : 0; if (totalDamage > 0) { string contribution = String.Format("{0:0.00}", 100.0 * finalTotalDamage / totalDamage); - sw.Write("
    " + agent.getName() + " did " + contribution + "% of " + p.getCharacter() + "'s total " + (toBoss ? "boss " : "") + "dps
    "); + sw.Write("
    " + minions.getCharacter() + " did " + contribution + "% of " + p.getCharacter() + "'s total " + (toBoss ? "boss " : "") + "dps
    "); } sw.Write(""); sw.Write("
    "); { - SkillData s_data = skill_data; - List s_list = s_data.getSkillList(); HTMLHelper.writeDamageDistTableHeader(sw); sw.Write(""); { - HashSet usedIDs = new HashSet(); - HTMLHelper.writeDamageDistTableCondi(sw, usedIDs, damageLogs, finalTotalDamage); - foreach (int id in damageLogs.Where(x => !usedIDs.Contains(x.getID())).Select(x => x.getID()).Distinct()) - {//foreach casted skill - SkillItem skill = s_list.FirstOrDefault(x => x.getID() == id); - if (skill != null) - { - HTMLHelper.writeDamageDistTableSkill(sw, skill, damageLogs.Where(x => x.getID() == id).ToList(), finalTotalDamage); - } - } + CreateDMGDistTableBody(sw, toBoss, casting, damageLogs, finalTotalDamage); } sw.Write(""); HTMLHelper.writeDamageDistTableFoot(sw, finalTotalDamage); @@ -2972,9 +2966,9 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) { sw.Write("
  • " + boss.getCharacter() + "
  • "); //foreach pet loop here - foreach (AgentItem agent in boss.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) + foreach (KeyValuePair pair in boss.getMinions(boss_data, combat_data.getCombatList(), agent_data)) { - sw.Write("
  • " + agent.getName() + "
  • "); + sw.Write("
  • " + pair.Key + "
  • "); } } sw.Write(""); @@ -3064,11 +3058,11 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) sw.Write(" "); CreateDMGDistTable(sw, boss, false, phase_index); sw.Write(""); - foreach (AgentItem agent in boss.getMinionsDamageLogs(0, boss_data, combat_data.getCombatList(), agent_data).Keys) + foreach (KeyValuePair pair in boss.getMinions(boss_data, combat_data.getCombatList(), agent_data)) { - sw.Write("
    "); + sw.Write("
    "); { - CreateDMGDistTable(sw, boss, agent, false, phase_index); + CreateDMGDistTable(sw, boss, pair.Value, false, phase_index); } sw.Write("
    "); } diff --git a/LuckParser/LuckParser.csproj b/LuckParser/LuckParser.csproj index 004964773..0e5e2eb69 100644 --- a/LuckParser/LuckParser.csproj +++ b/LuckParser/LuckParser.csproj @@ -86,15 +86,15 @@ MainForm.cs - - + + - - + + - + @@ -127,7 +127,7 @@ - + diff --git a/LuckParser/Models/ParseModels/Minions.cs b/LuckParser/Models/ParseModels/Minions.cs deleted file mode 100644 index f93441f59..000000000 --- a/LuckParser/Models/ParseModels/Minions.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace LuckParser.Models.ParseModels -{ - class Minions : List - { - } -} diff --git a/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs new file mode 100644 index 000000000..17c9ecdcc --- /dev/null +++ b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LuckParser.Models.ParseModels +{ + public abstract class AbstractMasterPlayer : AbstractPlayer + { + + // Minions + private Dictionary minions = new Dictionary(); + + public AbstractMasterPlayer(AgentItem agent) : base(agent) + { + + } + + + public Dictionary getMinions(BossData bossData, List combatList, AgentData agentData) + { + if (minions.Count == 0) + { + setMinions(bossData, combatList, agentData); + } + return minions; + } + + private void setMinions(BossData bossData, List combatList, AgentData agentData) + { + List combatMinionIDList = combatList.Where(x => x.getSrcMasterInstid() == instid).Select(x => x.getSrcInstid()).Distinct().ToList(); + foreach (int petid in combatMinionIDList) + { + AgentItem agent = agentData.getNPCAgentList().FirstOrDefault(x => x.getInstid() == petid); + if (agent != null) + { + List damageLogs = getDamageLogs(0, bossData, combatList, agentData, 0, bossData.getAwareDuration()).Where(x => x.getSrcAgent() == agent.getAgent()).ToList(); + if (damageLogs.Count == 0) + { + continue; + } + string id = agent.getName(); + if (!minions.ContainsKey(id)) + { + minions[id] = new Minions(); + } + minions[id].Add(new Minion(instid, agent)); + } + } + } + + } +} diff --git a/LuckParser/Models/ParseModels/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs similarity index 86% rename from LuckParser/Models/ParseModels/AbstractPlayer.cs rename to LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index 7555fcabe..6660a2fd4 100644 --- a/LuckParser/Models/ParseModels/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -18,10 +18,6 @@ public abstract class AbstractPlayer protected List damage_logs = new List(); private List damage_logsFiltered = new List(); private Dictionary> dps_graph = new Dictionary>(); - // Minions - private List combatMinionIDList = new List(); - private Dictionary> minion_damage_logs = new Dictionary>(); - private Dictionary> minion_damage_logsFiltered = new Dictionary>(); // Taken damage protected List damageTaken_logs = new List(); // Casts @@ -143,36 +139,6 @@ public List getCastLogsActDur(BossData bossData, List comba return cast_logs.Where(x => x.getTime() + x.getActDur() >= start && x.getTime() <= end).ToList(); } - public Dictionary> getMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData) - { - if (minion_damage_logs.Count == 0) - { - // make sure the keys matches - foreach (AgentItem agent in minion_damage_logsFiltered.Keys) - { - minion_damage_logs[agent] = new List(); - } - setMinionsDamageLogs(0, bossData, combatList, agentData, minion_damage_logs); - } - - if (minion_damage_logsFiltered.Count == 0) - { - // make sure the keys matches - foreach (AgentItem agent in minion_damage_logs.Keys) - { - minion_damage_logsFiltered[agent] = new List(); - } - setMinionsDamageLogs(bossData.getInstid(), bossData, combatList, agentData, minion_damage_logsFiltered); - } - if (instidFilter == 0) - { - return minion_damage_logs; - } - else - { - return minion_damage_logsFiltered; - } - } public List getJustPlayerDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, long start, long end) { return getDamageLogs(instidFilter, bossData, combatList, agentData, start, end).Where(x => x.getInstidt() == instid).ToList(); @@ -386,31 +352,6 @@ private void setCastLogs(BossData bossData, List combatList, AgentDa } } } - private void setMinionsDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, Dictionary> toFill) - { - List minionList = getCombatMinionList(bossData, combatList, agentData); - foreach (int petid in minionList) - { - AgentItem agent = agentData.getNPCAgentList().FirstOrDefault(x => x.getInstid() == petid); - if (agent != null) - { - List damageLogs = getDamageLogs(instidFilter, bossData, combatList, agentData, 0, bossData.getAwareDuration()).Where(x => x.getSrcAgent() == agent.getAgent()).ToList(); - if (damageLogs.Count == 0) - { - continue; - } - AgentItem key = toFill.Keys.ToList().FirstOrDefault(x => x.getName() == agent.getName()); - if (key == null) - { - toFill[agent] = damageLogs; - } - else - { - toFill[key].AddRange(damageLogs); - } - } - } - } protected abstract void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data); // private getters private BoonMap getBoonMap(BossData bossData, SkillData skillData, List combatList, bool add_condi) @@ -496,14 +437,7 @@ private BoonMap getBoonMap(BossData bossData, SkillData skillData, List getCombatMinionList(BossData bossData, List combatList, AgentData agentData) - { - if (combatMinionIDList.Count == 0) - { - combatMinionIDList = combatList.Where(x => x.getSrcMasterInstid() == instid).Select(x => x.getSrcInstid()).Distinct().ToList(); - } - return combatMinionIDList; - } + } } diff --git a/LuckParser/Models/ParseModels/Boss.cs b/LuckParser/Models/ParseModels/Players/Boss.cs similarity index 99% rename from LuckParser/Models/ParseModels/Boss.cs rename to LuckParser/Models/ParseModels/Players/Boss.cs index ee738819f..b0133397b 100644 --- a/LuckParser/Models/ParseModels/Boss.cs +++ b/LuckParser/Models/ParseModels/Players/Boss.cs @@ -3,7 +3,7 @@ namespace LuckParser.Models.ParseModels { - public class Boss : AbstractPlayer + public class Boss : AbstractMasterPlayer { // Constructors public Boss(AgentItem agent) : base(agent) diff --git a/LuckParser/Models/ParseModels/Minion.cs b/LuckParser/Models/ParseModels/Players/Minion.cs similarity index 91% rename from LuckParser/Models/ParseModels/Minion.cs rename to LuckParser/Models/ParseModels/Players/Minion.cs index 08e416dc4..d7c46ae7f 100644 --- a/LuckParser/Models/ParseModels/Minion.cs +++ b/LuckParser/Models/ParseModels/Players/Minion.cs @@ -13,6 +13,7 @@ public class Minion : AbstractPlayer public Minion(ushort master, AgentItem agent) : base(agent) { master_id = master; + prof = "Minion"; } protected override void setDamageLogs(BossData bossData, List combatList, AgentData agentData) @@ -20,7 +21,7 @@ protected override void setDamageLogs(BossData bossData, List combat long time_start = bossData.getFirstAware(); foreach (CombatItem c in combatList) { - if (instid == c.getSrcInstid())//selecting player or minion as caster + if (instid == c.getSrcInstid())//selecting minion as caster { long time = c.getTime() - time_start; foreach (AgentItem item in agentData.getNPCAgentList()) diff --git a/LuckParser/Models/ParseModels/Players/Minions.cs b/LuckParser/Models/ParseModels/Players/Minions.cs new file mode 100644 index 000000000..4ba309661 --- /dev/null +++ b/LuckParser/Models/ParseModels/Players/Minions.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace LuckParser.Models.ParseModels +{ + public class Minions : List + { + public Minions() : base() + { + } + + public List getDamageLogs(int instidFilter, BossData bossData, List combatList, AgentData agentData, long start, long end) + { + List res = new List(); + foreach (Minion minion in this) + { + res.AddRange(minion.getDamageLogs(instidFilter, bossData, combatList, agentData, start, end)); + } + return res; + } + + public List getCastLogs(BossData bossData, List combatList, AgentData agentData, long start, long end) + { + List res = new List(); + foreach (Minion minion in this) + { + res.AddRange(minion.getCastLogs( bossData, combatList, agentData, start, end)); + } + return res; + } + + public ushort getInstid() + { + if (Count > 0) + { + return this[0].getInstid(); + } + return 0; + } + + public string getCharacter() + { + if (Count > 0) + { + return this[0].getCharacter(); + } + return ""; + } + + } +} diff --git a/LuckParser/Models/ParseModels/Player.cs b/LuckParser/Models/ParseModels/Players/Player.cs similarity index 99% rename from LuckParser/Models/ParseModels/Player.cs rename to LuckParser/Models/ParseModels/Players/Player.cs index 9be542b5f..e408d6e7c 100644 --- a/LuckParser/Models/ParseModels/Player.cs +++ b/LuckParser/Models/ParseModels/Players/Player.cs @@ -4,7 +4,7 @@ namespace LuckParser.Models.ParseModels { - public class Player : AbstractPlayer + public class Player : AbstractMasterPlayer { // Fields private String account; From 1e4fbbfd48d7ac4030346bcff679aac92dc8b3fd Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 19:44:16 +0200 Subject: [PATCH 41/53] some minion correction --- LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs index 17c9ecdcc..cf11bd09d 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs @@ -30,12 +30,12 @@ public Dictionary getMinions(BossData bossData, List combatList, AgentData agentData) { List combatMinionIDList = combatList.Where(x => x.getSrcMasterInstid() == instid).Select(x => x.getSrcInstid()).Distinct().ToList(); - foreach (int petid in combatMinionIDList) + foreach (ushort petid in combatMinionIDList) { AgentItem agent = agentData.getNPCAgentList().FirstOrDefault(x => x.getInstid() == petid); if (agent != null) { - List damageLogs = getDamageLogs(0, bossData, combatList, agentData, 0, bossData.getAwareDuration()).Where(x => x.getSrcAgent() == agent.getAgent()).ToList(); + List damageLogs = getDamageLogs(0, bossData, combatList, agentData, 0, bossData.getAwareDuration()).Where(x => x.getInstidt() == petid).ToList(); if (damageLogs.Count == 0) { continue; From 06602fe5c6eb9a2a8eaedd12414711b8af75d956 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 19:51:33 +0200 Subject: [PATCH 42/53] ground work for phase based boons --- LuckParser/Controllers/Controller1.cs | 30 +++++++++++-------- LuckParser/Controllers/HTMLHelper.cs | 19 +++++++----- .../ParseModels/Players/AbstractPlayer.cs | 14 ++++----- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 47d88cfe7..da7e5029a 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1668,6 +1668,7 @@ private void CreateSupTable(StreamWriter sw, int phase_index) { /// id of the table private void CreateUptimeTable(StreamWriter sw, List list_to_use, string table_id, int phase_index) { + List phases = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data); //Generate Boon table------------------------------------------------------------------------------------------------ sw.Write(""); List> footList = new List>(); @@ -1680,7 +1681,7 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t { foreach (Player player in p_list) { - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player); List boonArrayToList = new List(); boonArrayToList.Add(player.getGroup()); int count = 0; @@ -1692,7 +1693,7 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t if (boonTable) { long fight_duration = boss_data.getLastAware() - boss_data.getFirstAware(); - Dictionary boonPresence = player.getBoonPresence(boss_data, skill_data, combat_data.getCombatList()); + Dictionary boonPresence = player.getBoonPresence(boss_data, skill_data, combat_data.getCombatList(), phases); double avg_boons = 0.0; foreach(Boon boon in list_to_use) { @@ -1803,7 +1804,7 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string { List playerID = new List(); playerID.Add(player); - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerID); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerID); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1834,7 +1835,7 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string if (p.getGroup() == player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1864,7 +1865,7 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin if (p.getGroup() != player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1893,7 +1894,7 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string } foreach (Player player in p_list) { - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1908,7 +1909,8 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string /// Settings to use private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_index) { - PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List phases = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data); + PhaseData phase = phases[phase_index]; long start = phase.getStart() + boss_data.getFirstAware(); long end = phase.getEnd() + boss_data.getFirstAware(); List s_list = skill_data.getSkillList(); @@ -2036,7 +2038,7 @@ private void CreatePlayerTab(StreamWriter sw, bool[] settingsSnap, int phase_ind { parseBoonsList.AddRange(present_personnal[p.getInstid()]); } - Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList()); + Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList(), phases); foreach (int boonid in boonGraphData.Keys.Reverse()) { BoonsGraphModel bgm = boonGraphData[boonid]; @@ -2937,7 +2939,7 @@ private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) sw.Write("
    "); { sw.Write(""); - Dictionary boonArray = HTMLHelper.getfinalcondis(boss_data,combat_data,skill_data,boss); + Dictionary boonArray = HTMLHelper.getfinalcondis(boss_data,combat_data,skill_data,agent_data, boss,boss); foreach (Boon boon in Boon.getCondiBoonList()) { sw.Write(""); @@ -2956,7 +2958,8 @@ private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) private void CreateBossSummary(StreamWriter sw, int phase_index) { //generate Player list Graphs - PhaseData phase = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data)[phase_index]; + List phases = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data); + PhaseData phase = phases[phase_index]; List casting = boss.getCastLogsActDur(boss_data, combat_data.getCombatList(), agent_data, phase.getStart(), phase.getEnd()); List s_list = skill_data.getSkillList(); string charname = boss.getCharacter(); @@ -2995,7 +2998,7 @@ private void CreateBossSummary(StreamWriter sw, int phase_index) parseBoonsList.AddRange(Boon.getCondiBoonList()); //Every buffs and boons parseBoonsList.AddRange(Boon.getAllBuffList()); - Dictionary boonGraphData = boss.getBoonGraphs(boss_data, skill_data,combat_data.getCombatList()); + Dictionary boonGraphData = boss.getBoonGraphs(boss_data, skill_data,combat_data.getCombatList(), phases); foreach (int boonid in boonGraphData.Keys.Reverse()) { if (parseBoonsList.FirstOrDefault(x => x.getID() == boonid) != null) @@ -3609,6 +3612,7 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) } public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) { + List phases = boss.getPhases(boss_data, combat_data.getCombatList(), agent_data); double fight_duration = (boss_data.getAwareDuration()) / 1000.0; Player p = p_list[0]; List casting = p.getCastLogsActDur(boss_data, combat_data.getCombatList(), agent_data, 0, boss_data.getAwareDuration()); @@ -3642,7 +3646,7 @@ public void CreateSoloHTML(StreamWriter sw, bool[] settingsSnap) { parseBoonsList.AddRange(present_personnal[p.getInstid()]); } - Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList()); + Dictionary boonGraphData = p.getBoonGraphs(boss_data, skill_data, combat_data.getCombatList(), phases); foreach (int boonid in boonGraphData.Keys.Reverse()) { if (parseBoonsList.FirstOrDefault(x => x.getID() == boonid) != null) @@ -3782,7 +3786,7 @@ public void CreateCSV(StreamWriter sw,String delimiter) finaldps[10] + delimiter + // condi finaldps[0] + delimiter); // all dps - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,p); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,agent_data, boss,p); sw.Write(boonArray[1187] + delimiter + // Quickness boonArray[30328] + delimiter + // Alacrity boonArray[740] + delimiter); // Might diff --git a/LuckParser/Controllers/HTMLHelper.cs b/LuckParser/Controllers/HTMLHelper.cs index 5bbc54e1c..52f81aa30 100644 --- a/LuckParser/Controllers/HTMLHelper.cs +++ b/LuckParser/Controllers/HTMLHelper.cs @@ -316,9 +316,10 @@ public static string[] getFinalSupport(BossData b_data, CombatData c_data, Agent String[] statsArray = new string[] { resurrects.ToString(), (restime / 1000f).ToString(), condiCleanse.ToString(), (condiCleansetime / 1000f).ToString() }; return statsArray; } - public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, Player p) + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p) { - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases); Dictionary rates = new Dictionary(); long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); foreach (Boon boon in Boon.getAllBuffList()) @@ -340,17 +341,18 @@ public static Dictionary getfinalboons(BossData b_data, CombatData } return rates; } - public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, Player p, List trgetPlayers) - { + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p, List trgetPlayers) + { if (trgetPlayers.Count() == 0) { - return getfinalboons(b_data, c_data, s_data, p); + return getfinalboons(b_data, c_data, s_data, a_data, boss, p); } + List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); Dictionary boon_logsDist = new Dictionary(); foreach (Player player in trgetPlayers) { - boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases); } Dictionary rates = new Dictionary(); foreach (Boon boon in Boon.getAllBuffList()) @@ -390,9 +392,10 @@ public static Dictionary getfinalboons(BossData b_data, CombatData } return rates; } - public static Dictionary getfinalcondis(BossData b_data, CombatData c_data, SkillData s_data, AbstractPlayer p) + public static Dictionary getfinalcondis(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, AbstractPlayer p) { - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList()); + List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(),phases); Dictionary rates = new Dictionary(); foreach (Boon boon in Boon.getCondiBoonList()) { diff --git a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index 6660a2fd4..b2a16a627 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -96,27 +96,27 @@ public List getDamageTakenLogs(BossData bossData, List co } return damageTaken_logs.Where(x => x.getTime() >= start && x.getTime() <= end).ToList(); } - public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList) + public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList, List phases) { if (boon_distribution.Count == 0) { - setBoonDistribution(bossData, skillData, combatList); + setBoonDistribution(bossData, skillData, combatList, phases); } return boon_distribution; } - public Dictionary getBoonGraphs(BossData bossData, SkillData skillData, List combatList) + public Dictionary getBoonGraphs(BossData bossData, SkillData skillData, List combatList, List phases) { if (boon_distribution.Count == 0) { - setBoonDistribution(bossData, skillData, combatList); + setBoonDistribution(bossData, skillData, combatList, phases); } return boon_points; } - public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList) + public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList, List phases) { if (boon_distribution.Count == 0) { - setBoonDistribution(bossData, skillData, combatList); + setBoonDistribution(bossData, skillData, combatList, phases); } return boon_presence; } @@ -205,7 +205,7 @@ private void setFilteredLogs(BossData bossData, List combatList, Age } } } - private void setBoonDistribution(BossData bossData, SkillData skillData, List combatList) + private void setBoonDistribution(BossData bossData, SkillData skillData, List combatList, List phases) { BoonMap to_use = getBoonMap(bossData, skillData, combatList, true); List boon_to_use = Boon.getAllBuffList(); From 26cbcf9a7796824001f1628f57f4a27d32515b04 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 20:45:05 +0200 Subject: [PATCH 43/53] average boons per phase done --- LuckParser/Controllers/Controller1.cs | 18 +++--- LuckParser/Controllers/HTMLHelper.cs | 18 +++--- .../ParseModels/Players/AbstractPlayer.cs | 59 +++++++++++-------- .../Simulator/BoonSimulationItem.cs | 12 +++- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index da7e5029a..b0b4af7ba 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1681,7 +1681,7 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t { foreach (Player player in p_list) { - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, phase_index); List boonArrayToList = new List(); boonArrayToList.Add(player.getGroup()); int count = 0; @@ -1692,8 +1692,8 @@ private void CreateUptimeTable(StreamWriter sw, List list_to_use, string t sw.Write(""); if (boonTable) { - long fight_duration = boss_data.getLastAware() - boss_data.getFirstAware(); - Dictionary boonPresence = player.getBoonPresence(boss_data, skill_data, combat_data.getCombatList(), phases); + long fight_duration = phases[phase_index].getEnd() - phases[phase_index].getStart(); + Dictionary boonPresence = player.getBoonPresence(boss_data, skill_data, combat_data.getCombatList(), phases, phase_index); double avg_boons = 0.0; foreach(Boon boon in list_to_use) { @@ -1804,7 +1804,7 @@ private void CreateGenSelfTable(StreamWriter sw, List list_to_use, string { List playerID = new List(); playerID.Add(player); - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerID); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerID, phase_index); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1835,7 +1835,7 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string if (p.getGroup() == player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS, phase_index); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1865,7 +1865,7 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin if (p.getGroup() != player.getGroup()) playerIDS.Add(p); } - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS, phase_index); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -1894,7 +1894,7 @@ private void CreateGenSquadTable(StreamWriter sw, List list_to_use, string } foreach (Player player in p_list) { - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data, agent_data, boss,player, playerIDS, phase_index); HTMLHelper.writeBoonGenTableBody(sw, player, list_to_use, boonArray); } } @@ -2939,7 +2939,7 @@ private void CreateCondiUptimeTable(StreamWriter sw,Boss boss, int phase_index) sw.Write(""); { sw.Write(""); - Dictionary boonArray = HTMLHelper.getfinalcondis(boss_data,combat_data,skill_data,agent_data, boss,boss); + Dictionary boonArray = HTMLHelper.getfinalcondis(boss_data,combat_data,skill_data,agent_data, boss,boss, phase_index); foreach (Boon boon in Boon.getCondiBoonList()) { sw.Write(""); @@ -3786,7 +3786,7 @@ public void CreateCSV(StreamWriter sw,String delimiter) finaldps[10] + delimiter + // condi finaldps[0] + delimiter); // all dps - Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,agent_data, boss,p); + Dictionary boonArray = HTMLHelper.getfinalboons(boss_data,combat_data,skill_data,agent_data, boss,p, 0); sw.Write(boonArray[1187] + delimiter + // Quickness boonArray[30328] + delimiter + // Alacrity boonArray[740] + delimiter); // Might diff --git a/LuckParser/Controllers/HTMLHelper.cs b/LuckParser/Controllers/HTMLHelper.cs index 52f81aa30..a652554aa 100644 --- a/LuckParser/Controllers/HTMLHelper.cs +++ b/LuckParser/Controllers/HTMLHelper.cs @@ -316,12 +316,12 @@ public static string[] getFinalSupport(BossData b_data, CombatData c_data, Agent String[] statsArray = new string[] { resurrects.ToString(), (restime / 1000f).ToString(), condiCleanse.ToString(), (condiCleansetime / 1000f).ToString() }; return statsArray; } - public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p) + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p, int phase_index) { List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases); + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases, phase_index); Dictionary rates = new Dictionary(); - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + long fight_duration = phases[phase_index].getEnd() - phases[phase_index].getStart(); foreach (Boon boon in Boon.getAllBuffList()) { string rate = "0"; @@ -341,18 +341,18 @@ public static Dictionary getfinalboons(BossData b_data, CombatData } return rates; } - public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p, List trgetPlayers) + public static Dictionary getfinalboons(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, Player p, List trgetPlayers, int phase_index) { if (trgetPlayers.Count() == 0) { - return getfinalboons(b_data, c_data, s_data, a_data, boss, p); + return getfinalboons(b_data, c_data, s_data, a_data, boss, p, phase_index); } List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); - long fight_duration = b_data.getLastAware() - b_data.getFirstAware(); + long fight_duration = phases[phase_index].getEnd() - phases[phase_index].getStart(); Dictionary boon_logsDist = new Dictionary(); foreach (Player player in trgetPlayers) { - boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases); + boon_logsDist[player] = player.getBoonDistribution(b_data, s_data, c_data.getCombatList(), phases, phase_index); } Dictionary rates = new Dictionary(); foreach (Boon boon in Boon.getAllBuffList()) @@ -392,10 +392,10 @@ public static Dictionary getfinalboons(BossData b_data, CombatData } return rates; } - public static Dictionary getfinalcondis(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, AbstractPlayer p) + public static Dictionary getfinalcondis(BossData b_data, CombatData c_data, SkillData s_data, AgentData a_data, Boss boss, AbstractPlayer p, int phase_index) { List phases = boss.getPhases(b_data, c_data.getCombatList(), a_data); - BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(),phases); + BoonDistribution boon_distrib = p.getBoonDistribution(b_data, s_data, c_data.getCombatList(),phases, phase_index); Dictionary rates = new Dictionary(); foreach (Boon boon in Boon.getCondiBoonList()) { diff --git a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index b2a16a627..fd734a523 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -11,8 +11,8 @@ public abstract class AbstractPlayer private String character; protected String prof; // Boons - private BoonDistribution boon_distribution = new BoonDistribution(); - private Dictionary boon_presence = new Dictionary(); + private List boon_distribution = new List(); + private List> boon_presence = new List>(); private Dictionary boon_points = new Dictionary(); // DPS protected List damage_logs = new List(); @@ -96,13 +96,13 @@ public List getDamageTakenLogs(BossData bossData, List co } return damageTaken_logs.Where(x => x.getTime() >= start && x.getTime() <= end).ToList(); } - public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList, List phases) + public BoonDistribution getBoonDistribution(BossData bossData, SkillData skillData, List combatList, List phases, int phase_index) { if (boon_distribution.Count == 0) { setBoonDistribution(bossData, skillData, combatList, phases); } - return boon_distribution; + return boon_distribution[phase_index]; } public Dictionary getBoonGraphs(BossData bossData, SkillData skillData, List combatList, List phases) { @@ -112,13 +112,13 @@ public Dictionary getBoonGraphs(BossData bossData, SkillDa } return boon_points; } - public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList, List phases) + public Dictionary getBoonPresence(BossData bossData, SkillData skillData, List combatList, List phases, int phase_index) { if (boon_distribution.Count == 0) { setBoonDistribution(bossData, skillData, combatList, phases); } - return boon_presence; + return boon_presence[phase_index]; } public List getCastLogs(BossData bossData, List combatList, AgentData agentData, long start, long end) { @@ -218,6 +218,11 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List()); + } foreach (Boon boon in boon_to_use) { int boonid = boon.getID(); @@ -228,11 +233,10 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List(); BoonSimulator simulator = boon.getSimulator(); simulator.simulate(logs, dur); long death = getDeath(bossData, combatList, 0, dur); @@ -247,29 +251,38 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List simulation = simulator.getSimulationResult(); foreach (BoonSimulationItem simul in simulation) { - if (!boon_presence.ContainsKey(boonid)) - { - boon_presence[boonid] = simul.getItemDuration(); - } - else + for (int i = 0; i < phases.Count; i++) { - boon_presence[boonid] += simul.getItemDuration(); - } - foreach (ushort src in simul.getSrc()) - { - if (!boon_distribution[boonid].ContainsKey(src)) + PhaseData phase = phases[i]; + Dictionary presenceDict = boon_presence[i]; + BoonDistribution distrib = boon_distribution[i]; + distrib[boonid] = new Dictionary(); + if (!presenceDict.ContainsKey(boonid)) { - boon_distribution[boonid][src] = new OverAndValue(simul.getDuration(src), simul.getOverstack(src)); + presenceDict[boonid] = simul.getItemDuration(phase.getStart(), phase.getEnd()); } else { - OverAndValue toModify = boon_distribution[boonid][src]; - toModify.value += simul.getDuration(src); - toModify.overstack += simul.getOverstack(src); - boon_distribution[boonid][src] = toModify; + presenceDict[boonid] += simul.getItemDuration(phase.getStart(), phase.getEnd()); + } + foreach (ushort src in simul.getSrc()) + { + if (!distrib[boonid].ContainsKey(src)) + { + distrib[boonid][src] = new OverAndValue(simul.getDuration(src), simul.getOverstack(src)); + } + else + { + OverAndValue toModify = distrib[boonid][src]; + toModify.value += simul.getDuration(src); + toModify.overstack += simul.getOverstack(src); + distrib[boonid][src] = toModify; + } } } + } + // Graphs // full precision List toFill = new List(); List toFillPresence = new List(); diff --git a/LuckParser/Models/ParseModels/Simulator/BoonSimulationItem.cs b/LuckParser/Models/ParseModels/Simulator/BoonSimulationItem.cs index ad7a673ce..6bfae693c 100644 --- a/LuckParser/Models/ParseModels/Simulator/BoonSimulationItem.cs +++ b/LuckParser/Models/ParseModels/Simulator/BoonSimulationItem.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace LuckParser.Models.ParseModels { @@ -38,8 +39,15 @@ public long getEnd() public abstract long getOverstack(ushort src); - public long getItemDuration() + public long getItemDuration(long start = 0, long end = 0) { + if (end > 0) + { + long start_offset = Math.Max(Math.Min(duration, start - this.start),0); + long item_end = this.start + duration; + long end_offset = Math.Max(Math.Min(duration, item_end - end),0); + return duration - start_offset - end_offset; + } return duration; } From b7253f2593b6c5c21762cc1189911f688558ad14 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 20:48:18 +0200 Subject: [PATCH 44/53] oops --- LuckParser/Models/ParseModels/Players/AbstractPlayer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index fd734a523..e3386a95c 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -256,7 +256,9 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List presenceDict = boon_presence[i]; BoonDistribution distrib = boon_distribution[i]; - distrib[boonid] = new Dictionary(); + if (!distrib.ContainsKey(boonid)) { + distrib[boonid] = new Dictionary(); + } if (!presenceDict.ContainsKey(boonid)) { presenceDict[boonid] = simul.getItemDuration(phase.getStart(), phase.getEnd()); From e7aa66c2dad0726ac7403c16680294b576e9e84d Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 23:26:49 +0200 Subject: [PATCH 45/53] added phase names --- LuckParser/Controllers/Controller1.cs | 7 ++++-- LuckParser/Models/ParseModels/Players/Boss.cs | 25 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index b0b4af7ba..a9e56b23b 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -3274,8 +3274,10 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { for (int i = 0; i < phases.Count; i++) { + if (phases[i].getDuration() == 0) + continue; string active = (i > 0 ? "" : "active"); - string name = i > 0 ? "Phase " + i : "Full Fight"; + string name = boss.getPhaseName(i); sw.Write("
  • " + "" + "" + name+ "" + @@ -3291,7 +3293,8 @@ public void CreateHTML(StreamWriter sw, bool[] settingsSnap) { string active = (i > 0 ? "" : "show active"); - + if (phases[i].getDuration() == 0) + continue; sw.Write("
    "); { string Html_playerDropdown = ""; diff --git a/LuckParser/Models/ParseModels/Players/Boss.cs b/LuckParser/Models/ParseModels/Players/Boss.cs index b0133397b..235effb04 100644 --- a/LuckParser/Models/ParseModels/Players/Boss.cs +++ b/LuckParser/Models/ParseModels/Players/Boss.cs @@ -27,17 +27,38 @@ public void addPhaseData(long data) { phaseData.Add(data); } + + public string getPhaseName(int phase_index) + { + if (phase_index == 0) + { + return "Full Fight"; + } + + switch (getCharacter()) + { + case "Matthias Gabrel": + return new string[] { "Fire Phase", "Ice Phase", "Storm Phase", "Abomination Phase" }[phase_index + 1]; + case "Dhuum": + return new string[] { "Roleplay", "Main Fight", "Ritual" }[phase_index + 1]; + case "Keep Construct": + return new string[] { "Phase 1", "Burn 1", "Phase 2", "Burn 2", "Phase 3", "Burn 3" }[phase_index + 1]; + default: + break; + } + + return "Phase " + phase_index; + } // Private Methods private void setPhases(BossData bossData, List combatList, AgentData agentData) { long fight_dur = bossData.getAwareDuration(); phases.Add(new PhaseData(0, fight_dur)); - string name = getCharacter(); long start = 0; long end = 0; getCastLogs(bossData, combatList, agentData, 0, fight_dur); - switch (name) + switch (getCharacter()) { case "Vale Guardian": // Invul check From 39be852ca85b9654ee13196e212be4ef10b2ef7d Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Wed, 13 Jun 2018 23:27:49 +0200 Subject: [PATCH 46/53] boons per phase done --- LuckParser/Models/ParseModels/PhaseData.cs | 2 +- .../Models/ParseModels/Players/AbstractPlayer.cs | 6 +++--- .../ParseModels/Simulator/BoonSimulationItem.cs | 4 ++-- .../Simulator/BoonSimulationItemDuration.cs | 11 ++++++++--- .../Simulator/BoonSimulationItemIntensity.cs | 8 ++++---- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/LuckParser/Models/ParseModels/PhaseData.cs b/LuckParser/Models/ParseModels/PhaseData.cs index cee133b6e..921470202 100644 --- a/LuckParser/Models/ParseModels/PhaseData.cs +++ b/LuckParser/Models/ParseModels/PhaseData.cs @@ -11,7 +11,7 @@ public PhaseData(long start, long end) this.end = end; } - public long getDuration(string format) + public long getDuration(string format = "ms") { switch (format) { diff --git a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index e3386a95c..3db98d733 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -271,13 +271,13 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List 0) + { + long dur = getItemDuration(start, end); + return (long)Math.Round((double)dur / duration * overstack); + } return overstack; } diff --git a/LuckParser/Models/ParseModels/Simulator/BoonSimulationItemIntensity.cs b/LuckParser/Models/ParseModels/Simulator/BoonSimulationItemIntensity.cs index 6f8590d96..9f0f5d681 100644 --- a/LuckParser/Models/ParseModels/Simulator/BoonSimulationItemIntensity.cs +++ b/LuckParser/Models/ParseModels/Simulator/BoonSimulationItemIntensity.cs @@ -28,12 +28,12 @@ public override void setEnd(long end) this.duration = this.stacks.Max(x => x.getDuration(0)); } - public override long getDuration(ushort src) + public override long getDuration(ushort src, long start = 0, long end = 0) { long total = 0; foreach (BoonSimulationItemDuration stack in stacks.Where(x => src == 0 || x.getSrc()[0] == src)) { - total += stack.getDuration(src); + total += stack.getDuration(src, start, end); } return total; } @@ -48,12 +48,12 @@ public override int getStack(long end) return stacks.Where(x => x.getEnd() >= end).Count(); } - public override long getOverstack(ushort src) + public override long getOverstack(ushort src, long start = 0, long end = 0) { long total = 0; foreach (BoonSimulationItemDuration stack in stacks.Where(x => src == 0 || x.getSrc()[0] == src)) { - total += stack.getOverstack(src); + total += stack.getOverstack(src, start, end); } return total; } From a387f69bfabae91c47cbfd27a29e81a1674e0612 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 00:08:59 +0200 Subject: [PATCH 47/53] added u long parsing --- LuckParser/Controllers/ParseHelper.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/LuckParser/Controllers/ParseHelper.cs b/LuckParser/Controllers/ParseHelper.cs index 08af657c7..322b78d58 100644 --- a/LuckParser/Controllers/ParseHelper.cs +++ b/LuckParser/Controllers/ParseHelper.cs @@ -65,6 +65,18 @@ public static long getLong(MemoryStream stream) // return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong(); return BitConverter.ToInt64(bytes, 0); } + public static ulong getULong(MemoryStream stream) + { + byte[] bytes = new byte[8]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + } + + // return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong(); + return BitConverter.ToUInt64(bytes, 0); + } public static string getString(MemoryStream stream, int length) { byte[] bytes = new byte[length]; From 681a0ed5b6a292d44fcd4712d361d16e0167c14b Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 00:09:46 +0200 Subject: [PATCH 48/53] moved agents to ulong --- LuckParser/Controllers/Controller1.cs | 8 ++++---- LuckParser/Models/ParseModels/Agents/Agent.cs | 6 +++--- .../Models/ParseModels/Agents/AgentData.cs | 2 +- .../Models/ParseModels/Agents/AgentItem.cs | 8 ++++---- LuckParser/Models/ParseModels/BossData.cs | 6 +++--- LuckParser/Models/ParseModels/CombatItem.cs | 16 ++++++++-------- LuckParser/Models/ParseModels/Logs/DamageLog.cs | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index a9e56b23b..d669d9a91 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -129,7 +129,7 @@ private void parseAgentData(MemoryStream stream) for (int i = 0; i < player_count; i++) { // 8 bytes: agent - long agent = ParseHelper.getLong(stream); + ulong agent = ParseHelper.getULong(stream); // 4 bytes: profession int prof = ParseHelper.getInt(stream); @@ -227,10 +227,10 @@ private void parseCombatList(MemoryStream stream) long time = ParseHelper.getLong(stream); // 8 bytes: src_agent - long src_agent = ParseHelper.getLong(stream); + ulong src_agent = ParseHelper.getULong(stream); // 8 bytes: dst_agent - long dst_agent = ParseHelper.getLong(stream); + ulong dst_agent = ParseHelper.getULong(stream); // 4 bytes: value int value = ParseHelper.getInt(stream); @@ -373,7 +373,7 @@ private void fillMissingData(MemoryStream stream) } if (c.isStateChange().getID() == 13 && log_data.getPOV() == "N/A")//Point of View { - long pov_agent = c.getSrcAgent(); + ulong pov_agent = c.getSrcAgent(); foreach (AgentItem p in player_list) { if (pov_agent == p.getAgent()) diff --git a/LuckParser/Models/ParseModels/Agents/Agent.cs b/LuckParser/Models/ParseModels/Agents/Agent.cs index 5c5013629..2e3da2218 100644 --- a/LuckParser/Models/ParseModels/Agents/Agent.cs +++ b/LuckParser/Models/ParseModels/Agents/Agent.cs @@ -31,12 +31,12 @@ public class Agent // Fields private String name; - private long ID; + private ulong ID; private int is_elite; private int prof; // Constructor - public Agent(long ID, String name, int prof, int elite) + public Agent(ulong ID, String name, int prof, int elite) { this.name = name; this.ID = ID; @@ -193,7 +193,7 @@ public String getName() return name; } - public long getID() + public ulong getID() { return ID; } diff --git a/LuckParser/Models/ParseModels/Agents/AgentData.cs b/LuckParser/Models/ParseModels/Agents/AgentData.cs index 46048578b..b4833f2b0 100644 --- a/LuckParser/Models/ParseModels/Agents/AgentData.cs +++ b/LuckParser/Models/ParseModels/Agents/AgentData.cs @@ -55,7 +55,7 @@ public List getAllAgentsList() { return all_agents_list; } - public AgentItem GetAgent(long agent) { + public AgentItem GetAgent(ulong agent) { if (agent != 0) { AgentItem agtreturn = all_agents_list.FirstOrDefault(x => x.getAgent() == agent); diff --git a/LuckParser/Models/ParseModels/Agents/AgentItem.cs b/LuckParser/Models/ParseModels/Agents/AgentItem.cs index cfd1ac1d4..406fe4db0 100644 --- a/LuckParser/Models/ParseModels/Agents/AgentItem.cs +++ b/LuckParser/Models/ParseModels/Agents/AgentItem.cs @@ -5,7 +5,7 @@ namespace LuckParser.Models.ParseModels public class AgentItem { // Fields - private long agent; + private ulong agent; private ushort instid = 0; private long first_aware = 0; private long last_aware = long.MaxValue; @@ -16,14 +16,14 @@ public class AgentItem private int condition = 0; // Constructors - public AgentItem(long agent, String name, String prof) + public AgentItem(ulong agent, String name, String prof) { this.agent = agent; this.name = name; this.prof = prof; } - public AgentItem(long agent, String name, String prof, int toughness, int healing, int condition) + public AgentItem(ulong agent, String name, String prof, int toughness, int healing, int condition) { this.agent = agent; this.name = name; @@ -50,7 +50,7 @@ public String[] toStringArray() } // Getters - public long getAgent() + public ulong getAgent() { return agent; } diff --git a/LuckParser/Models/ParseModels/BossData.cs b/LuckParser/Models/ParseModels/BossData.cs index 127224aa5..b184a1a20 100644 --- a/LuckParser/Models/ParseModels/BossData.cs +++ b/LuckParser/Models/ParseModels/BossData.cs @@ -7,7 +7,7 @@ namespace LuckParser.Models.ParseModels public class BossData { // Fields - private long agent = 0; + private ulong agent = 0; private ushort instid = 0; private long first_aware = 0; private long last_aware = long.MaxValue; @@ -36,7 +36,7 @@ public String[] toStringArray() } // Getters - public long getAgent() + public ulong getAgent() { return agent; } @@ -85,7 +85,7 @@ public List getHealthOverTime() { return healthOverTime; } // Setters - public void setAgent(long agent) + public void setAgent(ulong agent) { this.agent = agent; } diff --git a/LuckParser/Models/ParseModels/CombatItem.cs b/LuckParser/Models/ParseModels/CombatItem.cs index 3c04fcc2e..995dbf59f 100644 --- a/LuckParser/Models/ParseModels/CombatItem.cs +++ b/LuckParser/Models/ParseModels/CombatItem.cs @@ -8,8 +8,8 @@ public class CombatItem // Fields private long time; - private long src_agent; - private long dst_agent; + private ulong src_agent; + private ulong dst_agent; private int value; private int buff_dmg; private ushort overstack_value; @@ -29,7 +29,7 @@ public class CombatItem private ushort is_flanking; private ushort is_shields; // Constructor - public CombatItem(long time, long src_agent, long dst_agent, int value, int buff_dmg, ushort overstack_value, + public CombatItem(long time, ulong src_agent, ulong dst_agent, int value, int buff_dmg, ushort overstack_value, int skill_id, ushort src_instid, ushort dst_instid, ushort src_master_instid, IFF iff, ushort buff, Result result, Activation is_activation,BuffRemove is_buffremove, ushort is_ninety, ushort is_fifty, ushort is_moving, StateChange is_statechange, ushort is_flanking) @@ -55,7 +55,7 @@ public CombatItem(long time, long src_agent, long dst_agent, int value, int buff this.is_statechange = is_statechange; this.is_flanking = is_flanking; } - public CombatItem(long time, long src_agent, long dst_agent, int value, int buff_dmg, ushort overstack_value, + public CombatItem(long time, ulong src_agent, ulong dst_agent, int value, int buff_dmg, ushort overstack_value, int skill_id, ushort src_instid, ushort dst_instid, ushort src_master_instid, IFF iff, ushort buff, Result result, Activation is_activation, BuffRemove is_buffremove, ushort is_ninety, ushort is_fifty, ushort is_moving, StateChange is_statechange, ushort is_flanking, ushort is_shields) @@ -116,12 +116,12 @@ public long getTime() return time; } - public long getSrcAgent() + public ulong getSrcAgent() { return src_agent; } - public long getDstAgent() + public ulong getDstAgent() { return dst_agent; } @@ -214,12 +214,12 @@ public ushort isShields() { return is_shields; } // Setters - public void setSrcAgent(long src_agent) + public void setSrcAgent(ulong src_agent) { this.src_agent = src_agent; } - public void setDstAgent(long dst_agent) + public void setDstAgent(ulong dst_agent) { this.dst_agent = dst_agent; } diff --git a/LuckParser/Models/ParseModels/Logs/DamageLog.cs b/LuckParser/Models/ParseModels/Logs/DamageLog.cs index 2b9794e59..f0e963106 100644 --- a/LuckParser/Models/ParseModels/Logs/DamageLog.cs +++ b/LuckParser/Models/ParseModels/Logs/DamageLog.cs @@ -15,7 +15,7 @@ public abstract class DamageLog private ushort is_flanking; private Activation is_activation; private ushort is_shields; - private long src_agent; + private ulong src_agent; private ushort src_instid; // Constructor @@ -81,7 +81,7 @@ public Activation isActivation() public ushort isShields() { return is_shields; } - public long getSrcAgent() + public ulong getSrcAgent() { return src_agent; } From 0c7922e5e94662ed5f005dac2cf89d11a8476331 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 01:17:43 +0200 Subject: [PATCH 49/53] removed gadget from all agents --- LuckParser/Models/ParseModels/Agents/AgentData.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LuckParser/Models/ParseModels/Agents/AgentData.cs b/LuckParser/Models/ParseModels/Agents/AgentData.cs index b4833f2b0..46a404049 100644 --- a/LuckParser/Models/ParseModels/Agents/AgentData.cs +++ b/LuckParser/Models/ParseModels/Agents/AgentData.cs @@ -27,6 +27,7 @@ public void addItem(Agent agent, AgentItem item,string buildVersion,GW2APIContro else if (agent.getProf(buildVersion, apiController) == "GDG") { gadget_agent_list.Add(item); + return; } else { From a86eab04ef3c40275e05dea38ef911da8f7884a8 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 01:18:19 +0200 Subject: [PATCH 50/53] fixed agent parsing --- LuckParser/Controllers/Controller1.cs | 23 ++++++++++--------- LuckParser/Controllers/ParseHelper.cs | 11 +++++++++ LuckParser/Models/ParseModels/Agents/Agent.cs | 12 +++++----- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index d669d9a91..06da35b95 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -132,20 +132,21 @@ private void parseAgentData(MemoryStream stream) ulong agent = ParseHelper.getULong(stream); // 4 bytes: profession - int prof = ParseHelper.getInt(stream); + uint prof = ParseHelper.getUInt(stream); // 4 bytes: is_elite - int is_elite = ParseHelper.getInt(stream); - - // 4 bytes: toughness - int toughness = ParseHelper.getInt(stream); - - // 4 bytes: healing - int healing = ParseHelper.getInt(stream); - - // 4 bytes: condition - int condition = ParseHelper.getInt(stream); + uint is_elite = ParseHelper.getUInt(stream); + // 2 bytes: toughness + int toughness = ParseHelper.getShort(stream); + // skip concentration + ParseHelper.safeSkip(stream, 2); + // 2 bytes: healing + int healing = ParseHelper.getShort(stream); + ParseHelper.safeSkip(stream, 2); + // 2 bytes: condition + int condition = ParseHelper.getShort(stream); + ParseHelper.safeSkip(stream, 2); // 68 bytes: name String name = ParseHelper.getString(stream, 68); //Save diff --git a/LuckParser/Controllers/ParseHelper.cs b/LuckParser/Controllers/ParseHelper.cs index 322b78d58..1c11b6471 100644 --- a/LuckParser/Controllers/ParseHelper.cs +++ b/LuckParser/Controllers/ParseHelper.cs @@ -53,6 +53,17 @@ public static int getInt(MemoryStream stream) //return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); return BitConverter.ToInt32(bytes, 0); } + public static uint getUInt(MemoryStream stream) + { + byte[] bytes = new byte[4]; + for (int b = 0; b < bytes.Length; b++) + { + bytes[b] = Convert.ToByte(stream.ReadByte()); + // stream.Position++; + } + //return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt(); + return BitConverter.ToUInt32(bytes, 0); + } public static long getLong(MemoryStream stream) { byte[] bytes = new byte[8]; diff --git a/LuckParser/Models/ParseModels/Agents/Agent.cs b/LuckParser/Models/ParseModels/Agents/Agent.cs index 2e3da2218..55ef2ee6f 100644 --- a/LuckParser/Models/ParseModels/Agents/Agent.cs +++ b/LuckParser/Models/ParseModels/Agents/Agent.cs @@ -32,11 +32,11 @@ public class Agent // Fields private String name; private ulong ID; - private int is_elite; - private int prof; + private uint is_elite; + private uint prof; // Constructor - public Agent(ulong ID, String name, int prof, int elite) + public Agent(ulong ID, String name, uint prof, uint elite) { this.name = name; this.ID = ID; @@ -46,8 +46,8 @@ public Agent(ulong ID, String name, int prof, int elite) // Public Methods public string getProf(string build, GW2APIController apiController) { - if (is_elite == -1) { - if ((ID & 0xffff0000) == 0xffff0000) + if (is_elite == 0xFFFFFFFF) { + if ((prof & 0xffff0000) == 0xffff0000) { return "GDG"; } @@ -168,7 +168,7 @@ public string getProf(string build, GW2APIController apiController) { } - GW2APISpec spec = apiController.GetSpec(is_elite); + GW2APISpec spec = apiController.GetSpec((int)is_elite); if (spec.elite) { return spec.name; From d3dc79751b2f42600baacd66b366f9d1fce245d8 Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 01:32:58 +0200 Subject: [PATCH 51/53] some minion related fixes and removed agents with instid == 0 --- LuckParser/Controllers/Controller1.cs | 1 + .../Models/ParseModels/Agents/AgentData.cs | 7 +++ .../Players/AbstractMasterPlayer.cs | 50 +++++++++++++++++++ .../ParseModels/Players/AbstractPlayer.cs | 50 +------------------ .../Models/ParseModels/Players/Minion.cs | 39 ++++++++++++++- 5 files changed, 97 insertions(+), 50 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 06da35b95..8f297459d 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -562,6 +562,7 @@ private void fillMissingData(MemoryStream stream) } } + agent_data.clean(); // Sort p_list = p_list.OrderBy(a => int.Parse(a.getGroup())).ToList();//p_list.Sort((a, b)=>int.Parse(a.getGroup()) - int.Parse(b.getGroup())) setMechData(); diff --git a/LuckParser/Models/ParseModels/Agents/AgentData.cs b/LuckParser/Models/ParseModels/Agents/AgentData.cs index 46a404049..f0cc1e2cb 100644 --- a/LuckParser/Models/ParseModels/Agents/AgentData.cs +++ b/LuckParser/Models/ParseModels/Agents/AgentData.cs @@ -74,5 +74,12 @@ public AgentItem GetAgentWInst(ushort instid) { return all_agents_list.FirstOrDefault(x => x.getInstid() == instid); } + + public void clean() + { + NPC_agent_list = NPC_agent_list.Where(x => x.getInstid() != 0).ToList(); + gadget_agent_list = NPC_agent_list.Where(x => x.getInstid() != 0).ToList(); + all_agents_list = all_agents_list.Where(x => x.getInstid() != 0).ToList(); + } } } \ No newline at end of file diff --git a/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs index cf11bd09d..c6676373f 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractMasterPlayer.cs @@ -50,5 +50,55 @@ private void setMinions(BossData bossData, List combatList, AgentDat } } + protected override void setCastLogs(BossData bossData, List combatList, AgentData agentData) + { + long time_start = bossData.getFirstAware(); + CastLog curCastLog = null; + + foreach (CombatItem c in combatList) + { + LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); + if (state.getID() == 0) + { + if (instid == c.getSrcInstid())//selecting player as caster + { + if (c.isActivation().getID() > 0) + { + if (c.isActivation().getID() < 3) + { + long time = c.getTime() - time_start; + curCastLog = new CastLog(time, c.getSkillID(), c.getValue(), c.isActivation()); + } + else + { + if (curCastLog != null) + { + if (curCastLog.getID() == c.getSkillID()) + { + curCastLog = new CastLog(curCastLog.getTime(), curCastLog.getID(), curCastLog.getExpDur(), curCastLog.startActivation(), c.getValue(), c.isActivation()); + cast_logs.Add(curCastLog); + curCastLog = null; + } + } + } + } + } + } + else if (state.getID() == 11) + {//Weapon swap + if (instid == c.getSrcInstid())//selecting player as caster + { + if ((int)c.getDstAgent() == 4 || (int)c.getDstAgent() == 5) + { + long time = c.getTime() - time_start; + curCastLog = new CastLog(time, -2, (int)c.getDstAgent(), c.isActivation()); + cast_logs.Add(curCastLog); + curCastLog = null; + } + } + } + } + } + } } diff --git a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs index 3db98d733..4da0da0c8 100644 --- a/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs +++ b/LuckParser/Models/ParseModels/Players/AbstractPlayer.cs @@ -318,55 +318,7 @@ private void setBoonDistribution(BossData bossData, SkillData skillData, List combatList, AgentData agentData) - { - long time_start = bossData.getFirstAware(); - CastLog curCastLog = null; - - foreach (CombatItem c in combatList) - { - LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); - if (state.getID() == 0) - { - if (instid == c.getSrcInstid())//selecting player as caster - { - if (c.isActivation().getID() > 0) - { - if (c.isActivation().getID() < 3) - { - long time = c.getTime() - time_start; - curCastLog = new CastLog(time, c.getSkillID(), c.getValue(), c.isActivation()); - } - else - { - if (curCastLog != null) - { - if (curCastLog.getID() == c.getSkillID()) - { - curCastLog = new CastLog(curCastLog.getTime(), curCastLog.getID(), curCastLog.getExpDur(), curCastLog.startActivation(), c.getValue(), c.isActivation()); - cast_logs.Add(curCastLog); - curCastLog = null; - } - } - } - } - } - } - else if (state.getID() == 11) - {//Weapon swap - if (instid == c.getSrcInstid())//selecting player as caster - { - if ((int)c.getDstAgent() == 4 || (int)c.getDstAgent() == 5) - { - long time = c.getTime() - time_start; - curCastLog = new CastLog(time, -2, (int)c.getDstAgent(), c.isActivation()); - cast_logs.Add(curCastLog); - curCastLog = null; - } - } - } - } - } + protected abstract void setCastLogs(BossData bossData, List combatList, AgentData agentData); protected abstract void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data); // private getters private BoonMap getBoonMap(BossData bossData, SkillData skillData, List combatList, bool add_condi) diff --git a/LuckParser/Models/ParseModels/Players/Minion.cs b/LuckParser/Models/ParseModels/Players/Minion.cs index d7c46ae7f..74dc49cf5 100644 --- a/LuckParser/Models/ParseModels/Players/Minion.cs +++ b/LuckParser/Models/ParseModels/Players/Minion.cs @@ -21,7 +21,7 @@ protected override void setDamageLogs(BossData bossData, List combat long time_start = bossData.getFirstAware(); foreach (CombatItem c in combatList) { - if (instid == c.getSrcInstid())//selecting minion as caster + if (instid == c.getSrcInstid() && c.getSrcMasterInstid() == master_id)//selecting minion as caster { long time = c.getTime() - time_start; foreach (AgentItem item in agentData.getNPCAgentList()) @@ -33,6 +33,43 @@ protected override void setDamageLogs(BossData bossData, List combat } } + protected override void setCastLogs(BossData bossData, List combatList, AgentData agentData) + { + long time_start = bossData.getFirstAware(); + CastLog curCastLog = null; + + foreach (CombatItem c in combatList) + { + LuckParser.Models.ParseEnums.StateChange state = c.isStateChange(); + if (state.getID() == 0) + { + if (instid == c.getSrcInstid() && c.getSrcMasterInstid() == master_id)//selecting player as caster + { + if (c.isActivation().getID() > 0) + { + if (c.isActivation().getID() < 3) + { + long time = c.getTime() - time_start; + curCastLog = new CastLog(time, c.getSkillID(), c.getValue(), c.isActivation()); + } + else + { + if (curCastLog != null) + { + if (curCastLog.getID() == c.getSkillID()) + { + curCastLog = new CastLog(curCastLog.getTime(), curCastLog.getID(), curCastLog.getExpDur(), curCastLog.startActivation(), c.getValue(), c.isActivation()); + cast_logs.Add(curCastLog); + curCastLog = null; + } + } + } + } + } + } + } + } + protected override void setDamagetakenLogs(BossData bossData, List combatList, AgentData agentData, MechanicData m_data) { // nothing to do From 4b5d3ab00a09da548194282b52d3b814270e1d0c Mon Sep 17 00:00:00 2001 From: Jekfer Bichon Date: Thu, 14 Jun 2018 02:26:15 +0200 Subject: [PATCH 52/53] fixed a bug in boon g gen and boon o gen --- LuckParser/Controllers/Controller1.cs | 4 ++-- LuckParser/Models/ParseModels/Simulator/BoonSimulator.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/LuckParser/Controllers/Controller1.cs b/LuckParser/Controllers/Controller1.cs index 8f297459d..147b8c044 100644 --- a/LuckParser/Controllers/Controller1.cs +++ b/LuckParser/Controllers/Controller1.cs @@ -1829,9 +1829,9 @@ private void CreateGenGroupTable(StreamWriter sw, List list_to_use, string HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write("
  • "); { - List playerIDS = new List(); foreach (Player player in p_list) { + List playerIDS = new List(); foreach (Player p in p_list) { if (p.getGroup() == player.getGroup()) @@ -1859,9 +1859,9 @@ private void CreateGenOGroupTable(StreamWriter sw, List list_to_use, strin HTMLHelper.writeBoonTableHeader(sw, list_to_use); sw.Write(""); { - List playerIDS = new List(); foreach (Player player in p_list) { + List playerIDS = new List(); foreach (Player p in p_list) { if (p.getGroup() != player.getGroup()) diff --git a/LuckParser/Models/ParseModels/Simulator/BoonSimulator.cs b/LuckParser/Models/ParseModels/Simulator/BoonSimulator.cs index f088ef43b..bb0d60f50 100644 --- a/LuckParser/Models/ParseModels/Simulator/BoonSimulator.cs +++ b/LuckParser/Models/ParseModels/Simulator/BoonSimulator.cs @@ -65,6 +65,7 @@ public void trim(long fight_duration) break; } } + simulation = simulation.Where(x => x.getDuration(0) > 0).ToList(); } public void simulate(List logs, long fight_duration) { From e012172e7db2448707dece34f95432e18d44289d Mon Sep 17 00:00:00 2001 From: EliphasNUIT Date: Thu, 14 Jun 2018 02:58:49 +0200 Subject: [PATCH 53/53] Removed duplicate file --- LuckParser/Models/PhaseData.cs | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 LuckParser/Models/PhaseData.cs diff --git a/LuckParser/Models/PhaseData.cs b/LuckParser/Models/PhaseData.cs deleted file mode 100644 index ed54076c8..000000000 --- a/LuckParser/Models/PhaseData.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace LuckParser.Models.ParseModels -{ - public class PhaseData - { - public long start; - public long end; - - public PhaseData(long start, long end) - { - this.start = start; - this.end = end; - } - - public long getDuration(string format) - { - switch (format) - { - case "m": - return (end - start) / 60000; - case "s": - return (end - start) / 1000; - case "ms": - default: - return (end - start) / 1000; - } - - } - - public bool inInterval(long time, long offset = 0) - { - return start <= time - offset && time - offset <= end; - } - } -}
    " + boss.getCharacter().ToString() + "" + boonArray[boon.getID()] + "" + "\""" + "
    " + boss.getCharacter().ToString() + "" + boonArray[boon.getID()] + "