acdream/tests/AcDream.Core.Tests/Combat/CombatInputPlannerTests.cs
Erik 2215c76c7e feat(combat): port retail basic combat bar
Mount authored gmCombatUI, share one press/hold/release request state machine across DAT buttons and keybindings, and recover the exact 1.0s/0.8s power timing from matching retail x86. The same timer fixes jump charge, while ready-stance, response queueing, auto-repeat, layout binding, migration, and conformance coverage keep behavior architectural rather than panel-local.

Co-Authored-By: Codex <codex@openai.com>
2026-07-11 14:03:28 +02:00

125 lines
4.1 KiB
C#

using AcDream.Core.Combat;
using AcDream.Core.Items;
namespace AcDream.Core.Tests.Combat;
public sealed class CombatInputPlannerTests
{
[Fact]
public void GetDefaultCombatMode_MissileCombatUseSelectsMissile()
{
var bow = Equipped(EquipMask.MissileWeapon, ItemType.MissileWeapon, combatUse: 2);
Assert.Equal(
CombatMode.Missile,
CombatInputPlanner.GetDefaultCombatMode([bow]));
}
[Fact]
public void GetDefaultCombatMode_PrimaryWeaponOrderMatchesRetailInventoryPlacement()
{
var bow = Equipped(EquipMask.MissileWeapon, ItemType.MissileWeapon, combatUse: 2);
var sword = Equipped(EquipMask.MeleeWeapon, ItemType.MeleeWeapon, combatUse: 1);
Assert.Equal(
CombatMode.Missile,
CombatInputPlanner.GetDefaultCombatMode([bow, sword]));
Assert.Equal(
CombatMode.Melee,
CombatInputPlanner.GetDefaultCombatMode([sword, bow]));
}
[Fact]
public void GetDefaultCombatMode_HeldCasterSelectsMagic()
{
var wand = Equipped(EquipMask.Held, ItemType.Caster, combatUse: 0);
Assert.Equal(
CombatMode.Magic,
CombatInputPlanner.GetDefaultCombatMode([wand]));
}
[Fact]
public void GetDefaultCombatMode_HeldNonCasterCannotEnterCombat()
{
var held = Equipped(EquipMask.Held, ItemType.Misc, combatUse: 0);
Assert.Equal(
CombatMode.NonCombat,
CombatInputPlanner.GetDefaultCombatMode([held]));
}
[Fact]
public void GetDefaultCombatMode_NoWeaponDefaultsToUnarmedMelee()
{
Assert.Equal(
CombatMode.Melee,
CombatInputPlanner.GetDefaultCombatMode([]));
}
[Fact]
public void ToggleMode_FromNonCombat_UsesDefaultCombatMode()
{
Assert.Equal(CombatMode.Melee, CombatInputPlanner.ToggleMode(CombatMode.NonCombat));
Assert.Equal(
CombatMode.Missile,
CombatInputPlanner.ToggleMode(CombatMode.NonCombat, CombatMode.Missile));
}
[Fact]
public void ToggleMode_FromCombat_ReturnsNonCombat()
{
Assert.Equal(CombatMode.NonCombat, CombatInputPlanner.ToggleMode(CombatMode.Melee));
Assert.Equal(CombatMode.NonCombat, CombatInputPlanner.ToggleMode(CombatMode.Magic));
}
[Theory]
[InlineData(CombatAttackAction.Low, AttackHeight.Low)]
[InlineData(CombatAttackAction.Medium, AttackHeight.Medium)]
[InlineData(CombatAttackAction.High, AttackHeight.High)]
public void HeightFor_MapsRetailAttackKeys(CombatAttackAction action, AttackHeight expected)
{
Assert.Equal(expected, CombatInputPlanner.HeightFor(action));
}
[Theory]
[InlineData(CombatMode.Melee, true)]
[InlineData(CombatMode.Missile, true)]
[InlineData(CombatMode.NonCombat, false)]
[InlineData(CombatMode.Magic, false)]
public void SupportsTargetedAttack_MatchesRetailExecuteAttackModes(
CombatMode mode,
bool expected)
{
Assert.Equal(expected, CombatInputPlanner.SupportsTargetedAttack(mode));
}
[Theory]
[InlineData(CombatMode.Melee, 0x8000003Du, 0u, true)]
[InlineData(CombatMode.Missile, 0x8000003Fu, CombatInputPlanner.ReadyForwardCommand, true)]
[InlineData(CombatMode.Missile, 0x80000041u, CombatInputPlanner.ReadyForwardCommand, true)]
[InlineData(CombatMode.Missile, 0x8000003Du, CombatInputPlanner.ReadyForwardCommand, false)]
[InlineData(CombatMode.Missile, 0x8000003Fu, 0x41000006u, false)]
[InlineData(CombatMode.NonCombat, 0x8000003Du, CombatInputPlanner.ReadyForwardCommand, false)]
public void PlayerInReadyPositionForAttack_MatchesRetailAttackBranch(
CombatMode mode,
uint style,
uint forward,
bool expected)
{
Assert.Equal(
expected,
CombatInputPlanner.PlayerInReadyPositionForAttack(mode, style, forward));
}
private static ClientObject Equipped(
EquipMask location,
ItemType type,
byte combatUse) => new()
{
ObjectId = 1,
CurrentlyEquippedLocation = location,
Type = type,
CombatUse = combatUse,
};
}