fix(inventory): sequence secondary wield blockers
Preserve retail AmmoType from CreateObject and port BlocksUseOfShield so bow, caster, and two-handed switches remove incompatible shields, while mismatched missile ammo is also returned to the pack. Each blocker remains server-confirmed before AutoWield re-enters. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
17b5712d53
commit
815ce0dec4
14 changed files with 206 additions and 16 deletions
|
|
@ -19,6 +19,9 @@ internal sealed class AutoWieldController : IDisposable
|
|||
| EquipMask.Held
|
||||
| EquipMask.TwoHanded;
|
||||
|
||||
private const byte CombatUseMissile = 0x02;
|
||||
private const byte CombatUseTwoHanded = 0x05;
|
||||
|
||||
private static readonly EquipMask[] AutoEquipOrder =
|
||||
{
|
||||
EquipMask.HeadWear,
|
||||
|
|
@ -105,6 +108,20 @@ internal sealed class AutoWieldController : IDisposable
|
|||
if (blocker is not null)
|
||||
return BeginWeaponReplacement(item.ObjectId, blocker.ObjectId);
|
||||
|
||||
// Retail checks secondary blockers only after the primary weapon
|
||||
// slot is vacant, then re-enters AutoWield after each confirmed
|
||||
// move. ACCWeenieObject::BlocksUseOfShield @ 0x0055D3E0.
|
||||
if (BlocksUseOfShield(item)
|
||||
&& GetEquippedObjectAtLocation(
|
||||
EquipMask.Shield, priority: 0, item.ObjectId) is { } shield)
|
||||
return BeginWeaponReplacement(item.ObjectId, shield.ObjectId);
|
||||
|
||||
if (item.AmmoType is > 0
|
||||
&& GetEquippedObjectAtLocation(
|
||||
EquipMask.MissileAmmo, priority: 0, item.ObjectId) is { } ammo
|
||||
&& ammo.AmmoType != item.AmmoType)
|
||||
return BeginWeaponReplacement(item.ObjectId, ammo.ObjectId);
|
||||
|
||||
return SendWield(item, weaponLocation);
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +287,14 @@ internal sealed class AutoWieldController : IDisposable
|
|||
&& (item.WielderId == player || item.ContainerId == player);
|
||||
}
|
||||
|
||||
internal static bool BlocksUseOfShield(ClientObject item)
|
||||
{
|
||||
byte combatUse = item.CombatUse ?? 0;
|
||||
return combatUse == CombatUseTwoHanded
|
||||
|| (combatUse == CombatUseMissile && item.AmmoType is > 0)
|
||||
|| item.Type.HasFlag(ItemType.Caster);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue