public override void ComputeNPCCombatReplayActors(NPC target, ParsedLog log, CombatReplay replay) { List <AbstractCastEvent> cls = target.GetCastLogs(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ParseEnum.TargetID.Nikare: //CC var barrageN = cls.Where(x => x.SkillId == 51977).ToList(); foreach (AbstractCastEvent c in barrageN) { replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)c.Time, (int)c.EndTime), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } //Platform wipe (CM only) var aquaticDomainN = cls.Where(x => x.SkillId == 52374).ToList(); foreach (AbstractCastEvent c in aquaticDomainN) { int start = (int)c.Time; int end = (int)c.EndTime; int radius = 800; replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 255, 0, 0.3)", new AgentConnector(target))); } break; case (int)ParseEnum.TargetID.Kenut: //CC var barrageK = cls.Where(x => x.SkillId == 51977).ToList(); foreach (AbstractCastEvent c in barrageK) { replay.Decorations.Add(new CircleDecoration(true, 0, 250, ((int)c.Time, (int)c.EndTime), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } //Platform wipe (CM only) var aquaticDomainK = cls.Where(x => x.SkillId == 52374).ToList(); foreach (AbstractCastEvent c in aquaticDomainK) { int start = (int)c.Time; int end = (int)c.EndTime; int radius = 800; replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 255, 0, 0.3)", new AgentConnector(target))); } var shockwave = cls.Where(x => x.SkillId == 53018).ToList(); foreach (AbstractCastEvent c in shockwave) { int start = (int)c.Time; int delay = 960; int duration = 3000; int radius = 1200; replay.Decorations.Add(new CircleDecoration(false, start + delay + duration, radius, (start + delay, start + delay + duration), "rgba(100, 200, 255, 0.5)", new AgentConnector(target))); } var boonSteal = cls.Where(x => x.SkillId == 51965).ToList(); foreach (AbstractCastEvent c in boonSteal) { int start = (int)c.Time; int delay = 1000; int duration = 500; int width = 500; int height = 250; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing != null) { int rotation = Point3D.GetRotationFromFacing(facing); replay.Decorations.Add(new RotatedRectangleDecoration(false, 0, width, height, rotation, width / 2, (start + delay, start + delay + duration), "rgba(255, 175, 0, 0.8)", new AgentConnector(target))); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, rotation, width / 2, (start + delay, start + delay + duration), "rgba(255, 175, 0, 0.2)", new AgentConnector(target))); } } break; default: break; } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { // spirit transform var spiritTransform = log.CombatData.GetBuffData(46950).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); NPC mainTarget = Targets.Find(x => x.ID == (int)ParseEnum.TargetID.Dhuum); if (mainTarget == null) { throw new InvalidOperationException("Dhuum not found"); } foreach (AbstractBuffEvent c in spiritTransform) { int duration = 15000; HealthUpdateEvent hpUpdate = log.CombatData.GetHealthUpdateEvents(mainTarget.AgentItem).FirstOrDefault(x => x.Time > c.Time); if (hpUpdate != null && hpUpdate.HPPercent < 10.50) { duration = 30000; } AbstractBuffEvent removedBuff = log.CombatData.GetBuffRemoveAllData(48281).FirstOrDefault(x => x.To == p.AgentItem && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)c.Time; int end = start + duration; if (removedBuff != null) { end = (int)removedBuff.Time; } replay.Decorations.Add(new CircleDecoration(true, 0, 100, (start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, start + duration, 100, (start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p))); } // bomb List <AbstractBuffEvent> bombDhuum = GetFilteredList(log.CombatData, 47646, p, true); int bombDhuumStart = 0; foreach (AbstractBuffEvent c in bombDhuum) { if (c is BuffApplyEvent) { bombDhuumStart = (int)c.Time; } else { int bombDhuumEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 100, (bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.3)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, bombDhuumStart + 13000, 100, (bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.5)", new AgentConnector(p))); } } // shackles connection var shackles = GetFilteredList(log.CombatData, 47335, p, true).Concat(GetFilteredList(log.CombatData, 48591, p, true)).ToList(); int shacklesStart = 0; Player shacklesTarget = null; foreach (AbstractBuffEvent c in shackles) { if (c is BuffApplyEvent) { shacklesStart = (int)c.Time; shacklesTarget = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By); } else { int shacklesEnd = (int)c.Time; if (shacklesTarget != null) { replay.Decorations.Add(new LineDecoration(0, (shacklesStart, shacklesEnd), "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesTarget))); } } } // shackles damage (identical to the connection for now, not yet properly distinguishable from the pure connection, further investigation needed due to inconsistent behavior (triggering too early, not triggering the damaging skill though) // shackles start with buff 47335 applied from one player to the other, this is switched over to buff 48591 after mostly 2 seconds, sometimes later. This is switched to 48042 usually 4 seconds after initial application and the damaging skill 47164 starts to deal damage from that point on. // Before that point, 47164 is only logged when evaded/blocked, but doesn't deal damage. Further investigation needed. List <AbstractBuffEvent> shacklesDmg = GetFilteredList(log.CombatData, 48042, p, true); int shacklesDmgStart = 0; Player shacklesDmgTarget = null; foreach (AbstractBuffEvent c in shacklesDmg) { if (c is BuffApplyEvent) { shacklesDmgStart = (int)c.Time; shacklesDmgTarget = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By); } else { int shacklesDmgEnd = (int)c.Time; if (shacklesDmgTarget != null) { replay.Decorations.Add(new LineDecoration(0, (shacklesDmgStart, shacklesDmgEnd), "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesDmgTarget))); } } } }
public override void ComputeNPCCombatReplayActors(NPC target, ParsedLog log, CombatReplay replay) { List <AbstractCastEvent> cls = target.GetCastLogs(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ParseEnum.TargetIDS.PeerlessQadim: var cataCycle = cls.Where(x => x.SkillId == 56329).ToList(); foreach (AbstractCastEvent c in cataCycle) { int magmaRadius = 850; start = (int)c.Time; end = start + c.ActualDuration; Point3D pylonPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= end); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (start, end), "rgba(255, 220, 50, 0.15)", new PositionConnector(pylonPosition))); replay.Decorations.Add(new CircleDecoration(true, end, magmaRadius, (start, end), "rgba(255, 220, 50, 0.25)", new PositionConnector(pylonPosition))); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (end, (int)log.FightData.FightEnd), "rgba(255, 220, 0, 0.5)", new PositionConnector(pylonPosition))); } break; case (int)EntropicDistortion: //sapping surge, red tether List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, 56118, target, true); int surgeStart = 0; AbstractSingleActor source = null; foreach (AbstractBuffEvent c in sappingSurge) { if (c is BuffApplyEvent) { NPC qadim = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.PeerlessQadim); surgeStart = (int)c.Time; source = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By) ?? qadim; } else { int surgeEnd = (int)c.Time; if (source != null) { replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(target), new AgentConnector(source))); } } } break; case (int)BigKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 450, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)Pylon1: break; case (int)Pylon2: break; case (int)EnergyOrb: break; default: break; } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TrashID.Jade: List <AbstractBuffEvent> shield = GetFilteredList(log.CombatData, 38155, target, true); int shieldStart = 0; int shieldRadius = 100; foreach (AbstractBuffEvent c in shield) { if (c is BuffApplyEvent) { shieldStart = (int)c.Time; } else { int shieldEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, shieldRadius, (shieldStart, shieldEnd), "rgba(255, 200, 0, 0.3)", new AgentConnector(target))); } } var explosion = cls.Where(x => x.SkillId == 37788).ToList(); foreach (AbstractCastEvent c in explosion) { int start = (int)c.Time; int precast = 1350; int duration = 100; int radius = 1200; replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, start + precast + duration), "rgba(255, 0, 0, 0.05)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start + precast, start + precast + duration), "rgba(255, 0, 0, 0.25)", new AgentConnector(target))); } break; default: break; } }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { // fixated List <AbstractBuffEvent> fixated = GetFilteredList(log.CombatData, 56510, p, true, true); int fixatedStart = 0; foreach (AbstractBuffEvent c in fixated) { if (c is BuffApplyEvent) { fixatedStart = Math.Max((int)c.Time, 0); } else { int fixatedEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 120, (fixatedStart, fixatedEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p))); } } // Chaos Corrosion List <AbstractBuffEvent> chaosCorrosion = GetFilteredList(log.CombatData, 56182, p, true, true); int corrosionStart = 0; foreach (AbstractBuffEvent c in chaosCorrosion) { if (c is BuffApplyEvent) { corrosionStart = (int)c.Time; } else { int corrosionEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 100, (corrosionStart, corrosionEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(p))); } } // Critical Mass, debuff while carrying an orb List <AbstractBuffEvent> criticalMass = GetFilteredList(log.CombatData, 56424, p, true, true); int criticalMassStart = 0; foreach (AbstractBuffEvent c in criticalMass) { if (c is BuffApplyEvent) { criticalMassStart = (int)c.Time; } else { int criticalMassEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(false, 0, 200, (criticalMassStart, criticalMassEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(p))); } } // Magma drop List <AbstractBuffEvent> magmaDrop = GetFilteredList(log.CombatData, 56475, p, true, true); int magmaDropStart = 0; int magmaRadius = 420; int magmaOffset = 4000; string[] magmaColors = { "255, 215, 0", "255, 130, 50" }; int magmaColor = 0; foreach (AbstractBuffEvent c in magmaDrop) { if (c is BuffApplyEvent) { magmaDropStart = (int)c.Time; } else { int magmaDropEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 50, 0, 0.15)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 50, 0, 0.25)", new AgentConnector(p))); Point3D magmaNextPos = replay.PolledPositions.FirstOrDefault(x => x.Time >= magmaDropEnd); Point3D magmaPrevPos = replay.PolledPositions.LastOrDefault(x => x.Time <= magmaDropEnd); if (magmaNextPos != null || magmaPrevPos != null) { string colorToUse = magmaColors[magmaColor]; magmaColor = (magmaColor + 1) % 2; replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(" + colorToUse + ", 0.15)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd + magmaOffset, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(" + colorToUse + ", 0.25)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd + magmaOffset, (int)log.FightData.FightEnd), "rgba(" + colorToUse + ", 0.5)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); } } } //sapping surge, bad red tether List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, 56118, p, true, true); int surgeStart = 0; AbstractSingleActor source = null; foreach (AbstractBuffEvent c in sappingSurge) { if (c is BuffApplyEvent) { AbstractSingleActor qadim = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.PeerlessQadim); surgeStart = (int)c.Time; source = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? qadim; } else { int surgeEnd = (int)c.Time; if (source != null) { replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.4)", new AgentConnector(p), new AgentConnector(source))); } } } // kinetic abundance, good (blue) tether List <AbstractBuffEvent> kineticAbundance = GetFilteredList(log.CombatData, 56609, p, true, true); int kinStart = 0; AbstractSingleActor kinSource = null; foreach (AbstractBuffEvent c in kineticAbundance) { if (c is BuffApplyEvent) { kinStart = (int)c.Time; //kinSource = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By); kinSource = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? TrashMobs.FirstOrDefault(x => x.AgentItem == c.CreditedBy); } else { int kinEnd = (int)c.Time; if (kinSource != null) { replay.Decorations.Add(new LineDecoration(0, (kinStart, kinEnd), "rgba(0, 0, 255, 0.4)", new AgentConnector(p), new AgentConnector(kinSource))); } } } }
public override void ComputeAdditionalPlayerData(Player p, ParsedLog log) { // spirit transform CombatReplay replay = p.CombatReplay; List <CombatItem> spiritTransform = log.CombatData.GetBoonData(46950).Where(x => x.DstInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.None).ToList(); Target mainTarget = Targets.Find(x => x.ID == (ushort)ParseEnum.TargetIDS.Dhuum); if (mainTarget == null) { throw new InvalidOperationException("Main target of the fight not found"); } foreach (CombatItem c in spiritTransform) { int duration = 15000; if (mainTarget.HealthOverTime.FirstOrDefault(x => x.logTime > c.Time).hp < 1050) { duration = 30000; } CombatItem removedBuff = log.CombatData.GetBoonData(48281).FirstOrDefault(x => x.SrcInstid == p.InstID && x.IsBuffRemove == ParseEnum.BuffRemove.All && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)(log.FightData.ToFightSpace(c.Time)); int end = start + duration; if (removedBuff != null) { end = (int)(log.FightData.ToFightSpace(removedBuff.Time)); } replay.Actors.Add(new CircleActor(true, 0, 100, (start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p))); replay.Actors.Add(new CircleActor(true, start + duration, 100, (start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p))); } // bomb List <CombatItem> bombDhuum = GetFilteredList(log, 47646, p, true); int bombDhuumStart = 0; foreach (CombatItem c in bombDhuum) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { bombDhuumStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { int bombDhuumEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(true, 0, 100, (bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.3)", new AgentConnector(p))); replay.Actors.Add(new CircleActor(true, bombDhuumStart + 13000, 100, (bombDhuumStart, bombDhuumEnd), "rgba(80, 180, 0, 0.5)", new AgentConnector(p))); } } // shackles connection List <CombatItem> shackles = GetFilteredList(log, 47335, p, true).Concat(GetFilteredList(log, 48591, p, true)).ToList(); int shacklesStart = 0; Player shacklesTarget = null; foreach (CombatItem c in shackles) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { shacklesStart = (int)(log.FightData.ToFightSpace(c.Time)); shacklesTarget = log.PlayerList.FirstOrDefault(x => x.Agent == c.SrcAgent); } else { int shacklesEnd = (int)(log.FightData.ToFightSpace(c.Time)); if (shacklesTarget != null) { replay.Actors.Add(new LineActor(0, (shacklesStart, shacklesEnd), "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesTarget))); } } } // shackles damage (identical to the connection for now, not yet properly distinguishable from the pure connection, further investigation needed due to inconsistent behavior (triggering too early, not triggering the damaging skill though) // shackles start with buff 47335 applied from one player to the other, this is switched over to buff 48591 after mostly 2 seconds, sometimes later. This is switched to 48042 usually 4 seconds after initial application and the damaging skill 47164 starts to deal damage from that point on. // Before that point, 47164 is only logged when evaded/blocked, but doesn't deal damage. Further investigation needed. List <CombatItem> shacklesDmg = GetFilteredList(log, 48042, p, true); int shacklesDmgStart = 0; Player shacklesDmgTarget = null; foreach (CombatItem c in shacklesDmg) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { shacklesDmgStart = (int)(log.FightData.ToFightSpace(c.Time)); shacklesDmgTarget = log.PlayerList.FirstOrDefault(x => x.Agent == c.SrcAgent); } else { int shacklesDmgEnd = (int)(log.FightData.ToFightSpace(c.Time)); if (shacklesDmgTarget != null) { replay.Actors.Add(new LineActor(0, (shacklesDmgStart, shacklesDmgEnd), "rgba(0, 255, 255, 0.5)", new AgentConnector(p), new AgentConnector(shacklesDmgTarget))); } } } }
public override void ComputeTargetCombatReplayActors(Target target, ParsedLog log, CombatReplay replay) { List <CastLog> cls = target.GetCastLogs(log, 0, log.FightData.FightDuration); switch (target.ID) { case (ushort)ParseEnum.TargetIDS.Slothasor: List <CastLog> sleepy = cls.Where(x => x.SkillId == 34515).ToList(); foreach (CastLog c in sleepy) { replay.Actors.Add(new CircleActor(true, 0, 180, ((int)c.Time, (int)c.Time + c.ActualDuration), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } List <CastLog> breath = cls.Where(x => x.SkillId == 34516).ToList(); foreach (CastLog c in breath) { int start = (int)c.Time; int preCastTime = 1000; int duration = 2000; int range = 600; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 1000); if (facing != null) { int direction = Point3D.GetRotationFromFacing(facing); int angle = 60; replay.Actors.Add(new PieActor(true, 0, range, direction, angle, (start, start + preCastTime), "rgba(255,200,0,0.1)", new AgentConnector(target))); replay.Actors.Add(new PieActor(true, 0, range, direction, angle, (start + preCastTime, start + preCastTime + duration), "rgba(255,200,0,0.4)", new AgentConnector(target))); } } List <CastLog> tantrum = cls.Where(x => x.SkillId == 34547).ToList(); foreach (CastLog c in tantrum) { int start = (int)c.Time; int end = start + c.ActualDuration; replay.Actors.Add(new CircleActor(false, 0, 300, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); replay.Actors.Add(new CircleActor(true, end, 300, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); } List <CastLog> shakes = cls.Where(x => x.SkillId == 34482).ToList(); foreach (CastLog c in shakes) { int start = (int)c.Time; int end = start + c.ActualDuration; replay.Actors.Add(new CircleActor(false, 0, 700, (start, end), "rgba(255, 0, 0, 0.4)", new AgentConnector(target))); replay.Actors.Add(new CircleActor(true, end, 700, (start, end), "rgba(255, 0, 0, 0.4)", new AgentConnector(target))); } break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ArcDPSEnums.TargetID.SoullessHorror: // arena reduction var center = new Point3D(-10581, 825, -817, 0); string destroyedRingColor = "rgba(255, 120, 30, 0.3)"; if (center != null) { List <(double, int, int)> destroyedRings; if (log.FightData.IsCM) { destroyedRings = new List <(double, int, int)>() { (100, 1330, 1550), (90, 1120, 1330), (66, 910, 1120), (33, 720, 910) }; } else { destroyedRings = new List <(double, int, int)>() { (90, 1330, 1550), (66, 1120, 1330), (33, 910, 1120), }; } foreach ((double hpVal, int innerRadius, int outerRadius) in destroyedRings) { Segment hpUpdate = target.GetHealthUpdates(log).FirstOrDefault(x => x.Value <= hpVal); if (hpUpdate != null) { replay.Decorations.Add(new DoughnutDecoration(true, (int)hpUpdate.Start + 3000, innerRadius, outerRadius, ((int)hpUpdate.Start, (int)log.FightData.FightEnd), destroyedRingColor, new PositionConnector(center))); replay.Decorations.Add(new DoughnutDecoration(true, 0, innerRadius, outerRadius, ((int)hpUpdate.Start, (int)log.FightData.FightEnd), destroyedRingColor, new PositionConnector(center))); } else { break; } } } // var howling = cls.Where(x => x.SkillId == 48662).ToList(); foreach (AbstractCastEvent c in howling) { start = (int)c.Time; end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, start + c.ExpectedDuration, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } var vortex = cls.Where(x => x.SkillId == 47327).ToList(); foreach (AbstractCastEvent c in vortex) { start = (int)c.Time; end = start + 4000; Point3D next = replay.PolledPositions.FirstOrDefault(x => x.Time >= start); Point3D prev = replay.PolledPositions.LastOrDefault(x => x.Time <= start); if (next != null || prev != null) { replay.Decorations.Add(new CircleDecoration(false, 0, 380, (start, end), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, start))); replay.Decorations.Add(new CircleDecoration(true, end, 380, (start, end), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, start))); replay.Decorations.Add(new DoughnutDecoration(true, 0, 380, 760, (end, end + 1000), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, start))); } } var deathBloom = cls.Where(x => x.SkillId == 48500).ToList(); foreach (AbstractCastEvent c in deathBloom) { start = (int)c.Time; end = (int)c.EndTime; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } for (int i = 0; i < 8; i++) { replay.Decorations.Add(new PieDecoration(true, 0, 3500, Point3D.GetRotationFromFacing(facing) + (i * 360 / 8), 360 / 12, (start, end), "rgba(255,200,0,0.5)", new AgentConnector(target))); } } var quad1 = cls.Where(x => x.SkillId == 48363).ToList(); var quad2 = cls.Where(x => x.SkillId == 47915).ToList(); foreach (AbstractCastEvent c in quad1) { start = (int)c.Time; end = (int)c.EndTime; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } for (int i = 0; i < 4; i++) { replay.Decorations.Add(new PieDecoration(true, 0, 3500, Point3D.GetRotationFromFacing(facing) + (i * 360 / 4), 360 / 12, (start, end), "rgba(255,200,0,0.5)", new AgentConnector(target))); } } foreach (AbstractCastEvent c in quad2) { start = (int)c.Time; end = (int)c.EndTime; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } for (int i = 0; i < 4; i++) { replay.Decorations.Add(new PieDecoration(true, 0, 3500, Point3D.GetRotationFromFacing(facing) + 45 + (i * 360 / 4), 360 / 12, (start, end), "rgba(255,200,0,0.5)", new AgentConnector(target))); } } break; case (int)ArcDPSEnums.TrashID.Scythe: replay.Decorations.Add(new CircleDecoration(true, 0, 80, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.TormentedDead: if (replay.Positions.Count == 0) { break; } replay.Decorations.Add(new CircleDecoration(true, 0, 400, (end, end + 60000), "rgba(255, 0, 0, 0.5)", new PositionConnector(replay.Positions.Last()))); break; case (int)ArcDPSEnums.TrashID.SurgingSoul: List <Point3D> positions = replay.Positions; if (positions.Count < 2) { break; } if (positions[0].X <-12000 || positions[0].X> -9250) { replay.Decorations.Add(new RectangleDecoration(true, 0, 240, 660, (start, end), "rgba(255,100,0,0.5)", new AgentConnector(target))); break; } else if (positions[0].Y < -525 || positions[0].Y > 2275) { replay.Decorations.Add(new RectangleDecoration(true, 0, 645, 238, (start, end), "rgba(255,100,0,0.5)", new AgentConnector(target))); break; } break; case (int)ArcDPSEnums.TrashID.FleshWurm: break; default: break; } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TargetID.Sabetha: var flameWall = cls.Where(x => x.SkillId == 31332).ToList(); foreach (AbstractCastEvent c in flameWall) { int start = (int)c.Time; int preCastTime = 2800; int duration = 10000; int width = 1300; int height = 60; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { int initialDirection = (int)(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, initialDirection, width / 2, (start, start + preCastTime), "rgba(255, 100, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, initialDirection, width / 2, 360, (start + preCastTime, start + preCastTime + duration), "rgba(255, 50, 0, 0.5)", new AgentConnector(target))); } } break; case (int)ArcDPSEnums.TrashID.Kernan: var bulletHail = cls.Where(x => x.SkillId == 31721).ToList(); foreach (AbstractCastEvent c in bulletHail) { int start = (int)c.Time; int firstConeStart = start; int secondConeStart = start + 800; int thirdConeStart = start + 1600; int firstConeEnd = firstConeStart + 400; int secondConeEnd = secondConeStart + 400; int thirdConeEnd = thirdConeStart + 400; int radius = 1500; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { replay.Decorations.Add(new PieDecoration(true, 0, radius, facing, 28, (firstConeStart, firstConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(target))); replay.Decorations.Add(new PieDecoration(true, 0, radius, facing, 54, (secondConeStart, secondConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(target))); replay.Decorations.Add(new PieDecoration(true, 0, radius, facing, 81, (thirdConeStart, thirdConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(target))); } } break; case (int)ArcDPSEnums.TrashID.Knuckles: var breakbar = cls.Where(x => x.SkillId == 31763).ToList(); foreach (AbstractCastEvent c in breakbar) { replay.Decorations.Add(new CircleDecoration(true, 0, 180, ((int)c.Time, (int)c.EndTime), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } break; case (int)ArcDPSEnums.TrashID.Karde: var flameBlast = cls.Where(x => x.SkillId == 31761).ToList(); foreach (AbstractCastEvent c in flameBlast) { int start = (int)c.Time; int end = start + 4000; int radius = 600; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { replay.Decorations.Add(new PieDecoration(true, 0, radius, facing, 60, (start, end), "rgba(255,200,0,0.5)", new AgentConnector(target))); } } break; default: break; } }
public abstract void AddPoint3D(CombatReplay replay);
public override void ComputeAdditionalBossData(Boss boss, ParsedLog log) { CombatReplay replay = boss.CombatReplay; List <CastLog> cls = boss.GetCastLogs(log, 0, log.FightData.FightDuration); switch (boss.ID) { case (ushort)ParseEnum.BossIDS.Sabetha: List <CastLog> flameWall = cls.Where(x => x.SkillId == 31332).ToList(); foreach (CastLog c in flameWall) { int start = (int)c.Time; int preCastTime = 2800; int duration = 10000; int width = 1300; int height = 60; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { int initialDirection = (int)(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI); replay.Actors.Add(new RotatedRectangleActor(true, 0, width, height, initialDirection, width / 2, new Tuple <int, int>(start, start + preCastTime), "rgba(255, 100, 0, 0.2)", new AgentConnector(boss))); replay.Actors.Add(new RotatedRectangleActor(true, 0, width, height, initialDirection, width / 2, 360, new Tuple <int, int>(start + preCastTime, start + preCastTime + duration), "rgba(255, 50, 0, 0.5)", new AgentConnector(boss))); } } break; case (ushort)Kernan: List <CastLog> bulletHail = cls.Where(x => x.SkillId == 31721).ToList(); foreach (CastLog c in bulletHail) { int start = (int)c.Time; int firstConeStart = start; int secondConeStart = start + 800; int thirdConeStart = start + 1600; int firstConeEnd = firstConeStart + 400; int secondConeEnd = secondConeStart + 400; int thirdConeEnd = thirdConeStart + 400; int radius = 1500; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { replay.Actors.Add(new PieActor(true, 0, radius, facing, 28, new Tuple <int, int>(firstConeStart, firstConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(boss))); replay.Actors.Add(new PieActor(true, 0, radius, facing, 54, new Tuple <int, int>(secondConeStart, secondConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(boss))); replay.Actors.Add(new PieActor(true, 0, radius, facing, 81, new Tuple <int, int>(thirdConeStart, thirdConeEnd), "rgba(255,200,0,0.3)", new AgentConnector(boss))); } } break; case (ushort)Knuckles: List <CastLog> breakbar = cls.Where(x => x.SkillId == 31763).ToList(); foreach (CastLog c in breakbar) { replay.Actors.Add(new CircleActor(true, 0, 180, new Tuple <int, int>((int)c.Time, (int)c.Time + c.ActualDuration), "rgba(0, 180, 255, 0.3)", new AgentConnector(boss))); } break; case (ushort)Karde: List <CastLog> flameBlast = cls.Where(x => x.SkillId == 31761).ToList(); foreach (CastLog c in flameBlast) { int start = (int)c.Time; int end = start + 4000; int radius = 600; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); if (facing != null) { replay.Actors.Add(new PieActor(true, 0, radius, facing, 60, new Tuple <int, int>(start, end), "rgba(255,200,0,0.5)", new AgentConnector(boss))); } } break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { // Bombs List <CombatItem> xeraFury = GetFilteredList(log.CombatData, 35103, p, true); int xeraFuryStart = 0; foreach (CombatItem c in xeraFury) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { xeraFuryStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { int xeraFuryEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(true, 0, 550, (xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.2)", new AgentConnector(p))); replay.Actors.Add(new CircleActor(true, xeraFuryEnd, 550, (xeraFuryStart, xeraFuryEnd), "rgba(200, 150, 0, 0.4)", new AgentConnector(p))); } } //fixated Statue List <CombatItem> fixatedStatue = GetFilteredList(log.CombatData, 34912, p, true).Concat(GetFilteredList(log.CombatData, 34925, p, true)).ToList(); int fixationStatueStart = 0; Mob statue = null; foreach (CombatItem c in fixatedStatue) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { fixationStatueStart = (int)(log.FightData.ToFightSpace(c.Time)); statue = TrashMobs.FirstOrDefault(x => x.Agent == c.SrcAgent); } else { int fixationStatueEnd = (int)(log.FightData.ToFightSpace(c.Time)); if (statue != null) { replay.Actors.Add(new LineActor(0, (fixationStatueStart, fixationStatueEnd), "rgba(255, 0, 255, 0.5)", new AgentConnector(p), new AgentConnector(statue))); } } } }
public override void ComputeTargetCombatReplayActors(Target target, ParsedLog log, CombatReplay replay) { List <CastLog> cls = target.GetCastLogs(log, 0, log.FightData.FightDuration); switch (target.ID) { case (ushort)ParseEnum.TargetIDS.KeepConstruct: List <CombatItem> kcOrbCollect = GetFilteredList(log.CombatData, 35025, target, true); int kcOrbStart = 0, kcOrbEnd = 0; foreach (CombatItem c in kcOrbCollect) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { kcOrbStart = (int)log.FightData.ToFightSpace(c.Time); } else { kcOrbEnd = (int)log.FightData.ToFightSpace(c.Time); replay.Actors.Add(new CircleActor(false, 0, 300, (kcOrbStart, kcOrbEnd), "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); replay.Actors.Add(new CircleActor(true, kcOrbEnd, 300, (kcOrbStart, kcOrbEnd), "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); } } List <CastLog> towerDrop = cls.Where(x => x.SkillId == 35086).ToList(); foreach (CastLog c in towerDrop) { int start = (int)c.Time; int end = start + c.ActualDuration; int skillCast = end - 1000; Point3D next = replay.Positions.FirstOrDefault(x => x.Time >= end); Point3D prev = replay.Positions.LastOrDefault(x => x.Time <= end); if (prev != null || next != null) { replay.Actors.Add(new CircleActor(false, 0, 400, (start, skillCast), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, end))); replay.Actors.Add(new CircleActor(true, skillCast, 400, (start, skillCast), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, end))); } } List <CastLog> blades1 = cls.Where(x => x.SkillId == 35064).ToList(); List <CastLog> blades2 = cls.Where(x => x.SkillId == 35137).ToList(); List <CastLog> blades3 = cls.Where(x => x.SkillId == 34971).ToList(); int bladeDelay = 150; int duration = 1000; foreach (CastLog c in blades1) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, (start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(target))); replay.Actors.Add(new PieActor(true, 0, 1600, facing, 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer } } foreach (CastLog c in blades2) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, (start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(target))); replay.Actors.Add(new PieActor(true, 0, 1600, facing, 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI), 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer } } foreach (CastLog c in blades3) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, (start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(target))); replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI), 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + 120), 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI - 120), 360 * 3 / 32, (start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8 + 120), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8 - 120), 360 * 3 / 32, (start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(target))); // First blade lasts longer } } // phantasms locations HashSet <ushort> phantasmsID = new HashSet <ushort> { (ushort)Jessica, (ushort)Olson, (ushort)Engul, (ushort)Faerla, (ushort)Caulle, (ushort)Henley, (ushort)Galletta, (ushort)Ianim, }; foreach (Mob m in TrashMobs) { if (phantasmsID.Contains(m.ID)) { int start = (int)log.FightData.ToFightSpace(m.FirstAware); Point3D pos = m.GetCombatReplayPositions(log).FirstOrDefault(); if (pos != null) { replay.Actors.Add(new CircleActor(true, 0, 300, (start - 5000, start), "rgba(220, 50, 0, 0.5)", new PositionConnector(pos))); replay.Actors.Add(new CircleActor(true, start, 300, (start - 5000, start), "rgba(220, 50, 0, 0.5)", new PositionConnector(pos))); } } } break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { // Water "Poison Bomb" List <AbstractBuffEvent> waterToDrop = GetFilteredList(log.CombatData, 53097, p, true); int toDropStart = 0; foreach (AbstractBuffEvent c in waterToDrop) { int timer = 5000; int duration = 83000; int debuffRadius = 100; int radius = 500; if (c is BuffApplyEvent) { toDropStart = (int)c.Time; } else { int toDropEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(false, 0, debuffRadius, (toDropStart, toDropEnd), "rgba(255, 100, 0, 0.4)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, toDropStart + timer, debuffRadius, (toDropStart, toDropEnd), "rgba(255, 100, 0, 0.4)", new AgentConnector(p))); Point3D poisonNextPos = replay.PolledPositions.FirstOrDefault(x => x.Time >= toDropEnd); Point3D poisonPrevPos = replay.PolledPositions.LastOrDefault(x => x.Time <= toDropEnd); if (poisonNextPos != null || poisonPrevPos != null) { replay.Decorations.Add(new CircleDecoration(true, toDropStart + duration, radius, (toDropEnd, toDropEnd + duration), "rgba(100, 100, 100, 0.3)", new InterpolatedPositionConnector(poisonPrevPos, poisonNextPos, toDropEnd), debuffRadius)); replay.Decorations.Add(new CircleDecoration(false, toDropStart + duration, radius, (toDropEnd, toDropEnd + duration), "rgba(230, 230, 230, 0.4)", new InterpolatedPositionConnector(poisonPrevPos, poisonNextPos, toDropEnd), debuffRadius)); } } } // Bubble (Aquatic Detainment) List <AbstractBuffEvent> bubble = GetFilteredList(log.CombatData, 51755, p, true); int bubbleStart = 0; foreach (AbstractBuffEvent c in bubble) { int radius = 100; if (c is BuffApplyEvent) { bubbleStart = Math.Max((int)c.Time, 0); } else { int bubbleEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, radius, (bubbleStart, bubbleEnd), "rgba(0, 200, 255, 0.3)", new AgentConnector(p))); } } }
public override void ComputeAdditionalTargetData(Target target, ParsedLog log) { // TODO: correct position CombatReplay replay = target.CombatReplay; List <CastLog> cls = target.GetCastLogs(log, 0, log.FightData.FightDuration); switch (target.ID) { case (ushort)ParseEnum.TargetIDS.Dhuum: List <CastLog> deathmark = cls.Where(x => x.SkillId == 48176).ToList(); CastLog majorSplit = cls.Find(x => x.SkillId == 47396); foreach (CastLog c in deathmark) { int start = (int)c.Time; int zoneActive = start + 1550; int zoneDeadly = zoneActive + 6000; //point where the zone becomes impossible to walk through unscathed int zoneEnd = zoneActive + 120000; int radius = 450; if (majorSplit != null) { zoneEnd = Math.Min(zoneEnd, (int)majorSplit.Time); zoneDeadly = Math.Min(zoneDeadly, (int)majorSplit.Time); } int spellCenterDistance = 200; //hitbox radius Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 3000); Point3D targetPosition = replay.Positions.LastOrDefault(x => x.Time <= start + 3000); if (facing != null && targetPosition != null) { Point3D position = new Point3D(targetPosition.X + (facing.X * spellCenterDistance), targetPosition.Y + (facing.Y * spellCenterDistance), targetPosition.Z, targetPosition.Time); replay.Actors.Add(new CircleActor(true, zoneActive, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Actors.Add(new CircleActor(false, 0, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Actors.Add(new CircleActor(true, 0, radius, (zoneActive, zoneDeadly), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Actors.Add(new CircleActor(true, 0, radius, (zoneDeadly, zoneEnd), "rgba(255, 100, 0, 0.5)", new PositionConnector(position))); } } List <CastLog> cataCycle = cls.Where(x => x.SkillId == 48398).ToList(); foreach (CastLog c in cataCycle) { int start = (int)c.Time; int end = start + c.ActualDuration; replay.Actors.Add(new CircleActor(true, end, 300, (start, end), "rgba(255, 150, 0, 0.7)", new AgentConnector(target))); replay.Actors.Add(new CircleActor(true, 0, 300, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } List <CastLog> slash = cls.Where(x => x.SkillId == 47561).ToList(); foreach (CastLog c in slash) { int start = (int)c.Time; int end = start + c.ActualDuration; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } replay.Actors.Add(new PieActor(false, 0, 850, facing, 60, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } if (majorSplit != null) { int start = (int)majorSplit.Time; int end = (int)log.FightData.FightDuration; replay.Actors.Add(new CircleActor(true, 0, 320, (start, end), "rgba(0, 180, 255, 0.2)", new AgentConnector(target))); } break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
internal override void ComputePlayerCombatReplayActors(Player p, ParsedEvtcLog log, CombatReplay replay) { // timed bombs var timedBombs = log.CombatData.GetBuffData(31485).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in timedBombs) { int start = (int)c.Time; int end = start + 3000; replay.Decorations.Add(new CircleDecoration(false, 0, 280, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, end, 280, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(p))); } // Sapper bombs List <AbstractBuffEvent> sapperBombs = GetFilteredList(log.CombatData, 31473, p, true); int sapperStart = 0; foreach (AbstractBuffEvent c in sapperBombs) { if (c is BuffApplyEvent) { sapperStart = (int)c.Time; } else { int sapperEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(false, 0, 180, (sapperStart, sapperEnd), "rgba(200, 255, 100, 0.5)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, sapperStart + 5000, 180, (sapperStart, sapperEnd), "rgba(200, 255, 100, 0.5)", new AgentConnector(p))); } } }
public override void ComputeAdditionalTrashMobData(Mob mob, ParsedLog log) { CombatReplay replay = mob.CombatReplay; int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (mob.ID) { case (ushort)Echo: replay.Actors.Add(new CircleActor(true, 0, 120, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(mob))); break; case (ushort)Enforcer: break; case (ushort)Messenger: replay.Actors.Add(new CircleActor(true, 0, 180, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(mob))); break; case (ushort)Deathling: break; case (ushort)UnderworldReaper: if (!_isBugged && _reapersSeen >= 0) { if (_greenStart == 0) { List <CombatItem> greenTaken = log.CombatData.GetBoonData(46950).Where(x => x.IsBuffRemove == ParseEnum.BuffRemove.None).ToList(); if (greenTaken.Count > 0) { _greenStart = (int)log.FightData.ToFightSpace(greenTaken[0].Time) - 5000; } else { _greenStart = 30600; } } int multiplier = 210000; int gStart = _greenStart + _reapersSeen * 30000; List <int> greens = new List <int>() { gStart, gStart + multiplier, gStart + 2 * multiplier }; foreach (int gstart in greens) { int gend = gstart + 5000; replay.Actors.Add(new CircleActor(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(mob))); replay.Actors.Add(new CircleActor(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(mob))); } } List <CombatItem> stealths = GetFilteredList(log, 13017, mob, true); int stealthStart = 0; int stealthEnd = 0; foreach (CombatItem c in stealths) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { stealthStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { stealthEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(true, 0, 180, (stealthStart, stealthEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(mob))); } } _reapersSeen++; break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
public override void ComputeAdditionalBossData(Boss boss, ParsedLog log) { CombatReplay replay = boss.CombatReplay; List <CastLog> cls = boss.GetCastLogs(log, 0, log.FightData.FightDuration); switch (boss.ID) { case (ushort)ParseEnum.BossIDS.KeepConstruct: List <CastLog> magicCharge = cls.Where(x => x.SkillId == 35048).ToList(); List <CastLog> magicExplode = cls.Where(x => x.SkillId == 34894).ToList(); for (var i = 0; i < magicCharge.Count; i++) { CastLog charge = magicCharge[i]; if (i < magicExplode.Count) { CastLog fire = magicExplode[i]; int start = (int)charge.Time; int end = (int)fire.Time + fire.ActualDuration; replay.Actors.Add(new CircleActor(false, 0, 300, new Tuple <int, int>(start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(boss))); replay.Actors.Add(new CircleActor(true, end, 300, new Tuple <int, int>(start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(boss))); } } List <CastLog> towerDrop = cls.Where(x => x.SkillId == 35086).ToList(); foreach (CastLog c in towerDrop) { int start = (int)c.Time; int end = start + c.ActualDuration; int skillCast = end - 1000; Point3D next = replay.Positions.FirstOrDefault(x => x.Time >= end); Point3D prev = replay.Positions.LastOrDefault(x => x.Time <= end); if (prev != null || next != null) { replay.Actors.Add(new CircleActor(false, 0, 400, new Tuple <int, int>(start, skillCast), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, end))); replay.Actors.Add(new CircleActor(true, skillCast, 400, new Tuple <int, int>(start, skillCast), "rgba(255, 150, 0, 0.5)", new InterpolatedPositionConnector(prev, next, end))); } } List <CastLog> blades1 = cls.Where(x => x.SkillId == 35064).ToList(); List <CastLog> blades2 = cls.Where(x => x.SkillId == 35137).ToList(); List <CastLog> blades3 = cls.Where(x => x.SkillId == 34971).ToList(); int bladeDelay = 150; int duration = 1000; foreach (CastLog c in blades1) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, new Tuple <int, int>(start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(boss))); replay.Actors.Add(new PieActor(true, 0, 1600, facing, 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer } } foreach (CastLog c in blades2) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, new Tuple <int, int>(start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(boss))); replay.Actors.Add(new PieActor(true, 0, 1600, facing, 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI), 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer } } foreach (CastLog c in blades3) { int ticks = (int)Math.Max(0, Math.Min(Math.Ceiling((c.ActualDuration - 1150) / 1000.0), 9)); int start = (int)c.Time + bladeDelay; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time < start + 1000); if (facing == null) { continue; } replay.Actors.Add(new CircleActor(true, 0, 200, new Tuple <int, int>(start, start + (ticks + 1) * 1000), "rgba(255,0,0,0.4)", new AgentConnector(boss))); replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI), 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + 120), 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI - 120), 360 * 3 / 32, new Tuple <int, int>(start, start + 2 * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts twice as long for (int i = 1; i < ticks; i++) { replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8 + 120), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer replay.Actors.Add(new PieActor(true, 0, 1600, (int)Math.Round(Math.Atan2(-facing.Y, -facing.X) * 180 / Math.PI + i * 360 / 8 - 120), 360 * 3 / 32, new Tuple <int, int>(start + 1000 + i * duration, start + 1000 + (i + 1) * duration), "rgba(255,200,0,0.5)", new AgentConnector(boss))); // First blade lasts longer } } break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { // TODO: correct position IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ArcDPSEnums.TargetID.Dhuum: var deathmark = cls.Where(x => x.SkillId == 48176).ToList(); AbstractCastEvent majorSplit = cls.FirstOrDefault(x => x.SkillId == 47396); foreach (AbstractCastEvent c in deathmark) { start = (int)c.Time; int zoneActive = start + 1550; int zoneDeadly = zoneActive + 6000; //point where the zone becomes impossible to walk through unscathed int zoneEnd = zoneActive + 120000; int radius = 450; if (majorSplit != null) { zoneEnd = Math.Min(zoneEnd, (int)majorSplit.Time); zoneDeadly = Math.Min(zoneDeadly, (int)majorSplit.Time); } int spellCenterDistance = 200; //hitbox radius Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 3000); Point3D targetPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= start + 3000); if (facing != null && targetPosition != null) { var position = new Point3D(targetPosition.X + (facing.X * spellCenterDistance), targetPosition.Y + (facing.Y * spellCenterDistance), targetPosition.Z); replay.Decorations.Add(new CircleDecoration(true, zoneActive, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(false, 0, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneActive, zoneDeadly), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneDeadly, zoneEnd), "rgba(255, 100, 0, 0.5)", new PositionConnector(position))); } } var cataCycle = cls.Where(x => x.SkillId == 48398).ToList(); foreach (AbstractCastEvent c in cataCycle) { start = (int)c.Time; end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, end, 300, (start, end), "rgba(255, 150, 0, 0.7)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } var slash = cls.Where(x => x.SkillId == 47561).ToList(); foreach (AbstractCastEvent c in slash) { start = (int)c.Time; end = (int)c.EndTime; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } replay.Decorations.Add(new PieDecoration(false, 0, 850, facing, 60, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } if (majorSplit != null) { start = (int)majorSplit.Time; end = (int)log.FightData.FightEnd; replay.Decorations.Add(new CircleDecoration(true, 0, 320, (start, end), "rgba(0, 180, 255, 0.2)", new AgentConnector(target))); } break; case (int)ArcDPSEnums.TrashID.DhuumDesmina: break; case (int)ArcDPSEnums.TrashID.Echo: replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.Enforcer: break; case (int)ArcDPSEnums.TrashID.Messenger: replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.Deathling: break; case (int)ArcDPSEnums.TrashID.UnderworldReaper: List <AbstractBuffEvent> stealths = GetFilteredList(log.CombatData, 13017, target, true, true); int stealthStart = 0; int stealthEnd = 0; foreach (AbstractBuffEvent c in stealths) { if (c is BuffApplyEvent) { stealthStart = (int)c.Time; } else { stealthEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 180, (stealthStart, stealthEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(target))); } } if (!_isBugged) { if (_greenStart == 0) { AbstractBuffEvent greenTaken = log.CombatData.GetBuffData(46950).Where(x => x is BuffApplyEvent).FirstOrDefault(); if (greenTaken != null) { _greenStart = (int)greenTaken.Time - 5000; } else { _greenStart = 30600; } } Point3D pos = replay.Positions.FirstOrDefault(); if (replay.Positions.Count > 1) { replay.Trim(replay.Positions.LastOrDefault().Time, replay.TimeOffsets.end); } if (pos == null) { break; } int reaper = -1; foreach (KeyValuePair <Point3D, int> pair in ReapersToGreen) { if (pair.Key.DistanceToPoint(pos) < 10) { reaper = pair.Value; break; } } if (reaper == -1) { break; } int multiplier = 210000; int gStart = _greenStart + reaper * 30000; var greens = new List <int>() { gStart, gStart + multiplier, gStart + 2 * multiplier }; foreach (int gstart in greens) { int gend = gstart + 5000; replay.Decorations.Add(new CircleDecoration(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); } } break; default: break; } }
public override void ComputeAdditionalTargetData(Target target, ParsedLog log) { CombatReplay replay = target.CombatReplay; List <CastLog> cls = target.GetCastLogs(log, 0, log.FightData.FightDuration); (int, int)lifespan = ((int)target.CombatReplay.TimeOffsets.start, (int)target.CombatReplay.TimeOffsets.end); switch (target.ID) { case (ushort)ParseEnum.TargetIDS.ValeGuardian: List <CastLog> magicStorms = cls.Where(x => x.SkillId == 31419).ToList(); foreach (CastLog c in magicStorms) { replay.Actors.Add(new CircleActor(true, 0, 100, ((int)c.Time, (int)c.Time + c.ActualDuration), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } int distributedMagicDuration = 6700; int arenaRadius = 1600; int impactDuration = 110; List <CastLog> distributedMagicGreen = cls.Where(x => x.SkillId == 31750).ToList(); foreach (CastLog c in distributedMagicGreen) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Actors.Add(new PieActor(true, start + distributedMagicDuration, arenaRadius, 151, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new PieActor(true, 0, arenaRadius, 151, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new CircleActor(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-5449.0f, -20219.0f, 0.0f, 0)))); } List <CastLog> distributedMagicBlue = cls.Where(x => x.SkillId == 31340).ToList(); foreach (CastLog c in distributedMagicBlue) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Actors.Add(new PieActor(true, start + distributedMagicDuration, arenaRadius, 31, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new PieActor(true, 0, arenaRadius, 31, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new CircleActor(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-4063.0f, -20195.0f, 0.0f, 0)))); } List <CastLog> distributedMagicRed = cls.Where(x => x.SkillId == 31391).ToList(); foreach (CastLog c in distributedMagicRed) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Actors.Add(new PieActor(true, start + distributedMagicDuration, arenaRadius, 271, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new PieActor(true, 0, arenaRadius, 271, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Actors.Add(new CircleActor(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-4735.0f, -21407.0f, 0.0f, 0)))); } break; case (ushort)BlueGuardian: replay.Actors.Add(new CircleActor(false, 0, 1500, lifespan, "rgba(0, 0, 255, 0.5)", new AgentConnector(target))); break; case (ushort)GreenGuardian: replay.Actors.Add(new CircleActor(false, 0, 1500, lifespan, "rgba(0, 255, 0, 0.5)", new AgentConnector(target))); break; case (ushort)RedGuardian: replay.Actors.Add(new CircleActor(false, 0, 1500, lifespan, "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; default: throw new InvalidOperationException("Unknown ID in ComputeAdditionalData"); } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { // Poison List <CombatItem> poisonToDrop = GetFilteredList(log.CombatData, 34387, p, true); int toDropStart = 0; foreach (CombatItem c in poisonToDrop) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { toDropStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { int toDropEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(false, 0, 180, (toDropStart, toDropEnd), "rgba(255, 255, 100, 0.5)", new AgentConnector(p))); replay.Actors.Add(new CircleActor(true, toDropStart + 8000, 180, (toDropStart, toDropEnd), "rgba(255, 255, 100, 0.5)", new AgentConnector(p))); Point3D poisonNextPos = replay.Positions.FirstOrDefault(x => x.Time >= toDropEnd); Point3D poisonPrevPos = replay.Positions.LastOrDefault(x => x.Time <= toDropEnd); if (poisonNextPos != null || poisonPrevPos != null) { replay.Actors.Add(new CircleActor(true, toDropStart + 90000, 900, (toDropEnd, toDropEnd + 90000), "rgba(255, 0, 0, 0.3)", new InterpolatedPositionConnector(poisonPrevPos, poisonNextPos, toDropEnd), 180)); } } } // Transformation List <CombatItem> slubTrans = GetFilteredList(log.CombatData, 34362, p, true); int transfoStart = 0; foreach (CombatItem c in slubTrans) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { transfoStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { int transfoEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(true, 0, 180, (transfoStart, transfoEnd), "rgba(0, 80, 255, 0.3)", new AgentConnector(p))); } } // fixated List <CombatItem> fixatedSloth = GetFilteredList(log.CombatData, 34508, p, true); int fixatedSlothStart = 0; foreach (CombatItem c in fixatedSloth) { if (c.IsBuffRemove == ParseEnum.BuffRemove.None) { fixatedSlothStart = (int)(log.FightData.ToFightSpace(c.Time)); } else { int fixatedSlothEnd = (int)(log.FightData.ToFightSpace(c.Time)); replay.Actors.Add(new CircleActor(true, 0, 120, (fixatedSlothStart, fixatedSlothEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p))); } } }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { var spiritTransform = log.CombatData.GetBuffData(46950).Where(x => x.To == p.AgentItem && x is BuffApplyEvent).ToList(); foreach (AbstractBuffEvent c in spiritTransform) { int duration = 30000; AbstractBuffEvent removedBuff = log.CombatData.GetBuffRemoveAllData(48583).FirstOrDefault(x => x.To == p.AgentItem && x.Time > c.Time && x.Time < c.Time + duration); int start = (int)c.Time; int end = start + duration; if (removedBuff != null) { end = (int)removedBuff.Time; } replay.Decorations.Add(new CircleDecoration(true, 0, 100, (start, end), "rgba(0, 50, 200, 0.3)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, start + duration, 100, (start, end), "rgba(0, 50, 200, 0.5)", new AgentConnector(p))); } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ArcDPSEnums.TargetID.PeerlessQadim: var cataCycle = cls.Where(x => x.SkillId == 56329).ToList(); var forceOfHavoc = cls.Where(x => x.SkillId == 56017).ToList(); var forceOfRetal = cls.Where(x => x.SkillId == 56405).ToList(); var etherStrikes = cls.Where(x => x.SkillId == 56012 || x.SkillId == 56653).ToList(); var causticChaos = cls.Where(x => x.SkillId == 56332).ToList(); var expoReperc = cls.Where(x => x.SkillId == 56223).ToList(); foreach (AbstractCastEvent c in cataCycle) { int magmaRadius = 850; start = (int)c.Time; end = (int)c.EndTime; Point3D pylonPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= end); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (start, end), "rgba(255, 50, 50, 0.15)", new PositionConnector(pylonPosition))); replay.Decorations.Add(new CircleDecoration(true, end, magmaRadius, (start, end), "rgba(255, 50, 50, 0.25)", new PositionConnector(pylonPosition))); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (end, (int)log.FightData.FightEnd), "rgba(255, 50, 0, 0.5)", new PositionConnector(pylonPosition))); } foreach (AbstractCastEvent c in forceOfHavoc) { int roadLength = 2400; int roadWidth = 360; int hitboxOffset = 200; int subdivisions = 100; int rollOutTime = 3250; start = (int)c.Time; int preCastTime = 1500; int duration = 22500; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 1000); Point3D position = replay.Positions.LastOrDefault(x => x.Time <= start + 1000); if (facing != null && position != null) { int direction = (int)(Math.Atan2(facing.Y, facing.X) * 180 / Math.PI); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, roadLength, roadWidth, direction, roadLength / 2 + 200, (start, start + preCastTime), "rgba(255, 0, 0, 0.1)", new PositionConnector(position))); for (int i = 0; i < subdivisions; i++) { replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, roadLength / subdivisions, roadWidth, direction, (int)((i + 0.5) * roadLength / subdivisions + hitboxOffset), (start + preCastTime + i * (rollOutTime / subdivisions), start + preCastTime + i * (rollOutTime / subdivisions) + duration), "rgba(143, 0, 179, 0.6)", new PositionConnector(position))); } } } foreach (AbstractCastEvent c in forceOfRetal) { int radius = 650; double radiusIncrement = 433.3; int preCastTime = 1800; int timeBetweenCascades = 200; int cascades = 5; start = (int)c.Time + 1400; Point3D position = replay.Positions.LastOrDefault(x => x.Time <= start + 1000); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, start + preCastTime), "rgba(255, 220, 50, 0.15)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, start + preCastTime, radius, (start, start + preCastTime), "rgba(255, 220, 50, 0.25)", new PositionConnector(position))); for (int i = 0; i < cascades; i++) { replay.Decorations.Add(new DoughnutDecoration(true, 0, radius + (int)(radiusIncrement * i), radius + (int)(radiusIncrement * (i + 1)), (start + preCastTime + timeBetweenCascades * i, start + preCastTime + timeBetweenCascades * (i + 1)), "rgba(30, 30, 30, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new DoughnutDecoration(true, 0, radius + (int)(radiusIncrement * i), radius + (int)(radiusIncrement * (i + 1)), (start + preCastTime + timeBetweenCascades * (i + 1), start + preCastTime + timeBetweenCascades * (i + 2)), "rgba(50, 20, 50, 0.25)", new PositionConnector(position))); } } foreach (AbstractCastEvent c in etherStrikes) { int coneRadius = 2600; int coneAngle = 60; start = (int)c.Time; end = start + 250; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 300); replay.Decorations.Add(new PieDecoration(false, 0, coneRadius, facing, coneAngle, (start, end), "rgba(255, 100, 0, 0.30)", new AgentConnector(target))); replay.Decorations.Add(new PieDecoration(true, 0, coneRadius, facing, coneAngle, (start, end), "rgba(255, 100, 0, 0.1)", new AgentConnector(target))); } foreach (AbstractCastEvent c in causticChaos) { double acceleration = c.Acceleration; double ratio = 1.0; if (acceleration > 0) { ratio = acceleration * 0.5 + 1; } else { ratio = acceleration * 0.6 + 1; } int chaosLength = 2600; int chaosWidth = 100; start = (int)c.Time; end = (int)c.EndTime; int aimTime = (int)((double)c.ExpectedDuration * ratio); replay.Decorations.Add(new FacingDecoration((0, end), new AgentConnector(target), replay.PolledRotations)); replay.Decorations.Add(new FacingRectangleDecoration((start, end), new AgentConnector(target), replay.PolledRotations, chaosLength, chaosWidth, chaosLength / 2, "rgba(255,100,0,0.3)")); if (end > start + aimTime) { replay.Decorations.Add(new FacingRectangleDecoration((start + aimTime, end), new AgentConnector(target), replay.PolledRotations, chaosLength, chaosWidth, chaosLength / 2, "rgba(100,100,100,0.7)")); } } foreach (AbstractCastEvent c in expoReperc) { int radius = 650; start = (int)c.Time; end = (int)c.EndTime; Point3D position = replay.Positions.LastOrDefault(x => x.Time <= start + 1000); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(255, 220, 0, 0.15)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 220, 50, 0.25)", new PositionConnector(position))); foreach (NPC pylon in TrashMobs.Where(x => x.ID == 21962)) { replay.Decorations.Add(new CircleDecoration(true, 0, radius, (start, end), "rgba(255, 220, 0, 0.15)", new AgentConnector(pylon))); replay.Decorations.Add(new CircleDecoration(true, end, radius, (start, end), "rgba(255, 220, 50, 0.25)", new AgentConnector(pylon))); } } break; case (int)ArcDPSEnums.TrashID.EntropicDistortion: //sapping surge, red tether List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, 56118, target, true, true); int surgeStart = 0; AbstractSingleActor source = null; foreach (AbstractBuffEvent c in sappingSurge) { if (c is BuffApplyEvent) { AbstractSingleActor qadim = Targets.FirstOrDefault(x => x.ID == (int)ArcDPSEnums.TargetID.PeerlessQadim); surgeStart = (int)c.Time; source = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.CreditedBy) ?? qadim; } else { int surgeEnd = (int)c.Time; if (source != null) { replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.3)", new AgentConnector(target), new AgentConnector(source))); } } } Point3D firstEntropicPosition = replay.PolledPositions.FirstOrDefault(); if (firstEntropicPosition != null) { replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start - 5000, start), "rgba(255, 0, 0, 0.4)", new PositionConnector(firstEntropicPosition))); replay.Decorations.Add(new CircleDecoration(true, start, 300, (start - 5000, start), "rgba(255, 0, 0, 0.4)", new PositionConnector(firstEntropicPosition))); } break; case (int)ArcDPSEnums.TrashID.BigKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 450, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.Pylon1: break; case (int)ArcDPSEnums.TrashID.Pylon2: break; case (int)ArcDPSEnums.TrashID.EnergyOrb: replay.Decorations.Add(new CircleDecoration(true, 0, 200, (start, end), "rgba(0, 255, 0, 0.3)", new AgentConnector(target))); break; default: break; } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ArcDPSEnums.TargetID.SoulEater: var breakbar = cls.Where(x => x.SkillId == 48007).ToList(); foreach (AbstractCastEvent c in breakbar) { start = (int)c.Time; end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, start + c.ExpectedDuration, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } var vomit = cls.Where(x => x.SkillId == 47303).ToList(); foreach (AbstractCastEvent c in vomit) { start = (int)c.Time + 2100; int cascading = 1500; int duration = 15000 + cascading; end = start + duration; int radius = 900; Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start); Point3D position = replay.PolledPositions.LastOrDefault(x => x.Time <= start); if (facing != null && position != null) { replay.Decorations.Add(new PieDecoration(true, start + cascading, radius, facing, 60, (start, end), "rgba(220,255,0,0.5)", new PositionConnector(position))); } } var pseudoDeath = cls.Where(x => x.SkillId == 47440).ToList(); foreach (AbstractCastEvent c in pseudoDeath) { start = (int)c.Time; //int duration = 900; end = (int)c.EndTime; //duration; //replay.Actors.Add(new CircleActor(true, 0, 180, (start, end), "rgba(255, 150, 255, 0.35)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, end, 180, (start, end), "rgba(255, 180, 220, 0.7)", new AgentConnector(target))); } break; case (int)ArcDPSEnums.TrashID.GreenSpirit1: case (int)ArcDPSEnums.TrashID.GreenSpirit2: var green = cls.Where(x => x.SkillId == 47153).ToList(); foreach (AbstractCastEvent c in green) { int gstart = (int)c.Time + 667; int gend = gstart + 5000; replay.Decorations.Add(new CircleDecoration(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); } break; case (int)ArcDPSEnums.TrashID.SpiritHorde1: case (int)ArcDPSEnums.TrashID.SpiritHorde2: case (int)ArcDPSEnums.TrashID.SpiritHorde3: case (int)ArcDPSEnums.TrashID.OrbSpider: break; default: break; } }
public override void ComputeNPCCombatReplayActors(NPC target, ParsedLog log, CombatReplay replay) { // TODO: correct position List <AbstractCastEvent> cls = target.GetCastLogs(log, 0, log.FightData.FightEnd); int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ParseEnum.TargetID.Dhuum: var deathmark = cls.Where(x => x.SkillId == 48176).ToList(); AbstractCastEvent majorSplit = cls.Find(x => x.SkillId == 47396); foreach (AbstractCastEvent c in deathmark) { start = (int)c.Time; int zoneActive = start + 1550; int zoneDeadly = zoneActive + 6000; //point where the zone becomes impossible to walk through unscathed int zoneEnd = zoneActive + 120000; int radius = 450; if (majorSplit != null) { zoneEnd = Math.Min(zoneEnd, (int)majorSplit.Time); zoneDeadly = Math.Min(zoneDeadly, (int)majorSplit.Time); } int spellCenterDistance = 200; //hitbox radius Point3D facing = replay.Rotations.LastOrDefault(x => x.Time <= start + 3000); Point3D targetPosition = replay.PolledPositions.LastOrDefault(x => x.Time <= start + 3000); if (facing != null && targetPosition != null) { var position = new Point3D(targetPosition.X + (facing.X * spellCenterDistance), targetPosition.Y + (facing.Y * spellCenterDistance), targetPosition.Z, targetPosition.Time); replay.Decorations.Add(new CircleDecoration(true, zoneActive, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(false, 0, radius, (start, zoneActive), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneActive, zoneDeadly), "rgba(200, 255, 100, 0.5)", new PositionConnector(position))); replay.Decorations.Add(new CircleDecoration(true, 0, radius, (zoneDeadly, zoneEnd), "rgba(255, 100, 0, 0.5)", new PositionConnector(position))); } } var cataCycle = cls.Where(x => x.SkillId == 48398).ToList(); foreach (AbstractCastEvent c in cataCycle) { start = (int)c.Time; end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, end, 300, (start, end), "rgba(255, 150, 0, 0.7)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, 300, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } var slash = cls.Where(x => x.SkillId == 47561).ToList(); foreach (AbstractCastEvent c in slash) { start = (int)c.Time; end = (int)c.EndTime; Point3D facing = replay.Rotations.FirstOrDefault(x => x.Time >= start); if (facing == null) { continue; } replay.Decorations.Add(new PieDecoration(false, 0, 850, facing, 60, (start, end), "rgba(255, 150, 0, 0.5)", new AgentConnector(target))); } if (majorSplit != null) { start = (int)majorSplit.Time; end = (int)log.FightData.FightEnd; replay.Decorations.Add(new CircleDecoration(true, 0, 320, (start, end), "rgba(0, 180, 255, 0.2)", new AgentConnector(target))); } break; case (int)DhuumDesmina: break; case (int)Echo: replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; case (int)Enforcer: break; case (int)Messenger: replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(255, 125, 0, 0.5)", new AgentConnector(target))); break; case (int)Deathling: break; case (int)UnderworldReaper: // if not bugged and we assumed we are still on the reapers at the door, check if start is above 2 seconds (first reaper spawns around 10+ seconds). If yes, put _reapersSeen at 0 to start greens. if (!_isBugged && _reapersSeen < 0 && start > 2000) { //Reminder that agents appear in chronological order, after this one, reaper has spawned afer the first one _reapersSeen = 0; } if (!_isBugged && _reapersSeen >= 0) { if (_greenStart == 0) { AbstractBuffEvent greenTaken = log.CombatData.GetBuffData(46950).Where(x => x is BuffApplyEvent).FirstOrDefault(); if (greenTaken != null) { _greenStart = (int)greenTaken.Time - 5000; } else { _greenStart = 30600; } } int multiplier = 210000; int gStart = _greenStart + _reapersSeen * 30000; var greens = new List <int>() { gStart, gStart + multiplier, gStart + 2 * multiplier }; foreach (int gstart in greens) { int gend = gstart + 5000; replay.Decorations.Add(new CircleDecoration(true, 0, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, gend, 240, (gstart, gend), "rgba(0, 255, 0, 0.2)", new AgentConnector(target))); } } List <AbstractBuffEvent> stealths = GetFilteredList(log.CombatData, 13017, target, true); int stealthStart = 0; int stealthEnd = 0; foreach (AbstractBuffEvent c in stealths) { if (c is BuffApplyEvent) { stealthStart = (int)c.Time; } else { stealthEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 180, (stealthStart, stealthEnd), "rgba(80, 80, 80, 0.3)", new AgentConnector(target))); } } _reapersSeen++; break; default: break; } }
internal override void ComputePlayerCombatReplayActors(AbstractPlayer p, ParsedEvtcLog log, CombatReplay replay) { List <AbstractBuffEvent> radiantBlindnesses = GetFilteredList(log.CombatData, 56593, p, true, true); int radiantBlindnessStart = 0; foreach (AbstractBuffEvent c in radiantBlindnesses) { if (c is BuffApplyEvent) { radiantBlindnessStart = (int)c.Time; } else { replay.Decorations.Add(new CircleDecoration(true, 0, 90, (radiantBlindnessStart, (int)c.Time), "rgba(200, 0, 200, 0.3)", new AgentConnector(p))); } } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); var lifespan = ((int)replay.TimeOffsets.start, (int)replay.TimeOffsets.end); switch (target.ID) { case (int)ArcDPSEnums.TargetID.ValeGuardian: var magicStorms = cls.Where(x => x.SkillId == 31419).ToList(); foreach (AbstractCastEvent c in magicStorms) { int start = (int)c.Time; int end = (int)c.EndTime; replay.Decorations.Add(new CircleDecoration(true, start + c.ExpectedDuration, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0, 180, 255, 0.3)", new AgentConnector(target))); } int distributedMagicDuration = 6700; int arenaRadius = 1600; int impactDuration = 110; var distributedMagicGreen = cls.Where(x => x.SkillId == 31750).ToList(); foreach (AbstractCastEvent c in distributedMagicGreen) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Decorations.Add(new PieDecoration(true, start + distributedMagicDuration, arenaRadius, 151, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new PieDecoration(true, 0, arenaRadius, 151, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-5449.0f, -20219.0f, 0.0f, 0)))); } var distributedMagicBlue = cls.Where(x => x.SkillId == 31340).ToList(); foreach (AbstractCastEvent c in distributedMagicBlue) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Decorations.Add(new PieDecoration(true, start + distributedMagicDuration, arenaRadius, 31, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new PieDecoration(true, 0, arenaRadius, 31, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-4063.0f, -20195.0f, 0.0f, 0)))); } var distributedMagicRed = cls.Where(x => x.SkillId == 31391).ToList(); foreach (AbstractCastEvent c in distributedMagicRed) { int start = (int)c.Time; int end = start + distributedMagicDuration; replay.Decorations.Add(new PieDecoration(true, start + distributedMagicDuration, arenaRadius, 271, 120, (start, end), "rgba(0,255,0,0.1)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new PieDecoration(true, 0, arenaRadius, 271, 120, (end, end + impactDuration), "rgba(0,255,0,0.3)", new PositionConnector(new Point3D(-4749.838867f, -20607.296875f, 0.0f, 0)))); replay.Decorations.Add(new CircleDecoration(true, 0, 180, (start, end), "rgba(0,255,0,0.2)", new PositionConnector(new Point3D(-4735.0f, -21407.0f, 0.0f, 0)))); } break; case (int)ArcDPSEnums.TrashID.BlueGuardian: replay.Decorations.Add(new CircleDecoration(false, 0, 1500, lifespan, "rgba(0, 0, 255, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.GreenGuardian: replay.Decorations.Add(new CircleDecoration(false, 0, 1500, lifespan, "rgba(0, 255, 0, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.RedGuardian: replay.Decorations.Add(new CircleDecoration(false, 0, 1500, lifespan, "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.Seekers: replay.Decorations.Add(new CircleDecoration(false, 0, 180, lifespan, "rgba(255, 0, 0, 0.5)", new AgentConnector(target))); break; default: break; } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { int crStart = (int)replay.TimeOffsets.start; int crEnd = (int)replay.TimeOffsets.end; IReadOnlyList <AbstractCastEvent> cls = target.GetCastEvents(log, 0, log.FightData.FightEnd); switch (target.ID) { case (int)ArcDPSEnums.TargetID.Adina: var doubleQuantumQuakes = cls.Where(x => x.SkillId == 56035).ToList(); foreach (AbstractCastEvent c in doubleQuantumQuakes) { int start = (int)c.Time; int preCastTime = 2990; // casttime 0 int duration = c.ActualDuration; int width = 1100; int height = 60; foreach (int angle in new List <int> { 90, 270 }) { replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, angle, width / 2, (start, start + preCastTime), "rgba(255, 100, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, angle, width / 2, 360, (start + preCastTime, start + duration), "rgba(255, 50, 0, 0.5)", new AgentConnector(target))); } } // var tripleQuantumQuakes = cls.Where(x => x.SkillId == 56381).ToList(); foreach (AbstractCastEvent c in tripleQuantumQuakes) { int start = (int)c.Time; int preCastTime = 2990; // casttime 0 int duration = c.ActualDuration; int width = 1100; int height = 60; foreach (int angle in new List <int> { 30, 150, 270 }) { replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, angle, width / 2, (start, start + preCastTime), "rgba(255, 100, 0, 0.2)", new AgentConnector(target))); replay.Decorations.Add(new RotatedRectangleDecoration(true, 0, width, height, angle, width / 2, 360, (start + preCastTime, start + duration), "rgba(255, 50, 0, 0.5)", new AgentConnector(target))); } } // var terraforms = cls.Where(x => x.SkillId == 56049).ToList(); foreach (AbstractCastEvent c in terraforms) { int start = (int)c.Time; int delay = 2000; // casttime 0 from skill def int duration = 5000; int radius = 1100; replay.Decorations.Add(new CircleDecoration(false, start + duration, radius, (start + delay, start + duration), "rgba(255, 150, 0, 0.7)", new AgentConnector(target))); } // List <AbstractBuffEvent> diamondPalisades = GetFilteredList(log.CombatData, 56636, target, true, true); int diamondPalisadeStart = 0; foreach (AbstractBuffEvent c in diamondPalisades) { if (c is BuffApplyEvent) { diamondPalisadeStart = (int)c.Time; } else { replay.Decorations.Add(new CircleDecoration(true, 0, 90, (diamondPalisadeStart, (int)c.Time), "rgba(200, 0, 0, 0.3)", new AgentConnector(target))); } } // var boulderBarrages = cls.Where(x => x.SkillId == 56648).ToList(); foreach (AbstractCastEvent c in boulderBarrages) { int start = (int)c.Time; int duration = 4600; // cycle 3 from skill def int radius = 1100; replay.Decorations.Add(new CircleDecoration(true, start + duration, radius, (start, start + duration), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); } break; default: break; } }
public override void ComputePlayerCombatReplayActors(Player p, ParsedLog log, CombatReplay replay) { // fixated List <AbstractBuffEvent> fixated = GetFilteredList(log.CombatData, 56510, p, true); int fixatedStart = 0; foreach (AbstractBuffEvent c in fixated) { if (c is BuffApplyEvent) { fixatedStart = Math.Max((int)c.Time, 0); } else { int fixatedEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, 120, (fixatedStart, fixatedEnd), "rgba(255, 80, 255, 0.3)", new AgentConnector(p))); } } // Magma drop List <AbstractBuffEvent> magmaDrop = GetFilteredList(log.CombatData, 56475, p, true); int magmaDropStart = 0; int magmaRadius = 420; int magmaOffset = 4000; foreach (AbstractBuffEvent c in magmaDrop) { if (c is BuffApplyEvent) { magmaDropStart = (int)c.Time; } else { int magmaDropEnd = (int)c.Time; replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 150, 0, 0.15)", new AgentConnector(p))); replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd, magmaRadius, (magmaDropStart, magmaDropEnd), "rgba(255, 150, 0, 0.25)", new AgentConnector(p))); Point3D magmaNextPos = replay.PolledPositions.FirstOrDefault(x => x.Time >= magmaDropEnd); Point3D magmaPrevPos = replay.PolledPositions.LastOrDefault(x => x.Time <= magmaDropEnd); if (magmaNextPos != null || magmaPrevPos != null) { replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(255, 220, 50, 0.15)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); replay.Decorations.Add(new CircleDecoration(true, magmaDropEnd + magmaOffset, magmaRadius, (magmaDropEnd, magmaDropEnd + magmaOffset), "rgba(255, 220, 50, 0.25)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); replay.Decorations.Add(new CircleDecoration(true, 0, magmaRadius, (magmaDropEnd + magmaOffset, (int)log.FightData.FightEnd), "rgba(255, 220, 50, 0.5)", new InterpolatedPositionConnector(magmaPrevPos, magmaNextPos, magmaDropEnd))); } } } //sapping surge, bad red tether List <AbstractBuffEvent> sappingSurge = GetFilteredList(log.CombatData, 56118, p, true); int surgeStart = 0; AbstractSingleActor source = null; foreach (AbstractBuffEvent c in sappingSurge) { if (c is BuffApplyEvent) { NPC qadim = Targets.Find(x => x.ID == (int)ParseEnum.TargetIDS.PeerlessQadim); surgeStart = (int)c.Time; source = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By) ?? qadim; } else { int surgeEnd = (int)c.Time; if (source != null) { replay.Decorations.Add(new LineDecoration(0, (surgeStart, surgeEnd), "rgba(255, 0, 0, 0.4)", new AgentConnector(p), new AgentConnector(source))); } } } // kinetic abundance, good (blue) tether List <AbstractBuffEvent> kineticAbundance = GetFilteredList(log.CombatData, 56609, p, true); int kinStart = 0; AbstractSingleActor kinSource = null; foreach (AbstractBuffEvent c in kineticAbundance) { if (c is BuffApplyEvent) { kinStart = (int)c.Time; //kinSource = log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By); kinSource = (AbstractSingleActor)log.PlayerList.FirstOrDefault(x => x.AgentItem == c.By) ?? TrashMobs.FirstOrDefault(x => x.AgentItem == c.By); } else { int kinEnd = (int)c.Time; if (kinSource != null) { replay.Decorations.Add(new LineDecoration(0, (kinStart, kinEnd), "rgba(0, 0, 255, 0.4)", new AgentConnector(p), new AgentConnector(kinSource))); } } } }
internal override void ComputeNPCCombatReplayActors(NPC target, ParsedEvtcLog log, CombatReplay replay) { int start = (int)replay.TimeOffsets.start; int end = (int)replay.TimeOffsets.end; switch (target.ID) { case (int)ArcDPSEnums.TrashID.BigKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 420, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.SmallKillerTornado: replay.Decorations.Add(new CircleDecoration(true, 0, 120, (start, end), "rgba(255, 150, 0, 0.4)", new AgentConnector(target))); break; case (int)ArcDPSEnums.TrashID.SmallJumpyTornado: case (int)ArcDPSEnums.TrashID.ParalyzingWisp: case (int)ArcDPSEnums.TrashID.VoltaicWisp: break; default: break; } }