using AcDream.App.Net; using DatReaderWriter.DBObjs; using DatReaderWriter.Enums; using DatReaderWriter.Types; namespace AcDream.App.Tests.Net; public sealed class RetailSkillFormulaTests { [Fact] public void ZeroDivisorIsTheOnlyFormulaFailureGate() { SkillFormula invalid = Formula(w: 7, x: 1, y: 1, z: 0); Assert.False(RetailSkillFormula.TryCalculate(invalid, 10u, 20u, out uint invalidResult)); Assert.Equal(0u, invalidResult); SkillFormula zeroX = Formula(w: 7, x: 0, y: 2, z: 3); Assert.True(RetailSkillFormula.TryCalculate(zeroX, 10u, 4u, out uint validResult)); Assert.Equal(5u, validResult); } [Theory] [InlineData(9u, 4u, 2u)] [InlineData(10u, 4u, 3u)] [InlineData(11u, 4u, 3u)] [InlineData(12u, 4u, 3u)] public void DivisionRoundsToNearestWithExactHalvesUp( uint numerator, uint divisor, uint expected) { SkillFormula formula = Formula(w: 0, x: 1, y: 0, z: divisor); Assert.True(RetailSkillFormula.TryCalculate( formula, numerator, 0u, out uint result)); Assert.Equal(expected, result); } [Fact] public void AdditiveWordIsInsideTheNumerator() { SkillFormula formula = Formula(w: 3, x: 1, y: 1, z: 4); Assert.True(RetailSkillFormula.TryCalculate(formula, 4u, 2u, out uint result)); Assert.Equal(2u, result); } [Fact] public void NumeratorUsesUnsignedThirtyTwoBitWrap() { SkillFormula formula = Formula(w: 1, x: 2, y: 0, z: 2); Assert.True(RetailSkillFormula.TryCalculate( formula, uint.MaxValue, 0u, out uint result)); Assert.Equal(0x80000000u, result); } [Fact] public void SignedDatStorageIsReinterpretedAsRetailUnsignedWords() { SkillFormula formula = Formula(w: -1, x: 0, y: 0, z: 1); Assert.True(RetailSkillFormula.TryCalculate(formula, 0u, 0u, out uint result)); Assert.Equal(uint.MaxValue, result); } [Fact] public void LiveResolverLooksUpTheDatFormulaAndTreatsMissingAttributesAsZero() { const uint skillId = 0x345u; const uint firstAttributeId = 1u; const uint secondAttributeId = 2u; var skillTable = new SkillTable(); skillTable.Skills.Add((SkillId)skillId, new SkillBase { Formula = new SkillFormula { AdditiveBonus = 1, Attribute1Multiplier = 1, Attribute2Multiplier = 2, Divisor = 3, Attribute1 = (AttributeId)firstAttributeId, Attribute2 = (AttributeId)secondAttributeId, }, }); var resolver = new LiveSkillCreditResolver(skillTable); uint result = resolver.Resolve( skillId, new Dictionary { [firstAttributeId] = 8u }); Assert.Equal(3u, result); Assert.Equal(0u, resolver.Resolve(0x999u, new Dictionary())); } private static SkillFormula Formula(int w, int x, int y, uint z) => new() { AdditiveBonus = w, Attribute1Multiplier = x, Attribute2Multiplier = y, Divisor = unchecked((int)z), }; }