Files
Genarrative/src/data/economy.ts

94 lines
2.9 KiB
TypeScript

import { resolveCustomWorldRuleProfile } from '../services/customWorldOwnedSettingLayers';
import { CustomWorldProfile, InventoryItem, WorldType } from '../types';
import { getRuntimeCustomWorldProfile } from './customWorldRuntime';
const RARITY_BASE_VALUES: Record<InventoryItem['rarity'], number> = {
common: 12,
uncommon: 24,
rare: 48,
epic: 92,
legendary: 168,
};
function resolveEconomyProfile(
worldType: WorldType | null,
customWorldProfile?: CustomWorldProfile | null,
) {
const profile =
customWorldProfile ??
(worldType === WorldType.CUSTOM ? getRuntimeCustomWorldProfile() : null);
return resolveCustomWorldRuleProfile(profile);
}
export function getCurrencyName(
worldType: WorldType | null,
customWorldProfile?: CustomWorldProfile | null,
) {
const ruleProfile = resolveEconomyProfile(worldType, customWorldProfile);
if (ruleProfile) {
return ruleProfile.resourceLabels.currency;
}
if (worldType === WorldType.XIANXIA) return '灵石';
if (worldType === WorldType.WUXIA) return '铜钱';
return '钱币';
}
export function getInitialPlayerCurrency(
worldType: WorldType | null,
customWorldProfile?: CustomWorldProfile | null,
) {
const ruleProfile = resolveEconomyProfile(worldType, customWorldProfile);
if (ruleProfile) {
return ruleProfile.economyProfile.initialCurrency;
}
return worldType === WorldType.XIANXIA ? 140 : 160;
}
export function getDiscountTierForAffinity(affinity: number) {
if (affinity >= 90) return 3;
if (affinity >= 60) return 2;
if (affinity >= 30) return 1;
return 0;
}
export function getInventoryItemValue(item: InventoryItem) {
if (typeof item.value === 'number' && Number.isFinite(item.value)) {
return Math.max(8, Math.round(item.value));
}
let value = RARITY_BASE_VALUES[item.rarity];
if (item.tags.includes('weapon')) value += 14;
if (item.tags.includes('armor')) value += 12;
if (item.tags.includes('relic')) value += 16;
if (item.tags.includes('mana')) value += 8;
if (item.tags.includes('healing')) value += 8;
if (item.tags.includes('material')) value += 4;
if (item.category.includes('专属')) value += 10;
return Math.max(8, value);
}
export function getNpcPurchasePrice(item: InventoryItem, affinity: number) {
const discountTier = getDiscountTierForAffinity(affinity);
const discountMultiplier = 1 - (discountTier * 0.08);
return Math.max(6, Math.round(getInventoryItemValue(item) * discountMultiplier));
}
export function getNpcBuybackPrice(item: InventoryItem, affinity: number) {
const discountTier = getDiscountTierForAffinity(affinity);
const buybackMultiplier = 0.4 + (discountTier * 0.06);
return Math.max(4, Math.round(getInventoryItemValue(item) * buybackMultiplier));
}
export function formatCurrency(
value: number,
worldType: WorldType | null,
customWorldProfile?: CustomWorldProfile | null,
) {
return `${value} ${getCurrencyName(worldType, customWorldProfile)}`;
}