pet_data/core/temple-system.js

293 lines
8.1 KiB
JavaScript
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.

// 神明系統 - 與 API 整合
import { apiService } from './api-service.js'
import { JIAOBEI_CONFIG } from '../data/jiaobei-config.js'
export class TempleSystem {
constructor(petSystem, api = apiService) {
this.petSystem = petSystem
this.api = api
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)]
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) {
const state = this.petSystem.getState()
const favor = state.deityFavors[deityId] || 0
const stars = Math.floor(favor / 20)
return '★'.repeat(stars) + '☆'.repeat(5 - stars)
}
// 抽籤
async drawFortune() {
try {
const result = await this.api.drawFortune()
// 根據籤詩等級應用效果
const { FORTUNE_LOTS } = await import('../data/fortune-lots.js')
const lot = FORTUNE_LOTS.find(l => l.grade === result.lot.grade) || FORTUNE_LOTS[0]
if (lot.effects?.addBuff) {
// 應用 Buff需要透過 eventSystem
return {
success: true,
lot: result.lot,
buff: lot.effects.addBuff
}
}
return {
success: true,
lot: result.lot
}
} catch (error) {
console.error('[TempleSystem] 抽籤失敗:', error)
return { success: false, message: '抽籤失敗' }
}
}
// 擲筊
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)
// 選擇訊息
const messages = JIAOBEI_CONFIG.messages[result]
const message = messages[Math.floor(Math.random() * messages.length)]
// 聖筊獎勵:增加好感度
if (result === 'holy') {
const currentFavor = state.deityFavors[deity.id] || 0
const bonus = JIAOBEI_CONFIG.holyFavorBonus || 1
const newFavor = Math.min(100, currentFavor + bonus)
await this.petSystem.updateState({
deityFavors: {
...state.deityFavors,
[deity.id]: newFavor
}
})
// 重新計算屬性
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,
result,
message,
deity: deity.name,
probabilities,
question
}
}
// 計算擲筊概率(考慮運勢和好感度)
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: '已重置祈福次數' }
}
}