mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-12 16:05:12 +08:00
feat: 重构战报弹窗与模拟器视图,优化UI与逻辑
重构BattleReportDialog和BattleSimulatorView相关静态资源,替换旧版JS/CSS文件,提升界面一致性和交互体验。新增和优化空状态、滚动区域等通用UI组件,移除部分冗余composable,完善多语言内容。引入导弹逻辑,补充版本检测工具,提升整体代码结构和可维护性。
This commit is contained in:
@@ -1,63 +0,0 @@
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import * as gameLogic from '@/logic/gameLogic'
|
||||
import * as planetLogic from '@/logic/planetLogic'
|
||||
import * as resourceLogic from '@/logic/resourceLogic'
|
||||
import * as officerLogic from '@/logic/officerLogic'
|
||||
|
||||
/**
|
||||
* 游戏生命周期管理
|
||||
* 处理游戏初始化、NPC星球生成等
|
||||
*/
|
||||
export const useGameLifecycle = () => {
|
||||
const gameStore = useGameStore()
|
||||
const universeStore = useUniverseStore()
|
||||
|
||||
/**
|
||||
* 生成NPC星球
|
||||
*/
|
||||
const generateNPCPlanets = (npcCount: number, planetPrefix: string) => {
|
||||
for (let i = 0; i < npcCount; i++) {
|
||||
const position = gameLogic.generateRandomPosition()
|
||||
const key = gameLogic.generatePositionKey(position.galaxy, position.system, position.position)
|
||||
if (universeStore.planets[key]) continue
|
||||
const npcPlanet = planetLogic.createNPCPlanet(i, position, planetPrefix)
|
||||
universeStore.planets[key] = npcPlanet
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化游戏
|
||||
*/
|
||||
const initGame = async (playerName: string, homePlanetName: string, planetPrefix: string) => {
|
||||
const shouldInit = gameLogic.shouldInitializeGame(gameStore.player.planets)
|
||||
|
||||
if (!shouldInit) {
|
||||
const now = Date.now()
|
||||
|
||||
// 计算离线收益(直接同步计算)
|
||||
const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now)
|
||||
gameStore.player.planets.forEach(planet => {
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses)
|
||||
})
|
||||
|
||||
// 只在没有NPC星球时才生成(首次加载已有玩家数据时)
|
||||
if (Object.keys(universeStore.planets).length === 0) {
|
||||
generateNPCPlanets(200, planetPrefix)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
gameStore.player = gameLogic.initializePlayer(gameStore.player.id, playerName)
|
||||
const initialPlanet = planetLogic.createInitialPlanet(gameStore.player.id, homePlanetName)
|
||||
gameStore.player.planets = [initialPlanet]
|
||||
gameStore.currentPlanetId = initialPlanet.id
|
||||
// 新玩家初始化时生成NPC星球
|
||||
generateNPCPlanets(200, planetPrefix)
|
||||
}
|
||||
|
||||
return {
|
||||
initGame,
|
||||
generateNPCPlanets
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useNPCStore } from '@/stores/npcStore'
|
||||
import type { FleetMission } from '@/types/game'
|
||||
import * as gameLogic from '@/logic/gameLogic'
|
||||
|
||||
/**
|
||||
* 游戏更新循环
|
||||
* 处理游戏状态的定期更新
|
||||
*/
|
||||
export const useGameUpdate = (
|
||||
processMissionArrival: (mission: FleetMission) => Promise<void>,
|
||||
processMissionReturn: (mission: FleetMission) => void,
|
||||
processNPCMissionArrival: (npc: any, mission: FleetMission) => void,
|
||||
processNPCMissionReturn: (npc: any, mission: FleetMission) => void,
|
||||
updateNPCGrowth: (deltaSeconds: number) => void,
|
||||
updateNPCBehavior: (deltaSeconds: number) => void
|
||||
) => {
|
||||
const gameStore = useGameStore()
|
||||
const npcStore = useNPCStore()
|
||||
|
||||
/**
|
||||
* 游戏主更新函数
|
||||
*/
|
||||
const updateGame = () => {
|
||||
if (gameStore.isPaused) return
|
||||
const now = Date.now()
|
||||
gameStore.gameTime = now
|
||||
|
||||
// 检查军官过期
|
||||
gameLogic.checkOfficersExpiration(gameStore.player.officers, now)
|
||||
|
||||
// 处理游戏更新(建造队列、研究队列等)
|
||||
const result = gameLogic.processGameUpdate(gameStore.player, now)
|
||||
gameStore.player.researchQueue = result.updatedResearchQueue
|
||||
|
||||
// 处理舰队任务
|
||||
gameStore.player.fleetMissions.forEach(mission => {
|
||||
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
||||
processMissionArrival(mission)
|
||||
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
||||
processMissionReturn(mission)
|
||||
}
|
||||
})
|
||||
|
||||
// 处理NPC舰队任务
|
||||
npcStore.npcs.forEach(npc => {
|
||||
if (npc.fleetMissions) {
|
||||
npc.fleetMissions.forEach(mission => {
|
||||
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
||||
processNPCMissionArrival(npc, mission)
|
||||
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
||||
processNPCMissionReturn(npc, mission)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// NPC成长系统更新
|
||||
updateNPCGrowth(1) // 传入1秒的时间间隔
|
||||
|
||||
// NPC行为系统更新(侦查和攻击决策)
|
||||
updateNPCBehavior(1)
|
||||
}
|
||||
|
||||
return {
|
||||
updateGame
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ export const useI18n = () => {
|
||||
const messages = computed(() => locales[currentLocale.value])
|
||||
|
||||
// 获取翻译文本的辅助函数
|
||||
const t = (key: string): string => {
|
||||
const t = (key: string, params?: Record<string, string | number>): string => {
|
||||
const keys = key.split('.')
|
||||
let value: any = messages.value
|
||||
|
||||
@@ -22,7 +22,16 @@ export const useI18n = () => {
|
||||
}
|
||||
}
|
||||
|
||||
return typeof value === 'string' ? value : key
|
||||
let result = typeof value === 'string' ? value : key
|
||||
|
||||
// 替换参数占位符
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
result = result.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue))
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const setLocale = (locale: Locale) => {
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import { useNPCStore } from '@/stores/npcStore'
|
||||
import type { FleetMission } from '@/types/game'
|
||||
import { MissionType } from '@/types/game'
|
||||
import * as gameLogic from '@/logic/gameLogic'
|
||||
import * as fleetLogic from '@/logic/fleetLogic'
|
||||
import * as shipLogic from '@/logic/shipLogic'
|
||||
import * as resourceLogic from '@/logic/resourceLogic'
|
||||
import * as diplomaticLogic from '@/logic/diplomaticLogic'
|
||||
|
||||
/**
|
||||
* 舰队任务处理
|
||||
* 处理玩家舰队任务的到达和返回
|
||||
*/
|
||||
export const useMissionHandler = (t: (key: string) => string) => {
|
||||
const gameStore = useGameStore()
|
||||
const universeStore = useUniverseStore()
|
||||
const npcStore = useNPCStore()
|
||||
|
||||
/**
|
||||
* 处理任务到达
|
||||
*/
|
||||
const processMissionArrival = async (mission: FleetMission) => {
|
||||
// 从宇宙星球地图中查找目标星球
|
||||
const targetKey = gameLogic.generatePositionKey(
|
||||
mission.targetPosition.galaxy,
|
||||
mission.targetPosition.system,
|
||||
mission.targetPosition.position
|
||||
)
|
||||
// 先从玩家星球中查找,再从宇宙地图中查找
|
||||
const targetPlanet =
|
||||
gameStore.player.planets.find(
|
||||
p =>
|
||||
p.position.galaxy === mission.targetPosition.galaxy &&
|
||||
p.position.system === mission.targetPosition.system &&
|
||||
p.position.position === mission.targetPosition.position
|
||||
) || universeStore.planets[targetKey]
|
||||
|
||||
// 获取起始星球名称(用于报告)
|
||||
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
||||
const originPlanetName = originPlanet?.name || t('fleetView.unknownPlanet')
|
||||
|
||||
if (mission.missionType === MissionType.Transport) {
|
||||
const result = fleetLogic.processTransportArrival(mission, targetPlanet, gameStore.player, npcStore.npcs)
|
||||
// 生成运输任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Transport,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName:
|
||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||
success: result.success,
|
||||
message: result.success ? t('missionReports.transportSuccess') : t('missionReports.transportFailed'),
|
||||
details: {
|
||||
transportedResources: mission.cargo
|
||||
},
|
||||
read: false
|
||||
})
|
||||
} else if (mission.missionType === MissionType.Attack) {
|
||||
const attackResult = await fleetLogic.processAttackArrival(mission, targetPlanet, gameStore.player, null, gameStore.player.planets)
|
||||
if (attackResult) {
|
||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||
|
||||
// 检查是否攻击了NPC星球,更新外交关系
|
||||
if (targetPlanet) {
|
||||
const targetNpc = npcStore.npcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
||||
if (targetNpc) {
|
||||
diplomaticLogic.handleAttackReputation(gameStore.player, targetNpc, attackResult.battleResult, npcStore.npcs)
|
||||
}
|
||||
}
|
||||
|
||||
if (attackResult.moon) {
|
||||
gameStore.player.planets.push(attackResult.moon)
|
||||
}
|
||||
if (attackResult.debrisField) {
|
||||
// 将残骸场添加到游戏状态
|
||||
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
||||
}
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Colonize) {
|
||||
const newPlanet = fleetLogic.processColonizeArrival(mission, targetPlanet, gameStore.player, t('planet.colonyPrefix'))
|
||||
// 生成殖民任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Colonize,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: newPlanet?.id,
|
||||
targetPlanetName: newPlanet?.name,
|
||||
success: !!newPlanet,
|
||||
message: newPlanet ? t('missionReports.colonizeSuccess') : t('missionReports.colonizeFailed'),
|
||||
details: newPlanet
|
||||
? {
|
||||
newPlanetId: newPlanet.id,
|
||||
newPlanetName: newPlanet.name
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
if (newPlanet) {
|
||||
gameStore.player.planets.push(newPlanet)
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Spy) {
|
||||
const spyReport = fleetLogic.processSpyArrival(mission, targetPlanet, gameStore.player, null, npcStore.npcs)
|
||||
if (spyReport) gameStore.player.spyReports.push(spyReport)
|
||||
} else if (mission.missionType === MissionType.Deploy) {
|
||||
const deployed = fleetLogic.processDeployArrival(mission, targetPlanet, gameStore.player.id)
|
||||
// 生成部署任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Deploy,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName:
|
||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||
success: deployed,
|
||||
message: deployed ? t('missionReports.deploySuccess') : t('missionReports.deployFailed'),
|
||||
details: {
|
||||
deployedFleet: mission.fleet
|
||||
},
|
||||
read: false
|
||||
})
|
||||
if (deployed) {
|
||||
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||
return
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Recycle) {
|
||||
// 处理回收任务
|
||||
const debrisId = `debris_${mission.targetPosition.galaxy}_${mission.targetPosition.system}_${mission.targetPosition.position}`
|
||||
const debrisField = universeStore.debrisFields[debrisId]
|
||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||
|
||||
// 生成回收任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Recycle,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
success: !!recycleResult,
|
||||
message: recycleResult ? t('missionReports.recycleSuccess') : t('missionReports.recycleFailed'),
|
||||
details: recycleResult
|
||||
? {
|
||||
recycledResources: recycleResult.collectedResources,
|
||||
remainingDebris: recycleResult.remainingDebris || undefined
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
|
||||
if (recycleResult && debrisField) {
|
||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||
// 更新残骸场
|
||||
universeStore.debrisFields[debrisId] = {
|
||||
id: debrisField.id,
|
||||
position: debrisField.position,
|
||||
resources: recycleResult.remainingDebris,
|
||||
createdAt: debrisField.createdAt,
|
||||
expiresAt: debrisField.expiresAt
|
||||
}
|
||||
} else {
|
||||
// 残骸场已被完全收集,删除
|
||||
delete universeStore.debrisFields[debrisId]
|
||||
}
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Destroy) {
|
||||
// 处理行星毁灭任务
|
||||
const destroyResult = fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player)
|
||||
|
||||
// 生成毁灭任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Destroy,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName: targetPlanet?.name,
|
||||
success: destroyResult?.success || false,
|
||||
message: destroyResult?.success ? t('missionReports.destroySuccess') : t('missionReports.destroyFailed'),
|
||||
details: destroyResult?.success
|
||||
? {
|
||||
destroyedPlanetName:
|
||||
targetPlanet?.name ||
|
||||
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
|
||||
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
||||
// 星球被摧毁
|
||||
// 从玩家星球列表中移除(如果是玩家的星球)
|
||||
const planetIndex = gameStore.player.planets.findIndex(p => p.id === destroyResult.planetId)
|
||||
if (planetIndex > -1) {
|
||||
gameStore.player.planets.splice(planetIndex, 1)
|
||||
} else {
|
||||
// 不是玩家星球,从宇宙地图中移除
|
||||
delete universeStore.planets[targetKey]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任务返回
|
||||
*/
|
||||
const processMissionReturn = (mission: FleetMission) => {
|
||||
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
||||
if (!originPlanet) return
|
||||
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
||||
resourceLogic.addResources(originPlanet.resources, mission.cargo)
|
||||
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||
}
|
||||
|
||||
return {
|
||||
processMissionArrival,
|
||||
processMissionReturn
|
||||
}
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import { useNPCStore } from '@/stores/npcStore'
|
||||
import type { NPC, FleetMission, IncomingFleetAlert } from '@/types/game'
|
||||
import { MissionType } from '@/types/game'
|
||||
import * as gameLogic from '@/logic/gameLogic'
|
||||
import * as fleetLogic from '@/logic/fleetLogic'
|
||||
import * as shipLogic from '@/logic/shipLogic'
|
||||
import * as npcGrowthLogic from '@/logic/npcGrowthLogic'
|
||||
import * as npcBehaviorLogic from '@/logic/npcBehaviorLogic'
|
||||
|
||||
/**
|
||||
* NPC处理
|
||||
* 处理NPC舰队任务、成长系统、行为系统
|
||||
*/
|
||||
export const useNPCHandler = () => {
|
||||
const gameStore = useGameStore()
|
||||
const universeStore = useUniverseStore()
|
||||
const npcStore = useNPCStore()
|
||||
|
||||
/**
|
||||
* 移除即将到来的舰队警告
|
||||
*/
|
||||
const removeIncomingFleetAlert = (alert: IncomingFleetAlert) => {
|
||||
if (!gameStore.player.incomingFleetAlerts) return
|
||||
const index = gameStore.player.incomingFleetAlerts.indexOf(alert)
|
||||
if (index > -1) {
|
||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务ID移除即将到来的舰队警告
|
||||
*/
|
||||
const removeIncomingFleetAlertById = (missionId: string) => {
|
||||
if (!gameStore.player.incomingFleetAlerts) return
|
||||
const index = gameStore.player.incomingFleetAlerts.findIndex(a => a.id === missionId)
|
||||
if (index > -1) {
|
||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC任务到达
|
||||
*/
|
||||
const processNPCMissionArrival = (npc: NPC, mission: FleetMission) => {
|
||||
if (mission.missionType === MissionType.Recycle) {
|
||||
// NPC回收任务到达
|
||||
const debrisId = mission.debrisFieldId
|
||||
if (!debrisId) {
|
||||
console.warn('[NPC Mission] Recycle mission missing debrisFieldId')
|
||||
mission.status = 'returning'
|
||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||
return
|
||||
}
|
||||
|
||||
const debrisField = universeStore.debrisFields[debrisId]
|
||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||
|
||||
if (recycleResult && debrisField) {
|
||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||
// 更新残骸场
|
||||
universeStore.debrisFields[debrisId] = {
|
||||
id: debrisField.id,
|
||||
position: debrisField.position,
|
||||
resources: recycleResult.remainingDebris,
|
||||
createdAt: debrisField.createdAt
|
||||
}
|
||||
} else {
|
||||
// 残骸已被完全回收,从宇宙中删除
|
||||
delete universeStore.debrisFields[debrisId]
|
||||
}
|
||||
}
|
||||
|
||||
// 移除即将到来的警告(回收任务已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
|
||||
// 设置返回时间
|
||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||
return
|
||||
}
|
||||
|
||||
// 找到目标星球
|
||||
const targetKey = gameLogic.generatePositionKey(
|
||||
mission.targetPosition.galaxy,
|
||||
mission.targetPosition.system,
|
||||
mission.targetPosition.position
|
||||
)
|
||||
const targetPlanet =
|
||||
gameStore.player.planets.find(
|
||||
p =>
|
||||
p.position.galaxy === mission.targetPosition.galaxy &&
|
||||
p.position.system === mission.targetPosition.system &&
|
||||
p.position.position === mission.targetPosition.position
|
||||
) || universeStore.planets[targetKey]
|
||||
|
||||
if (!targetPlanet) {
|
||||
console.warn('[NPC Mission] Target planet not found')
|
||||
return
|
||||
}
|
||||
|
||||
if (mission.missionType === MissionType.Spy) {
|
||||
// NPC侦查到达
|
||||
const { spiedNotification, spyReport } = npcBehaviorLogic.processNPCSpyArrival(npc, mission, targetPlanet, gameStore.player)
|
||||
|
||||
// 保存侦查报告到NPC(用于后续攻击决策)
|
||||
if (!npc.playerSpyReports) {
|
||||
npc.playerSpyReports = {}
|
||||
}
|
||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||
|
||||
// 添加被侦查通知给玩家
|
||||
if (!gameStore.player.spiedNotifications) {
|
||||
gameStore.player.spiedNotifications = []
|
||||
}
|
||||
gameStore.player.spiedNotifications.push(spiedNotification)
|
||||
|
||||
// 移除即将到来的警告(侦查已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
} else if (mission.missionType === MissionType.Attack) {
|
||||
// NPC攻击到达 - 使用专门的NPC攻击处理逻辑
|
||||
fleetLogic.processNPCAttackArrival(npc, mission, targetPlanet, gameStore.player, gameStore.player.planets).then(attackResult => {
|
||||
if (attackResult) {
|
||||
// 添加战斗报告给玩家
|
||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||
|
||||
// 如果生成月球,添加到玩家星球列表
|
||||
if (attackResult.moon) {
|
||||
gameStore.player.planets.push(attackResult.moon)
|
||||
}
|
||||
|
||||
// 如果生成残骸场,添加到宇宙残骸场列表
|
||||
if (attackResult.debrisField) {
|
||||
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
||||
}
|
||||
}
|
||||
|
||||
// 移除即将到来的警告(攻击已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC任务返回
|
||||
*/
|
||||
const processNPCMissionReturn = (npc: NPC, mission: FleetMission) => {
|
||||
// 找到NPC的起始星球
|
||||
const originPlanet = npc.planets.find(p => p.id === mission.originPlanetId)
|
||||
if (!originPlanet) return
|
||||
|
||||
// 返还舰队
|
||||
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
||||
|
||||
// 如果携带掠夺资源,给NPC添加资源
|
||||
if (mission.cargo) {
|
||||
originPlanet.resources.metal += mission.cargo.metal
|
||||
originPlanet.resources.crystal += mission.cargo.crystal
|
||||
originPlanet.resources.deuterium += mission.cargo.deuterium
|
||||
}
|
||||
|
||||
// 从NPC任务列表中移除
|
||||
if (npc.fleetMissions) {
|
||||
const missionIndex = npc.fleetMissions.indexOf(mission)
|
||||
if (missionIndex > -1) {
|
||||
npc.fleetMissions.splice(missionIndex, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NPC成长系统更新
|
||||
let npcUpdateCounter = 0
|
||||
const NPC_UPDATE_INTERVAL = 10
|
||||
|
||||
/**
|
||||
* 更新NPC成长系统
|
||||
*/
|
||||
const updateNPCGrowth = (deltaSeconds: number) => {
|
||||
// 累积时间
|
||||
npcUpdateCounter += deltaSeconds
|
||||
|
||||
// 只在达到更新间隔时才执行
|
||||
if (npcUpdateCounter < NPC_UPDATE_INTERVAL) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取所有星球
|
||||
const allPlanets = Object.values(universeStore.planets)
|
||||
|
||||
// 如果NPC store为空,从星球数据中初始化NPC
|
||||
if (npcStore.npcs.length === 0) {
|
||||
const npcMap = new Map<string, any>()
|
||||
|
||||
allPlanets.forEach(planet => {
|
||||
// 跳过玩家的星球
|
||||
if (planet.ownerId === gameStore.player.id || !planet.ownerId) return
|
||||
|
||||
// 这是NPC的星球
|
||||
if (!npcMap.has(planet.ownerId)) {
|
||||
npcMap.set(planet.ownerId, {
|
||||
id: planet.ownerId,
|
||||
name: `NPC-${planet.ownerId.substring(0, 8)}`,
|
||||
planets: [],
|
||||
technologies: {},
|
||||
difficulty: 'medium' as const,
|
||||
relations: {},
|
||||
allies: [],
|
||||
enemies: []
|
||||
})
|
||||
}
|
||||
|
||||
npcMap.get(planet.ownerId)!.planets.push(planet)
|
||||
})
|
||||
|
||||
// 保存到store
|
||||
npcStore.npcs = Array.from(npcMap.values())
|
||||
|
||||
// 如果有NPC,基于玩家实力初始化NPC
|
||||
if (npcStore.npcs.length > 0) {
|
||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||
planets: allPlanets,
|
||||
player: gameStore.player,
|
||||
npcs: npcStore.npcs
|
||||
}
|
||||
|
||||
const playerPower = npcGrowthLogic.calculatePlayerAveragePower(gameState)
|
||||
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcGrowthLogic.initializeNPCStartingPower(npc, playerPower)
|
||||
})
|
||||
|
||||
// 初始化NPC之间的外交关系(盟友/敌人)
|
||||
npcGrowthLogic.initializeNPCDiplomacy(npcStore.npcs)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有NPC,直接返回
|
||||
if (npcStore.npcs.length === 0) {
|
||||
npcUpdateCounter = 0
|
||||
return
|
||||
}
|
||||
|
||||
// 构建游戏状态
|
||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||
planets: allPlanets,
|
||||
player: gameStore.player,
|
||||
npcs: npcStore.npcs
|
||||
}
|
||||
|
||||
// 使用累积的时间更新每个NPC
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcGrowthLogic.updateNPCGrowth(npc, gameState, npcUpdateCounter)
|
||||
})
|
||||
|
||||
// 重置计数器
|
||||
npcUpdateCounter = 0
|
||||
}
|
||||
|
||||
// NPC行为系统更新
|
||||
let npcBehaviorCounter = 0
|
||||
const NPC_BEHAVIOR_INTERVAL = 5
|
||||
|
||||
/**
|
||||
* 更新NPC行为系统
|
||||
*/
|
||||
const updateNPCBehavior = (deltaSeconds: number) => {
|
||||
// 累积时间
|
||||
npcBehaviorCounter += deltaSeconds
|
||||
|
||||
// 只在达到更新间隔时才执行
|
||||
if (npcBehaviorCounter < NPC_BEHAVIOR_INTERVAL) {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果没有NPC,直接返回
|
||||
if (npcStore.npcs.length === 0) {
|
||||
npcBehaviorCounter = 0
|
||||
return
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const allPlanets = Object.values(universeStore.planets)
|
||||
|
||||
// 更新每个NPC的行为
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcBehaviorLogic.updateNPCBehavior(npc, gameStore.player, allPlanets, universeStore.debrisFields, now)
|
||||
})
|
||||
|
||||
npcBehaviorCounter = 0
|
||||
}
|
||||
|
||||
return {
|
||||
processNPCMissionArrival,
|
||||
processNPCMissionReturn,
|
||||
removeIncomingFleetAlert,
|
||||
removeIncomingFleetAlertById,
|
||||
updateNPCGrowth,
|
||||
updateNPCBehavior
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
import type { Ref } from 'vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import type { BuildQueueItem } from '@/types/game'
|
||||
import * as buildingValidation from '@/logic/buildingValidation'
|
||||
import * as resourceLogic from '@/logic/resourceLogic'
|
||||
import * as researchValidation from '@/logic/researchValidation'
|
||||
|
||||
/**
|
||||
* 队列处理
|
||||
* 处理建造队列和研究队列的取消操作
|
||||
*/
|
||||
export const useQueueHandler = (
|
||||
t: (key: string) => string,
|
||||
confirmDialogOpen: Ref<boolean>,
|
||||
confirmDialogTitle: Ref<string>,
|
||||
confirmDialogMessage: Ref<string>,
|
||||
confirmDialogAction: Ref<(() => void) | null>
|
||||
) => {
|
||||
const gameStore = useGameStore()
|
||||
|
||||
/**
|
||||
* 取消建造
|
||||
*/
|
||||
const handleCancelBuild = (queueId: string) => {
|
||||
confirmDialogTitle.value = t('queue.cancelBuild')
|
||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||
confirmDialogAction.value = () => {
|
||||
if (!gameStore.currentPlanet) return false
|
||||
const { item, index } = buildingValidation.findQueueItem(gameStore.currentPlanet.buildQueue, queueId)
|
||||
if (!item) return false
|
||||
if (item.type === 'building') {
|
||||
const refund = buildingValidation.cancelBuildingUpgrade(gameStore.currentPlanet, item)
|
||||
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
||||
}
|
||||
gameStore.currentPlanet.buildQueue.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
confirmDialogOpen.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消研究
|
||||
*/
|
||||
const handleCancelResearch = (queueId: string) => {
|
||||
confirmDialogTitle.value = t('queue.cancelResearch')
|
||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||
confirmDialogAction.value = () => {
|
||||
if (!gameStore.currentPlanet) return false
|
||||
const { item, index } = buildingValidation.findQueueItem(gameStore.player.researchQueue, queueId)
|
||||
if (!item) return false
|
||||
if (item.type === 'technology') {
|
||||
const refund = researchValidation.cancelTechnologyResearch(item)
|
||||
resourceLogic.addResources(gameStore.currentPlanet.resources, refund)
|
||||
}
|
||||
gameStore.player.researchQueue.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
confirmDialogOpen.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列项名称
|
||||
*/
|
||||
const getItemName = (item: BuildQueueItem): string => {
|
||||
if (item.type === 'building' || item.type === 'demolish') {
|
||||
const buildingName = t(`buildings.${item.itemType}`)
|
||||
return item.type === 'demolish' ? `${t('buildingsView.demolish')} - ${buildingName}` : buildingName
|
||||
} else if (item.type === 'technology') {
|
||||
return t(`technologies.${item.itemType}`)
|
||||
} else if (item.type === 'ship') {
|
||||
return t(`ships.${item.itemType}`)
|
||||
} else if (item.type === 'defense') {
|
||||
return t(`defenses.${item.itemType}`)
|
||||
}
|
||||
return t('common.unknown')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取剩余时间(秒)
|
||||
*/
|
||||
const getRemainingTime = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
return Math.max(0, Math.floor((item.endTime - now) / 1000))
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列进度(百分比)
|
||||
*/
|
||||
const getQueueProgress = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
const total = item.endTime - item.startTime
|
||||
const elapsed = now - item.startTime
|
||||
return Math.min(100, Math.max(0, (elapsed / total) * 100))
|
||||
}
|
||||
|
||||
return {
|
||||
handleCancelBuild,
|
||||
handleCancelResearch,
|
||||
getItemName,
|
||||
getRemainingTime,
|
||||
getQueueProgress
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user