/// <summary> /// Get the correction info received from the server that is *right before* our first /// unacknowledged action. This simplifies our calculations a lot, since we just apply /// this correction, reapply all the unacknowledged actions and our correction is done. /// If we would always simply take the latest correction, we'd have to deal with applying /// corrections while simulating unacknowledged actions right before our correction, effectively /// undoing our actions. /// </summary> /// <returns>null if there are no unacknowledged actions or not enough corrections (must then ignore the correction for the frame).</returns> CorrectionInfo GetCorrectionBeforeUnackAction() { if (Corrections.Count == 0) // no corrections? no need to apply a server correction then. { return(null); } if (RecentActions.Count == 0) // no ations to redo? we just take our most recent correction and apply it { return(Corrections[Corrections.Count - 1]); } CorrectionInfo corr = null; int i; for (i = Corrections.Count - 1; i >= 0 && corr == null; --i) { // first unacknowledged action of that correction int firstAction = RecentActions.FindIndex(a => a.ID > Corrections[i].LastAcknowledgedActionId); if (firstAction < 0 || // if we have a correction with *no* unacknowledged action, we want to use it! (most recent correction) RecentActions[firstAction].Time > Corrections[i].Time) // we don't have unacknowledged actions before our correction, so this is our first before our first unack-ed action { corr = Corrections[i]; } } if (corr == null) { corr = Corrections[Corrections.Count - 1]; } return(corr); }
private CorrectionInfo[] GetCorrectionInfo(CommercialDocument document) { if (document.Definition.Category == DocumentCategory.InvoiceCorrection) { var correctionInfo = new CorrectionInfo(); var correctionDiff = Math.Abs(document.TotalValueWithoutTax); var taxCorrectionDiff = Math.Abs(document.TotalValueTax); correctionInfo.CorrectionTitle = "Zwrot towaru"; if (document.TotalValueWithoutTax < 0) { correctionInfo.TotalValueCorrectionInfo = $"Kwota zmniejszenia wartości bez podatku: {correctionDiff:N2} PLN"; correctionInfo.TotalTaxCorrectionInfo = $"Kwota zmniejszenia podatku należnego: {taxCorrectionDiff:N2} PLN"; } else if (document.TotalValueWithoutTax > 0) { correctionInfo.TotalValueCorrectionInfo = $"Kwota zwiększenia wartości bez podatku: {correctionDiff:N2} PLN"; correctionInfo.TotalTaxCorrectionInfo = $"Kwota zwiększenia podatku należnego: {taxCorrectionDiff:N2} PLN"; } return(new[] { correctionInfo }); } return(null); }
/// <summary> /// Takes the acknowledge info from the server (the position and velocity correction along with /// the last acknowledged action) and incorporate it in our game. /// The way that this works is that we take the most recent usable correction (that is to say, the /// correction that happened before any of our not-yet-acknowledged actions), and resimulate the /// world along with the unacknowledged actions up until now. This should give results very similar /// to a game without correction without external interaction. /// </summary> void ApplyCorrection(double currentTime) { // get a correction from the server to work with CorrectionInfo corr = GetCorrectionBeforeUnackAction(); if (corr == null) // no correction to use. { return; } ServerCorrectionUsed = corr.Position; // go back to our last acknowledged state (if any) double time = corr.Time; // apply the server's correction Position = corr.Position; Velocity = corr.Velocity; // resimulate up until the given state update for (int i = 0; i < RecentActions.Count; ++i) { if (RecentActions[i].ID > corr.LastAcknowledgedActionId) { var deltaT = RecentActions[i].Time - time; if (deltaT > 0) { Match.CurrentState.ApplyPhysicsUpdate(ID, deltaT); } ExecuteAction(RecentActions[i].Type); time = RecentActions[i].Time; } } var deltaTime = currentTime - time; if (deltaTime > 0) { Match.CurrentState.ApplyPhysicsUpdate(ID, deltaTime); } }
public override bool CommitCorrection(CorrectionInfo correctionInfo) => _editableInputConnection?.CommitCorrection(correctionInfo) ?? false;