// The stored geometry is the command actually emitted to the native aiming // tree, never a chain of refreshed approximations. Entity/report/node links // are weak; cancellation and physical projectile observation clear ownership. class ERR_MortarAimSolution { IEntity Gun; ERR_HQReport Report; int OrderId; int Shot; vector GunOrigin; vector Impact; vector AimTarget; vector SalvoOffset; int Charge; float FlightTime; bool Matches(ERR_MortarBattery battery, ERR_HQReport report) { return battery && Gun && Gun == battery.Gun && Report && Report == report && OrderId == battery.OrderId && Shot == battery.OrderShots; } } class ERR_MortarAimRules { // Three-dimensional tolerances include terrain/aim-height changes. These are // equivalence limits, not permission to move the gun or redirect its barrel. static bool Equivalent(int commandedCharge, int updatedCharge, vector commandedOrigin, vector updatedOrigin, vector commandedImpact, vector updatedImpact, vector commandedAim, vector updatedAim, float commandedFlight, float updatedFlight) { return commandedCharge >= 0 && commandedCharge == updatedCharge && commandedFlight > 0 && updatedFlight > 0 && vector.Distance(commandedOrigin, updatedOrigin) <= 0.05 && vector.Distance(commandedImpact, updatedImpact) <= 0.1 && vector.Distance(commandedAim, updatedAim) <= 0.1 && Math.AbsFloat(commandedFlight - updatedFlight) <= 0.05; } }