pet_data/core/deity-system.js

258 lines
8.1 KiB
JavaScript
Raw Permalink Normal View History

2025-11-27 08:42:55 +00:00
import { DEITIES } from '../data/deities.js'
import { TAROT_MAJOR_ARCANA } from '../data/tarot.js'
import { QUEST_TYPES, checkQuestProgress } from '../data/deity-quests.js'
export class DeitySystem {
constructor(petSystem) {
this.petSystem = petSystem
this.state = {
collectedDeities: [], // Array of { id, stageLevel, exp, quests: { questId: progress } }
currentDeityId: null,
lastEncounterTime: 0,
dailyFortune: null // { type: 'jiaobei'|'stick'|'tarot', result: ... }
}
}
// 保存狀態到 PetSystem (進而保存到 API/LocalStorage)
async saveState() {
if (this.petSystem && this.petSystem.updateState) {
await this.petSystem.updateState({ deitySystemState: this.state })
}
}
// 初始化
async initialize(savedState) {
if (savedState) {
this.state = { ...this.state, ...savedState }
}
// 確保至少有一個默認神明 (媽祖)
if (this.state.collectedDeities.length === 0) {
this.collectDeity('mazu');
}
}
// 獲取當前神明資料
getCurrentDeity() {
if (!this.state.currentDeityId) return null
return DEITIES.find(d => d.id === this.state.currentDeityId)
}
// 獲取當前神明的狀態 (等級、經驗等)
getCurrentDeityState() {
if (!this.state.currentDeityId) return null
return this.state.collectedDeities.find(d => d.id === this.state.currentDeityId)
}
// 獲取當前階段詳細資料
getCurrentStage() {
const deity = this.getCurrentDeity()
const deityState = this.getCurrentDeityState()
if (!deity || !deityState) return null
return deity.stages.find(s => s.level === deityState.stageLevel)
}
// 遭遇神明 (隨機)
triggerEncounter() {
const now = Date.now()
// 簡單的冷卻檢查 (例如 1 小時)
if (now - this.state.lastEncounterTime < 3600000) return null
// 隨機選擇一個未收集的神明
const collectedIds = this.state.collectedDeities.map(d => d.id)
const availableDeities = DEITIES.filter(d => !collectedIds.includes(d.id))
if (availableDeities.length === 0) return null
const randomDeity = availableDeities[Math.floor(Math.random() * availableDeities.length)]
this.state.lastEncounterTime = now
return randomDeity
}
// 嘗試邀請神明 (擲筊挑戰)
// 這裡只負責邏輯UI 負責顯示動畫
// return: { success: boolean, cups: [boolean, boolean, boolean] } (true=聖杯)
challengeInvite() {
// 模擬擲筊 3 次
const results = []
let successCount = 0
for (let i = 0; i < 3; i++) {
// 聖杯機率 50% (一正一反)
// 這裡簡化邏輯0=笑杯/陰杯, 1=聖杯
const isHolyCup = Math.random() > 0.5
results.push(isHolyCup)
if (isHolyCup) successCount++
}
// 連續 3 聖杯才算成功 (或者累積? 需求說是"三聖杯之後")
// 通常"博杯"請神需要連續三聖杯
const isSuccess = successCount === 3
return { success: isSuccess, results }
}
// 收集神明
collectDeity(deityId) {
if (this.state.collectedDeities.some(d => d.id === deityId)) return false
const deityConfig = DEITIES.find(d => d.id === deityId)
if (!deityConfig) return false
// 初始化神明狀態
const newDeityState = {
id: deityId,
stageLevel: 1,
exp: 0,
quests: {} // 任務進度
}
// 初始化任務進度 (第一階段的任務)
const firstStage = deityConfig.stages[0];
if (firstStage?.quests) {
firstStage.quests.forEach(q => {
newDeityState.quests[q.id] = 0;
});
}
this.state.collectedDeities.push(newDeityState)
// 如果是第一個神明,自動設為當前
if (!this.state.currentDeityId) {
this.state.currentDeityId = deityId
}
this.saveState();
return true
}
// 切換當前供奉神明
switchDeity(deityId) {
if (!this.state.collectedDeities.some(d => d.id === deityId)) return false
this.state.currentDeityId = deityId
this.saveState();
return true
}
// 更新任務進度
updateQuestProgress(actionType, value = 1) {
const deityState = this.getCurrentDeityState();
const deityConfig = this.getCurrentDeity();
if (!deityState || !deityConfig) return [];
// 獲取當前階段的任務(修正:從下一階段改為當前階段)
const currentStage = deityConfig.stages.find(s => s.level === deityState.stageLevel);
if (!currentStage || !currentStage.quests) return [];
const updates = [];
currentStage.quests.forEach(quest => {
// 檢查是否已經完成
if (deityState.quests[quest.id] >= quest.target) return;
const oldProgress = deityState.quests[quest.id] || 0;
const newProgress = checkQuestProgress(oldProgress, quest.target, actionType, quest.type, value);
if (newProgress !== oldProgress) {
deityState.quests[quest.id] = newProgress;
updates.push({
questId: quest.id,
progress: newProgress,
target: quest.target,
completed: newProgress >= quest.target
});
}
});
if (updates.length > 0) {
this.saveState();
}
return updates;
}
// 檢查是否可以進化
canEvolve() {
const deityState = this.getCurrentDeityState();
const deityConfig = this.getCurrentDeity();
if (!deityState || !deityConfig) return false;
// 檢查是否已達最高級
if (deityState.stageLevel >= deityConfig.stages.length) return false;
// 檢查下一階需求EXP
const nextStage = deityConfig.stages.find(s => s.level === deityState.stageLevel + 1);
if (!nextStage) return false;
// 檢查經驗值 (如果有)
if (deityState.exp < nextStage.requiredExp) return false;
// 檢查當前階段的所有任務是否完成(修正:檢查當前階段而非下一階段)
const currentStage = deityConfig.stages.find(s => s.level === deityState.stageLevel);
if (!currentStage || !currentStage.quests || currentStage.quests.length === 0) return true;
const allQuestsCompleted = currentStage.quests.every(q => {
return (deityState.quests[q.id] || 0) >= q.target;
});
return allQuestsCompleted;
}
// 進化
evolve() {
if (!this.canEvolve()) return false;
const deityState = this.getCurrentDeityState();
const deityConfig = this.getCurrentDeity();
deityState.stageLevel += 1;
// 初始化當前(剛進化到的)階段的任務
const currentStage = deityConfig.stages.find(s => s.level === deityState.stageLevel);
if (currentStage?.quests) {
currentStage.quests.forEach(q => {
if (!deityState.quests[q.id]) {
deityState.quests[q.id] = 0;
}
});
}
this.saveState();
return true;
}
// 塔羅占卜
drawTarot() {
const cardIndex = Math.floor(Math.random() * TAROT_MAJOR_ARCANA.length)
const card = TAROT_MAJOR_ARCANA[cardIndex]
// 記錄今日運勢
this.state.dailyFortune = {
type: 'tarot',
result: card,
timestamp: Date.now()
}
this.saveState();
return card
}
// 獲取當前生效的 Buffs
getActiveBuffs() {
const stage = this.getCurrentStage()
if (!stage) return {}
// 如果是最終階段,確保包含所有強力 Buff
// 邏輯上 Stage 3 的 buffs 已經包含了所有需要的屬性
return stage.buffs || {}
}
// 獲取狀態以供保存
getState() {
return this.state
}
}