550 lines
16 KiB
JavaScript
550 lines
16 KiB
JavaScript
|
|
/**
|
|||
|
|
* 事件系统 - 事件触发检测、对话管理
|
|||
|
|
* Phase 6 核心系统实现
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { NPC_CONFIG } from '@/config/npcs.js'
|
|||
|
|
import { EVENT_CONFIG } from '@/config/events.js'
|
|||
|
|
import { LOCATION_CONFIG } from '@/config/locations.js'
|
|||
|
|
import { unlockSkill } from './skillSystem.js'
|
|||
|
|
import { addItemToInventory } from './itemSystem.js'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查并触发事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @param {String} triggerType - 触发类型 'enter' | 'action' | 'timer'
|
|||
|
|
* @param {Object} context - 触发上下文
|
|||
|
|
* @returns {Object|null} 触发的事件信息
|
|||
|
|
*/
|
|||
|
|
export function checkAndTriggerEvent(gameStore, playerStore, triggerType = 'enter', context = {}) {
|
|||
|
|
// 检查首次进入事件
|
|||
|
|
if (!playerStore.flags) {
|
|||
|
|
playerStore.flags = {}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 新游戏初始化事件
|
|||
|
|
if (!playerStore.flags.introTriggered) {
|
|||
|
|
playerStore.flags.introTriggered = true
|
|||
|
|
triggerEvent(gameStore, 'intro', { playerStore })
|
|||
|
|
return { eventId: 'intro', type: 'story' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查位置事件
|
|||
|
|
if (triggerType === 'enter') {
|
|||
|
|
const locationEvent = checkLocationEvent(gameStore, playerStore, context.locationId)
|
|||
|
|
if (locationEvent) {
|
|||
|
|
return locationEvent
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查NPC对话事件
|
|||
|
|
if (triggerType === 'npc') {
|
|||
|
|
const npcEvent = checkNPCDialogue(gameStore, playerStore, context.npcId)
|
|||
|
|
if (npcEvent) {
|
|||
|
|
return npcEvent
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查战斗相关事件
|
|||
|
|
if (triggerType === 'combat') {
|
|||
|
|
const combatEvent = checkCombatEvent(gameStore, playerStore, context)
|
|||
|
|
if (combatEvent) {
|
|||
|
|
return combatEvent
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查解锁事件
|
|||
|
|
if (triggerType === 'unlock') {
|
|||
|
|
const unlockEvent = checkUnlockEvent(gameStore, playerStore, context)
|
|||
|
|
if (unlockEvent) {
|
|||
|
|
return unlockEvent
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查位置事件
|
|||
|
|
*/
|
|||
|
|
function checkLocationEvent(gameStore, playerStore, locationId) {
|
|||
|
|
const location = LOCATION_CONFIG[locationId]
|
|||
|
|
if (!location) return null
|
|||
|
|
|
|||
|
|
// 首次进入地下室警告
|
|||
|
|
if (locationId === 'basement' && !playerStore.flags.basementFirstEnter) {
|
|||
|
|
playerStore.flags.basementFirstEnter = true
|
|||
|
|
triggerEvent(gameStore, 'dark_warning', { locationName: location.name })
|
|||
|
|
return { eventId: 'dark_warning', type: 'tips' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 首次进入野外战斗提示
|
|||
|
|
if (locationId === 'wild1' && !playerStore.flags.wild1FirstEnter) {
|
|||
|
|
playerStore.flags.wild1FirstEnter = true
|
|||
|
|
triggerEvent(gameStore, 'first_combat', { locationName: location.name })
|
|||
|
|
return { eventId: 'first_combat', type: 'tips' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查NPC对话事件
|
|||
|
|
*/
|
|||
|
|
function checkNPCDialogue(gameStore, playerStore, npcId) {
|
|||
|
|
const npc = NPC_CONFIG[npcId]
|
|||
|
|
if (!npc) return null
|
|||
|
|
|
|||
|
|
// 启动NPC对话
|
|||
|
|
startNPCDialogue(gameStore, npcId, 'first')
|
|||
|
|
return { eventId: `npc_${npcId}`, type: 'dialogue' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查战斗事件
|
|||
|
|
*/
|
|||
|
|
function checkCombatEvent(gameStore, playerStore, context) {
|
|||
|
|
// 检查Boss解锁
|
|||
|
|
if (context.result === 'victory' && context.enemyId === 'wild_dog') {
|
|||
|
|
const killCount = (playerStore.killCount || {})[context.enemyId] || 0
|
|||
|
|
playerStore.killCount = playerStore.killCount || {}
|
|||
|
|
playerStore.killCount[context.enemyId] = killCount + 1
|
|||
|
|
|
|||
|
|
// 击杀5只野狗解锁Boss巢
|
|||
|
|
if (playerStore.killCount[context.enemyId] >= 5 && !playerStore.flags.bossUnlockTriggered) {
|
|||
|
|
playerStore.flags.bossUnlockTriggered = true
|
|||
|
|
triggerEvent(gameStore, 'boss_unlock', {})
|
|||
|
|
return { eventId: 'boss_unlock', type: 'unlock' }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Boss击败事件
|
|||
|
|
if (context.result === 'victory' && context.enemyId === 'test_boss' && !playerStore.flags.bossDefeatTriggered) {
|
|||
|
|
playerStore.flags.bossDefeatTriggered = true
|
|||
|
|
triggerEvent(gameStore, 'boss_defeat', {})
|
|||
|
|
return { eventId: 'boss_defeat', type: 'story' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查解锁事件
|
|||
|
|
*/
|
|||
|
|
function checkUnlockEvent(gameStore, playerStore, context) {
|
|||
|
|
// 区域解锁事件
|
|||
|
|
if (context.unlockType === 'location' && context.locationId === 'boss_lair') {
|
|||
|
|
// 已在战斗事件中处理
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 触发事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {String} eventId - 事件ID
|
|||
|
|
* @param {Object} context - 事件上下文
|
|||
|
|
*/
|
|||
|
|
export function triggerEvent(gameStore, eventId, context = {}) {
|
|||
|
|
const config = EVENT_CONFIG[eventId]
|
|||
|
|
if (!config) {
|
|||
|
|
console.warn(`Event ${eventId} not found`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 构建事件数据
|
|||
|
|
const eventData = {
|
|||
|
|
id: eventId,
|
|||
|
|
type: config.type,
|
|||
|
|
title: config.title || '',
|
|||
|
|
text: config.text || '',
|
|||
|
|
npc: config.npcId ? NPC_CONFIG[config.npcId] : null,
|
|||
|
|
choices: config.choices || [],
|
|||
|
|
actions: config.actions || [],
|
|||
|
|
context,
|
|||
|
|
triggers: config.triggers || []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理动态文本(替换变量)
|
|||
|
|
if (config.textTemplate && context) {
|
|||
|
|
eventData.text = renderTemplate(config.textTemplate, context)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置当前事件
|
|||
|
|
gameStore.currentEvent = eventData
|
|||
|
|
|
|||
|
|
// 打开事件抽屉
|
|||
|
|
gameStore.drawerState.event = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 渲染模板文本
|
|||
|
|
*/
|
|||
|
|
function renderTemplate(template, context) {
|
|||
|
|
let text = template
|
|||
|
|
for (const [key, value] of Object.entries(context)) {
|
|||
|
|
text = text.replace(new RegExp(`\\{${key}\\}`, 'g'), value)
|
|||
|
|
}
|
|||
|
|
return text
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动NPC对话
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {String} npcId - NPC ID
|
|||
|
|
* @param {String} dialogueKey - 对话键名
|
|||
|
|
*/
|
|||
|
|
export function startNPCDialogue(gameStore, npcId, dialogueKey = 'first') {
|
|||
|
|
const npc = NPC_CONFIG[npcId]
|
|||
|
|
if (!npc) {
|
|||
|
|
console.warn(`NPC ${npcId} not found`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const dialogue = npc.dialogue[dialogueKey]
|
|||
|
|
if (!dialogue) {
|
|||
|
|
console.warn(`Dialogue ${dialogueKey} not found for NPC ${npcId}`)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 构建事件数据
|
|||
|
|
const eventData = {
|
|||
|
|
id: `npc_${npcId}_${dialogueKey}`,
|
|||
|
|
type: 'dialogue',
|
|||
|
|
title: npc.name,
|
|||
|
|
text: dialogue.text,
|
|||
|
|
npc: npc,
|
|||
|
|
choices: dialogue.choices || [],
|
|||
|
|
currentDialogue: dialogueKey,
|
|||
|
|
npcId
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
gameStore.currentEvent = eventData
|
|||
|
|
gameStore.drawerState.event = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理对话选择
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @param {Object} choice - 选择项
|
|||
|
|
* @returns {Object} 处理结果
|
|||
|
|
*/
|
|||
|
|
export function handleDialogueChoice(gameStore, playerStore, choice) {
|
|||
|
|
const result = {
|
|||
|
|
success: true,
|
|||
|
|
closeEvent: false,
|
|||
|
|
message: ''
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 处理对话动作
|
|||
|
|
if (choice.action) {
|
|||
|
|
const actionResult = processDialogueAction(gameStore, playerStore, choice.action, choice.actionData)
|
|||
|
|
result.message = actionResult.message
|
|||
|
|
if (actionResult.closeEvent) {
|
|||
|
|
result.closeEvent = true
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查下一步
|
|||
|
|
if (choice.next === null) {
|
|||
|
|
// 对话结束
|
|||
|
|
result.closeEvent = true
|
|||
|
|
} else if (choice.next) {
|
|||
|
|
// 继续对话
|
|||
|
|
const currentEvent = gameStore.currentEvent
|
|||
|
|
if (currentEvent && currentEvent.npc) {
|
|||
|
|
startNPCDialogue(gameStore, currentEvent.npc.id, choice.next)
|
|||
|
|
result.closeEvent = false
|
|||
|
|
}
|
|||
|
|
} else if (!choice.action) {
|
|||
|
|
// 没有next也没有action,关闭
|
|||
|
|
result.closeEvent = true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 如果需要关闭事件
|
|||
|
|
if (result.closeEvent) {
|
|||
|
|
gameStore.drawerState.event = false
|
|||
|
|
gameStore.currentEvent = null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理对话动作
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @param {String} action - 动作类型
|
|||
|
|
* @param {Object} actionData - 动作数据
|
|||
|
|
* @returns {Object} 处理结果
|
|||
|
|
*/
|
|||
|
|
export function processDialogueAction(gameStore, playerStore, action, actionData = {}) {
|
|||
|
|
switch (action) {
|
|||
|
|
case 'give_stick':
|
|||
|
|
// 给予木棍
|
|||
|
|
const stickResult = addItemToInventory(playerStore, 'wooden_stick', 1, 100)
|
|||
|
|
if (stickResult.success) {
|
|||
|
|
// 自动解锁木棍精通技能
|
|||
|
|
unlockSkill(playerStore, 'stick_mastery')
|
|||
|
|
if (gameStore.addLog) {
|
|||
|
|
gameStore.addLog('获得了 木棍', 'reward')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return { success: true, message: '获得了木棍', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'open_shop':
|
|||
|
|
// 打开商店
|
|||
|
|
gameStore.drawerState.event = false
|
|||
|
|
// TODO: 打开商店抽屉
|
|||
|
|
gameStore.drawerState.shop = true
|
|||
|
|
return { success: true, message: '', closeEvent: true }
|
|||
|
|
|
|||
|
|
case 'give_item':
|
|||
|
|
// 给予物品
|
|||
|
|
if (actionData.itemId) {
|
|||
|
|
const itemResult = addItemToInventory(
|
|||
|
|
playerStore,
|
|||
|
|
actionData.itemId,
|
|||
|
|
actionData.count || 1,
|
|||
|
|
actionData.quality || null
|
|||
|
|
)
|
|||
|
|
if (itemResult.success && gameStore.addLog) {
|
|||
|
|
gameStore.addLog(`获得了 ${itemResult.item.name}`, 'reward')
|
|||
|
|
}
|
|||
|
|
return { success: true, message: `获得了 ${actionData.itemId}`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '物品参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'unlock_skill':
|
|||
|
|
// 解锁技能
|
|||
|
|
if (actionData.skillId) {
|
|||
|
|
unlockSkill(playerStore, actionData.skillId)
|
|||
|
|
if (gameStore.addLog) {
|
|||
|
|
const skillConfig = SKILL_CONFIG[actionData.skillId]
|
|||
|
|
gameStore.addLog(`解锁了技能: ${skillConfig?.name || actionData.skillId}`, 'system')
|
|||
|
|
}
|
|||
|
|
return { success: true, message: `解锁了技能 ${actionData.skillId}`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '技能参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'heal':
|
|||
|
|
// 治疗
|
|||
|
|
if (actionData.amount) {
|
|||
|
|
playerStore.currentStats.health = Math.min(
|
|||
|
|
playerStore.currentStats.maxHealth,
|
|||
|
|
playerStore.currentStats.health + actionData.amount
|
|||
|
|
)
|
|||
|
|
return { success: true, message: `恢复了${actionData.amount}生命`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '治疗参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'restore_stamina':
|
|||
|
|
// 恢复耐力
|
|||
|
|
if (actionData.amount) {
|
|||
|
|
playerStore.currentStats.stamina = Math.min(
|
|||
|
|
playerStore.currentStats.maxStamina,
|
|||
|
|
playerStore.currentStats.stamina + actionData.amount
|
|||
|
|
)
|
|||
|
|
return { success: true, message: `恢复了${actionData.amount}耐力`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '耐力参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'teleport':
|
|||
|
|
// 传送
|
|||
|
|
if (actionData.locationId) {
|
|||
|
|
playerStore.currentLocation = actionData.locationId
|
|||
|
|
if (gameStore.addLog) {
|
|||
|
|
const location = LOCATION_CONFIG[actionData.locationId]
|
|||
|
|
gameStore.addLog(`来到了 ${location?.name || actionData.locationId}`, 'system')
|
|||
|
|
}
|
|||
|
|
return { success: true, message: `传送到 ${actionData.locationId}`, closeEvent: true }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '位置参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'add_currency':
|
|||
|
|
// 添加货币
|
|||
|
|
if (actionData.amount) {
|
|||
|
|
playerStore.currency.copper += actionData.amount
|
|||
|
|
if (gameStore.addLog) {
|
|||
|
|
gameStore.addLog(`获得了 ${actionData.amount} 铜币`, 'reward')
|
|||
|
|
}
|
|||
|
|
return { success: true, message: `获得了${actionData.amount}铜币`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '货币参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'set_flag':
|
|||
|
|
// 设置标志
|
|||
|
|
if (actionData.flag) {
|
|||
|
|
playerStore.flags = playerStore.flags || {}
|
|||
|
|
playerStore.flags[actionData.flag] = actionData.value !== undefined ? actionData.value : true
|
|||
|
|
return { success: true, message: `设置标志 ${actionData.flag}`, closeEvent: false }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '标志参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'check_flag':
|
|||
|
|
// 检查标志(返回结果由调用者处理)
|
|||
|
|
if (actionData.flag) {
|
|||
|
|
const value = playerStore.flags?.[actionData.flag]
|
|||
|
|
return {
|
|||
|
|
success: true,
|
|||
|
|
message: '',
|
|||
|
|
closeEvent: false,
|
|||
|
|
flagValue: value
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '标志参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'start_combat':
|
|||
|
|
// 开始战斗
|
|||
|
|
if (actionData.enemyId) {
|
|||
|
|
gameStore.drawerState.event = false
|
|||
|
|
// TODO: 启动战斗
|
|||
|
|
return { success: true, message: '开始战斗', closeEvent: true }
|
|||
|
|
}
|
|||
|
|
return { success: false, message: '敌人参数错误', closeEvent: false }
|
|||
|
|
|
|||
|
|
case 'close':
|
|||
|
|
// 直接关闭
|
|||
|
|
return { success: true, message: '', closeEvent: true }
|
|||
|
|
|
|||
|
|
default:
|
|||
|
|
console.warn(`Unknown dialogue action: ${action}`)
|
|||
|
|
return { success: false, message: '未知动作', closeEvent: false }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 处理事件选择
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @param {Number} choiceIndex - 选择索引
|
|||
|
|
* @returns {Object} 处理结果
|
|||
|
|
*/
|
|||
|
|
export function handleEventChoice(gameStore, playerStore, choiceIndex) {
|
|||
|
|
const currentEvent = gameStore.currentEvent
|
|||
|
|
if (!currentEvent || !currentEvent.choices || !currentEvent.choices[choiceIndex]) {
|
|||
|
|
return { success: false, message: '选择无效' }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const choice = currentEvent.choices[choiceIndex]
|
|||
|
|
return handleDialogueChoice(gameStore, playerStore, choice)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭当前事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
*/
|
|||
|
|
export function closeEvent(gameStore) {
|
|||
|
|
gameStore.drawerState.event = false
|
|||
|
|
gameStore.currentEvent = null
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前事件信息
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @returns {Object|null} 当前事件
|
|||
|
|
*/
|
|||
|
|
export function getCurrentEvent(gameStore) {
|
|||
|
|
return gameStore.currentEvent
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查NPC是否可用
|
|||
|
|
* @param {String} npcId - NPC ID
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @returns {Boolean}
|
|||
|
|
*/
|
|||
|
|
export function isNPCAvailable(npcId, playerStore) {
|
|||
|
|
const npc = NPC_CONFIG[npcId]
|
|||
|
|
if (!npc) return false
|
|||
|
|
|
|||
|
|
// 检查位置
|
|||
|
|
if (npc.location && playerStore.currentLocation !== npc.location) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 检查解锁条件
|
|||
|
|
if (npc.unlockCondition) {
|
|||
|
|
const condition = npc.unlockCondition
|
|||
|
|
if (condition.flag && !playerStore.flags?.[condition.flag]) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
if (condition.item && !playerStore.inventory.some(i => i.id === condition.item)) {
|
|||
|
|
return false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前位置可用的NPC列表
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @returns {Array} NPC ID列表
|
|||
|
|
*/
|
|||
|
|
export function getAvailableNPCs(playerStore) {
|
|||
|
|
const location = LOCATION_CONFIG[playerStore.currentLocation]
|
|||
|
|
if (!location || !location.npcs) {
|
|||
|
|
return []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return location.npcs.filter(npcId => isNPCAvailable(npcId, playerStore))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置定时事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {String} eventId - 事件ID
|
|||
|
|
* @param {Number} delayMs - 延迟时间(毫秒)
|
|||
|
|
*/
|
|||
|
|
export function scheduleEvent(gameStore, eventId, delayMs) {
|
|||
|
|
if (!gameStore.scheduledEvents) {
|
|||
|
|
gameStore.scheduledEvents = []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
gameStore.scheduledEvents.push({
|
|||
|
|
eventId,
|
|||
|
|
triggerTime: Date.now() + delayMs,
|
|||
|
|
triggered: false
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查并触发定时事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
* @param {Object} playerStore - 玩家Store
|
|||
|
|
* @returns {Array} 触发的事件列表
|
|||
|
|
*/
|
|||
|
|
export function checkScheduledEvents(gameStore, playerStore) {
|
|||
|
|
if (!gameStore.scheduledEvents) {
|
|||
|
|
return []
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const now = Date.now()
|
|||
|
|
const triggeredEvents = []
|
|||
|
|
|
|||
|
|
for (const event of gameStore.scheduledEvents) {
|
|||
|
|
if (!event.triggered && now >= event.triggerTime) {
|
|||
|
|
event.triggered = true
|
|||
|
|
triggerEvent(gameStore, event.eventId, { playerStore })
|
|||
|
|
triggeredEvents.push(event.eventId)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 清理已触发的事件
|
|||
|
|
gameStore.scheduledEvents = gameStore.scheduledEvents.filter(e => !e.triggered)
|
|||
|
|
|
|||
|
|
return triggeredEvents
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清除所有定时事件
|
|||
|
|
* @param {Object} gameStore - 游戏Store
|
|||
|
|
*/
|
|||
|
|
export function clearScheduledEvents(gameStore) {
|
|||
|
|
gameStore.scheduledEvents = []
|
|||
|
|
}
|