pet_data/core/deity-system.js

258 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.

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
}
}