public PlayerDamageSeparationController(string playerName, long playerId, TimeSpan updateClock, TimeSpan instanceHistory, DamageParser owner, PSO2DamageTrackers activeTrackers) { trackerFlags = activeTrackers; name = playerName; id = playerId; updateInterval = updateClock; parser = owner; CombinedPlayer = new PSO2Player(playerName, playerId, updateClock, instanceHistory, activeTrackers, owner); Players.Add(CombinedPlayer); }
void buildSplitPlayer(PSO2DamageTrackers tracker, string nameSuffix) { if (IsSplit(tracker)) { if (parser.trackersToSuppress.HasFlag(tracker)) { return; //do nothing if tracker is suppressed } var player = new PSO2Player($"{name} | {nameSuffix}", id, updateInterval, parser.InstanceUpdateHistoryDuration, tracker, parser); player.SetSpecialPlayer(true, true); playerTrackerDict.Add(tracker, player); Players.Add(player); } }
public void AddDamageInstance(PSO2DamageInstance instance) { //this sends the damage instance to the correct split player, or the combined player if this instance isnt split //dispatchInstance returns true when damagetype matches split player, once true, wereAnyDispatched will be set to true. //we dont deal with ZV separation, since all players are accumulated for that, it is handled in DamageParser class itself bool wereAnyDispatched = dispatchInstance(instance.IsAISDamage, PSO2DamageTrackers.AIS, instance, "AIS"); wereAnyDispatched |= dispatchInstance(instance.IsDarkBlastDamage, PSO2DamageTrackers.DarkBlast, instance, "DB"); wereAnyDispatched |= dispatchInstance(instance.IsHeroFinishDamage, PSO2DamageTrackers.HTF, instance, "HTF"); wereAnyDispatched |= dispatchInstance(instance.IsLaconiumDamage, PSO2DamageTrackers.LSW, instance, "LSW"); wereAnyDispatched |= dispatchInstance(instance.IsPhotonDamage, PSO2DamageTrackers.PWP, instance, "PWP"); wereAnyDispatched |= dispatchInstance(instance.IsRideroidDamage, PSO2DamageTrackers.Ride, instance, "Ride"); wereAnyDispatched |= dispatchInstance(instance.IsElementalDamage && !PSO2Player.IsAllyId(instance.TargetId), PSO2DamageTrackers.Elem, instance, "Elem"); //don't split incoming elemental dmg if (!wereAnyDispatched) { CombinedPlayer.AddDamageInstance(instance); } }
private void summary_GenerateAllPlayerSummaryForPlayer(PSO2Player player, StringBuilder result) { result.AppendLine($"> {player.Name}"); result.Append($"> Contrib : {player.RelativeDPS * 100:#00.00}% dmg") .Append("\t|\t") .Append($"Dealt : {player.FilteredDamage.TotalDamage:#,##0}") .Append("\t|\t") .Append($"Taken : {player.DamageTaken.TotalDamage:#,##0}") .Append("\t|\t") .Append($"{player.FilteredDamage.TotalDPS:#,##0.##} DPS") .Append("\t|\t") .Append($"JA : {player.FilteredDamage.JustAttackPercent:#00.00}%") .Append("\t|\t") .Append($"Crit : {player.FilteredDamage.CritPercent:#00.00}%") .Append("\t|\t") .Append($"Max : {player.MaxHit:#,##0} ({player.MaxHitName})") .AppendLine() .AppendLine(); }
private void EnsurePlayerExists(PSO2DamageInstance instance) { if (PSO2Player.IsAllyId(instance.SourceId)) { if (!_players.ContainsKey(instance.SourceId)) { var controller = new PlayerDamageSeparationController(instance.SourceName, instance.SourceId, updateClock, InstanceUpdateHistoryDuration, this, trackersToSum); _players.Add(instance.SourceId, controller); Console.WriteLine($"Creating PSO2Player for source id {instance.SourceId}, name {instance.SourceName}"); } } if (PSO2Player.IsAllyId(instance.TargetId)) { if (!_players.ContainsKey(instance.TargetId)) { var controller = new PlayerDamageSeparationController(instance.TargetName, instance.TargetId, updateClock, InstanceUpdateHistoryDuration, this, trackersToSum); _players.Add(instance.TargetId, controller); Console.WriteLine($"Creating PSO2Player for target id {instance.TargetId}, name {instance.TargetName}"); } } }
public UserDoubleClickedEventArgs(PSO2Player player) { DoubleClickedPlayer = player; }
bool dispatchInstance(bool isCorrectType, PSO2DamageTrackers tracker, PSO2DamageInstance instance, string nameSuffix) { if (!isCorrectType) { return(false); } if (parser.trackersToSuppress.HasFlag(tracker) && (tracker == PSO2DamageTrackers.Elem ? !PSO2Player.IsAllyId(instance.TargetId) : true)) { return(true); //swallow this damage instance if it's suppressed. If element is hidden, only hide if its outgoing elemental dmg } else if (IsSplit(tracker)) { if (!playerTrackerDict.ContainsKey(tracker)) { buildSplitPlayer(tracker, nameSuffix); } playerTrackerDict[tracker].AddDamageInstance(instance); return(true); } return(false); }
private void updateTick(object user) { lock (updateLock) { if (resetQueued) { resetQueued = false; internalReset(); } if ((DateTime.Now - timeLastLogScanned).TotalSeconds > 10) { timeLastLogScanned = DateTime.Now; string latestLogFile = getLatestLogFile(); if (latestLogFile != lastOpenedFile) { initializeLogFile(latestLogFile); } } var damageInstances = getLatestDamageInstances(); NewDamageInstanceCount = damageInstances.Count; if (NewDamageInstanceCount > 0 && resetParserOnNewInstance) { resetParserOnNewInstance = false; internalReset(); foreach (var instance in damageInstances) { EnsurePlayerExists(instance); //since we clear the _players in internalReset, we must ensure all players exist again. } } foreach (var instance in damageInstances) { if (!hasLogStartTime) { hasLogStartTime = true; timeLogStarted = instance.Timestamp; NewSessionStarted?.Invoke(this, EventArgs.Empty); } instance.UpdateLogStartTime(timeLogStarted); lastDamageInstance = instance; if (_players.ContainsKey(instance.SourceId)) { var sourcePlayer = _players[instance.SourceId]; sourcePlayer.AddDamageInstance(instance); } if (_players.ContainsKey(instance.TargetId)) { var targetPlayer = _players[instance.TargetId]; targetPlayer.AddDamageInstance(instance); } if (instance.IsZanverseDamage && IsZanverseSplit && !trackersToSuppress.HasFlag(PSO2DamageTrackers.Zanverse)) { if (ZanversePlayer == null) { ZanversePlayer = new PSO2Player("Zanverse", long.MaxValue, updateClock, InstanceUpdateHistoryDuration, PSO2DamageTrackers.Zanverse, this); ZanversePlayer.SetSpecialPlayer(true, false); } ZanversePlayer.AddZanverseDamageInstance(instance); } damageInstancesQueued++; //should send out an update every time updateClock interval is passed between last update and this. //allows an old log to be pasted at once and still read out dps accurately over time while (lastDamageInstance.RelativeTimestamp - lastUpdateTime > updateClock) { DoUpdateTick(); } } if (timeLastUpdateInvoked != DateTime.MinValue && DateTime.Now - timeLastUpdateInvoked > timeUntilSendManualUpdate && damageInstancesQueued > 0) { NewDamageInstanceCount = damageInstancesQueued; //bugfix, NewDamageInstanceCount being set to 0 by above call is incorrect, since there actually are new instances being processed DoUpdateTick(); } if (AutoEndSession && timeLastUpdateInvoked != DateTime.MinValue && DateTime.Now - timeLastUpdateInvoked > AutoEndTimeout && !resetParserOnNewInstance) { Console.WriteLine("Notifying to end session"); AutoEndSessionEvent?.Invoke(this, EventArgs.Empty); } } }