Files
ashen-realms/apps/api/src/database/seeds/item-content.ts
Bastian Wagner b8ee56ca1a feat(content): translate seeded items, locations, and reputation faction to English
Converts all German player-facing content in the API's seed files to
English per the English Game Content Foundation glossary: item
name/description, monster name, location name/description, all
local-location POI/action content, and the border-guard reputation
faction. Technical keys are unchanged.
2026-08-21 20:00:04 +02:00

235 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { EquipmentSlot } from '../../items/equipment-slot.enum';
import { ItemRarity } from '../../items/item-rarity.enum';
import { ItemType } from '../../items/item-type.enum';
import {
ASH_RAT_LOOT_TABLE_ID,
ITEM_IDS,
ItemKey,
ROAD_BANDIT_LOOT_TABLE_ID,
} from './item.constants';
export interface SeedItemDefinition {
id: string;
key: ItemKey;
name: string;
description: string;
type: ItemType;
equipmentSlot: EquipmentSlot | null;
rarity: ItemRarity;
tier: number;
weaponDamage: number;
bonusHp: number;
bonusAttack: number;
bonusArmor: number;
sellPrice: number;
iconPath: string;
}
function item(
key: ItemKey,
name: string,
description: string,
type: ItemType,
equipmentSlot: EquipmentSlot | null,
rarity: ItemRarity,
stats: Partial<
Pick<
SeedItemDefinition,
'weaponDamage' | 'bonusHp' | 'bonusAttack' | 'bonusArmor'
>
> = {},
): SeedItemDefinition {
return {
id: ITEM_IDS[key],
key,
name,
description,
type,
equipmentSlot,
rarity,
tier: 1,
weaponDamage: stats.weaponDamage ?? 0,
bonusHp: stats.bonusHp ?? 0,
bonusAttack: stats.bonusAttack ?? 0,
bonusArmor: stats.bonusArmor ?? 0,
// Always 0: no merchants exist in Slice 0.4, and the balancing doc's
// Grenzmarken table lists purchase prices, not sell prices.
sellPrice: 0,
iconPath: `/images/items/${key}.png`,
};
}
// Stats from docs/Ashen_Realms_Balancing_Items_Loot_Design_V1.md §19.
export const ITEM_DEFINITIONS: SeedItemDefinition[] = [
item(
'worn-short-sword',
'Worn Shortsword',
"A recruit's blade, sharpened more often than it's been swung.",
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.COMMON,
{ weaponDamage: 8 },
),
item(
'bandit-blade',
'Bandit Blade',
'A roughly serrated blade, forged for quick raids.',
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.COMMON,
{ weaponDamage: 11, bonusAttack: 1 },
),
item(
'ash-blade',
'Ashen Blade',
'Tempered in the embers of the Ashen Fields; the edge still glows faintly.',
ItemType.EQUIPMENT,
EquipmentSlot.WEAPON,
ItemRarity.RARE,
{ weaponDamage: 15, bonusAttack: 2 },
),
item(
'bandit-hood',
'Bandit Hood',
"Scarred leather that hides both the wearer's face and their intent.",
ItemType.EQUIPMENT,
EquipmentSlot.HEAD,
ItemRarity.COMMON,
{ bonusArmor: 3, bonusHp: 5 },
),
item(
'reinforced-leather-jacket',
'Reinforced Leather Jacket',
'Leather sewn with iron plates, heavy and dependable.',
ItemType.EQUIPMENT,
EquipmentSlot.CHEST,
ItemRarity.RARE,
{ bonusArmor: 7, bonusHp: 10 },
),
item(
'raider-gloves',
'Plunderer Gloves',
"Studded gloves, worn smooth from handling other people's belongings.",
ItemType.EQUIPMENT,
EquipmentSlot.HANDS,
ItemRarity.COMMON,
{ bonusArmor: 3, bonusAttack: 1 },
),
item(
'guardsman-legs',
"Watchman's Leggings",
'Leg armor of the Border Watch, patched at the knees.',
ItemType.EQUIPMENT,
EquipmentSlot.LEGS,
ItemRarity.RARE,
{ bonusArmor: 5, bonusHp: 5 },
),
item(
'ash-boots',
'Ashen Boots',
'Boots that walked through smoldering fields and never quite left them behind.',
ItemType.EQUIPMENT,
EquipmentSlot.FEET,
ItemRarity.RARE,
{ bonusArmor: 4, bonusHp: 5 },
),
item(
'borderwatch-sigil',
'Mark of the Border Watch',
'The crest of a watchtower that no longer stands.',
ItemType.EQUIPMENT,
EquipmentSlot.AMULET,
ItemRarity.RARE,
{ bonusAttack: 3, bonusHp: 10 },
),
item(
'burned-captain-pendant',
"Charred Captain's Pendant",
'A skull cast in slag, its embers never quite gone out.',
ItemType.EQUIPMENT,
EquipmentSlot.AMULET,
ItemRarity.EPIC,
{ bonusAttack: 3, bonusHp: 15, bonusArmor: 2 },
),
// Seeded as content only. Slice 0.4 implements no consumable use, and the
// Road Bandit loot entry for it is deliberately deferred (spec §16).
item(
'small-healing-potion',
'Small Healing Potion',
'A bitter draught that makes wounds forgettable, if only for a breath.',
ItemType.CONSUMABLE,
null,
ItemRarity.COMMON,
),
// A Trade Good (spec §17): turned in to the Border Watch for Silver and
// reputation rather than crafted with.
item(
'ash-pelt',
'Ash Pelt',
'Singed pelt, tough as leather and grey with drifting ash.',
ItemType.TRADE_GOOD,
null,
ItemRarity.COMMON,
),
item(
'bandit-insignia',
'Bandit Insignia',
'A roughly stamped token marking a road bandit as one of their band.',
ItemType.TROPHY,
null,
ItemRarity.COMMON,
),
];
export const LOOT_TABLES = [
{ id: ASH_RAT_LOOT_TABLE_ID, key: 'ash-rat-loot', name: 'Ash Rat Loot' },
{
id: ROAD_BANDIT_LOOT_TABLE_ID,
key: 'road-bandit-loot',
name: 'Road Bandit Loot',
},
];
export interface SeedLootTableEntry {
lootTableId: string;
itemDefinitionId: string;
position: number;
dropChance: string;
minQuantity: number;
maxQuantity: number;
enabled: boolean;
}
function entry(
lootTableId: string,
key: ItemKey,
position: number,
dropChance: string,
): SeedLootTableEntry {
return {
lootTableId,
itemDefinitionId: ITEM_IDS[key],
position,
dropChance,
minQuantity: 1,
maxQuantity: 1,
enabled: true,
};
}
/**
* Drop chances from docs/Ashen_Realms_Balancing_Items_Loot_Design_V1.md §2728.
* Every entry is an independent roll (spec §17), rolled in `position` order.
*
* DEFERRED: the Straßenräuber table also lists 10 % Kleiner Heiltrank. It is
* omitted here because Slice 0.4 implements no consumables (spec §16).
*/
export const LOOT_TABLE_ENTRIES: SeedLootTableEntry[] = [
entry(ASH_RAT_LOOT_TABLE_ID, 'ash-pelt', 1, '0.6000'),
entry(ASH_RAT_LOOT_TABLE_ID, 'worn-short-sword', 2, '0.0800'),
entry(ROAD_BANDIT_LOOT_TABLE_ID, 'bandit-blade', 1, '0.1800'),
entry(ROAD_BANDIT_LOOT_TABLE_ID, 'bandit-hood', 2, '0.1200'),
entry(ROAD_BANDIT_LOOT_TABLE_ID, 'raider-gloves', 3, '0.0800'),
entry(ROAD_BANDIT_LOOT_TABLE_ID, 'bandit-insignia', 4, '0.4000'),
];