2025-11-23 18:03:56 +00:00
|
|
|
|
// 事件系統核心 - 與 API 整合
|
|
|
|
|
|
import { apiService } from './api-service.js'
|
|
|
|
|
|
|
|
|
|
|
|
export class EventSystem {
|
2025-11-24 10:34:02 +00:00
|
|
|
|
constructor(petSystem, api = apiService, achievementSystem = null, inventorySystem = null) {
|
2025-11-23 18:03:56 +00:00
|
|
|
|
this.petSystem = petSystem
|
|
|
|
|
|
this.api = api
|
2025-11-24 10:34:02 +00:00
|
|
|
|
this.achievementSystem = achievementSystem
|
|
|
|
|
|
this.inventorySystem = inventorySystem
|
2025-11-23 18:03:56 +00:00
|
|
|
|
this.events = []
|
|
|
|
|
|
this.buffManager = new BuffManager()
|
|
|
|
|
|
this.eventHistory = []
|
|
|
|
|
|
this.eventCheckInterval = null
|
|
|
|
|
|
this.lastEventCheckTime = 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化(從 API 載入事件配置)
|
|
|
|
|
|
async initialize() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
this.events = await this.api.getEvents()
|
|
|
|
|
|
console.log(`[EventSystem] 載入 ${this.events.length} 個事件`)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('[EventSystem] 載入事件失敗:', error)
|
|
|
|
|
|
// 降級到本地載入
|
|
|
|
|
|
const { EVENT_CONFIG } = await import('../data/events.js')
|
|
|
|
|
|
this.events = EVENT_CONFIG
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 07:38:44 +00:00
|
|
|
|
// 啟動事件檢查循環(从配置读取间隔)
|
2025-11-23 18:03:56 +00:00
|
|
|
|
startEventCheck() {
|
|
|
|
|
|
if (this.eventCheckInterval) this.stopEventCheck()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
|
|
|
|
|
// 从配置读取间隔时间
|
|
|
|
|
|
const petConfig = this.petSystem.speciesConfig
|
|
|
|
|
|
const interval = petConfig?.baseStats?.eventCheckInterval || 10000
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
this.eventCheckInterval = setInterval(() => {
|
|
|
|
|
|
this.checkTriggers()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
}, interval)
|
2025-11-23 18:03:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stopEventCheck() {
|
|
|
|
|
|
if (this.eventCheckInterval) {
|
|
|
|
|
|
clearInterval(this.eventCheckInterval)
|
|
|
|
|
|
this.eventCheckInterval = null
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 隨機選擇事件(依權重)
|
|
|
|
|
|
selectRandomEvent() {
|
|
|
|
|
|
const totalWeight = this.events.reduce((sum, e) => sum + e.weight, 0)
|
|
|
|
|
|
let rand = Math.random() * totalWeight
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
for (const event of this.events) {
|
|
|
|
|
|
rand -= event.weight
|
|
|
|
|
|
if (rand <= 0) return event
|
|
|
|
|
|
}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return this.events[0] // fallback
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 檢查觸發條件(10% 機率 + 條件檢查)
|
|
|
|
|
|
async checkTriggers() {
|
|
|
|
|
|
const petState = this.petSystem.getState()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
if (petState.isDead) return
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
|
|
|
|
|
// 睡眠時不觸發事件(類似暫停)
|
|
|
|
|
|
if (petState.isSleeping) return
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 10% 機率觸發
|
|
|
|
|
|
if (Math.random() >= 0.1) return
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
const event = this.selectRandomEvent()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 檢查條件
|
|
|
|
|
|
if (event.condition && !event.condition(petState)) {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 觸發事件
|
|
|
|
|
|
await this.triggerEvent(event.id, petState)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 觸發事件(同步到 API)
|
|
|
|
|
|
async triggerEvent(eventId, petState = null) {
|
|
|
|
|
|
const event = this.events.find(e => e.id === eventId)
|
|
|
|
|
|
if (!event) {
|
|
|
|
|
|
console.warn(`[EventSystem] 找不到事件: ${eventId}`)
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const currentState = petState || this.petSystem.getState()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 檢查條件
|
|
|
|
|
|
if (event.condition && !event.condition(currentState)) {
|
2025-11-24 07:38:44 +00:00
|
|
|
|
console.log(`\n❌ 事件 ${event.id} 觸發失敗`)
|
|
|
|
|
|
console.log(` 條件: ${event.conditionDescription || '未定義'}`)
|
|
|
|
|
|
console.log(` 當前狀態:`)
|
|
|
|
|
|
console.log(` - 飢餓: ${currentState.hunger.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - 快樂: ${currentState.happiness.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - 健康: ${currentState.health.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - 運勢: ${currentState.luck.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - 體重: ${currentState.weight.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - DEX: ${currentState.dex.toFixed(1)}`)
|
|
|
|
|
|
console.log(` - INT: ${currentState.int.toFixed(1)}`)
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`\n[事件觸發] ${event.id} (${event.type}): 機率檢查通過!`)
|
|
|
|
|
|
|
|
|
|
|
|
// 執行效果
|
|
|
|
|
|
const results = []
|
|
|
|
|
|
for (const effect of event.effects) {
|
|
|
|
|
|
const result = await this.executeEffect(effect, currentState)
|
|
|
|
|
|
results.push(result)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 記錄歷史
|
|
|
|
|
|
this.eventHistory.push({
|
|
|
|
|
|
timestamp: Date.now(),
|
|
|
|
|
|
eventId: event.id,
|
|
|
|
|
|
eventType: event.type,
|
|
|
|
|
|
effects: results
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2025-11-24 10:34:02 +00:00
|
|
|
|
// 通知成就系統(如果存在)
|
|
|
|
|
|
if (this.achievementSystem) {
|
|
|
|
|
|
await this.achievementSystem.recordEvent(event)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 同步到 API
|
|
|
|
|
|
try {
|
|
|
|
|
|
await this.api.triggerEvent(eventId, currentState)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.warn('[EventSystem] API 同步失敗:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return { event, results }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 執行效果
|
|
|
|
|
|
async executeEffect(effect, petState) {
|
|
|
|
|
|
switch (effect.type) {
|
|
|
|
|
|
case 'modifyStats':
|
|
|
|
|
|
return await this.modifyStats(effect.payload, petState)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
case 'addBuff':
|
|
|
|
|
|
return await this.addBuff(effect.payload)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-24 10:34:02 +00:00
|
|
|
|
case 'addItem':
|
|
|
|
|
|
return await this.addItem(effect.payload)
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
case 'spawnPoop':
|
|
|
|
|
|
return await this.spawnPoop(effect.payload)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
case 'templeFavor':
|
|
|
|
|
|
return await this.modifyTempleFavor(effect.payload)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
case 'logMessage':
|
|
|
|
|
|
console.log(`[訊息] ${effect.payload}`)
|
|
|
|
|
|
return { type: 'logMessage', message: effect.payload }
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
default:
|
|
|
|
|
|
console.warn(`[EventSystem] 未知效果類型: ${effect.type}`)
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 修改屬性
|
|
|
|
|
|
async modifyStats(payload, petState) {
|
2025-11-24 07:38:44 +00:00
|
|
|
|
// 獲取最新狀態(因為 petState 可能是舊的快照)
|
|
|
|
|
|
const currentState = this.petSystem.getState()
|
2025-11-23 18:03:56 +00:00
|
|
|
|
const updates = {}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
for (const [key, value] of Object.entries(payload)) {
|
|
|
|
|
|
if (key === 'isSleeping' || key === 'isSick' || key === 'isDead') {
|
|
|
|
|
|
updates[key] = value
|
|
|
|
|
|
} else {
|
2025-11-24 07:38:44 +00:00
|
|
|
|
const current = currentState[key] || 0
|
|
|
|
|
|
let newValue = current
|
|
|
|
|
|
|
|
|
|
|
|
if (value > 0) {
|
|
|
|
|
|
// 增加屬性:如果是自然增長(非道具),上限為 100
|
|
|
|
|
|
// 如果當前已經 >= 100,則不再增加(除非是道具,但這裡是事件系統)
|
|
|
|
|
|
// 如果當前 < 100,則最多增加到 100
|
|
|
|
|
|
newValue = current < 100 ? Math.min(100, current + value) : current
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 減少屬性:總是生效,最低為 0
|
|
|
|
|
|
newValue = Math.max(0, current + value)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
updates[key] = newValue
|
2025-11-24 07:38:44 +00:00
|
|
|
|
console.log(`[效果] ${key} ${value > 0 ? '+' : ''}${value} (${current.toFixed(1)} → ${newValue.toFixed(1)})`)
|
2025-11-23 18:03:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
await this.petSystem.updateState(updates)
|
|
|
|
|
|
return { type: 'modifyStats', updates }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加 Buff
|
|
|
|
|
|
async addBuff(buffData) {
|
|
|
|
|
|
this.buffManager.addBuff(buffData)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 同步到 API
|
|
|
|
|
|
try {
|
|
|
|
|
|
await this.api.applyBuff(buffData)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.warn('[EventSystem] Buff API 同步失敗:', error)
|
|
|
|
|
|
}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return { type: 'addBuff', buff: buffData }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成便便
|
|
|
|
|
|
async spawnPoop(payload) {
|
|
|
|
|
|
const count = payload?.count || 1
|
|
|
|
|
|
const currentPoop = this.petSystem.getState().poopCount
|
|
|
|
|
|
const newPoop = Math.min(4, currentPoop + count)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
await this.petSystem.updateState({ poopCount: newPoop })
|
|
|
|
|
|
console.log(`[效果] 生成便便: ${count} 個,總數: ${newPoop}`)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return { type: 'spawnPoop', count, total: newPoop }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 修改神明好感度
|
|
|
|
|
|
async modifyTempleFavor(payload) {
|
|
|
|
|
|
const { deityId, amount } = payload
|
|
|
|
|
|
const currentState = this.petSystem.getState()
|
|
|
|
|
|
const currentFavor = currentState.deityFavors[deityId] || 0
|
|
|
|
|
|
const newFavor = Math.max(0, Math.min(100, currentFavor + amount))
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
await this.petSystem.updateState({
|
|
|
|
|
|
deityFavors: {
|
|
|
|
|
|
...currentState.deityFavors,
|
|
|
|
|
|
[deityId]: newFavor
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
console.log(`[效果] ${deityId} 好感度 ${amount > 0 ? '+' : ''}${amount} → ${newFavor}`)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return { type: 'templeFavor', deityId, favor: newFavor }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-24 10:34:02 +00:00
|
|
|
|
// 添加道具效果
|
|
|
|
|
|
async addItem(payload) {
|
|
|
|
|
|
if (!this.inventorySystem) {
|
|
|
|
|
|
console.warn('[EventSystem] 背包系統未初始化,無法添加道具')
|
|
|
|
|
|
return { type: 'addItem', success: false, message: '背包系統未初始化' }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const { itemId, count = 1 } = payload
|
|
|
|
|
|
const result = await this.inventorySystem.addItem(itemId, count)
|
|
|
|
|
|
|
|
|
|
|
|
if (result.success) {
|
|
|
|
|
|
console.log(`[事件] 獲得道具: ${result.item.name} x${count}`)
|
|
|
|
|
|
return { type: 'addItem', success: true, itemId, count, item: result.item }
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.warn(`[事件] 添加道具失敗: ${result.message}`)
|
|
|
|
|
|
return { type: 'addItem', success: false, message: result.message }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 應用 Buff 到狀態(每 tick 呼叫)
|
|
|
|
|
|
async applyBuffs() {
|
|
|
|
|
|
const petState = this.petSystem.getState()
|
|
|
|
|
|
const buffs = this.buffManager.getActiveBuffs()
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 計算最終屬性(考慮 Buff)
|
|
|
|
|
|
const finalStats = this.calculateFinalStats(petState, buffs)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 更新狀態
|
|
|
|
|
|
await this.petSystem.updateState(finalStats)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return finalStats
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 計算最終屬性(Base + Flat + Percent)
|
|
|
|
|
|
calculateFinalStats(baseState, buffs) {
|
|
|
|
|
|
const stats = { ...baseState }
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 收集所有 Buff 的 flat 和 percent 加成
|
|
|
|
|
|
const flatMods = {}
|
|
|
|
|
|
const percentMods = {}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
buffs.forEach(buff => {
|
|
|
|
|
|
if (buff.flat) {
|
|
|
|
|
|
Object.entries(buff.flat).forEach(([key, value]) => {
|
|
|
|
|
|
flatMods[key] = (flatMods[key] || 0) + value
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
if (buff.percent) {
|
|
|
|
|
|
Object.entries(buff.percent).forEach(([key, value]) => {
|
|
|
|
|
|
percentMods[key] = (percentMods[key] || 0) + value
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
// 應用加成
|
|
|
|
|
|
Object.keys(stats).forEach(key => {
|
|
|
|
|
|
if (typeof stats[key] === 'number' && key !== 'ageSeconds' && key !== 'weight' && key !== 'generation') {
|
|
|
|
|
|
const base = stats[key]
|
|
|
|
|
|
const flat = flatMods[key] || 0
|
|
|
|
|
|
const percent = percentMods[key] || 0
|
|
|
|
|
|
stats[key] = Math.max(0, Math.min(100, (base + flat) * (1 + percent)))
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return stats
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 獲取事件歷史
|
|
|
|
|
|
getHistory() {
|
|
|
|
|
|
return [...this.eventHistory]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 獲取 Buff 管理器
|
|
|
|
|
|
getBuffManager() {
|
|
|
|
|
|
return this.buffManager
|
|
|
|
|
|
}
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
|
|
|
|
|
// Debug: 強制觸發事件
|
|
|
|
|
|
async debugTriggerEvent(eventId = null) {
|
|
|
|
|
|
let event
|
|
|
|
|
|
if (eventId) {
|
|
|
|
|
|
event = this.events.find(e => e.id === eventId)
|
|
|
|
|
|
if (!event) {
|
|
|
|
|
|
console.warn(`[Debug] 找不到事件: ${eventId}`)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
event = this.selectRandomEvent()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log(`[Debug] 強制觸發事件: ${event.id}`)
|
|
|
|
|
|
await this.triggerEvent(event.id)
|
|
|
|
|
|
return event
|
|
|
|
|
|
}
|
2025-11-23 18:03:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Buff 管理器
|
|
|
|
|
|
class BuffManager {
|
|
|
|
|
|
constructor() {
|
|
|
|
|
|
this.buffs = []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addBuff(buff) {
|
|
|
|
|
|
// 檢查是否可堆疊
|
|
|
|
|
|
const existing = this.buffs.find(b => b.id === buff.id)
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
if (existing && !buff.stacks) {
|
|
|
|
|
|
// 不可堆疊,重置持續時間
|
|
|
|
|
|
existing.currentTicks = buff.durationTicks
|
|
|
|
|
|
console.log(`[Buff] 重置: ${buff.name} (持續 ${buff.durationTicks} ticks)`)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 可堆疊或新 Buff
|
|
|
|
|
|
this.buffs.push({
|
|
|
|
|
|
...buff,
|
|
|
|
|
|
currentTicks: buff.durationTicks,
|
|
|
|
|
|
currentStacks: (existing?.currentStacks || 0) + 1
|
|
|
|
|
|
})
|
|
|
|
|
|
console.log(`[Buff] 新增: ${buff.name} (持續 ${buff.durationTicks} ticks)`)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tick() {
|
|
|
|
|
|
this.buffs = this.buffs.filter(b => {
|
|
|
|
|
|
if (b.durationTicks === Infinity) return true // 永久 Buff
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
b.currentTicks--
|
|
|
|
|
|
if (b.currentTicks <= 0) {
|
|
|
|
|
|
console.log(`[Buff] 過期: ${b.name}`)
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
return true
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getActiveBuffs() {
|
|
|
|
|
|
return this.buffs.filter(b => b.currentTicks > 0 || b.durationTicks === Infinity)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
getFinalModifier(statKey) {
|
|
|
|
|
|
const activeBuffs = this.getActiveBuffs()
|
|
|
|
|
|
let flatTotal = 0
|
|
|
|
|
|
let percentTotal = 0
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
activeBuffs.forEach(b => {
|
|
|
|
|
|
if (b.flat?.[statKey]) flatTotal += b.flat[statKey]
|
|
|
|
|
|
if (b.percent?.[statKey]) percentTotal += b.percent[statKey]
|
|
|
|
|
|
})
|
2025-11-24 07:38:44 +00:00
|
|
|
|
|
2025-11-23 18:03:56 +00:00
|
|
|
|
return { flat: flatTotal, percent: percentTotal }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|