// 神明系統 - 與 API 整合 import { apiService } from './api-service.js' import { JIAOBEI_CONFIG } from '../data/jiaobei-config.js' export class TempleSystem { constructor(petSystem, api = apiService, achievementSystem = null) { this.petSystem = petSystem this.api = api this.achievementSystem = achievementSystem this.deities = [] } // 初始化(從 API 載入神明資料) async initialize() { try { this.deities = await this.api.getDeities() console.log(`[TempleSystem] 載入 ${this.deities.length} 位神明`) } catch (error) { console.error('[TempleSystem] 載入神明失敗:', error) // 降級到本地載入 const { DEITIES } = await import('../data/deities.js') this.deities = DEITIES } } // 獲取所有神明 getDeities() { return [...this.deities] } // 獲取當前神明 getCurrentDeity() { const state = this.petSystem.getState() return this.deities.find(d => d.id === state.currentDeityId) || this.deities[0] } // 切換神明 async switchDeity(deityId) { const deity = this.deities.find(d => d.id === deityId) if (!deity) { return { success: false, message: '找不到該神明' } } await this.petSystem.updateState({ currentDeityId: deityId }) // 重新計算屬性(新神明的加成) this.petSystem.calculateCombatStats() // 同步 effective 属性到状态 await this.petSystem.updateState({ effectiveStr: this.petSystem.state.effectiveStr, effectiveInt: this.petSystem.state.effectiveInt, effectiveDex: this.petSystem.state.effectiveDex, effectiveLuck: this.petSystem.state.effectiveLuck }) return { success: true, deity } } // 祈福(每日上限 3 次) async pray() { const state = this.petSystem.getState() if (state.dailyPrayerCount >= 3) { return { success: false, message: '今日祈福次數已用完' } } try { const result = await this.api.prayToDeity({ deityId: state.currentDeityId, petState: state }) // 更新好感度 const currentFavor = state.deityFavors[state.currentDeityId] || 0 const newFavor = Math.min(100, currentFavor + result.favorIncrease) // 檢查是否等級提升或達到滿級 const deity = this.getCurrentDeity() const oldLevel = deity.favorLevelBuffs ? Math.floor(currentFavor / deity.favorLevelBuffs.interval) : 0 const newLevel = deity.favorLevelBuffs ? Math.floor(newFavor / deity.favorLevelBuffs.interval) : 0 const levelUp = newLevel > oldLevel const reachedMax = currentFavor < 100 && newFavor >= 100 await this.petSystem.updateState({ deityFavors: { ...state.deityFavors, [state.currentDeityId]: newFavor }, dailyPrayerCount: state.dailyPrayerCount + 1 }) // 重新計算屬性(好感度變化影響加成) this.petSystem.calculateCombatStats() // 同步 effective 属性到状态 await this.petSystem.updateState({ effectiveStr: this.petSystem.state.effectiveStr, effectiveInt: this.petSystem.state.effectiveInt, effectiveDex: this.petSystem.state.effectiveDex, effectiveLuck: this.petSystem.state.effectiveLuck }) // 獲取神明對話 const dialogue = deity.dialogues[Math.floor(Math.random() * deity.dialogues.length)] // 記錄到成就系統 if (this.achievementSystem) { await this.achievementSystem.recordAction('pray') // 檢查神明好感度成就 await this.achievementSystem.checkAndUnlockAchievements() } return { success: true, favorIncrease: result.favorIncrease, newFavor, oldLevel, newLevel, levelUp, reachedMax, dialogue, message: result.message, deity } } catch (error) { console.error('[TempleSystem] 祈福失敗:', error) return { success: false, message: '祈福失敗' } } } // 獲取好感度星級(每 20 點一星) getFavorStars(deityId) { if (!deityId) return '☆☆☆☆☆' const state = this.petSystem.getState() if (!state || !state.deityFavors) return '☆☆☆☆☆' const favor = state.deityFavors[deityId] || 0 const stars = Math.floor(favor / 20) return '★'.repeat(stars) + '☆'.repeat(5 - stars) } // 抽籤 // 求籤(需要三聖筊驗證) async drawLot(lotType = 'guanyin_100') { const state = this.petSystem.getState() const deity = this.getCurrentDeity() // 檢查神明是否支持此簽詩 if (!deity.lotTypes || !deity.lotTypes.includes(lotType)) { return { success: false, message: `${deity.name}不提供${lotType}簽詩` } } try { // 載入簽詩資料 const lots = await this.loadLots(lotType) // 隨機抽一支簽 const randomIndex = Math.floor(Math.random() * lots.length) const lot = lots[randomIndex] // 記錄到成就系統 if (this.achievementSystem) { await this.achievementSystem.recordAction('drawFortune') await this.achievementSystem.checkAndUnlockAchievements() } // 返回需要擲筊驗證的狀態 return { success: true, needVerification: true, lot, lotType, deity: deity.name, verificationCount: 0, requiredHoly: 3 // 需要三個聖筊 } } catch (error) { console.error('[TempleSystem] 抽籤失敗:', error) return { success: false, message: '抽籤失敗' } } } // 驗證簽詩(擲筊確認) async verifyLot(lotData) { // 擲筊 const jiaobeiResult = await this.throwJiaobei(`求問第${lotData.lot.no}籤`) if (jiaobeiResult.result === 'holy') { // 聖筊 const newCount = (lotData.verificationCount || 0) + 1 if (newCount >= lotData.requiredHoly) { // 三聖筊,可以解簽 return { success: true, verified: true, lot: lotData.lot, jiaobeiResult, message: `三聖筊!${lotData.deity}允准解籤` } } else { // 還需要更多聖筊 return { success: true, verified: false, needMore: true, verificationCount: newCount, requiredHoly: lotData.requiredHoly, lot: lotData.lot, jiaobeiResult, message: `第${newCount}個聖筊,還需${lotData.requiredHoly - newCount}個聖筊` } } } else { // 笑筊或陰筊,需要重抽 return { success: true, verified: false, needRedraw: true, jiaobeiResult, message: `${jiaobeiResult.result === 'laughing' ? '笑筊' : '陰筊'},請重新抽籤` } } } // 載入簽詩資料 async loadLots(lotType) { if (lotType === 'guanyin_100') { const data = await import('../data/guanyin_100_lots.json') return data.default || data } throw new Error(`未知的簽詩類型: ${lotType}`) } // 擲筊 async throwJiaobei(question = '') { const state = this.petSystem.getState() const deity = this.getCurrentDeity() try { // 計算實際概率 const probabilities = this.calculateJiaobeiProbabilities() // 嘗試使用 API const apiResult = await this.api.throwJiaobei({ petId: state.id, deityId: deity.id, question, probabilities }) // 如果 API 回傳本地降級標記,使用本地邏輯 if (!apiResult.localFallback) { return apiResult } } catch (error) { console.warn('[TempleSystem] 擲筊 API 失敗,使用本地邏輯', error) } // 本地邏輯 const probabilities = this.calculateJiaobeiProbabilities() const result = this.rollJiaobei(probabilities) return { success: true, result, deity: deity.name, message: result === 'holy' ? '聖筊' : result === 'laughing' ? '笑筊' : '陰筊', probabilities } } // 取得當前神明可用的 lotTypes(可能有多個) getCurrentDeityLotTypes() { const deity = this.getCurrentDeity() // 若未設定則回傳空陣列,避免錯誤 return deity?.lotTypes ?? [] } // 計算擲筊概率(考慮運勢和好感度) calculateJiaobeiProbabilities() { const state = this.petSystem.getState() const deity = this.getCurrentDeity() // 基礎概率 let { holy, laughing, negative } = JIAOBEI_CONFIG.baseProbability // 運勢影響:增加聖筊概率 const luck = state.luck || 10 const luckBonus = Math.min( luck * JIAOBEI_CONFIG.luckModifier, JIAOBEI_CONFIG.maxModifier ) // 好感度影響:減少陰筊概率 const favor = state.deityFavors[deity.id] || 0 const favorBonus = Math.min( favor * JIAOBEI_CONFIG.favorModifier, JIAOBEI_CONFIG.maxModifier ) // 調整概率 holy += luckBonus + favorBonus / 2 negative -= favorBonus laughing -= luckBonus / 2 // 確保非負 holy = Math.max(0.1, holy) laughing = Math.max(0.1, laughing) negative = Math.max(0.1, negative) // 歸一化(確保總和為1) const total = holy + laughing + negative return { holy: holy / total, laughing: laughing / total, negative: negative / total } } // 投擲筊杯(隨機結果) rollJiaobei(probabilities) { const rand = Math.random() if (rand < probabilities.holy) { return 'holy' } else if (rand < probabilities.holy + probabilities.laughing) { return 'laughing' } else { return 'negative' } } // Debug: 重置每日祈福次數 async debugResetDailyPrayer() { console.log('[Debug] 重置每日祈福次數') await this.petSystem.updateState({ dailyPrayerCount: 0 }) return { success: true, message: '已重置祈福次數' } } }