feat(equipment): remove the requiredLevel equipment gate - owned items are always equippable
This commit is contained in:
@@ -4,7 +4,6 @@ export type EquipmentErrorCode =
|
||||
| 'CHARACTER_ITEM_NOT_FOUND'
|
||||
| 'ITEM_NOT_OWNED'
|
||||
| 'ITEM_NOT_EQUIPPABLE'
|
||||
| 'ITEM_LEVEL_REQUIREMENT_NOT_MET'
|
||||
| 'INVALID_EQUIPMENT_SLOT'
|
||||
| 'CHARACTER_IN_COMBAT';
|
||||
|
||||
@@ -42,14 +41,6 @@ export function itemNotEquippable(): EquipmentDomainError {
|
||||
);
|
||||
}
|
||||
|
||||
export function itemLevelRequirementNotMet(): EquipmentDomainError {
|
||||
return new EquipmentDomainError(
|
||||
'ITEM_LEVEL_REQUIREMENT_NOT_MET',
|
||||
HttpStatus.BAD_REQUEST,
|
||||
"The character does not meet this item's level requirement.",
|
||||
);
|
||||
}
|
||||
|
||||
// Defensive: slot is always derived from the item definition server-side, so
|
||||
// this is unreachable in practice (spec §27 still names it explicitly).
|
||||
export function invalidEquipmentSlot(): EquipmentDomainError {
|
||||
|
||||
@@ -143,7 +143,6 @@ function itemDefinition(overrides: Partial<ItemDefinition> = {}): ItemDefinition
|
||||
equipmentSlot: EquipmentSlot.WEAPON,
|
||||
rarity: ItemRarity.COMMON,
|
||||
tier: 1,
|
||||
requiredLevel: 1,
|
||||
weaponDamage: 8,
|
||||
bonusHp: 0,
|
||||
bonusAttack: 0,
|
||||
@@ -160,7 +159,6 @@ function character(overrides: Partial<Character> = {}): Character {
|
||||
return {
|
||||
id: CHARACTER_ID,
|
||||
name: 'Aric Duskwalker',
|
||||
level: 1,
|
||||
baseHp: 100,
|
||||
baseAttack: 6,
|
||||
currentHp: 100,
|
||||
@@ -300,29 +298,28 @@ describe('EquipmentService', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('rejects equipping an item above the character level', async () => {
|
||||
const highLevelHelm = itemDefinition({
|
||||
it('equips an owned item regardless of the item content that used to carry a level requirement', async () => {
|
||||
const highTierHelm = itemDefinition({
|
||||
id: BANDIT_HOOD_ITEM_ID,
|
||||
key: 'bandit-hood',
|
||||
equipmentSlot: EquipmentSlot.HEAD,
|
||||
requiredLevel: 5,
|
||||
tier: 5,
|
||||
});
|
||||
const { service } = createHarness({
|
||||
itemDefinitions: [highLevelHelm],
|
||||
itemDefinitions: [highTierHelm],
|
||||
characterItems: [
|
||||
{
|
||||
id: BANDIT_HOOD_ITEM_ID,
|
||||
characterId: CHARACTER_ID,
|
||||
itemDefinitionId: highLevelHelm.id,
|
||||
itemDefinitionId: highTierHelm.id,
|
||||
quantity: 1,
|
||||
} as CharacterItem,
|
||||
],
|
||||
});
|
||||
|
||||
await expectEquipmentDomainError(
|
||||
service.equip(CHARACTER_ID, BANDIT_HOOD_ITEM_ID),
|
||||
'ITEM_LEVEL_REQUIREMENT_NOT_MET',
|
||||
);
|
||||
const result = await service.equip(CHARACTER_ID, BANDIT_HOOD_ITEM_ID);
|
||||
|
||||
expect(result.slots.HEAD?.characterItemId).toBe(BANDIT_HOOD_ITEM_ID);
|
||||
});
|
||||
|
||||
it('rejects equipping a non-equippable item', async () => {
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
characterInCombat,
|
||||
characterItemNotFound,
|
||||
characterNotFound,
|
||||
itemLevelRequirementNotMet,
|
||||
itemNotEquippable,
|
||||
itemNotOwned,
|
||||
} from './equipment.errors';
|
||||
@@ -102,9 +101,6 @@ export class EquipmentService {
|
||||
if (!definition.equipmentSlot) {
|
||||
throw itemNotEquippable();
|
||||
}
|
||||
if (definition.requiredLevel > character.level) {
|
||||
throw itemLevelRequirementNotMet();
|
||||
}
|
||||
|
||||
const existing = await equipmentRepo.findOne({
|
||||
where: { characterId, slot: definition.equipmentSlot },
|
||||
|
||||
Reference in New Issue
Block a user