using AcDream.Core.Items; using Xunit; namespace AcDream.Core.Tests.Items; /// /// #297: pins — the ported /// retail PublicWeenieDesc::SetPlayerKillerStatus@0x005AC7C0 bit /// rewrite — byte-for-byte against /// acclient_2013_pseudo_c.txt:441868-441890. Covers all four arms /// (PK / PKLite / Free / else-clears-all) and mutual exclusivity. /// public sealed class PlayerKillerStatusBitfieldTests { [Fact] public void Pk_SetsPkBit_ClearsFreeAndPkLite() { // Starting bitfield already has Free(0x200000) and PKLite(0x2000000) // set (shouldn't happen in practice, but the mask must still clear // them — mutual exclusivity is enforced by the rewrite, not by the // caller). uint result = PlayerKillerStatusBitfield.Apply( bitfield: 0x2200000u, pkStatus: PlayerKillerStatusBitfield.Pk); Assert.Equal(0x20u, result); } [Fact] public void PkLite_SetsPkLiteBit_ClearsPkAndFree() { uint result = PlayerKillerStatusBitfield.Apply( bitfield: 0x200020u, pkStatus: PlayerKillerStatusBitfield.PkLite); Assert.Equal(0x2000000u, result); } [Fact] public void Free_SetsFreeBit_ClearsPkAndPkLite() { uint result = PlayerKillerStatusBitfield.Apply( bitfield: 0x2000020u, pkStatus: PlayerKillerStatusBitfield.Free); Assert.Equal(0x200000u, result); } [Fact] public void OtherValue_ClearsAllThreeBits() { // Retail's implicit "NPK" default (any arg2 not in {4, 0x20, 0x40}) // clears PK/Free/PKLite and sets nothing. uint result = PlayerKillerStatusBitfield.Apply( bitfield: 0x2200020u, pkStatus: 0); Assert.Equal(0u, result); } [Theory] [InlineData(PlayerKillerStatusBitfield.Pk)] [InlineData(PlayerKillerStatusBitfield.PkLite)] [InlineData(PlayerKillerStatusBitfield.Free)] [InlineData(0)] public void NeverTouchesUnrelatedBits(int pkStatus) { // BF_PLAYER (0x8) and every other PWD bit must survive every arm — // the retail masks only ever touch bits 5/21/25. const uint unrelatedBits = 0x8u | 0x100u | 0x400000u; uint result = PlayerKillerStatusBitfield.Apply( bitfield: unrelatedBits, pkStatus: pkStatus); Assert.Equal(unrelatedBits, result & unrelatedBits); } [Fact] public void MutualExclusivity_TransitioningPkToFreeToPkLite() { uint bitfield = 0u; bitfield = PlayerKillerStatusBitfield.Apply(bitfield, PlayerKillerStatusBitfield.Pk); Assert.Equal(0x20u, bitfield); bitfield = PlayerKillerStatusBitfield.Apply(bitfield, PlayerKillerStatusBitfield.Free); Assert.Equal(0x200000u, bitfield); bitfield = PlayerKillerStatusBitfield.Apply(bitfield, PlayerKillerStatusBitfield.PkLite); Assert.Equal(0x2000000u, bitfield); bitfield = PlayerKillerStatusBitfield.Apply(bitfield, pkStatus: -1); Assert.Equal(0u, bitfield); } }