341 lines
8.1 KiB
JavaScript
341 lines
8.1 KiB
JavaScript
|
|
/**
|
|||
|
|
* 制造配方配置
|
|||
|
|
* 支持武器、防具、消耗品、特殊道具的制造
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { ITEM_CONFIG } from './items.js'
|
|||
|
|
import { getItemCount } from '@/utils/itemSystem.js'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 配方类型枚举
|
|||
|
|
*/
|
|||
|
|
export const RECIPE_TYPES = {
|
|||
|
|
WEAPON: 'weapon', // 武器
|
|||
|
|
ARMOR: 'armor', // 防具
|
|||
|
|
SHIELD: 'shield', // 盾牌
|
|||
|
|
CONSUMABLE: 'consumable', // 消耗品
|
|||
|
|
SPECIAL: 'special' // 特殊道具
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 配方配置
|
|||
|
|
* 每个配方包含:
|
|||
|
|
* - id: 配方ID
|
|||
|
|
* - type: 配方类型
|
|||
|
|
* - resultItem: 产出物品ID
|
|||
|
|
* - resultCount: 产出数量
|
|||
|
|
* - materials: 材料需求列表
|
|||
|
|
* - requiredSkill: 所需技能ID
|
|||
|
|
* - requiredSkillLevel: 所需技能等级
|
|||
|
|
* - baseTime: 基础制造时间(秒)
|
|||
|
|
* - baseSuccessRate: 基础成功率
|
|||
|
|
* - unlockCondition: 解锁条件(可选)
|
|||
|
|
*/
|
|||
|
|
export const RECIPE_CONFIG = {
|
|||
|
|
// ===== 武器配方 =====
|
|||
|
|
wooden_club: {
|
|||
|
|
id: 'wooden_club',
|
|||
|
|
type: RECIPE_TYPES.WEAPON,
|
|||
|
|
resultItem: 'wooden_club',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'dog_skin', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'club_mastery',
|
|||
|
|
requiredSkillLevel: 1,
|
|||
|
|
baseTime: 30,
|
|||
|
|
baseSuccessRate: 0.95
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
stone_axe: {
|
|||
|
|
id: 'stone_axe',
|
|||
|
|
type: RECIPE_TYPES.WEAPON,
|
|||
|
|
resultItem: 'stone_axe',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'iron_ore', count: 3 },
|
|||
|
|
{ itemId: 'leather', count: 1 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'axe_mastery',
|
|||
|
|
requiredSkillLevel: 1,
|
|||
|
|
baseTime: 60,
|
|||
|
|
baseSuccessRate: 0.85
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
hunter_bow: {
|
|||
|
|
id: 'hunter_bow',
|
|||
|
|
type: RECIPE_TYPES.WEAPON,
|
|||
|
|
resultItem: 'hunter_bow',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'dog_skin', count: 3 },
|
|||
|
|
{ itemId: 'leather', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'archery',
|
|||
|
|
requiredSkillLevel: 3,
|
|||
|
|
baseTime: 120,
|
|||
|
|
baseSuccessRate: 0.80
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
iron_sword: {
|
|||
|
|
id: 'iron_sword',
|
|||
|
|
type: RECIPE_TYPES.WEAPON,
|
|||
|
|
resultItem: 'iron_sword',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'iron_ore', count: 5 },
|
|||
|
|
{ itemId: 'leather', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'sword_mastery',
|
|||
|
|
requiredSkillLevel: 5,
|
|||
|
|
baseTime: 180,
|
|||
|
|
baseSuccessRate: 0.75,
|
|||
|
|
unlockCondition: {
|
|||
|
|
type: 'skill',
|
|||
|
|
skillId: 'crafting',
|
|||
|
|
level: 3
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ===== 防具配方 =====
|
|||
|
|
leather_armor: {
|
|||
|
|
id: 'leather_armor',
|
|||
|
|
type: RECIPE_TYPES.ARMOR,
|
|||
|
|
resultItem: 'leather_armor',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'leather', count: 5 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 1,
|
|||
|
|
baseTime: 60,
|
|||
|
|
baseSuccessRate: 0.90
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
wooden_shield: {
|
|||
|
|
id: 'wooden_shield',
|
|||
|
|
type: RECIPE_TYPES.SHIELD,
|
|||
|
|
resultItem: 'wooden_shield',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'leather', count: 2 },
|
|||
|
|
{ itemId: 'dog_skin', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 2,
|
|||
|
|
baseTime: 45,
|
|||
|
|
baseSuccessRate: 0.92
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
iron_shield: {
|
|||
|
|
id: 'iron_shield',
|
|||
|
|
type: RECIPE_TYPES.SHIELD,
|
|||
|
|
resultItem: 'iron_shield',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'iron_ore', count: 8 },
|
|||
|
|
{ itemId: 'leather', count: 3 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 5,
|
|||
|
|
baseTime: 120,
|
|||
|
|
baseSuccessRate: 0.75
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ===== 消耗品配方 =====
|
|||
|
|
bandage: {
|
|||
|
|
id: 'bandage',
|
|||
|
|
type: RECIPE_TYPES.CONSUMABLE,
|
|||
|
|
resultItem: 'bandage',
|
|||
|
|
resultCount: 3,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'dog_skin', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 1,
|
|||
|
|
baseTime: 15,
|
|||
|
|
baseSuccessRate: 0.98
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
health_potion_small: {
|
|||
|
|
id: 'health_potion_small',
|
|||
|
|
type: RECIPE_TYPES.CONSUMABLE,
|
|||
|
|
resultItem: 'health_potion_small',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'healing_herb', count: 3 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'herbalism',
|
|||
|
|
requiredSkillLevel: 2,
|
|||
|
|
baseTime: 30,
|
|||
|
|
baseSuccessRate: 0.90
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
health_potion: {
|
|||
|
|
id: 'health_potion',
|
|||
|
|
type: RECIPE_TYPES.CONSUMABLE,
|
|||
|
|
resultItem: 'health_potion',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'healing_herb', count: 5 },
|
|||
|
|
{ itemId: 'bandage', count: 1 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'herbalism',
|
|||
|
|
requiredSkillLevel: 5,
|
|||
|
|
baseTime: 60,
|
|||
|
|
baseSuccessRate: 0.80
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ===== 特殊道具 =====
|
|||
|
|
bomb: {
|
|||
|
|
id: 'bomb',
|
|||
|
|
type: RECIPE_TYPES.SPECIAL,
|
|||
|
|
resultItem: 'bomb',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'iron_ore', count: 3 },
|
|||
|
|
{ itemId: 'bat_wing', count: 2 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 5,
|
|||
|
|
baseTime: 90,
|
|||
|
|
baseSuccessRate: 0.75
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// 炸弹堆(一次制造多个)
|
|||
|
|
bomb_batch: {
|
|||
|
|
id: 'bomb_batch',
|
|||
|
|
type: RECIPE_TYPES.SPECIAL,
|
|||
|
|
resultItem: 'bomb',
|
|||
|
|
resultCount: 3,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'iron_ore', count: 8 },
|
|||
|
|
{ itemId: 'bat_wing', count: 5 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 8,
|
|||
|
|
baseTime: 200,
|
|||
|
|
baseSuccessRate: 0.70
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// ===== 剧情道具 =====
|
|||
|
|
mystic_key: {
|
|||
|
|
id: 'mystic_key',
|
|||
|
|
type: RECIPE_TYPES.SPECIAL,
|
|||
|
|
resultItem: 'mystic_key',
|
|||
|
|
resultCount: 1,
|
|||
|
|
materials: [
|
|||
|
|
{ itemId: 'rare_gem', count: 1 },
|
|||
|
|
{ itemId: 'iron_ore', count: 10 }
|
|||
|
|
],
|
|||
|
|
requiredSkill: 'crafting',
|
|||
|
|
requiredSkillLevel: 10,
|
|||
|
|
baseTime: 300,
|
|||
|
|
baseSuccessRate: 0.50,
|
|||
|
|
unlockCondition: {
|
|||
|
|
type: 'quest',
|
|||
|
|
flag: 'found_mystic_recipe'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取所有配方
|
|||
|
|
* @returns {Array} 配方列表
|
|||
|
|
*/
|
|||
|
|
export function getAllRecipes() {
|
|||
|
|
return Object.values(RECIPE_CONFIG)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取指定类型的配方
|
|||
|
|
* @param {String} type - 配方类型
|
|||
|
|
* @returns {Array} 配方列表
|
|||
|
|
*/
|
|||
|
|
export function getRecipesByType(type) {
|
|||
|
|
return Object.values(RECIPE_CONFIG).filter(recipe => recipe.type === type)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取玩家可制作的配方
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @returns {Array} 可制作的配方列表
|
|||
|
|
*/
|
|||
|
|
export function getAvailableRecipes(playerStore) {
|
|||
|
|
return Object.values(RECIPE_CONFIG)
|
|||
|
|
.filter(recipe => {
|
|||
|
|
// 检查技能要求
|
|||
|
|
if (recipe.requiredSkill) {
|
|||
|
|
const skill = playerStore.skills?.[recipe.requiredSkill]
|
|||
|
|
if (!skill || !skill.unlocked) return false
|
|||
|
|
if (skill.level < recipe.requiredSkillLevel) return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查解锁条件
|
|||
|
|
if (recipe.unlockCondition) {
|
|||
|
|
if (recipe.unlockCondition.type === 'skill') {
|
|||
|
|
const skill = playerStore.skills?.[recipe.unlockCondition.skillId]
|
|||
|
|
if (!skill || skill.level < recipe.unlockCondition.level) return false
|
|||
|
|
} else if (recipe.unlockCondition.type === 'quest') {
|
|||
|
|
if (!playerStore.flags?.[recipe.unlockCondition.flag]) return false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
})
|
|||
|
|
.map(recipe => ({
|
|||
|
|
...recipe,
|
|||
|
|
canCraft: true,
|
|||
|
|
displayName: ITEM_CONFIG[recipe.resultItem]?.name || recipe.resultItem,
|
|||
|
|
displayIcon: ITEM_CONFIG[recipe.resultItem]?.icon || '📦'
|
|||
|
|
}))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取配方信息
|
|||
|
|
* @param {String} recipeId - 配方ID
|
|||
|
|
* @returns {Object|null} 配方信息
|
|||
|
|
*/
|
|||
|
|
export function getRecipe(recipeId) {
|
|||
|
|
return RECIPE_CONFIG[recipeId] || null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查是否可以制造(材料是否足够)
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @param {Object} recipe - 配方对象
|
|||
|
|
* @returns {Object} { canCraft: boolean, missingMaterials: Array }
|
|||
|
|
*/
|
|||
|
|
export function checkMaterials(playerStore, recipe) {
|
|||
|
|
const missing = []
|
|||
|
|
|
|||
|
|
for (const material of recipe.materials) {
|
|||
|
|
const itemCount = getItemCount(playerStore, material.itemId)
|
|||
|
|
if (itemCount < material.count) {
|
|||
|
|
const itemConfig = ITEM_CONFIG[material.itemId]
|
|||
|
|
missing.push({
|
|||
|
|
itemId: material.itemId,
|
|||
|
|
itemName: itemConfig?.name || material.itemId,
|
|||
|
|
need: material.count,
|
|||
|
|
have: itemCount
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
canCraft: missing.length === 0,
|
|||
|
|
missingMaterials: missing
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 配方分类配置
|
|||
|
|
*/
|
|||
|
|
export const RECIPE_CATEGORIES = {
|
|||
|
|
weapon: { id: 'weapon', name: '武器', icon: '⚔️' },
|
|||
|
|
armor: { id: 'armor', name: '防具', icon: '🛡️' },
|
|||
|
|
shield: { id: 'shield', name: '盾牌', icon: '🛡️' },
|
|||
|
|
consumable: { id: 'consumable', name: '消耗品', icon: '🧪' },
|
|||
|
|
special: { id: 'special', name: '特殊', icon: '✨' }
|
|||
|
|
}
|